lyskom-server-2.1.2/0000777000015100472110000000000007723710421010102 5lyskom-server-2.1.2/scripts/0000777000015100472110000000000007723710255011576 5lyskom-server-2.1.2/scripts/common.make0000664000015100472110000000177707717413232013655 # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # RM = rm -f dbdir = $(localstatedir)/lyskomd/db exportdir = $(localstatedir)/lyskomd/exportdb lyskom-server-2.1.2/scripts/Makefile.am0000664000015100472110000000223407721716116013551 # $Id: Makefile.am,v 1.9 2003/08/23 16:38:21 ceder Exp $ # Copyright (C) 1998, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # include $(top_srcdir)/scripts/common.make EXTRA_DIST = .cvsignore $(noinst_SCRIPTS) \ xenofarm.sh warnings.sed noinst_SCRIPTS = unprefix definepath lyskomd-copyrights update-copyright lyskom-server-2.1.2/scripts/Makefile.in0000664000015100472110000002257407723707422013575 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # $Id: Makefile.am,v 1.9 2003/08/23 16:38:21 ceder Exp $ # Copyright (C) 1998, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEBUG_CALLS = @DEBUG_CALLS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EFENCE = @EFENCE@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FLEX = @FLEX@ HAVE_PYTHON_FALSE = @HAVE_PYTHON_FALSE@ HAVE_PYTHON_TRUE = @HAVE_PYTHON_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSURE = @INSURE@ LANGUAGE_SUFFIX = @LANGUAGE_SUFFIX@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ SED = @SED@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRACED_ALLOCATIONS = @TRACED_ALLOCATIONS@ U = @U@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ YACC = @YACC@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ RM = rm -f dbdir = $(localstatedir)/lyskomd/db exportdir = $(localstatedir)/lyskomd/exportdb EXTRA_DIST = .cvsignore $(noinst_SCRIPTS) \ xenofarm.sh warnings.sed noinst_SCRIPTS = unprefix definepath lyskomd-copyrights update-copyright subdir = scripts ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = SCRIPTS = $(noinst_SCRIPTS) DIST_SOURCES = DIST_COMMON = $(top_srcdir)/scripts/common.make Makefile.am Makefile.in \ depcomp install-sh mdate-sh missing mkinstalldirs texinfo.tex all: all-am .SUFFIXES: $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/scripts/common.make $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu scripts/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) uninstall-info-am: tags: TAGS TAGS: ctags: CTAGS CTAGS: DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = .. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) $(mkinstalldirs) $(distdir)/../scripts @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(SCRIPTS) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am info info-am install \ install-am install-data install-data-am install-exec \ install-exec-am install-info install-info-am install-man \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \ uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/scripts/depcomp0000755000015100000310000003256107716517055013070 #! /bin/sh # depcomp - compile a program generating dependencies as side-effects # Copyright 1999, 2000 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # `libtool' can also be set to `yes' or `no'. if test -z "$depfile"; then base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'` dir=`echo "$object" | sed 's,/.*$,/,'` if test "$dir" = "$object"; then dir= fi # FIXME: should be _deps on DOS. depfile="$dir.deps/$base" fi tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> $depfile echo >> $depfile # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> $depfile else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. This file always lives in the current directory. # Also, the AIX compiler puts `$object:' at the start of each line; # $object doesn't have directory information. stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'` tmpdepfile="$stripped.u" outname="$stripped.o" if test "$libtool" = yes; then "$@" -Wc,-M else "$@" -M fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi if test -f "$tmpdepfile"; then # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; icc) # Intel's C compiler understands `-MD -MF file'. However on # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c # ICC 7.0 will fill foo.d with something like # foo.o: sub/foo.c # foo.o: sub/foo.h # which is wrong. We want: # sub/foo.o: sub/foo.c # sub/foo.o: sub/foo.h # sub/foo.c: # sub/foo.h: # ICC 7.1 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using \ : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1="$dir.libs/$base.lo.d" tmpdepfile2="$dir.libs/$base.d" "$@" -Wc,-MD else tmpdepfile1="$dir$base.o.d" tmpdepfile2="$dir$base.d" "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi if test -f "$tmpdepfile1"; then tmpdepfile="$tmpdepfile1" else tmpdepfile="$tmpdepfile2" fi if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a space and a tab in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for `:' # in the target name. This is to cope with DOS-style filenames: # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. "$@" $dashmflag | sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # X makedepend shift cleared=no for arg in "$@"; do case $cleared in no) set ""; shift cleared=yes ;; esac case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix="`echo $object | sed 's/^.*\././'`" touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E | sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. "$@" || exit $? IFS=" " for arg do case "$arg" in "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 lyskom-server-2.1.2/scripts/install-sh0000755000015100000310000001572207716517054013516 #!/bin/sh # # install - install a program, script, or datafile # # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd=$cpprog shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd=$stripprog shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "$0: no input file specified" >&2 exit 1 else : fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d "$dst" ]; then instcmd=: chmodcmd="" else instcmd=$mkdirprog fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f "$src" ] || [ -d "$src" ] then : else echo "$0: $src does not exist" >&2 exit 1 fi if [ x"$dst" = x ] then echo "$0: no destination specified" >&2 exit 1 else : fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d "$dst" ] then dst=$dst/`basename "$src"` else : fi fi ## this sed command emulates the dirname command dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-$defaultIFS}" oIFS=$IFS # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` IFS=$oIFS pathcomp='' while [ $# -ne 0 ] ; do pathcomp=$pathcomp$1 shift if [ ! -d "$pathcomp" ] ; then $mkdirprog "$pathcomp" else : fi pathcomp=$pathcomp/ done fi if [ x"$dir_arg" != x ] then $doit $instcmd "$dst" && if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename "$dst"` else dstfile=`basename "$dst" $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename "$dst"` else : fi # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up temp files at exit. trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 trap '(exit $?); exit' 1 2 13 15 # Move or copy the file name to the temp name $doit $instcmd "$src" "$dsttmp" && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && # Now remove or move aside any old file at destination location. We try this # two ways since rm can't unlink itself on some systems and the destination # file might be busy for other reasons. In this case, the final cleanup # might fail but the new file should still install successfully. { if [ -f "$dstdir/$dstfile" ] then $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || { echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 (exit 1); exit } else : fi } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" fi && # The final little trick to "correctly" pass the exit status to the exit trap. { (exit 0); exit } lyskom-server-2.1.2/scripts/mdate-sh0000755000015100000310000001013007716517054013126 #!/bin/sh # Get modification time of a file or directory and pretty-print it. # Copyright (C) 1995, 1996, 1997, 2003 Free Software Foundation, Inc. # written by Ulrich Drepper , June 1995 # # 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 2, 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, write to the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Prevent date giving response in another language. LANG=C export LANG LC_ALL=C export LC_ALL LC_TIME=C export LC_TIME save_arg1="$1" # Find out how to get the extended ls output of a file or directory. if ls -L /dev/null 1>/dev/null 2>&1; then ls_command='ls -L -l -d' else ls_command='ls -l -d' fi # A `ls -l' line looks as follows on OS/2. # drwxrwx--- 0 Aug 11 2001 foo # This differs from Unix, which adds ownership information. # drwxrwx--- 2 root root 4096 Aug 11 2001 foo # # To find the date, we split the line on spaces and iterate on words # until we find a month. This cannot work with files whose owner is a # user named `Jan', or `Feb', etc. However, it's unlikely that `/' # will be owned by a user whose name is a month. So we first look at # the extended ls output of the root directory to decide how many # words should be skipped to get the date. # On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below. set - x`$ls_command /` # Find which argument is the month. month= command= until test $month do shift # Add another shift to the command. command="$command shift;" case $1 in Jan) month=January; nummonth=1;; Feb) month=February; nummonth=2;; Mar) month=March; nummonth=3;; Apr) month=April; nummonth=4;; May) month=May; nummonth=5;; Jun) month=June; nummonth=6;; Jul) month=July; nummonth=7;; Aug) month=August; nummonth=8;; Sep) month=September; nummonth=9;; Oct) month=October; nummonth=10;; Nov) month=November; nummonth=11;; Dec) month=December; nummonth=12;; esac done # Get the extended ls output of the file or directory. set - x`eval "$ls_command \"\$save_arg1\""` # Remove all preceding arguments eval $command # Get the month. Next argument is day, followed by the year or time. case $1 in Jan) month=January; nummonth=1;; Feb) month=February; nummonth=2;; Mar) month=March; nummonth=3;; Apr) month=April; nummonth=4;; May) month=May; nummonth=5;; Jun) month=June; nummonth=6;; Jul) month=July; nummonth=7;; Aug) month=August; nummonth=8;; Sep) month=September; nummonth=9;; Oct) month=October; nummonth=10;; Nov) month=November; nummonth=11;; Dec) month=December; nummonth=12;; esac day=$2 # Here we have to deal with the problem that the ls output gives either # the time of day or the year. case $3 in *:*) set `date`; eval year=\$$# case $2 in Jan) nummonthtod=1;; Feb) nummonthtod=2;; Mar) nummonthtod=3;; Apr) nummonthtod=4;; May) nummonthtod=5;; Jun) nummonthtod=6;; Jul) nummonthtod=7;; Aug) nummonthtod=8;; Sep) nummonthtod=9;; Oct) nummonthtod=10;; Nov) nummonthtod=11;; Dec) nummonthtod=12;; esac # For the first six month of the year the time notation can also # be used for files modified in the last year. if (expr $nummonth \> $nummonthtod) > /dev/null; then year=`expr $year - 1` fi;; *) year=$3;; esac # The result. echo $day $month $year lyskom-server-2.1.2/scripts/missing0000755000015100000310000002403607716517055013110 #! /bin/sh # Common stub for a few missing GNU programs while installing. # Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi case "$1" in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case "$1" in -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch]" ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing 0.4 - GNU automake" ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; aclocal*) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case "$f" in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. You can get \`$1Help2man' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.h fi ;; esac fi if [ ! -f y.tab.h ]; then echo >y.tab.h fi if [ ! -f y.tab.c ]; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if [ ! -f lex.yy.c ]; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` fi if [ -f "$file" ]; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then # We have makeinfo, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` fi touch $file ;; tar) shift if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 fi # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case "$firstarg" in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case "$firstarg" in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequirements for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 lyskom-server-2.1.2/scripts/mkinstalldirs0000755000015100000310000000370407716517055014316 #! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain errstatus=0 dirmode="" usage="\ Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." # process command line arguments while test $# -gt 0 ; do case $1 in -h | --help | --h*) # -h for help echo "$usage" 1>&2 exit 0 ;; -m) # -m PERM arg shift test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } dirmode=$1 shift ;; --) # stop option processing shift break ;; -*) # unknown option echo "$usage" 1>&2 exit 1 ;; *) # first non-opt arg break ;; esac done for file do if test -d "$file"; then shift else break fi done case $# in 0) exit 0 ;; esac case $dirmode in '') if mkdir -p -- . 2>/dev/null; then echo "mkdir -p -- $*" exec mkdir -p -- "$@" fi ;; *) if mkdir -m "$dirmode" -p -- . 2>/dev/null; then echo "mkdir -m $dirmode -p -- $*" exec mkdir -m "$dirmode" -p -- "$@" fi ;; esac for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case $pathcomp in -*) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr else if test ! -z "$dirmode"; then echo "chmod $dirmode $pathcomp" lasterr="" chmod "$dirmode" "$pathcomp" || lasterr=$? if test ! -z "$lasterr"; then errstatus=$lasterr fi fi fi fi pathcomp="$pathcomp/" done done exit $errstatus # Local Variables: # mode: shell-script # sh-indentation: 2 # End: # mkinstalldirs ends here lyskom-server-2.1.2/scripts/texinfo.tex0000644000015100000310000066176607716517054013727 % texinfo.tex -- TeX macros to handle Texinfo files. % % Load plain if necessary, i.e., if running under initex. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % \def\texinfoversion{2003-05-04.08} % % Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, % 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. % % This texinfo.tex file 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 2, or (at % your option) any later version. % % This texinfo.tex file 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 texinfo.tex file; see the file COPYING. If not, write % to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, % Boston, MA 02111-1307, USA. % % In other words, you are welcome to use, share and improve this program. % You are forbidden to forbid anyone else to use, share and improve % what you give them. Help stamp out software-hoarding! % % Please try the latest version of texinfo.tex before submitting bug % reports; you can get the latest version from: % ftp://ftp.gnu.org/gnu/texinfo/texinfo.tex % (and all GNU mirrors, see http://www.gnu.org/order/ftp.html) % ftp://tug.org/tex/texinfo.tex % (and all CTAN mirrors, see http://www.ctan.org), % and /home/gd/gnu/doc/texinfo.tex on the GNU machines. % % The GNU Texinfo home page is http://www.gnu.org/software/texinfo. % % The texinfo.tex in any given Texinfo distribution could well be out % of date, so if that's what you're using, please check. % % Send bug reports to bug-texinfo@gnu.org. Please include including a % complete document in each bug report with which we can reproduce the % problem. Patches are, of course, greatly appreciated. % % To process a Texinfo manual with TeX, it's most reliable to use the % texi2dvi shell script that comes with the distribution. For a simple % manual foo.texi, however, you can get away with this: % tex foo.texi % texindex foo.?? % tex foo.texi % tex foo.texi % dvips foo.dvi -o # or whatever; this makes foo.ps. % The extra TeX runs get the cross-reference information correct. % Sometimes one run after texindex suffices, and sometimes you need more % than two; texi2dvi does it as many times as necessary. % % It is possible to adapt texinfo.tex for other languages, to some % extent. You can get the existing language-specific files from the % full Texinfo distribution. \message{Loading texinfo [version \texinfoversion]:} % If in a .fmt file, print the version number % and turn on active characters that we couldn't do earlier because % they might have appeared in the input file name. \everyjob{\message{[Texinfo version \texinfoversion]}% \catcode`+=\active \catcode`\_=\active} \message{Basics,} \chardef\other=12 % We never want plain's \outer definition of \+ in Texinfo. % For @tex, we can use \tabalign. \let\+ = \relax % Save some plain tex macros whose names we will redefine. \let\ptexb=\b \let\ptexbullet=\bullet \let\ptexc=\c \let\ptexcomma=\, \let\ptexdot=\. \let\ptexdots=\dots \let\ptexend=\end \let\ptexequiv=\equiv \let\ptexexclam=\! \let\ptexgtr=> \let\ptexhat=^ \let\ptexi=\i \let\ptexindent=\indent \let\ptexlbrace=\{ \let\ptexless=< \let\ptexplus=+ \let\ptexrbrace=\} \let\ptexslash=\/ \let\ptexstar=\* \let\ptext=\t % If this character appears in an error message or help string, it % starts a new line in the output. \newlinechar = `^^J % Set up fixed words for English if not already set. \ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi \ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi \ifx\putwordfile\undefined \gdef\putwordfile{file}\fi \ifx\putwordin\undefined \gdef\putwordin{in}\fi \ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi \ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi \ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi \ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi \ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi \ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi \ifx\putwordof\undefined \gdef\putwordof{of}\fi \ifx\putwordon\undefined \gdef\putwordon{on}\fi \ifx\putwordpage\undefined \gdef\putwordpage{page}\fi \ifx\putwordsection\undefined \gdef\putwordsection{section}\fi \ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi \ifx\putwordsee\undefined \gdef\putwordsee{see}\fi \ifx\putwordSee\undefined \gdef\putwordSee{See}\fi \ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi \ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi % \ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi \ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi \ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi \ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi \ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi \ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi \ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi \ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi \ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi \ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi \ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi \ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi % \ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi \ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi \ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi \ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi \ifx\putwordDeftypevar\undefined\gdef\putwordDeftypevar{Variable}\fi \ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi \ifx\putwordDeftypefun\undefined\gdef\putwordDeftypefun{Function}\fi % In some macros, we cannot use the `\? notation---the left quote is % in some cases the escape char. \chardef\colonChar = `\: \chardef\commaChar = `\, \chardef\dotChar = `\. \chardef\equalChar = `\= \chardef\exclamChar= `\! \chardef\questChar = `\? \chardef\semiChar = `\; \chardef\spaceChar = `\ % \chardef\underChar = `\_ % Ignore a token. % \def\gobble#1{} % True if #1 is the empty string, i.e., called like `\ifempty{}'. % \def\ifempty#1{\ifemptyx #1\emptymarkA\emptymarkB}% \def\ifemptyx#1#2\emptymarkB{\ifx #1\emptymarkA}% % Hyphenation fixes. \hyphenation{ap-pen-dix} \hyphenation{eshell} \hyphenation{mini-buf-fer mini-buf-fers} \hyphenation{time-stamp} \hyphenation{white-space} % Margin to add to right of even pages, to left of odd pages. \newdimen\bindingoffset \newdimen\normaloffset \newdimen\pagewidth \newdimen\pageheight % Sometimes it is convenient to have everything in the transcript file % and nothing on the terminal. We don't just call \tracingall here, % since that produces some useless output on the terminal. We also make % some effort to order the tracing commands to reduce output in the log % file; cf. trace.sty in LaTeX. % \def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% \def\loggingall{% \tracingstats2 \tracingpages1 \tracinglostchars2 % 2 gives us more in etex \tracingparagraphs1 \tracingoutput1 \tracingmacros2 \tracingrestores1 \showboxbreadth\maxdimen \showboxdepth\maxdimen \ifx\eTeXversion\undefined\else % etex gives us more logging \tracingscantokens1 \tracingifs1 \tracinggroups1 \tracingnesting2 \tracingassigns1 \fi \tracingcommands3 % 3 gives us more in etex \errorcontextlines\maxdimen }% % add check for \lastpenalty to plain's definitions. If the last thing % we did was a \nobreak, we don't want to insert more space. % \def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount \removelastskip\penalty-50\smallskip\fi\fi} \def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount \removelastskip\penalty-100\medskip\fi\fi} \def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount \removelastskip\penalty-200\bigskip\fi\fi} % For @cropmarks command. % Do @cropmarks to get crop marks. % \newif\ifcropmarks \let\cropmarks = \cropmarkstrue % % Dimensions to add cropmarks at corners. % Added by P. A. MacKay, 12 Nov. 1986 % \newdimen\outerhsize \newdimen\outervsize % set by the paper size routines \newdimen\cornerlong \cornerlong=1pc \newdimen\cornerthick \cornerthick=.3pt \newdimen\topandbottommargin \topandbottommargin=.75in % Main output routine. \chardef\PAGE = 255 \output = {\onepageout{\pagecontents\PAGE}} \newbox\headlinebox \newbox\footlinebox % \onepageout takes a vbox as an argument. Note that \pagecontents % does insertions, but you have to call it yourself. \def\onepageout#1{% \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi % \ifodd\pageno \advance\hoffset by \bindingoffset \else \advance\hoffset by -\bindingoffset\fi % % Do this outside of the \shipout so @code etc. will be expanded in % the headline as they should be, not taken literally (outputting ''code). \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}% % {% % Have to do this stuff outside the \shipout because we want it to % take effect in \write's, yet the group defined by the \vbox ends % before the \shipout runs. % \escapechar = `\\ % use backslash in output files. \indexdummies % don't expand commands in the output. \normalturnoffactive % \ in index entries must not stay \, e.g., if % the page break happens to be in the middle of an example. \shipout\vbox{% % Do this early so pdf references go to the beginning of the page. \ifpdfmakepagedest \pdfmkdest{\the\pageno} \fi % \ifcropmarks \vbox to \outervsize\bgroup \hsize = \outerhsize \vskip-\topandbottommargin \vtop to0pt{% \line{\ewtop\hfil\ewtop}% \nointerlineskip \line{% \vbox{\moveleft\cornerthick\nstop}% \hfill \vbox{\moveright\cornerthick\nstop}% }% \vss}% \vskip\topandbottommargin \line\bgroup \hfil % center the page within the outer (page) hsize. \ifodd\pageno\hskip\bindingoffset\fi \vbox\bgroup \fi % \unvbox\headlinebox \pagebody{#1}% \ifdim\ht\footlinebox > 0pt % Only leave this space if the footline is nonempty. % (We lessened \vsize for it in \oddfootingxxx.) % The \baselineskip=24pt in plain's \makefootline has no effect. \vskip 2\baselineskip \unvbox\footlinebox \fi % \ifcropmarks \egroup % end of \vbox\bgroup \hfil\egroup % end of (centering) \line\bgroup \vskip\topandbottommargin plus1fill minus1fill \boxmaxdepth = \cornerthick \vbox to0pt{\vss \line{% \vbox{\moveleft\cornerthick\nsbot}% \hfill \vbox{\moveright\cornerthick\nsbot}% }% \nointerlineskip \line{\ewbot\hfil\ewbot}% }% \egroup % \vbox from first cropmarks clause \fi }% end of \shipout\vbox }% end of group with \normalturnoffactive \advancepageno \ifnum\outputpenalty>-20000 \else\dosupereject\fi } \newinsert\margin \dimen\margin=\maxdimen \def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} {\catcode`\@ =11 \gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi % marginal hacks, juha@viisa.uucp (Juha Takala) \ifvoid\margin\else % marginal info is present \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi \dimen@=\dp#1 \unvbox#1 \ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi \ifr@ggedbottom \kern-\dimen@ \vfil \fi} } % Here are the rules for the cropmarks. Note that they are % offset so that the space between them is truly \outerhsize or \outervsize % (P. A. MacKay, 12 November, 1986) % \def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} \def\nstop{\vbox {\hrule height\cornerthick depth\cornerlong width\cornerthick}} \def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} \def\nsbot{\vbox {\hrule height\cornerlong depth\cornerthick width\cornerthick}} % Parse an argument, then pass it to #1. The argument is the rest of % the input line (except we remove a trailing comment). #1 should be a % macro which expects an ordinary undelimited TeX argument. % \def\parsearg#1{% \let\next = #1% \begingroup \obeylines \futurelet\temp\parseargx } % If the next token is an obeyed space (from an @example environment or % the like), remove it and recurse. Otherwise, we're done. \def\parseargx{% % \obeyedspace is defined far below, after the definition of \sepspaces. \ifx\obeyedspace\temp \expandafter\parseargdiscardspace \else \expandafter\parseargline \fi } % Remove a single space (as the delimiter token to the macro call). {\obeyspaces % \gdef\parseargdiscardspace {\futurelet\temp\parseargx}} {\obeylines % \gdef\parseargline#1^^M{% \endgroup % End of the group started in \parsearg. % % First remove any @c comment, then any @comment. % Result of each macro is put in \toks0. \argremovec #1\c\relax % \expandafter\argremovecomment \the\toks0 \comment\relax % % % Call the caller's macro, saved as \next in \parsearg. \expandafter\next\expandafter{\the\toks0}% }% } % Since all \c{,omment} does is throw away the argument, we can let TeX % do that for us. The \relax here is matched by the \relax in the call % in \parseargline; it could be more or less anything, its purpose is % just to delimit the argument to the \c. \def\argremovec#1\c#2\relax{\toks0 = {#1}} \def\argremovecomment#1\comment#2\relax{\toks0 = {#1}} % \argremovec{,omment} might leave us with trailing spaces, though; e.g., % @end itemize @c foo % will have two active spaces as part of the argument with the % `itemize'. Here we remove all active spaces from #1, and assign the % result to \toks0. % % This loses if there are any *other* active characters besides spaces % in the argument -- _ ^ +, for example -- since they get expanded. % Fortunately, Texinfo does not define any such commands. (If it ever % does, the catcode of the characters in questionwill have to be changed % here.) But this means we cannot call \removeactivespaces as part of % \argremovec{,omment}, since @c uses \parsearg, and thus the argument % that \parsearg gets might well have any character at all in it. % \def\removeactivespaces#1{% \begingroup \ignoreactivespaces \edef\temp{#1}% \global\toks0 = \expandafter{\temp}% \endgroup } % Change the active space to expand to nothing. % \begingroup \obeyspaces \gdef\ignoreactivespaces{\obeyspaces\let =\empty} \endgroup \def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} %% These are used to keep @begin/@end levels from running away %% Call \inENV within environments (after a \begingroup) \newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi} \def\ENVcheck{% \ifENV\errmessage{Still within an environment; press RETURN to continue} \endgroup\fi} % This is not perfect, but it should reduce lossage % @begin foo is the same as @foo, for now. \newhelp\EMsimple{Press RETURN to continue.} \outer\def\begin{\parsearg\beginxxx} \def\beginxxx #1{% \expandafter\ifx\csname #1\endcsname\relax {\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else \csname #1\endcsname\fi} % @end foo executes the definition of \Efoo. % \def\end{\parsearg\endxxx} \def\endxxx #1{% \removeactivespaces{#1}% \edef\endthing{\the\toks0}% % \expandafter\ifx\csname E\endthing\endcsname\relax \expandafter\ifx\csname \endthing\endcsname\relax % There's no \foo, i.e., no ``environment'' foo. \errhelp = \EMsimple \errmessage{Undefined command `@end \endthing'}% \else \unmatchedenderror\endthing \fi \else % Everything's ok; the right environment has been started. \csname E\endthing\endcsname \fi } % There is an environment #1, but it hasn't been started. Give an error. % \def\unmatchedenderror#1{% \errhelp = \EMsimple \errmessage{This `@end #1' doesn't have a matching `@#1'}% } % Define the control sequence \E#1 to give an unmatched @end error. % \def\defineunmatchedend#1{% \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}% } %% Simple single-character @ commands % @@ prints an @ % Kludge this until the fonts are right (grr). \def\@{{\tt\char64}} % This is turned off because it was never documented % and you can use @w{...} around a quote to suppress ligatures. %% Define @` and @' to be the same as ` and ' %% but suppressing ligatures. %\def\`{{`}} %\def\'{{'}} % Used to generate quoted braces. \def\mylbrace {{\tt\char123}} \def\myrbrace {{\tt\char125}} \let\{=\mylbrace \let\}=\myrbrace \begingroup % Definitions to produce \{ and \} commands for indices, % and @{ and @} for the aux file. \catcode`\{ = \other \catcode`\} = \other \catcode`\[ = 1 \catcode`\] = 2 \catcode`\! = 0 \catcode`\\ = \other !gdef!lbracecmd[\{]% !gdef!rbracecmd[\}]% !gdef!lbraceatcmd[@{]% !gdef!rbraceatcmd[@}]% !endgroup % Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent % Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H. \let\, = \c \let\dotaccent = \. \def\ringaccent#1{{\accent23 #1}} \let\tieaccent = \t \let\ubaraccent = \b \let\udotaccent = \d % Other special characters: @questiondown @exclamdown % Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss. \def\questiondown{?`} \def\exclamdown{!`} % Dotless i and dotless j, used for accents. \def\imacro{i} \def\jmacro{j} \def\dotless#1{% \def\temp{#1}% \ifx\temp\imacro \ptexi \else\ifx\temp\jmacro \j \else \errmessage{@dotless can be used only with i or j}% \fi\fi } % Be sure we're in horizontal mode when doing a tie, since we make space % equivalent to this in @example-like environments. Otherwise, a space % at the beginning of a line will start with \penalty -- and % since \penalty is valid in vertical mode, we'd end up putting the % penalty on the vertical list instead of in the new paragraph. {\catcode`@ = 11 % Avoid using \@M directly, because that causes trouble % if the definition is written into an index file. \global\let\tiepenalty = \@M \gdef\tie{\leavevmode\penalty\tiepenalty\ } } % @: forces normal size whitespace following. \def\:{\spacefactor=1000 } % @* forces a line break. \def\*{\hfil\break\hbox{}\ignorespaces} % @/ allows a line break. \let\/=\allowbreak % @. is an end-of-sentence period. \def\.{.\spacefactor=3000 } % @! is an end-of-sentence bang. \def\!{!\spacefactor=3000 } % @? is an end-of-sentence query. \def\?{?\spacefactor=3000 } % @w prevents a word break. Without the \leavevmode, @w at the % beginning of a paragraph, when TeX is still in vertical mode, would % produce a whole line of output instead of starting the paragraph. \def\w#1{\leavevmode\hbox{#1}} % @group ... @end group forces ... to be all on one page, by enclosing % it in a TeX vbox. We use \vtop instead of \vbox to construct the box % to keep its height that of a normal line. According to the rules for % \topskip (p.114 of the TeXbook), the glue inserted is % max (\topskip - \ht (first item), 0). If that height is large, % therefore, no glue is inserted, and the space between the headline and % the text is small, which looks bad. % % Another complication is that the group might be very large. This can % cause the glue on the previous page to be unduly stretched, because it % does not have much material. In this case, it's better to add an % explicit \vfill so that the extra space is at the bottom. The % threshold for doing this is if the group is more than \vfilllimit % percent of a page (\vfilllimit can be changed inside of @tex). % \newbox\groupbox \def\vfilllimit{0.7} % \def\group{\begingroup \ifnum\catcode13=\active \else \errhelp = \groupinvalidhelp \errmessage{@group invalid in context where filling is enabled}% \fi % % The \vtop we start below produces a box with normal height and large % depth; thus, TeX puts \baselineskip glue before it, and (when the % next line of text is done) \lineskip glue after it. (See p.82 of % the TeXbook.) Thus, space below is not quite equal to space % above. But it's pretty close. \def\Egroup{% \egroup % End the \vtop. % \dimen0 is the vertical size of the group's box. \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox % \dimen2 is how much space is left on the page (more or less). \dimen2 = \pageheight \advance\dimen2 by -\pagetotal % if the group doesn't fit on the current page, and it's a big big % group, force a page break. \ifdim \dimen0 > \dimen2 \ifdim \pagetotal < \vfilllimit\pageheight \page \fi \fi \copy\groupbox \endgroup % End the \group. }% % \setbox\groupbox = \vtop\bgroup % We have to put a strut on the last line in case the @group is in % the midst of an example, rather than completely enclosing it. % Otherwise, the interline space between the last line of the group % and the first line afterwards is too small. But we can't put the % strut in \Egroup, since there it would be on a line by itself. % Hence this just inserts a strut at the beginning of each line. \everypar = {\strut}% % % Since we have a strut on every line, we don't need any of TeX's % normal interline spacing. \offinterlineskip % % OK, but now we have to do something about blank % lines in the input in @example-like environments, which normally % just turn into \lisppar, which will insert no space now that we've % turned off the interline space. Simplest is to make them be an % empty paragraph. \ifx\par\lisppar \edef\par{\leavevmode \par}% % % Reset ^^M's definition to new definition of \par. \obeylines \fi % % Do @comment since we are called inside an environment such as % @example, where each end-of-line in the input causes an % end-of-line in the output. We don't want the end-of-line after % the `@group' to put extra space in the output. Since @group % should appear on a line by itself (according to the Texinfo % manual), we don't worry about eating any user text. \comment } % % TeX puts in an \escapechar (i.e., `@') at the beginning of the help % message, so this ends up printing `@group can only ...'. % \newhelp\groupinvalidhelp{% group can only be used in environments such as @example,^^J% where each line of input produces a line of output.} % @need space-in-mils % forces a page break if there is not space-in-mils remaining. \newdimen\mil \mil=0.001in \def\need{\parsearg\needx} % Old definition--didn't work. %\def\needx #1{\par % %% This method tries to make TeX break the page naturally %% if the depth of the box does not fit. %{\baselineskip=0pt% %\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak %\prevdepth=-1000pt %}} \def\needx#1{% % Ensure vertical mode, so we don't make a big box in the middle of a % paragraph. \par % % If the @need value is less than one line space, it's useless. \dimen0 = #1\mil \dimen2 = \ht\strutbox \advance\dimen2 by \dp\strutbox \ifdim\dimen0 > \dimen2 % % Do a \strut just to make the height of this box be normal, so the % normal leading is inserted relative to the preceding line. % And a page break here is fine. \vtop to #1\mil{\strut\vfil}% % % TeX does not even consider page breaks if a penalty added to the % main vertical list is 10000 or more. But in order to see if the % empty box we just added fits on the page, we must make it consider % page breaks. On the other hand, we don't want to actually break the % page after the empty box. So we use a penalty of 9999. % % There is an extremely small chance that TeX will actually break the % page at this \penalty, if there are no other feasible breakpoints in % sight. (If the user is using lots of big @group commands, which % almost-but-not-quite fill up a page, TeX will have a hard time doing % good page breaking, for example.) However, I could not construct an % example where a page broke at this \penalty; if it happens in a real % document, then we can reconsider our strategy. \penalty9999 % % Back up by the size of the box, whether we did a page break or not. \kern -#1\mil % % Do not allow a page break right after this kern. \nobreak \fi } % @br forces paragraph break \let\br = \par % @dots{} output an ellipsis using the current font. % We do .5em per period so that it has the same spacing in a typewriter % font as three actual period characters. % \def\dots{% \leavevmode \hbox to 1.5em{% \hskip 0pt plus 0.25fil minus 0.25fil .\hss.\hss.% \hskip 0pt plus 0.5fil minus 0.5fil }% } % @enddots{} is an end-of-sentence ellipsis. % \def\enddots{% \leavevmode \hbox to 2em{% \hskip 0pt plus 0.25fil minus 0.25fil .\hss.\hss.\hss.% \hskip 0pt plus 0.5fil minus 0.5fil }% \spacefactor=3000 } % @page forces the start of a new page. % \def\page{\par\vfill\supereject} % @exdent text.... % outputs text on separate line in roman font, starting at standard page margin % This records the amount of indent in the innermost environment. % That's how much \exdent should take out. \newskip\exdentamount % This defn is used inside fill environments such as @defun. \def\exdent{\parsearg\exdentyyy} \def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}} % This defn is used inside nofill environments such as @example. \def\nofillexdent{\parsearg\nofillexdentyyy} \def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount \leftline{\hskip\leftskip{\rm#1}}}} % @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current % paragraph. For more general purposes, use the \margin insertion % class. WHICH is `l' or `r'. % \newskip\inmarginspacing \inmarginspacing=1cm \def\strutdepth{\dp\strutbox} % \def\doinmargin#1#2{\strut\vadjust{% \nobreak \kern-\strutdepth \vtop to \strutdepth{% \baselineskip=\strutdepth \vss % if you have multiple lines of stuff to put here, you'll need to % make the vbox yourself of the appropriate size. \ifx#1l% \llap{\ignorespaces #2\hskip\inmarginspacing}% \else \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}% \fi \null }% }} \def\inleftmargin{\doinmargin l} \def\inrightmargin{\doinmargin r} % % @inmargin{TEXT [, RIGHT-TEXT]} % (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right; % else use TEXT for both). % \def\inmargin#1{\parseinmargin #1,,\finish} \def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing. \setbox0 = \hbox{\ignorespaces #2}% \ifdim\wd0 > 0pt \def\lefttext{#1}% have both texts \def\righttext{#2}% \else \def\lefttext{#1}% have only one text \def\righttext{#1}% \fi % \ifodd\pageno \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin \else \def\temp{\inleftmargin\lefttext}% \fi \temp } % @include file insert text of that file as input. % Allow normal characters that we make active in the argument (a file name). \def\include{\begingroup \catcode`\\=\other \catcode`~=\other \catcode`^=\other \catcode`_=\other \catcode`|=\other \catcode`<=\other \catcode`>=\other \catcode`+=\other \parsearg\includezzz} % Restore active chars for included file. \def\includezzz#1{\endgroup\begingroup % Read the included file in a group so nested @include's work. \def\thisfile{#1}% \let\value=\expandablevalue \input\thisfile \endgroup} \def\thisfile{} % @center line % outputs that line, centered. % \def\center{\parsearg\docenter} \def\docenter#1{{% \ifhmode \hfil\break \fi \advance\hsize by -\leftskip \advance\hsize by -\rightskip \line{\hfil \ignorespaces#1\unskip \hfil}% \ifhmode \break \fi }} % @sp n outputs n lines of vertical space \def\sp{\parsearg\spxxx} \def\spxxx #1{\vskip #1\baselineskip} % @comment ...line which is ignored... % @c is the same as @comment % @ignore ... @end ignore is another way to write a comment \def\comment{\begingroup \catcode`\^^M=\other% \catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% \commentxxx} {\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}} \let\c=\comment % @paragraphindent NCHARS % We'll use ems for NCHARS, close enough. % NCHARS can also be the word `asis' or `none'. % We cannot feasibly implement @paragraphindent asis, though. % \def\asisword{asis} % no translation, these are keywords \def\noneword{none} % \def\paragraphindent{\parsearg\doparagraphindent} \def\doparagraphindent#1{% \def\temp{#1}% \ifx\temp\asisword \else \ifx\temp\noneword \defaultparindent = 0pt \else \defaultparindent = #1em \fi \fi \parindent = \defaultparindent } % @exampleindent NCHARS % We'll use ems for NCHARS like @paragraphindent. % It seems @exampleindent asis isn't necessary, but % I preserve it to make it similar to @paragraphindent. \def\exampleindent{\parsearg\doexampleindent} \def\doexampleindent#1{% \def\temp{#1}% \ifx\temp\asisword \else \ifx\temp\noneword \lispnarrowing = 0pt \else \lispnarrowing = #1em \fi \fi } % @firstparagraphindent WORD % If WORD is `none', then suppress indentation of the first paragraph % after a section heading. If WORD is `insert', then do indentat such % paragraphs. % % The paragraph indentation is suppressed or not by calling % \suppressfirstparagraphindent, which the sectioning commands do. We % switch the definition of this back and forth according to WORD. By % default, we suppress indentation. % \def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent} \newdimen\currentparindent % \def\insertword{insert} % \def\firstparagraphindent{\parsearg\dofirstparagraphindent} \def\dofirstparagraphindent#1{% \def\temp{#1}% \ifx\temp\noneword \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent \else\ifx\temp\insertword \let\suppressfirstparagraphindent = \relax \else \errhelp = \EMsimple \errmessage{Unknown @firstparagraphindent option `\temp'}% \fi\fi } % Here is how we actually suppress indentation. Redefine \everypar to % \kern backwards by \parindent, and then reset itself to empty. % % We also make \indent itself not actually do anything until the next % paragraph. % \gdef\dosuppressfirstparagraphindent{% \gdef\indent{% \global\let\indent=\ptexindent \global\everypar = {}% }% \global\everypar = {% \kern-\parindent \global\let\indent=\ptexindent \global\everypar = {}% }% }% % @asis just yields its argument. Used with @table, for example. % \def\asis#1{#1} % @math outputs its argument in math mode. % We don't use $'s directly in the definition of \math because we need % to set catcodes according to plain TeX first, to allow for subscripts, % superscripts, special math chars, etc. % \let\implicitmath = $%$ font-lock fix % % One complication: _ usually means subscripts, but it could also mean % an actual _ character, as in @math{@var{some_variable} + 1}. So make % _ within @math be active (mathcode "8000), and distinguish by seeing % if the current family is \slfam, which is what @var uses. % {\catcode\underChar = \active \gdef\mathunderscore{% \catcode\underChar=\active \def_{\ifnum\fam=\slfam \_\else\sb\fi}% }} % % Another complication: we want \\ (and @\) to output a \ character. % FYI, plain.tex uses \\ as a temporary control sequence (why?), but % this is not advertised and we don't care. Texinfo does not % otherwise define @\. % % The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\. \def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi} % \def\math{% \tex \mathcode`\_="8000 \mathunderscore \let\\ = \mathbackslash \mathactive \implicitmath\finishmath} \def\finishmath#1{#1\implicitmath\Etex} % Some active characters (such as <) are spaced differently in math. % We have to reset their definitions in case the @math was an % argument to a command which set the catcodes (such as @item or @section). % { \catcode`^ = \active \catcode`< = \active \catcode`> = \active \catcode`+ = \active \gdef\mathactive{% \let^ = \ptexhat \let< = \ptexless \let> = \ptexgtr \let+ = \ptexplus } } % @bullet and @minus need the same treatment as @math, just above. \def\bullet{\implicitmath\ptexbullet\implicitmath} \def\minus{\implicitmath-\implicitmath} % @refill is a no-op. \let\refill=\relax % If working on a large document in chapters, it is convenient to % be able to disable indexing, cross-referencing, and contents, for test runs. % This is done with @novalidate (before @setfilename). % \newif\iflinks \linkstrue % by default we want the aux files. \let\novalidate = \linksfalse % @setfilename is done at the beginning of every texinfo file. % So open here the files we need to have open while reading the input. % This makes it possible to make a .fmt file for texinfo. \def\setfilename{% \iflinks \readauxfile \fi % \openindices needs to do some work in any case. \openindices \fixbackslash % Turn off hack to swallow `\input texinfo'. \global\let\setfilename=\comment % Ignore extra @setfilename cmds. % % If texinfo.cnf is present on the system, read it. % Useful for site-wide @afourpaper, etc. % Just to be on the safe side, close the input stream before the \input. \openin 1 texinfo.cnf \ifeof1 \let\temp=\relax \else \def\temp{\input texinfo.cnf }\fi \closein1 \temp % \comment % Ignore the actual filename. } % Called from \setfilename. % \def\openindices{% \newindex{cp}% \newcodeindex{fn}% \newcodeindex{vr}% \newcodeindex{tp}% \newcodeindex{ky}% \newcodeindex{pg}% } % @bye. \outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} \message{pdf,} % adobe `portable' document format \newcount\tempnum \newcount\lnkcount \newtoks\filename \newcount\filenamelength \newcount\pgn \newtoks\toksA \newtoks\toksB \newtoks\toksC \newtoks\toksD \newbox\boxA \newcount\countA \newif\ifpdf \newif\ifpdfmakepagedest \ifx\pdfoutput\undefined \pdffalse \let\pdfmkdest = \gobble \let\pdfurl = \gobble \let\endlink = \relax \let\linkcolor = \relax \let\pdfmakeoutlines = \relax \else \pdftrue \pdfoutput = 1 \input pdfcolor \def\dopdfimage#1#2#3{% \def\imagewidth{#2}% \def\imageheight{#3}% % without \immediate, pdftex seg faults when the same image is % included twice. (Version 3.14159-pre-1.0-unofficial-20010704.) \ifnum\pdftexversion < 14 \immediate\pdfimage \else \immediate\pdfximage \fi \ifx\empty\imagewidth\else width \imagewidth \fi \ifx\empty\imageheight\else height \imageheight \fi \ifnum\pdftexversion<13 #1.pdf% \else {#1.pdf}% \fi \ifnum\pdftexversion < 14 \else \pdfrefximage \pdflastximage \fi} \def\pdfmkdest#1{{\normalturnoffactive \pdfdest name{#1} xyz}} \def\pdfmkpgn#1{#1} \let\linkcolor = \Blue % was Cyan, but that seems light? \def\endlink{\Black\pdfendlink} % Adding outlines to PDF; macros for calculating structure of outlines % come from Petr Olsak \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% \else \csname#1\endcsname \fi} \def\advancenumber#1{\tempnum=\expnumber{#1}\relax \advance\tempnum by1 \expandafter\xdef\csname#1\endcsname{\the\tempnum}} \def\pdfmakeoutlines{{% \openin 1 \jobname.toc \ifeof 1\else\begingroup \closein 1 % Thanh's hack / proper braces in bookmarks \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace % \def\chapentry ##1##2##3{} \def\secentry ##1##2##3##4{\advancenumber{chap##2}} \def\subsecentry ##1##2##3##4##5{\advancenumber{sec##2.##3}} \def\subsubsecentry ##1##2##3##4##5##6{\advancenumber{subsec##2.##3.##4}} \let\appendixentry = \chapentry \let\unnumbchapentry = \chapentry \let\unnumbsecentry = \secentry \let\unnumbsubsecentry = \subsecentry \let\unnumbsubsubsecentry = \subsubsecentry \input \jobname.toc \def\chapentry ##1##2##3{% \pdfoutline goto name{\pdfmkpgn{##3}}count-\expnumber{chap##2}{##1}} \def\secentry ##1##2##3##4{% \pdfoutline goto name{\pdfmkpgn{##4}}count-\expnumber{sec##2.##3}{##1}} \def\subsecentry ##1##2##3##4##5{% \pdfoutline goto name{\pdfmkpgn{##5}}count-\expnumber{subsec##2.##3.##4}{##1}} \def\subsubsecentry ##1##2##3##4##5##6{% \pdfoutline goto name{\pdfmkpgn{##6}}{##1}} \let\appendixentry = \chapentry \let\unnumbchapentry = \chapentry \let\unnumbsecentry = \secentry \let\unnumbsubsecentry = \subsecentry \let\unnumbsubsubsecentry = \subsubsecentry % % Make special characters normal for writing to the pdf file. % \indexnofonts \let\tt=\relax \turnoffactive \input \jobname.toc \endgroup\fi }} \def\makelinks #1,{% \def\params{#1}\def\E{END}% \ifx\params\E \let\nextmakelinks=\relax \else \let\nextmakelinks=\makelinks \ifnum\lnkcount>0,\fi \picknum{#1}% \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{\the\pgn}}% \linkcolor #1% \advance\lnkcount by 1% \endlink \fi \nextmakelinks } \def\picknum#1{\expandafter\pn#1} \def\pn#1{% \def\p{#1}% \ifx\p\lbrace \let\nextpn=\ppn \else \let\nextpn=\ppnn \def\first{#1} \fi \nextpn } \def\ppn#1{\pgn=#1\gobble} \def\ppnn{\pgn=\first} \def\pdfmklnk#1{\lnkcount=0\makelinks #1,END,} \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} \def\skipspaces#1{\def\PP{#1}\def\D{|}% \ifx\PP\D\let\nextsp\relax \else\let\nextsp\skipspaces \ifx\p\space\else\addtokens{\filename}{\PP}% \advance\filenamelength by 1 \fi \fi \nextsp} \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax} \ifnum\pdftexversion < 14 \let \startlink \pdfannotlink \else \let \startlink \pdfstartlink \fi \def\pdfurl#1{% \begingroup \normalturnoffactive\def\@{@}% \let\value=\expandablevalue \leavevmode\Red \startlink attr{/Border [0 0 0]}% user{/Subtype /Link /A << /S /URI /URI (#1) >>}% % #1 \endgroup} \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}} \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} \def\maketoks{% \expandafter\poptoks\the\toksA|ENDTOKS| \ifx\first0\adn0 \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9 \else \ifnum0=\countA\else\makelink\fi \ifx\first.\let\next=\done\else \let\next=\maketoks \addtokens{\toksB}{\the\toksD} \ifx\first,\addtokens{\toksB}{\space}\fi \fi \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \next} \def\makelink{\addtokens{\toksB}% {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0} \def\pdflink#1{% \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}} \linkcolor #1\endlink} \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} \fi % \ifx\pdfoutput \message{fonts,} % Font-change commands. % Texinfo sort of supports the sans serif font style, which plain TeX does not. % So we set up a \sf analogous to plain's \rm, etc. \newfam\sffam \def\sf{\fam=\sffam \tensf} \let\li = \sf % Sometimes we call it \li, not \sf. % We don't need math for this one. \def\ttsl{\tenttsl} % Default leading. \newdimen\textleading \textleading = 13.2pt % Set the baselineskip to #1, and the lineskip and strut size % correspondingly. There is no deep meaning behind these magic numbers % used as factors; they just match (closely enough) what Knuth defined. % \def\lineskipfactor{.08333} \def\strutheightpercent{.70833} \def\strutdepthpercent {.29167} % \def\setleading#1{% \normalbaselineskip = #1\relax \normallineskip = \lineskipfactor\normalbaselineskip \normalbaselines \setbox\strutbox =\hbox{% \vrule width0pt height\strutheightpercent\baselineskip depth \strutdepthpercent \baselineskip }% } % Set the font macro #1 to the font named #2, adding on the % specified font prefix (normally `cm'). % #3 is the font's design size, #4 is a scale factor \def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4} % Use cm as the default font prefix. % To specify the font prefix, you must define \fontprefix % before you read in texinfo.tex. \ifx\fontprefix\undefined \def\fontprefix{cm} \fi % Support font families that don't use the same naming scheme as CM. \def\rmshape{r} \def\rmbshape{bx} %where the normal face is bold \def\bfshape{b} \def\bxshape{bx} \def\ttshape{tt} \def\ttbshape{tt} \def\ttslshape{sltt} \def\itshape{ti} \def\itbshape{bxti} \def\slshape{sl} \def\slbshape{bxsl} \def\sfshape{ss} \def\sfbshape{ss} \def\scshape{csc} \def\scbshape{csc} \newcount\mainmagstep \ifx\bigger\relax % not really supported. \mainmagstep=\magstep1 \setfont\textrm\rmshape{12}{1000} \setfont\texttt\ttshape{12}{1000} \else \mainmagstep=\magstephalf \setfont\textrm\rmshape{10}{\mainmagstep} \setfont\texttt\ttshape{10}{\mainmagstep} \fi % Instead of cmb10, you may want to use cmbx10. % cmbx10 is a prettier font on its own, but cmb10 % looks better when embedded in a line with cmr10 % (in Bob's opinion). \setfont\textbf\bfshape{10}{\mainmagstep} \setfont\textit\itshape{10}{\mainmagstep} \setfont\textsl\slshape{10}{\mainmagstep} \setfont\textsf\sfshape{10}{\mainmagstep} \setfont\textsc\scshape{10}{\mainmagstep} \setfont\textttsl\ttslshape{10}{\mainmagstep} \font\texti=cmmi10 scaled \mainmagstep \font\textsy=cmsy10 scaled \mainmagstep % A few fonts for @defun, etc. \setfont\defbf\bxshape{10}{\magstep1} %was 1314 \setfont\deftt\ttshape{10}{\magstep1} \def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf} % Fonts for indices, footnotes, small examples (9pt). \setfont\smallrm\rmshape{9}{1000} \setfont\smalltt\ttshape{9}{1000} \setfont\smallbf\bfshape{10}{900} \setfont\smallit\itshape{9}{1000} \setfont\smallsl\slshape{9}{1000} \setfont\smallsf\sfshape{9}{1000} \setfont\smallsc\scshape{10}{900} \setfont\smallttsl\ttslshape{10}{900} \font\smalli=cmmi9 \font\smallsy=cmsy9 % Fonts for small examples (8pt). \setfont\smallerrm\rmshape{8}{1000} \setfont\smallertt\ttshape{8}{1000} \setfont\smallerbf\bfshape{10}{800} \setfont\smallerit\itshape{8}{1000} \setfont\smallersl\slshape{8}{1000} \setfont\smallersf\sfshape{8}{1000} \setfont\smallersc\scshape{10}{800} \setfont\smallerttsl\ttslshape{10}{800} \font\smalleri=cmmi8 \font\smallersy=cmsy8 % Fonts for title page: \setfont\titlerm\rmbshape{12}{\magstep3} \setfont\titleit\itbshape{10}{\magstep4} \setfont\titlesl\slbshape{10}{\magstep4} \setfont\titlett\ttbshape{12}{\magstep3} \setfont\titlettsl\ttslshape{10}{\magstep4} \setfont\titlesf\sfbshape{17}{\magstep1} \let\titlebf=\titlerm \setfont\titlesc\scbshape{10}{\magstep4} \font\titlei=cmmi12 scaled \magstep3 \font\titlesy=cmsy10 scaled \magstep4 \def\authorrm{\secrm} \def\authortt{\sectt} % Chapter (and unnumbered) fonts (17.28pt). \setfont\chaprm\rmbshape{12}{\magstep2} \setfont\chapit\itbshape{10}{\magstep3} \setfont\chapsl\slbshape{10}{\magstep3} \setfont\chaptt\ttbshape{12}{\magstep2} \setfont\chapttsl\ttslshape{10}{\magstep3} \setfont\chapsf\sfbshape{17}{1000} \let\chapbf=\chaprm \setfont\chapsc\scbshape{10}{\magstep3} \font\chapi=cmmi12 scaled \magstep2 \font\chapsy=cmsy10 scaled \magstep3 % Section fonts (14.4pt). \setfont\secrm\rmbshape{12}{\magstep1} \setfont\secit\itbshape{10}{\magstep2} \setfont\secsl\slbshape{10}{\magstep2} \setfont\sectt\ttbshape{12}{\magstep1} \setfont\secttsl\ttslshape{10}{\magstep2} \setfont\secsf\sfbshape{12}{\magstep1} \let\secbf\secrm \setfont\secsc\scbshape{10}{\magstep2} \font\seci=cmmi12 scaled \magstep1 \font\secsy=cmsy10 scaled \magstep2 % Subsection fonts (13.15pt). \setfont\ssecrm\rmbshape{12}{\magstephalf} \setfont\ssecit\itbshape{10}{1315} \setfont\ssecsl\slbshape{10}{1315} \setfont\ssectt\ttbshape{12}{\magstephalf} \setfont\ssecttsl\ttslshape{10}{1315} \setfont\ssecsf\sfbshape{12}{\magstephalf} \let\ssecbf\ssecrm \setfont\ssecsc\scbshape{10}{\magstep1} \font\sseci=cmmi12 scaled \magstephalf \font\ssecsy=cmsy10 scaled 1315 % The smallcaps and symbol fonts should actually be scaled \magstep1.5, % but that is not a standard magnification. % In order for the font changes to affect most math symbols and letters, % we have to define the \textfont of the standard families. Since % texinfo doesn't allow for producing subscripts and superscripts except % in the main text, we don't bother to reset \scriptfont and % \scriptscriptfont (which would also require loading a lot more fonts). % \def\resetmathfonts{% \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf \textfont\ttfam=\tentt \textfont\sffam=\tensf } % The font-changing commands redefine the meanings of \tenSTYLE, instead % of just \STYLE. We do this so that font changes will continue to work % in math mode, where it is the current \fam that is relevant in most % cases, not the current font. Plain TeX does \def\bf{\fam=\bffam % \tenbf}, for example. By redefining \tenbf, we obviate the need to % redefine \bf itself. \def\textfonts{% \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \let\tenttsl=\textttsl \resetmathfonts \setleading{\textleading}} \def\titlefonts{% \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy \let\tenttsl=\titlettsl \resetmathfonts \setleading{25pt}} \def\titlefont#1{{\titlefonts\rm #1}} \def\chapfonts{% \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \let\tenttsl=\chapttsl \resetmathfonts \setleading{19pt}} \def\secfonts{% \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy \let\tenttsl=\secttsl \resetmathfonts \setleading{16pt}} \def\subsecfonts{% \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy \let\tenttsl=\ssecttsl \resetmathfonts \setleading{15pt}} \let\subsubsecfonts = \subsecfonts % Maybe make sssec fonts scaled magstephalf? \def\smallfonts{% \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy \let\tenttsl=\smallttsl \resetmathfonts \setleading{10.5pt}} \def\smallerfonts{% \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy \let\tenttsl=\smallerttsl \resetmathfonts \setleading{9.5pt}} % Set the fonts to use with the @small... environments. \let\smallexamplefonts = \smallfonts % About \smallexamplefonts. If we use \smallfonts (9pt), @smallexample % can fit this many characters: % 8.5x11=86 smallbook=72 a4=90 a5=69 % If we use \smallerfonts (8pt), then we can fit this many characters: % 8.5x11=90+ smallbook=80 a4=90+ a5=77 % For me, subjectively, the few extra characters that fit aren't worth % the additional smallness of 8pt. So I'm making the default 9pt. % % By the way, for comparison, here's what fits with @example (10pt): % 8.5x11=71 smallbook=60 a4=75 a5=58 % % I wish we used A4 paper on this side of the Atlantic. % % --karl, 24jan03. % Set up the default fonts, so we can use them for creating boxes. % \textfonts % Define these so they can be easily changed for other fonts. \def\angleleft{$\langle$} \def\angleright{$\rangle$} % Count depth in font-changes, for error checks \newcount\fontdepth \fontdepth=0 % Fonts for short table of contents. \setfont\shortcontrm\rmshape{12}{1000} \setfont\shortcontbf\bxshape{12}{1000} \setfont\shortcontsl\slshape{12}{1000} \setfont\shortconttt\ttshape{12}{1000} %% Add scribe-like font environments, plus @l for inline lisp (usually sans %% serif) and @ii for TeX italic % \smartitalic{ARG} outputs arg in italics, followed by an italic correction % unless the following character is such as not to need one. \def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else \ptexslash\fi\fi\fi} \def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx} \def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx} \let\i=\smartitalic \let\var=\smartslanted \let\dfn=\smartslanted \let\emph=\smartitalic \let\cite=\smartslanted \def\b#1{{\bf #1}} \let\strong=\b % We can't just use \exhyphenpenalty, because that only has effect at % the end of a paragraph. Restore normal hyphenation at the end of the % group within which \nohyphenation is presumably called. % \def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} \def\restorehyphenation{\hyphenchar\font = `- } % Set sfcode to normal for the chars that usually have another value. % Can't use plain's \frenchspacing because it uses the `\x notation, and % sometimes \x has an active definition that messes things up. % \catcode`@=11 \def\frenchspacing{% \sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m } \catcode`@=\other \def\t#1{% {\tt \rawbackslash \frenchspacing #1}% \null } \let\ttfont=\t \def\samp#1{`\tclose{#1}'\null} \setfont\keyrm\rmshape{8}{1000} \font\keysy=cmsy9 \def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% \vbox{\hrule\kern-0.4pt \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% \kern-0.4pt\hrule}% \kern-.06em\raise0.4pt\hbox{\angleright}}}} % The old definition, with no lozenge: %\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null} \def\ctrl #1{{\tt \rawbackslash \hat}#1} % @file, @option are the same as @samp. \let\file=\samp \let\option=\samp % @code is a modification of @t, % which makes spaces the same size as normal in the surrounding text. \def\tclose#1{% {% % Change normal interword space to be same as for the current font. \spaceskip = \fontdimen2\font % % Switch to typewriter. \tt % % But `\ ' produces the large typewriter interword space. \def\ {{\spaceskip = 0pt{} }}% % % Turn off hyphenation. \nohyphenation % \rawbackslash \frenchspacing #1% }% \null } % We *must* turn on hyphenation at `-' and `_' in \code. % Otherwise, it is too hard to avoid overfull hboxes % in the Emacs manual, the Library manual, etc. % Unfortunately, TeX uses one parameter (\hyphenchar) to control % both hyphenation at - and hyphenation within words. % We must therefore turn them both off (\tclose does that) % and arrange explicitly to hyphenate at a dash. % -- rms. { \catcode`\-=\active \catcode`\_=\active % \global\def\code{\begingroup \catcode`\-=\active \let-\codedash \catcode`\_=\active \let_\codeunder \codex } % % If we end up with any active - characters when handling the index, % just treat them as a normal -. \global\def\indexbreaks{\catcode`\-=\active \let-\realdash} } \def\realdash{-} \def\codedash{-\discretionary{}{}{}} \def\codeunder{% % this is all so @math{@code{var_name}+1} can work. In math mode, _ % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.) % will therefore expand the active definition of _, which is us % (inside @code that is), therefore an endless loop. \ifusingtt{\ifmmode \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_. \else\normalunderscore \fi \discretionary{}{}{}}% {\_}% } \def\codex #1{\tclose{#1}\endgroup} % @kbd is like @code, except that if the argument is just one @key command, % then @kbd has no effect. % @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), % `example' (@kbd uses ttsl only inside of @example and friends), % or `code' (@kbd uses normal tty font always). \def\kbdinputstyle{\parsearg\kbdinputstylexxx} \def\kbdinputstylexxx#1{% \def\arg{#1}% \ifx\arg\worddistinct \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% \else\ifx\arg\wordexample \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% \else\ifx\arg\wordcode \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% \else \errhelp = \EMsimple \errmessage{Unknown @kbdinputstyle option `\arg'}% \fi\fi\fi } \def\worddistinct{distinct} \def\wordexample{example} \def\wordcode{code} % Default is `distinct.' \kbdinputstyle distinct \def\xkey{\key} \def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}% \ifx\one\xkey\ifx\threex\three \key{#2}% \else{\tclose{\kbdfont\look}}\fi \else{\tclose{\kbdfont\look}}\fi} % For @url, @env, @command quotes seem unnecessary, so use \code. \let\url=\code \let\env=\code \let\command=\code % @uref (abbreviation for `urlref') takes an optional (comma-separated) % second argument specifying the text to display and an optional third % arg as text to display instead of (rather than in addition to) the url % itself. First (mandatory) arg is the url. Perhaps eventually put in % a hypertex \special here. % \def\uref#1{\douref #1,,,\finish} \def\douref#1,#2,#3,#4\finish{\begingroup \unsepspaces \pdfurl{#1}% \setbox0 = \hbox{\ignorespaces #3}% \ifdim\wd0 > 0pt \unhbox0 % third arg given, show only that \else \setbox0 = \hbox{\ignorespaces #2}% \ifdim\wd0 > 0pt \ifpdf \unhbox0 % PDF: 2nd arg given, show only it \else \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url \fi \else \code{#1}% only url given, so show it \fi \fi \endlink \endgroup} % rms does not like angle brackets --karl, 17may97. % So now @email is just like @uref, unless we are pdf. % %\def\email#1{\angleleft{\tt #1}\angleright} \ifpdf \def\email#1{\doemail#1,,\finish} \def\doemail#1,#2,#3\finish{\begingroup \unsepspaces \pdfurl{mailto:#1}% \setbox0 = \hbox{\ignorespaces #2}% \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi \endlink \endgroup} \else \let\email=\uref \fi % Check if we are currently using a typewriter font. Since all the % Computer Modern typewriter fonts have zero interword stretch (and % shrink), and it is reasonable to expect all typewriter fonts to have % this property, we can check that font parameter. % \def\ifmonospace{\ifdim\fontdimen3\font=0pt } % Typeset a dimension, e.g., `in' or `pt'. The only reason for the % argument is to make the input look right: @dmn{pt} instead of @dmn{}pt. % \def\dmn#1{\thinspace #1} \def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par} % @l was never documented to mean ``switch to the Lisp font'', % and it is not used as such in any manual I can find. We need it for % Polish suppressed-l. --karl, 22sep96. %\def\l#1{{\li #1}\null} % Explicit font changes: @r, @sc, undocumented @ii. \def\r#1{{\rm #1}} % roman font \def\sc#1{{\smallcaps#1}} % smallcaps font \def\ii#1{{\it #1}} % italic font % @acronym downcases the argument and prints in smallcaps. \def\acronym#1{{\smallcaps \lowercase{#1}}} % @pounds{} is a sterling sign. \def\pounds{{\it\$}} % @registeredsymbol - R in a circle. For now, only works in text size; % we'd have to redo the font mechanism to change the \scriptstyle and % \scriptscriptstyle font sizes to make it look right in headings. % Adapted from the plain.tex definition of \copyright. % \def\registeredsymbol{% $^{{\ooalign{\hfil\raise.07ex\hbox{$\scriptstyle\rm R$}\hfil\crcr\Orb}}% }$% } \message{page headings,} \newskip\titlepagetopglue \titlepagetopglue = 1.5in \newskip\titlepagebottomglue \titlepagebottomglue = 2pc % First the title page. Must do @settitle before @titlepage. \newif\ifseenauthor \newif\iffinishedtitlepage % Do an implicit @contents or @shortcontents after @end titlepage if the % user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage. % \newif\ifsetcontentsaftertitlepage \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue \newif\ifsetshortcontentsaftertitlepage \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue \def\shorttitlepage{\parsearg\shorttitlepagezzz} \def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% \endgroup\page\hbox{}\page} \def\titlepage{\begingroup \parindent=0pt \textfonts \let\subtitlerm=\tenrm \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}% % \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines \let\tt=\authortt}% % % Leave some space at the very top of the page. \vglue\titlepagetopglue % % Now you can print the title using @title. \def\title{\parsearg\titlezzz}% \def\titlezzz##1{\leftline{\titlefonts\rm ##1} % print a rule at the page bottom also. \finishedtitlepagefalse \vskip4pt \hrule height 4pt width \hsize \vskip4pt}% % No rule at page bottom unless we print one at the top with @title. \finishedtitlepagetrue % % Now you can put text using @subtitle. \def\subtitle{\parsearg\subtitlezzz}% \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}% % % @author should come last, but may come many times. \def\author{\parsearg\authorzzz}% \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi {\authorfont \leftline{##1}}}% % % Most title ``pages'' are actually two pages long, with space % at the top of the second. We don't want the ragged left on the second. \let\oldpage = \page \def\page{% \iffinishedtitlepage\else \finishtitlepage \fi \oldpage \let\page = \oldpage \hbox{}}% % \def\page{\oldpage \hbox{}} } \def\Etitlepage{% \iffinishedtitlepage\else \finishtitlepage \fi % It is important to do the page break before ending the group, % because the headline and footline are only empty inside the group. % If we use the new definition of \page, we always get a blank page % after the title page, which we certainly don't want. \oldpage \endgroup % % Need this before the \...aftertitlepage checks so that if they are % in effect the toc pages will come out with page numbers. \HEADINGSon % % If they want short, they certainly want long too. \ifsetshortcontentsaftertitlepage \shortcontents \contents \global\let\shortcontents = \relax \global\let\contents = \relax \fi % \ifsetcontentsaftertitlepage \contents \global\let\contents = \relax \global\let\shortcontents = \relax \fi } \def\finishtitlepage{% \vskip4pt \hrule height 2pt width \hsize \vskip\titlepagebottomglue \finishedtitlepagetrue } %%% Set up page headings and footings. \let\thispage=\folio \newtoks\evenheadline % headline on even pages \newtoks\oddheadline % headline on odd pages \newtoks\evenfootline % footline on even pages \newtoks\oddfootline % footline on odd pages % Now make Tex use those variables \headline={{\textfonts\rm \ifodd\pageno \the\oddheadline \else \the\evenheadline \fi}} \footline={{\textfonts\rm \ifodd\pageno \the\oddfootline \else \the\evenfootline \fi}\HEADINGShook} \let\HEADINGShook=\relax % Commands to set those variables. % For example, this is what @headings on does % @evenheading @thistitle|@thispage|@thischapter % @oddheading @thischapter|@thispage|@thistitle % @evenfooting @thisfile|| % @oddfooting ||@thisfile \def\evenheading{\parsearg\evenheadingxxx} \def\oddheading{\parsearg\oddheadingxxx} \def\everyheading{\parsearg\everyheadingxxx} \def\evenfooting{\parsearg\evenfootingxxx} \def\oddfooting{\parsearg\oddfootingxxx} \def\everyfooting{\parsearg\everyfootingxxx} {\catcode`\@=0 % \gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish} \gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{% \global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish} \gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{% \global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\everyheadingxxx#1{\oddheadingxxx{#1}\evenheadingxxx{#1}}% \gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish} \gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{% \global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish} \gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{% \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}% % % Leave some space for the footline. Hopefully ok to assume % @evenfooting will not be used by itself. \global\advance\pageheight by -\baselineskip \global\advance\vsize by -\baselineskip } \gdef\everyfootingxxx#1{\oddfootingxxx{#1}\evenfootingxxx{#1}} % }% unbind the catcode of @. % @headings double turns headings on for double-sided printing. % @headings single turns headings on for single-sided printing. % @headings off turns them off. % @headings on same as @headings double, retained for compatibility. % @headings after turns on double-sided headings after this page. % @headings doubleafter turns on double-sided headings after this page. % @headings singleafter turns on single-sided headings after this page. % By default, they are off at the start of a document, % and turned `on' after @end titlepage. \def\headings #1 {\csname HEADINGS#1\endcsname} \def\HEADINGSoff{ \global\evenheadline={\hfil} \global\evenfootline={\hfil} \global\oddheadline={\hfil} \global\oddfootline={\hfil}} \HEADINGSoff % When we turn headings on, set the page number to 1. % For double-sided printing, put current file name in lower left corner, % chapter name on inside top of right hand pages, document % title on inside top of left hand pages, and page numbers on outside top % edge of all pages. \def\HEADINGSdouble{ \global\pageno=1 \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\folio\hfil\thistitle}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chapoddpage } \let\contentsalignmacro = \chappager % For single-sided printing, chapter title goes across top left of page, % page number on top right. \def\HEADINGSsingle{ \global\pageno=1 \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\thischapter\hfil\folio}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chappager } \def\HEADINGSon{\HEADINGSdouble} \def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex} \let\HEADINGSdoubleafter=\HEADINGSafter \def\HEADINGSdoublex{% \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\folio\hfil\thistitle}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chapoddpage } \def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} \def\HEADINGSsinglex{% \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\thischapter\hfil\folio}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chappager } % Subroutines used in generating headings % This produces Day Month Year style of output. % Only define if not already defined, in case a txi-??.tex file has set % up a different format (e.g., txi-cs.tex does this). \ifx\today\undefined \def\today{% \number\day\space \ifcase\month \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec \fi \space\number\year} \fi % @settitle line... specifies the title of the document, for headings. % It generates no output of its own. \def\thistitle{\putwordNoTitle} \def\settitle{\parsearg\settitlezzz} \def\settitlezzz #1{\gdef\thistitle{#1}} \message{tables,} % Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x). % default indentation of table text \newdimen\tableindent \tableindent=.8in % default indentation of @itemize and @enumerate text \newdimen\itemindent \itemindent=.3in % margin between end of table item and start of table text. \newdimen\itemmargin \itemmargin=.1in % used internally for \itemindent minus \itemmargin \newdimen\itemmax % Note @table, @vtable, and @vtable define @item, @itemx, etc., with % these defs. % They also define \itemindex % to index the item name in whatever manner is desired (perhaps none). \newif\ifitemxneedsnegativevskip \def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi} \def\internalBitem{\smallbreak \parsearg\itemzzz} \def\internalBitemx{\itemxpar \parsearg\itemzzz} \def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz} \def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz} \def\internalBkitem{\smallbreak \parsearg\kitemzzz} \def\internalBkitemx{\itemxpar \parsearg\kitemzzz} \def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}% \itemzzz {#1}} \def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}% \itemzzz {#1}} \def\itemzzz #1{\begingroup % \advance\hsize by -\rightskip \advance\hsize by -\tableindent \setbox0=\hbox{\itemfont{#1}}% \itemindex{#1}% \nobreak % This prevents a break before @itemx. % % If the item text does not fit in the space we have, put it on a line % by itself, and do not allow a page break either before or after that % line. We do not start a paragraph here because then if the next % command is, e.g., @kindex, the whatsit would get put into the % horizontal list on a line by itself, resulting in extra blank space. \ifdim \wd0>\itemmax % % Make this a paragraph so we get the \parskip glue and wrapping, % but leave it ragged-right. \begingroup \advance\leftskip by-\tableindent \advance\hsize by\tableindent \advance\rightskip by0pt plus1fil \leavevmode\unhbox0\par \endgroup % % We're going to be starting a paragraph, but we don't want the % \parskip glue -- logically it's part of the @item we just started. \nobreak \vskip-\parskip % % Stop a page break at the \parskip glue coming up. (Unfortunately % we can't prevent a possible page break at the following % \baselineskip glue.) However, if what follows is an environment % such as @example, there will be no \parskip glue; then % the negative vskip we just would cause the example and the item to % crash together. So we use this bizarre value of 10001 as a signal % to \aboveenvbreak to insert \parskip glue after all. % (Possibly there are other commands that could be followed by % @example which need the same treatment, but not section titles; or % maybe section titles are the only special case and they should be % penalty 10001...) \penalty 10001 \endgroup \itemxneedsnegativevskipfalse \else % The item text fits into the space. Start a paragraph, so that the % following text (if any) will end up on the same line. \noindent % Do this with kerns and \unhbox so that if there is a footnote in % the item text, it can migrate to the main vertical list and % eventually be printed. \nobreak\kern-\tableindent \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0 \unhbox0 \nobreak\kern\dimen0 \endgroup \itemxneedsnegativevskiptrue \fi } \def\item{\errmessage{@item while not in a table}} \def\itemx{\errmessage{@itemx while not in a table}} \def\kitem{\errmessage{@kitem while not in a table}} \def\kitemx{\errmessage{@kitemx while not in a table}} \def\xitem{\errmessage{@xitem while not in a table}} \def\xitemx{\errmessage{@xitemx while not in a table}} % Contains a kludge to get @end[description] to work. \def\description{\tablez{\dontindex}{1}{}{}{}{}} % @table, @ftable, @vtable. \def\table{\begingroup\inENV\obeylines\obeyspaces\tablex} {\obeylines\obeyspaces% \gdef\tablex #1^^M{% \tabley\dontindex#1 \endtabley}} \def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex} {\obeylines\obeyspaces% \gdef\ftablex #1^^M{% \tabley\fnitemindex#1 \endtabley \def\Eftable{\endgraf\afterenvbreak\endgroup}% \let\Etable=\relax}} \def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex} {\obeylines\obeyspaces% \gdef\vtablex #1^^M{% \tabley\vritemindex#1 \endtabley \def\Evtable{\endgraf\afterenvbreak\endgroup}% \let\Etable=\relax}} \def\dontindex #1{} \def\fnitemindex #1{\doind {fn}{\code{#1}}}% \def\vritemindex #1{\doind {vr}{\code{#1}}}% {\obeyspaces % \gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup% \tablez{#1}{#2}{#3}{#4}{#5}{#6}}} \def\tablez #1#2#3#4#5#6{% \aboveenvbreak % \begingroup % \def\Edescription{\Etable}% Necessary kludge. \let\itemindex=#1% \ifnum 0#3>0 \advance \leftskip by #3\mil \fi % \ifnum 0#4>0 \tableindent=#4\mil \fi % \ifnum 0#5>0 \advance \rightskip by #5\mil \fi % \def\itemfont{#2}% \itemmax=\tableindent % \advance \itemmax by -\itemmargin % \advance \leftskip by \tableindent % \exdentamount=\tableindent \parindent = 0pt \parskip = \smallskipamount \ifdim \parskip=0pt \parskip=2pt \fi% \def\Etable{\endgraf\afterenvbreak\endgroup}% \let\item = \internalBitem % \let\itemx = \internalBitemx % \let\kitem = \internalBkitem % \let\kitemx = \internalBkitemx % \let\xitem = \internalBxitem % \let\xitemx = \internalBxitemx % } % This is the counter used by @enumerate, which is really @itemize \newcount \itemno \def\itemize{\parsearg\itemizezzz} \def\itemizezzz #1{% \begingroup % ended by the @end itemize \itemizey {#1}{\Eitemize} } \def\itemizey#1#2{% \aboveenvbreak \itemmax=\itemindent \advance\itemmax by -\itemmargin \advance\leftskip by \itemindent \exdentamount=\itemindent \parindent=0pt \parskip=\smallskipamount \ifdim\parskip=0pt \parskip=2pt \fi \def#2{\endgraf\afterenvbreak\endgroup}% \def\itemcontents{#1}% % @itemize with no arg is equivalent to @itemize @bullet. \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi \let\item=\itemizeitem } % \splitoff TOKENS\endmark defines \first to be the first token in % TOKENS, and \rest to be the remainder. % \def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% % Allow an optional argument of an uppercase letter, lowercase letter, % or number, to specify the first label in the enumerated list. No % argument is the same as `1'. % \def\enumerate{\parsearg\enumeratezzz} \def\enumeratezzz #1{\enumeratey #1 \endenumeratey} \def\enumeratey #1 #2\endenumeratey{% \begingroup % ended by the @end enumerate % % If we were given no argument, pretend we were given `1'. \def\thearg{#1}% \ifx\thearg\empty \def\thearg{1}\fi % % Detect if the argument is a single token. If so, it might be a % letter. Otherwise, the only valid thing it can be is a number. % (We will always have one token, because of the test we just made. % This is a good thing, since \splitoff doesn't work given nothing at % all -- the first parameter is undelimited.) \expandafter\splitoff\thearg\endmark \ifx\rest\empty % Only one token in the argument. It could still be anything. % A ``lowercase letter'' is one whose \lccode is nonzero. % An ``uppercase letter'' is one whose \lccode is both nonzero, and % not equal to itself. % Otherwise, we assume it's a number. % % We need the \relax at the end of the \ifnum lines to stop TeX from % continuing to look for a . % \ifnum\lccode\expandafter`\thearg=0\relax \numericenumerate % a number (we hope) \else % It's a letter. \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax \lowercaseenumerate % lowercase letter \else \uppercaseenumerate % uppercase letter \fi \fi \else % Multiple tokens in the argument. We hope it's a number. \numericenumerate \fi } % An @enumerate whose labels are integers. The starting integer is % given in \thearg. % \def\numericenumerate{% \itemno = \thearg \startenumeration{\the\itemno}% } % The starting (lowercase) letter is in \thearg. \def\lowercaseenumerate{% \itemno = \expandafter`\thearg \startenumeration{% % Be sure we're not beyond the end of the alphabet. \ifnum\itemno=0 \errmessage{No more lowercase letters in @enumerate; get a bigger alphabet}% \fi \char\lccode\itemno }% } % The starting (uppercase) letter is in \thearg. \def\uppercaseenumerate{% \itemno = \expandafter`\thearg \startenumeration{% % Be sure we're not beyond the end of the alphabet. \ifnum\itemno=0 \errmessage{No more uppercase letters in @enumerate; get a bigger alphabet} \fi \char\uccode\itemno }% } % Call itemizey, adding a period to the first argument and supplying the % common last two arguments. Also subtract one from the initial value in % \itemno, since @item increments \itemno. % \def\startenumeration#1{% \advance\itemno by -1 \itemizey{#1.}\Eenumerate\flushcr } % @alphaenumerate and @capsenumerate are abbreviations for giving an arg % to @enumerate. % \def\alphaenumerate{\enumerate{a}} \def\capsenumerate{\enumerate{A}} \def\Ealphaenumerate{\Eenumerate} \def\Ecapsenumerate{\Eenumerate} % Definition of @item while inside @itemize. \def\itemizeitem{% \advance\itemno by 1 {\let\par=\endgraf \smallbreak}% \ifhmode \errmessage{In hmode at itemizeitem}\fi {\parskip=0in \hskip 0pt \hbox to 0pt{\hss \itemcontents\hskip \itemmargin}% \vadjust{\penalty 1200}}% \flushcr} % @multitable macros % Amy Hendrickson, 8/18/94, 3/6/96 % % @multitable ... @end multitable will make as many columns as desired. % Contents of each column will wrap at width given in preamble. Width % can be specified either with sample text given in a template line, % or in percent of \hsize, the current width of text on page. % Table can continue over pages but will only break between lines. % To make preamble: % % Either define widths of columns in terms of percent of \hsize: % @multitable @columnfractions .25 .3 .45 % @item ... % % Numbers following @columnfractions are the percent of the total % current hsize to be used for each column. You may use as many % columns as desired. % Or use a template: % @multitable {Column 1 template} {Column 2 template} {Column 3 template} % @item ... % using the widest term desired in each column. % % For those who want to use more than one line's worth of words in % the preamble, break the line within one argument and it % will parse correctly, i.e., % % @multitable {Column 1 template} {Column 2 template} {Column 3 % template} % Not: % @multitable {Column 1 template} {Column 2 template} % {Column 3 template} % Each new table line starts with @item, each subsequent new column % starts with @tab. Empty columns may be produced by supplying @tab's % with nothing between them for as many times as empty columns are needed, % ie, @tab@tab@tab will produce two empty columns. % @item, @tab, @multitable or @end multitable do not need to be on their % own lines, but it will not hurt if they are. % Sample multitable: % @multitable {Column 1 template} {Column 2 template} {Column 3 template} % @item first col stuff @tab second col stuff @tab third col % @item % first col stuff % @tab % second col stuff % @tab % third col % @item first col stuff @tab second col stuff % @tab Many paragraphs of text may be used in any column. % % They will wrap at the width determined by the template. % @item@tab@tab This will be in third column. % @end multitable % Default dimensions may be reset by user. % @multitableparskip is vertical space between paragraphs in table. % @multitableparindent is paragraph indent in table. % @multitablecolmargin is horizontal space to be left between columns. % @multitablelinespace is space to leave between table items, baseline % to baseline. % 0pt means it depends on current normal line spacing. % \newskip\multitableparskip \newskip\multitableparindent \newdimen\multitablecolspace \newskip\multitablelinespace \multitableparskip=0pt \multitableparindent=6pt \multitablecolspace=12pt \multitablelinespace=0pt % Macros used to set up halign preamble: % \let\endsetuptable\relax \def\xendsetuptable{\endsetuptable} \let\columnfractions\relax \def\xcolumnfractions{\columnfractions} \newif\ifsetpercent % #1 is the part of the @columnfraction before the decimal point, which % is presumably either 0 or the empty string (but we don't check, we % just throw it away). #2 is the decimal part, which we use as the % percent of \hsize for this column. \def\pickupwholefraction#1.#2 {% \global\advance\colcount by 1 \expandafter\xdef\csname col\the\colcount\endcsname{.#2\hsize}% \setuptable } \newcount\colcount \def\setuptable#1{% \def\firstarg{#1}% \ifx\firstarg\xendsetuptable \let\go = \relax \else \ifx\firstarg\xcolumnfractions \global\setpercenttrue \else \ifsetpercent \let\go\pickupwholefraction \else \global\advance\colcount by 1 \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a % separator; typically that is always in the input, anyway. \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% \fi \fi \ifx\go\pickupwholefraction % Put the argument back for the \pickupwholefraction call, so % we'll always have a period there to be parsed. \def\go{\pickupwholefraction#1}% \else \let\go = \setuptable \fi% \fi \go } % @multitable ... @end multitable definitions: % \def\multitable{\parsearg\dotable} \def\dotable#1{\bgroup \vskip\parskip \let\item=\crcrwithfootnotes % A \tab used to include \hskip1sp. But then the space in a template % line is not enough. That is bad. So let's go back to just & until % we encounter the problem it was intended to solve again. --karl, % nathan@acm.org, 20apr99. \let\tab=&% \let\startfootins=\startsavedfootnote \tolerance=9500 \hbadness=9500 \setmultitablespacing \parskip=\multitableparskip \parindent=\multitableparindent \overfullrule=0pt \global\colcount=0 \def\Emultitable{% \global\setpercentfalse \crcrwithfootnotes\crcr \egroup\egroup }% % % To parse everything between @multitable and @item: \setuptable#1 \endsetuptable % % \everycr will reset column counter, \colcount, at the end of % each line. Every column entry will cause \colcount to advance by one. % The table preamble % looks at the current \colcount to find the correct column width. \everycr{\noalign{% % % \filbreak%% keeps underfull box messages off when table breaks over pages. % Maybe so, but it also creates really weird page breaks when the table % breaks over pages. Wouldn't \vfil be better? Wait until the problem % manifests itself, so it can be fixed for real --karl. \global\colcount=0\relax}}% % % This preamble sets up a generic column definition, which will % be used as many times as user calls for columns. % \vtop will set a single line and will also let text wrap and % continue for many paragraphs if desired. \halign\bgroup&\global\advance\colcount by 1\relax \multistrut\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname % % In order to keep entries from bumping into each other % we will add a \leftskip of \multitablecolspace to all columns after % the first one. % % If a template has been used, we will add \multitablecolspace % to the width of each template entry. % % If the user has set preamble in terms of percent of \hsize we will % use that dimension as the width of the column, and the \leftskip % will keep entries from bumping into each other. Table will start at % left margin and final column will justify at right margin. % % Make sure we don't inherit \rightskip from the outer environment. \rightskip=0pt \ifnum\colcount=1 % The first column will be indented with the surrounding text. \advance\hsize by\leftskip \else \ifsetpercent \else % If user has not set preamble in terms of percent of \hsize % we will advance \hsize by \multitablecolspace. \advance\hsize by \multitablecolspace \fi % In either case we will make \leftskip=\multitablecolspace: \leftskip=\multitablecolspace \fi % Ignoring space at the beginning and end avoids an occasional spurious % blank line, when TeX decides to break the line at the space before the % box from the multistrut, so the strut ends up on a line by itself. % For example: % @multitable @columnfractions .11 .89 % @item @code{#} % @tab Legal holiday which is valid in major parts of the whole country. % Is automatically provided with highlighting sequences respectively marking % characters. \noindent\ignorespaces##\unskip\multistrut}\cr } \def\setmultitablespacing{% test to see if user has set \multitablelinespace. % If so, do nothing. If not, give it an appropriate dimension based on % current baselineskip. \ifdim\multitablelinespace=0pt \setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip \global\advance\multitablelinespace by-\ht0 %% strut to put in table in case some entry doesn't have descenders, %% to keep lines equally spaced \let\multistrut = \strut \else %% FIXME: what is \box0 supposed to be? \gdef\multistrut{\vrule height\multitablelinespace depth\dp0 width0pt\relax} \fi %% Test to see if parskip is larger than space between lines of %% table. If not, do nothing. %% If so, set to same dimension as multitablelinespace. \ifdim\multitableparskip>\multitablelinespace \global\multitableparskip=\multitablelinespace \global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller %% than skip between lines in the table. \fi% \ifdim\multitableparskip=0pt \global\multitableparskip=\multitablelinespace \global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller %% than skip between lines in the table. \fi} % In case a @footnote appears inside an alignment, save the footnote % text to a box and make the \insert when a row of the table is % finished. Otherwise, the insertion is lost, it never migrates to the % main vertical list. --kasal, 22jan03. % \newbox\savedfootnotes % % \dotable \let's \startfootins to this, so that \dofootnote will call % it instead of starting the insertion right away. \def\startsavedfootnote{% \global\setbox\savedfootnotes = \vbox\bgroup \unvbox\savedfootnotes } \def\crcrwithfootnotes{% \crcr \ifvoid\savedfootnotes \else \noalign{\insert\footins{\box\savedfootnotes}}% \fi } \message{conditionals,} % Prevent errors for section commands. % Used in @ignore and in failing conditionals. \def\ignoresections{% \let\chapter=\relax \let\unnumbered=\relax \let\top=\relax \let\unnumberedsec=\relax \let\unnumberedsection=\relax \let\unnumberedsubsec=\relax \let\unnumberedsubsection=\relax \let\unnumberedsubsubsec=\relax \let\unnumberedsubsubsection=\relax \let\section=\relax \let\subsec=\relax \let\subsubsec=\relax \let\subsection=\relax \let\subsubsection=\relax \let\appendix=\relax \let\appendixsec=\relax \let\appendixsection=\relax \let\appendixsubsec=\relax \let\appendixsubsection=\relax \let\appendixsubsubsec=\relax \let\appendixsubsubsection=\relax \let\contents=\relax \let\smallbook=\relax \let\titlepage=\relax } % Used in nested conditionals, where we have to parse the Texinfo source % and so want to turn off most commands, in case they are used % incorrectly. % % We use \empty instead of \relax for the @def... commands, so that \end % doesn't throw an error. For instance: % @ignore % @deffn ... % @end deffn % @end ignore % % The @end deffn is going to get expanded, because we're trying to allow % nested conditionals. But we don't want to expand the actual @deffn, % since it might be syntactically correct and intended to be ignored. % Since \end checks for \relax, using \empty does not cause an error. % \def\ignoremorecommands{% \let\defcodeindex = \relax \let\defcv = \empty \let\defcvx = \empty \let\Edefcv = \empty \let\deffn = \empty \let\deffnx = \empty \let\Edeffn = \empty \let\defindex = \relax \let\defivar = \empty \let\defivarx = \empty \let\Edefivar = \empty \let\defmac = \empty \let\defmacx = \empty \let\Edefmac = \empty \let\defmethod = \empty \let\defmethodx = \empty \let\Edefmethod = \empty \let\defop = \empty \let\defopx = \empty \let\Edefop = \empty \let\defopt = \empty \let\defoptx = \empty \let\Edefopt = \empty \let\defspec = \empty \let\defspecx = \empty \let\Edefspec = \empty \let\deftp = \empty \let\deftpx = \empty \let\Edeftp = \empty \let\deftypefn = \empty \let\deftypefnx = \empty \let\Edeftypefn = \empty \let\deftypefun = \empty \let\deftypefunx = \empty \let\Edeftypefun = \empty \let\deftypeivar = \empty \let\deftypeivarx = \empty \let\Edeftypeivar = \empty \let\deftypemethod = \empty \let\deftypemethodx = \empty \let\Edeftypemethod = \empty \let\deftypeop = \empty \let\deftypeopx = \empty \let\Edeftypeop = \empty \let\deftypevar = \empty \let\deftypevarx = \empty \let\Edeftypevar = \empty \let\deftypevr = \empty \let\deftypevrx = \empty \let\Edeftypevr = \empty \let\defun = \empty \let\defunx = \empty \let\Edefun = \empty \let\defvar = \empty \let\defvarx = \empty \let\Edefvar = \empty \let\defvr = \empty \let\defvrx = \empty \let\Edefvr = \empty \let\clear = \relax \let\down = \relax \let\evenfooting = \relax \let\evenheading = \relax \let\everyfooting = \relax \let\everyheading = \relax \let\headings = \relax \let\include = \relax \let\item = \relax \let\lowersections = \relax \let\oddfooting = \relax \let\oddheading = \relax \let\printindex = \relax \let\pxref = \relax \let\raisesections = \relax \let\ref = \relax \let\set = \relax \let\setchapternewpage = \relax \let\setchapterstyle = \relax \let\settitle = \relax \let\up = \relax \let\verbatiminclude = \relax \let\xref = \relax } % Ignore @ignore, @ifhtml, @ifinfo, and the like. % \def\direntry{\doignore{direntry}} \def\documentdescriptionword{documentdescription} \def\documentdescription{\doignore{documentdescription}} \def\html{\doignore{html}} \def\ifhtml{\doignore{ifhtml}} \def\ifinfo{\doignore{ifinfo}} \def\ifnottex{\doignore{ifnottex}} \def\ifplaintext{\doignore{ifplaintext}} \def\ifxml{\doignore{ifxml}} \def\ignore{\doignore{ignore}} \def\menu{\doignore{menu}} \def\xml{\doignore{xml}} % @dircategory CATEGORY -- specify a category of the dir file % which this file should belong to. Ignore this in TeX. \let\dircategory = \comment % Ignore text until a line `@end #1'. % \def\doignore#1{\begingroup % Don't complain about control sequences we have declared \outer. \ignoresections % % Define a command to swallow text until we reach `@end #1'. % This @ is a catcode 12 token (that is the normal catcode of @ in % this texinfo.tex file). We change the catcode of @ below to match. \long\def\doignoretext##1@end #1{\enddoignore}% % % Make sure that spaces turn into tokens that match what \doignoretext wants. \catcode\spaceChar = 10 % % Ignore braces, too, so mismatched braces don't cause trouble. \catcode`\{ = 9 \catcode`\} = 9 % % We must not have @c interpreted as a control sequence. \catcode`\@ = 12 % \def\ignoreword{#1}% \ifx\ignoreword\documentdescriptionword % The c kludge breaks documentdescription, since % `documentdescription' contains a `c'. Means not everything will % be ignored inside @documentdescription, but oh well... \else % Make the letter c a comment character so that the rest of the line % will be ignored. This way, the document can have (for example) % @c @end ifinfo % and the @end ifinfo will be properly ignored. % (We've just changed @ to catcode 12.) \catcode`\c = 14 \fi % % And now expand the command defined above. \doignoretext } % What we do to finish off ignored text. % \def\enddoignore{\endgroup\ignorespaces}% \newif\ifwarnedobs\warnedobsfalse \def\obstexwarn{% \ifwarnedobs\relax\else % We need to warn folks that they may have trouble with TeX 3.0. % This uses \immediate\write16 rather than \message to get newlines. \immediate\write16{} \immediate\write16{WARNING: for users of Unix TeX 3.0!} \immediate\write16{This manual trips a bug in TeX version 3.0 (tex hangs).} \immediate\write16{If you are running another version of TeX, relax.} \immediate\write16{If you are running Unix TeX 3.0, kill this TeX process.} \immediate\write16{ Then upgrade your TeX installation if you can.} \immediate\write16{ (See ftp://ftp.gnu.org/non-gnu/TeX.README.)} \immediate\write16{If you are stuck with version 3.0, run the} \immediate\write16{ script ``tex3patch'' from the Texinfo distribution} \immediate\write16{ to use a workaround.} \immediate\write16{} \global\warnedobstrue \fi } % **In TeX 3.0, setting text in \nullfont hangs tex. For a % workaround (which requires the file ``dummy.tfm'' to be installed), % uncomment the following line: %%%%%\font\nullfont=dummy\let\obstexwarn=\relax % Ignore text, except that we keep track of conditional commands for % purposes of nesting, up to an `@end #1' command. % \def\nestedignore#1{% \obstexwarn % We must actually expand the ignored text to look for the @end % command, so that nested ignore constructs work. Thus, we put the % text into a \vbox and then do nothing with the result. To minimize % the chance of memory overflow, we follow the approach outlined on % page 401 of the TeXbook. % \setbox0 = \vbox\bgroup % Don't complain about control sequences we have declared \outer. \ignoresections % % Define `@end #1' to end the box, which will in turn undefine the % @end command again. \expandafter\def\csname E#1\endcsname{\egroup\ignorespaces}% % % We are going to be parsing Texinfo commands. Most cause no % trouble when they are used incorrectly, but some commands do % complicated argument parsing or otherwise get confused, so we % undefine them. % % We can't do anything about stray @-signs, unfortunately; % they'll produce `undefined control sequence' errors. \ignoremorecommands % % Set the current font to be \nullfont, a TeX primitive, and define % all the font commands to also use \nullfont. We don't use % dummy.tfm, as suggested in the TeXbook, because some sites % might not have that installed. Therefore, math mode will still % produce output, but that should be an extremely small amount of % stuff compared to the main input. % \nullfont \let\tenrm=\nullfont \let\tenit=\nullfont \let\tensl=\nullfont \let\tenbf=\nullfont \let\tentt=\nullfont \let\smallcaps=\nullfont \let\tensf=\nullfont % Similarly for index fonts. \let\smallrm=\nullfont \let\smallit=\nullfont \let\smallsl=\nullfont \let\smallbf=\nullfont \let\smalltt=\nullfont \let\smallsc=\nullfont \let\smallsf=\nullfont % Similarly for smallexample fonts. \let\smallerrm=\nullfont \let\smallerit=\nullfont \let\smallersl=\nullfont \let\smallerbf=\nullfont \let\smallertt=\nullfont \let\smallersc=\nullfont \let\smallersf=\nullfont % % Don't complain when characters are missing from the fonts. \tracinglostchars = 0 % % Don't bother to do space factor calculations. \frenchspacing % % Don't report underfull hboxes. \hbadness = 10000 % % Do minimal line-breaking. \pretolerance = 10000 % % Do not execute instructions in @tex. \def\tex{\doignore{tex}}% % Do not execute macro definitions. % `c' is a comment character, so the word `macro' will get cut off. \def\macro{\doignore{ma}}% } % @set VAR sets the variable VAR to an empty value. % @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. % % Since we want to separate VAR from REST-OF-LINE (which might be % empty), we can't just use \parsearg; we have to insert a space of our % own to delimit the rest of the line, and then take it out again if we % didn't need it. Make sure the catcode of space is correct to avoid % losing inside @example, for instance. % \def\set{\begingroup\catcode` =10 \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR. \parsearg\setxxx} \def\setxxx#1{\setyyy#1 \endsetyyy} \def\setyyy#1 #2\endsetyyy{% \def\temp{#2}% \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted. \fi \endgroup } % Can't use \xdef to pre-expand #2 and save some time, since \temp or % \next or other control sequences that we've defined might get us into % an infinite loop. Consider `@set foo @cite{bar}'. \def\setzzz#1#2 \endsetzzz{\expandafter\gdef\csname SET#1\endcsname{#2}} % @clear VAR clears (i.e., unsets) the variable VAR. % \def\clear{\parsearg\clearxxx} \def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax} % @value{foo} gets the text saved in variable foo. { \catcode`\_ = \active % % We might end up with active _ or - characters in the argument if % we're called from @code, as @code{@value{foo-bar_}}. So \let any % such active characters to their normal equivalents. \gdef\value{\begingroup \catcode`\-=\other \catcode`\_=\other \indexbreaks \let_\normalunderscore \valuexxx} } \def\valuexxx#1{\expandablevalue{#1}\endgroup} % We have this subroutine so that we can handle at least some @value's % properly in indexes (we \let\value to this in \indexdummies). Ones % whose names contain - or _ still won't work, but we can't do anything % about that. The command has to be fully expandable (if the variable % is set), since the result winds up in the index file. This means that % if the variable's value contains other Texinfo commands, it's almost % certain it will fail (although perhaps we could fix that with % sufficient work to do a one-level expansion on the result, instead of % complete). % \def\expandablevalue#1{% \expandafter\ifx\csname SET#1\endcsname\relax {[No value for ``#1'']}% \message{Variable `#1', used in @value, is not set.}% \else \csname SET#1\endcsname \fi } % @ifset VAR ... @end ifset reads the `...' iff VAR has been defined % with @set. % \def\ifset{\parsearg\doifset} \def\doifset#1{% \expandafter\ifx\csname SET#1\endcsname\relax \let\next=\ifsetfail \else \let\next=\ifsetsucceed \fi \next } \def\ifsetsucceed{\conditionalsucceed{ifset}} \def\ifsetfail{\nestedignore{ifset}} \defineunmatchedend{ifset} % @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been % defined with @set, or has been undefined with @clear. % \def\ifclear{\parsearg\doifclear} \def\doifclear#1{% \expandafter\ifx\csname SET#1\endcsname\relax \let\next=\ifclearsucceed \else \let\next=\ifclearfail \fi \next } \def\ifclearsucceed{\conditionalsucceed{ifclear}} \def\ifclearfail{\nestedignore{ifclear}} \defineunmatchedend{ifclear} % @iftex, @ifnothtml, @ifnotinfo, @ifnotplaintext always succeed; we % read the text following, through the first @end iftex (etc.). Make % `@end iftex' (etc.) valid only after an @iftex. % \def\iftex{\conditionalsucceed{iftex}} \def\ifnothtml{\conditionalsucceed{ifnothtml}} \def\ifnotinfo{\conditionalsucceed{ifnotinfo}} \def\ifnotplaintext{\conditionalsucceed{ifnotplaintext}} \defineunmatchedend{iftex} \defineunmatchedend{ifnothtml} \defineunmatchedend{ifnotinfo} \defineunmatchedend{ifnotplaintext} % True conditional. Since \set globally defines its variables, we can % just start and end a group (to keep the @end definition undefined at % the outer level). % \def\conditionalsucceed#1{\begingroup \expandafter\def\csname E#1\endcsname{\endgroup}% } % @defininfoenclose. \let\definfoenclose=\comment \message{indexing,} % Index generation facilities % Define \newwrite to be identical to plain tex's \newwrite % except not \outer, so it can be used within \newindex. {\catcode`\@=11 \gdef\newwrite{\alloc@7\write\chardef\sixt@@n}} % \newindex {foo} defines an index named foo. % It automatically defines \fooindex such that % \fooindex ...rest of line... puts an entry in the index foo. % It also defines \fooindfile to be the number of the output channel for % the file that accumulates this index. The file's extension is foo. % The name of an index should be no more than 2 characters long % for the sake of vms. % \def\newindex#1{% \iflinks \expandafter\newwrite \csname#1indfile\endcsname \openout \csname#1indfile\endcsname \jobname.#1 % Open the file \fi \expandafter\xdef\csname#1index\endcsname{% % Define @#1index \noexpand\doindex{#1}} } % @defindex foo == \newindex{foo} % \def\defindex{\parsearg\newindex} % Define @defcodeindex, like @defindex except put all entries in @code. % \def\defcodeindex{\parsearg\newcodeindex} % \def\newcodeindex#1{% \iflinks \expandafter\newwrite \csname#1indfile\endcsname \openout \csname#1indfile\endcsname \jobname.#1 \fi \expandafter\xdef\csname#1index\endcsname{% \noexpand\docodeindex{#1}}% } % @synindex foo bar makes index foo feed into index bar. % Do this instead of @defindex foo if you don't want it as a separate index. % % @syncodeindex foo bar similar, but put all entries made for index foo % inside @code. % \def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}} \def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}} % #1 is \doindex or \docodeindex, #2 the index getting redefined (foo), % #3 the target index (bar). \def\dosynindex#1#2#3{% % Only do \closeout if we haven't already done it, else we'll end up % closing the target index. \expandafter \ifx\csname donesynindex#2\endcsname \undefined % The \closeout helps reduce unnecessary open files; the limit on the % Acorn RISC OS is a mere 16 files. \expandafter\closeout\csname#2indfile\endcsname \expandafter\let\csname\donesynindex#2\endcsname = 1 \fi % redefine \fooindfile: \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname \expandafter\let\csname#2indfile\endcsname=\temp % redefine \fooindex: \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}% } % Define \doindex, the driver for all \fooindex macros. % Argument #1 is generated by the calling \fooindex macro, % and it is "foo", the name of the index. % \doindex just uses \parsearg; it calls \doind for the actual work. % This is because \doind is more useful to call from other macros. % There is also \dosubind {index}{topic}{subtopic} % which makes an entry in a two-level index such as the operation index. \def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} \def\singleindexer #1{\doind{\indexname}{#1}} % like the previous two, but they put @code around the argument. \def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} \def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} % Take care of Texinfo commands that can appear in an index entry. % Since there are some commands we want to expand, and others we don't, % we have to laboriously prevent expansion for those that we don't. % \def\indexdummies{% \def\@{@}% change to @@ when we switch to @ as escape char in index files. \def\ {\realbackslash\space }% % Need these in case \tex is in effect and \{ is a \delimiter again. % But can't use \lbracecmd and \rbracecmd because texindex assumes % braces and backslashes are used only as delimiters. \let\{ = \mylbrace \let\} = \myrbrace % % \definedummyword defines \#1 as \realbackslash #1\space, thus % effectively preventing its expansion. This is used only for control % words, not control letters, because the \space would be incorrect % for control characters, but is needed to separate the control word % from whatever follows. % % For control letters, we have \definedummyletter, which omits the % space. % % These can be used both for control words that take an argument and % those that do not. If it is followed by {arg} in the input, then % that will dutifully get written to the index (or wherever). % \def\definedummyword##1{% \expandafter\def\csname ##1\endcsname{\realbackslash ##1\space}% }% \def\definedummyletter##1{% \expandafter\def\csname ##1\endcsname{\realbackslash ##1}% }% % % Do the redefinitions. \commondummies } % For the aux file, @ is the escape character. So we want to redefine % everything using @ instead of \realbackslash. When everything uses % @, this will be simpler. % \def\atdummies{% \def\@{@@}% \def\ {@ }% \let\{ = \lbraceatcmd \let\} = \rbraceatcmd % % (See comments in \indexdummies.) \def\definedummyword##1{% \expandafter\def\csname ##1\endcsname{@##1\space}% }% \def\definedummyletter##1{% \expandafter\def\csname ##1\endcsname{@##1}% }% % % Do the redefinitions. \commondummies } % Called from \indexdummies and \atdummies. \definedummyword and % \definedummyletter must be defined first. % \def\commondummies{% % \normalturnoffactive % % Control letters and accents. \definedummyletter{_}% \definedummyletter{,}% \definedummyletter{"}% \definedummyletter{`}% \definedummyletter{'}% \definedummyletter{^}% \definedummyletter{~}% \definedummyletter{=}% \definedummyword{u}% \definedummyword{v}% \definedummyword{H}% \definedummyword{dotaccent}% \definedummyword{ringaccent}% \definedummyword{tieaccent}% \definedummyword{ubaraccent}% \definedummyword{udotaccent}% \definedummyword{dotless}% % % Other non-English letters. \definedummyword{AA}% \definedummyword{AE}% \definedummyword{L}% \definedummyword{OE}% \definedummyword{O}% \definedummyword{aa}% \definedummyword{ae}% \definedummyword{l}% \definedummyword{oe}% \definedummyword{o}% \definedummyword{ss}% % % Although these internal commands shouldn't show up, sometimes they do. \definedummyword{bf}% \definedummyword{gtr}% \definedummyword{hat}% \definedummyword{less}% \definedummyword{sf}% \definedummyword{sl}% \definedummyword{tclose}% \definedummyword{tt}% % % Texinfo font commands. \definedummyword{b}% \definedummyword{i}% \definedummyword{r}% \definedummyword{sc}% \definedummyword{t}% % \definedummyword{TeX}% \definedummyword{acronym}% \definedummyword{cite}% \definedummyword{code}% \definedummyword{command}% \definedummyword{dfn}% \definedummyword{dots}% \definedummyword{emph}% \definedummyword{env}% \definedummyword{file}% \definedummyword{kbd}% \definedummyword{key}% \definedummyword{math}% \definedummyword{option}% \definedummyword{samp}% \definedummyword{strong}% \definedummyword{uref}% \definedummyword{url}% \definedummyword{var}% \definedummyword{w}% % % Assorted special characters. \definedummyword{bullet}% \definedummyword{copyright}% \definedummyword{dots}% \definedummyword{enddots}% \definedummyword{equiv}% \definedummyword{error}% \definedummyword{expansion}% \definedummyword{minus}% \definedummyword{pounds}% \definedummyword{point}% \definedummyword{print}% \definedummyword{result}% % % Handle some cases of @value -- where the variable name does not % contain - or _, and the value does not contain any % (non-fully-expandable) commands. \let\value = \expandablevalue % % Normal spaces, not active ones. \unsepspaces % % No macro expansion. \turnoffmacros } % If an index command is used in an @example environment, any spaces % therein should become regular spaces in the raw index file, not the % expansion of \tie (\leavevmode \penalty \@M \ ). {\obeyspaces \gdef\unsepspaces{\obeyspaces\let =\space}} % \indexnofonts is used when outputting the strings to sort the index % by, and when constructing control sequence names. It eliminates all % control sequences and just writes whatever the best ASCII sort string % would be for a given command (usually its argument). % \def\indexdummytex{TeX} \def\indexdummydots{...} % \def\indexnofonts{% \def\ { }% \def\@{@}% % how to handle braces? \def\_{\normalunderscore}% % \let\,=\asis \let\"=\asis \let\`=\asis \let\'=\asis \let\^=\asis \let\~=\asis \let\==\asis \let\u=\asis \let\v=\asis \let\H=\asis \let\dotaccent=\asis \let\ringaccent=\asis \let\tieaccent=\asis \let\ubaraccent=\asis \let\udotaccent=\asis \let\dotless=\asis % % Other non-English letters. \def\AA{AA}% \def\AE{AE}% \def\L{L}% \def\OE{OE}% \def\O{O}% \def\aa{aa}% \def\ae{ae}% \def\l{l}% \def\oe{oe}% \def\o{o}% \def\ss{ss}% \def\exclamdown{!}% \def\questiondown{?}% % % Don't no-op \tt, since it isn't a user-level command % and is used in the definitions of the active chars like <, >, |, etc. % Likewise with the other plain tex font commands. %\let\tt=\asis % % Texinfo font commands. \let\b=\asis \let\i=\asis \let\r=\asis \let\sc=\asis \let\t=\asis % \let\TeX=\indexdummytex \let\acronym=\asis \let\cite=\asis \let\code=\asis \let\command=\asis \let\dfn=\asis \let\dots=\indexdummydots \let\emph=\asis \let\env=\asis \let\file=\asis \let\kbd=\asis \let\key=\asis \let\math=\asis \let\option=\asis \let\samp=\asis \let\strong=\asis \let\uref=\asis \let\url=\asis \let\var=\asis \let\w=\asis } \let\indexbackslash=0 %overridden during \printindex. \let\SETmarginindex=\relax % put index entries in margin (undocumented)? % For \ifx comparisons. \def\emptymacro{\empty} % Most index entries go through here, but \dosubind is the general case. % \def\doind#1#2{\dosubind{#1}{#2}\empty} % Workhorse for all \fooindexes. % #1 is name of index, #2 is stuff to put there, #3 is subentry -- % \empty if called from \doind, as we usually are. The main exception % is with defuns, which call us directly. % \def\dosubind#1#2#3{% % Put the index entry in the margin if desired. \ifx\SETmarginindex\relax\else \insert\margin{\hbox{\vrule height8pt depth3pt width0pt #2}}% \fi {% \count255=\lastpenalty {% \indexdummies % Must do this here, since \bf, etc expand at this stage \escapechar=`\\ {% \let\folio = 0% We will expand all macros now EXCEPT \folio. \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now % so it will be output as is; and it will print as backslash. % % The main index entry text. \toks0 = {#2}% % % If third arg is present, precede it with space in sort key. \def\thirdarg{#3}% \ifx\thirdarg\emptymacro \else % If the third (subentry) arg is present, add it to the index % line to write. \toks0 = \expandafter{\the\toks0 \space #3}% \fi % % Process the index entry with all font commands turned off, to % get the string to sort by. {\indexnofonts \edef\temp{\the\toks0}% need full expansion \xdef\indexsorttmp{\temp}% }% % % Set up the complete index entry, with both the sort key and % the original text, including any font commands. We write % three arguments to \entry to the .?? file (four in the % subentry case), texindex reduces to two when writing the .??s % sorted result. \edef\temp{% \write\csname#1indfile\endcsname{% \realbackslash entry{\indexsorttmp}{\folio}{\the\toks0}}% }% % % If a skip is the last thing on the list now, preserve it % by backing up by \lastskip, doing the \write, then inserting % the skip again. Otherwise, the whatsit generated by the % \write will make \lastskip zero. The result is that sequences % like this: % @end defun % @tindex whatever % @defun ... % will have extra space inserted, because the \medbreak in the % start of the @defun won't see the skip inserted by the @end of % the previous defun. % % But don't do any of this if we're not in vertical mode. We % don't want to do a \vskip and prematurely end a paragraph. % % Avoid page breaks due to these extra skips, too. % \iflinks \ifvmode \skip0 = \lastskip \ifdim\lastskip = 0pt \else \nobreak\vskip-\skip0 \fi \fi % \temp % do the write % \ifvmode \ifdim\skip0 = 0pt \else \nobreak\vskip\skip0 \fi \fi \fi }% }% \penalty\count255 }% } % The index entry written in the file actually looks like % \entry {sortstring}{page}{topic} % or % \entry {sortstring}{page}{topic}{subtopic} % The texindex program reads in these files and writes files % containing these kinds of lines: % \initial {c} % before the first topic whose initial is c % \entry {topic}{pagelist} % for a topic that is used without subtopics % \primary {topic} % for the beginning of a topic that is used with subtopics % \secondary {subtopic}{pagelist} % for each subtopic. % Define the user-accessible indexing commands % @findex, @vindex, @kindex, @cindex. \def\findex {\fnindex} \def\kindex {\kyindex} \def\cindex {\cpindex} \def\vindex {\vrindex} \def\tindex {\tpindex} \def\pindex {\pgindex} \def\cindexsub {\begingroup\obeylines\cindexsub} {\obeylines % \gdef\cindexsub "#1" #2^^M{\endgroup % \dosubind{cp}{#2}{#1}}} % Define the macros used in formatting output of the sorted index material. % @printindex causes a particular index (the ??s file) to get printed. % It does not print any chapter heading (usually an @unnumbered). % \def\printindex{\parsearg\doprintindex} \def\doprintindex#1{\begingroup \dobreak \chapheadingskip{10000}% % \smallfonts \rm \tolerance = 9500 \everypar = {}% don't want the \kern\-parindent from indentation suppression. \indexbreaks % % See if the index file exists and is nonempty. % Change catcode of @ here so that if the index file contains % \initial {@} % as its first line, TeX doesn't complain about mismatched braces % (because it thinks @} is a control sequence). \catcode`\@ = 11 \openin 1 \jobname.#1s \ifeof 1 % \enddoublecolumns gets confused if there is no text in the index, % and it loses the chapter title and the aux file entries for the % index. The easiest way to prevent this problem is to make sure % there is some text. \putwordIndexNonexistent \else % % If the index file exists but is empty, then \openin leaves \ifeof % false. We have to make TeX try to read something from the file, so % it can discover if there is anything in it. \read 1 to \temp \ifeof 1 \putwordIndexIsEmpty \else % Index files are almost Texinfo source, but we use \ as the escape % character. It would be better to use @, but that's too big a change % to make right now. \def\indexbackslash{\rawbackslashxx}% \catcode`\\ = 0 \escapechar = `\\ \begindoublecolumns \input \jobname.#1s \enddoublecolumns \fi \fi \closein 1 \endgroup} % These macros are used by the sorted index file itself. % Change them to control the appearance of the index. \def\initial#1{{% % Some minor font changes for the special characters. \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt % % Remove any glue we may have, we'll be inserting our own. \removelastskip % % We like breaks before the index initials, so insert a bonus. \penalty -300 % % Typeset the initial. Making this add up to a whole number of % baselineskips increases the chance of the dots lining up from column % to column. It still won't often be perfect, because of the stretch % we need before each entry, but it's better. % % No shrink because it confuses \balancecolumns. \vskip 1.67\baselineskip plus .5\baselineskip \leftline{\secbf #1}% \vskip .33\baselineskip plus .1\baselineskip % % Do our best not to break after the initial. \nobreak }} % This typesets a paragraph consisting of #1, dot leaders, and then #2 % flush to the right margin. It is used for index and table of contents % entries. The paragraph is indented by \leftskip. % \def\entry#1#2{\begingroup % % Start a new paragraph if necessary, so our assignments below can't % affect previous text. \par % % Do not fill out the last line with white space. \parfillskip = 0in % % No extra space above this paragraph. \parskip = 0in % % Do not prefer a separate line ending with a hyphen to fewer lines. \finalhyphendemerits = 0 % % \hangindent is only relevant when the entry text and page number % don't both fit on one line. In that case, bob suggests starting the % dots pretty far over on the line. Unfortunately, a large % indentation looks wrong when the entry text itself is broken across % lines. So we use a small indentation and put up with long leaders. % % \hangafter is reset to 1 (which is the value we want) at the start % of each paragraph, so we need not do anything with that. \hangindent = 2em % % When the entry text needs to be broken, just fill out the first line % with blank space. \rightskip = 0pt plus1fil % % A bit of stretch before each entry for the benefit of balancing columns. \vskip 0pt plus1pt % % Start a ``paragraph'' for the index entry so the line breaking % parameters we've set above will have an effect. \noindent % % Insert the text of the index entry. TeX will do line-breaking on it. #1% % The following is kludged to not output a line of dots in the index if % there are no page numbers. The next person who breaks this will be % cursed by a Unix daemon. \def\tempa{{\rm }}% \def\tempb{#2}% \edef\tempc{\tempa}% \edef\tempd{\tempb}% \ifx\tempc\tempd\ \else% % % If we must, put the page number on a line of its own, and fill out % this line with blank space. (The \hfil is overwhelmed with the % fill leaders glue in \indexdotfill if the page number does fit.) \hfil\penalty50 \null\nobreak\indexdotfill % Have leaders before the page number. % % The `\ ' here is removed by the implicit \unskip that TeX does as % part of (the primitive) \par. Without it, a spurious underfull % \hbox ensues. \ifpdf \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. \else \ #2% The page number ends the paragraph. \fi \fi% \par \endgroup} % Like \dotfill except takes at least 1 em. \def\indexdotfill{\cleaders \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill} \def\primary #1{\line{#1\hfil}} \newskip\secondaryindent \secondaryindent=0.5cm \def\secondary#1#2{{% \parfillskip=0in \parskip=0in \hangindent=1in \hangafter=1 \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill \ifpdf \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. \else #2 \fi \par }} % Define two-column mode, which we use to typeset indexes. % Adapted from the TeXbook, page 416, which is to say, % the manmac.tex format used to print the TeXbook itself. \catcode`\@=11 \newbox\partialpage \newdimen\doublecolumnhsize \def\begindoublecolumns{\begingroup % ended by \enddoublecolumns % Grab any single-column material above us. \output = {% % % Here is a possibility not foreseen in manmac: if we accumulate a % whole lot of material, we might end up calling this \output % routine twice in a row (see the doublecol-lose test, which is % essentially a couple of indexes with @setchapternewpage off). In % that case we just ship out what is in \partialpage with the normal % output routine. Generally, \partialpage will be empty when this % runs and this will be a no-op. See the indexspread.tex test case. \ifvoid\partialpage \else \onepageout{\pagecontents\partialpage}% \fi % \global\setbox\partialpage = \vbox{% % Unvbox the main output page. \unvbox\PAGE \kern-\topskip \kern\baselineskip }% }% \eject % run that output routine to set \partialpage % % Use the double-column output routine for subsequent pages. \output = {\doublecolumnout}% % % Change the page size parameters. We could do this once outside this % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 % format, but then we repeat the same computation. Repeating a couple % of assignments once per index is clearly meaningless for the % execution time, so we may as well do it in one place. % % First we halve the line length, less a little for the gutter between % the columns. We compute the gutter based on the line length, so it % changes automatically with the paper format. The magic constant % below is chosen so that the gutter has the same value (well, +-<1pt) % as it did when we hard-coded it. % % We put the result in a separate register, \doublecolumhsize, so we % can restore it in \pagesofar, after \hsize itself has (potentially) % been clobbered. % \doublecolumnhsize = \hsize \advance\doublecolumnhsize by -.04154\hsize \divide\doublecolumnhsize by 2 \hsize = \doublecolumnhsize % % Double the \vsize as well. (We don't need a separate register here, % since nobody clobbers \vsize.) \vsize = 2\vsize } % The double-column output routine for all double-column pages except % the last. % \def\doublecolumnout{% \splittopskip=\topskip \splitmaxdepth=\maxdepth % Get the available space for the double columns -- the normal % (undoubled) page height minus any material left over from the % previous page. \dimen@ = \vsize \divide\dimen@ by 2 \advance\dimen@ by -\ht\partialpage % % box0 will be the left-hand column, box2 the right. \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ \onepageout\pagesofar \unvbox255 \penalty\outputpenalty } % % Re-output the contents of the output page -- any previous material, % followed by the two boxes we just split, in box0 and box2. \def\pagesofar{% \unvbox\partialpage % \hsize = \doublecolumnhsize \wd0=\hsize \wd2=\hsize \hbox to\pagewidth{\box0\hfil\box2}% } % % All done with double columns. \def\enddoublecolumns{% \output = {% % Split the last of the double-column material. Leave it on the % current page, no automatic page break. \balancecolumns % % If we end up splitting too much material for the current page, % though, there will be another page break right after this \output % invocation ends. Having called \balancecolumns once, we do not % want to call it again. Therefore, reset \output to its normal % definition right away. (We hope \balancecolumns will never be % called on to balance too much material, but if it is, this makes % the output somewhat more palatable.) \global\output = {\onepageout{\pagecontents\PAGE}}% }% \eject \endgroup % started in \begindoublecolumns % % \pagegoal was set to the doubled \vsize above, since we restarted % the current page. We're now back to normal single-column % typesetting, so reset \pagegoal to the normal \vsize (after the % \endgroup where \vsize got restored). \pagegoal = \vsize } % % Called at the end of the double column material. \def\balancecolumns{% \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120. \dimen@ = \ht0 \advance\dimen@ by \topskip \advance\dimen@ by-\baselineskip \divide\dimen@ by 2 % target to split to %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}% \splittopskip = \topskip % Loop until we get a decent breakpoint. {% \vbadness = 10000 \loop \global\setbox3 = \copy0 \global\setbox1 = \vsplit3 to \dimen@ \ifdim\ht3>\dimen@ \global\advance\dimen@ by 1pt \repeat }% %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}% \setbox0=\vbox to\dimen@{\unvbox1}% \setbox2=\vbox to\dimen@{\unvbox3}% % \pagesofar } \catcode`\@ = \other \message{sectioning,} % Chapters, sections, etc. \newcount\chapno \newcount\secno \secno=0 \newcount\subsecno \subsecno=0 \newcount\subsubsecno \subsubsecno=0 % This counter is funny since it counts through charcodes of letters A, B, ... \newcount\appendixno \appendixno = `\@ % \def\appendixletter{\char\the\appendixno} % We do the following for the sake of pdftex, which needs the actual % letter in the expansion, not just typeset. \def\appendixletter{% \ifnum\appendixno=`A A% \else\ifnum\appendixno=`B B% \else\ifnum\appendixno=`C C% \else\ifnum\appendixno=`D D% \else\ifnum\appendixno=`E E% \else\ifnum\appendixno=`F F% \else\ifnum\appendixno=`G G% \else\ifnum\appendixno=`H H% \else\ifnum\appendixno=`I I% \else\ifnum\appendixno=`J J% \else\ifnum\appendixno=`K K% \else\ifnum\appendixno=`L L% \else\ifnum\appendixno=`M M% \else\ifnum\appendixno=`N N% \else\ifnum\appendixno=`O O% \else\ifnum\appendixno=`P P% \else\ifnum\appendixno=`Q Q% \else\ifnum\appendixno=`R R% \else\ifnum\appendixno=`S S% \else\ifnum\appendixno=`T T% \else\ifnum\appendixno=`U U% \else\ifnum\appendixno=`V V% \else\ifnum\appendixno=`W W% \else\ifnum\appendixno=`X X% \else\ifnum\appendixno=`Y Y% \else\ifnum\appendixno=`Z Z% % The \the is necessary, despite appearances, because \appendixletter is % expanded while writing the .toc file. \char\appendixno is not % expandable, thus it is written literally, thus all appendixes come out % with the same letter (or @) in the toc without it. \else\char\the\appendixno \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} % Each @chapter defines this as the name of the chapter. % page headings and footings can use it. @section does likewise. \def\thischapter{} \def\thissection{} \newcount\absseclevel % used to calculate proper heading level \newcount\secbase\secbase=0 % @raise/lowersections modify this count % @raisesections: treat @section as chapter, @subsection as section, etc. \def\raisesections{\global\advance\secbase by -1} \let\up=\raisesections % original BFox name % @lowersections: treat @chapter as section, @section as subsection, etc. \def\lowersections{\global\advance\secbase by 1} \let\down=\lowersections % original BFox name % Choose a numbered-heading macro % #1 is heading level if unmodified by @raisesections or @lowersections % #2 is text for heading \def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \chapterzzz{#2} \or \seczzz{#2} \or \numberedsubseczzz{#2} \or \numberedsubsubseczzz{#2} \else \ifnum \absseclevel<0 \chapterzzz{#2} \else \numberedsubsubseczzz{#2} \fi \fi \suppressfirstparagraphindent } % like \numhead, but chooses appendix heading levels \def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \appendixzzz{#2} \or \appendixsectionzzz{#2} \or \appendixsubseczzz{#2} \or \appendixsubsubseczzz{#2} \else \ifnum \absseclevel<0 \appendixzzz{#2} \else \appendixsubsubseczzz{#2} \fi \fi \suppressfirstparagraphindent } % like \numhead, but chooses numberless heading levels \def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \unnumberedzzz{#2} \or \unnumberedseczzz{#2} \or \unnumberedsubseczzz{#2} \or \unnumberedsubsubseczzz{#2} \else \ifnum \absseclevel<0 \unnumberedzzz{#2} \else \unnumberedsubsubseczzz{#2} \fi \fi \suppressfirstparagraphindent } % @chapter, @appendix, @unnumbered. \def\thischaptername{No Chapter Title} \outer\def\chapter{\parsearg\chapteryyy} \def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz \def\chapterzzz #1{% \secno=0 \subsecno=0 \subsubsecno=0 \global\advance \chapno by 1 \message{\putwordChapter\space \the\chapno}% \chapmacro {#1}{\the\chapno}% \gdef\thissection{#1}% \gdef\thischaptername{#1}% % We don't substitute the actual chapter name into \thischapter % because we don't want its macros evaluated now. \xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}% \writetocentry{chap}{#1}{{\the\chapno}} \donoderef \global\let\section = \numberedsec \global\let\subsection = \numberedsubsec \global\let\subsubsection = \numberedsubsubsec } % we use \chapno to avoid indenting back \def\appendixbox#1{% \setbox0 = \hbox{\putwordAppendix{} \the\chapno}% \hbox to \wd0{#1\hss}} \outer\def\appendix{\parsearg\appendixyyy} \def\appendixyyy #1{\apphead0{#1}} % normally apphead0 calls appendixzzz \def\appendixzzz #1{% \secno=0 \subsecno=0 \subsubsecno=0 \global\advance \appendixno by 1 \message{\putwordAppendix\space \appendixletter}% \chapmacro {#1}{\appendixbox{\putwordAppendix{} \appendixletter}}% \gdef\thissection{#1}% \gdef\thischaptername{#1}% \xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}% \writetocentry{appendix}{#1}{{\appendixletter}} \appendixnoderef \global\let\section = \appendixsec \global\let\subsection = \appendixsubsec \global\let\subsubsection = \appendixsubsubsec } % @centerchap is like @unnumbered, but the heading is centered. \outer\def\centerchap{\parsearg\centerchapyyy} \def\centerchapyyy #1{{\let\unnumbchapmacro=\centerchapmacro \unnumberedyyy{#1}}} % @top is like @unnumbered. \outer\def\top{\parsearg\unnumberedyyy} \outer\def\unnumbered{\parsearg\unnumberedyyy} \def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz \def\unnumberedzzz #1{% \secno=0 \subsecno=0 \subsubsecno=0 % % This used to be simply \message{#1}, but TeX fully expands the % argument to \message. Therefore, if #1 contained @-commands, TeX % expanded them. For example, in `@unnumbered The @cite{Book}', TeX % expanded @cite (which turns out to cause errors because \cite is meant % to be executed, not expanded). % % Anyway, we don't want the fully-expanded definition of @cite to appear % as a result of the \message, we just want `@cite' itself. We use % \the to achieve this: TeX expands \the only once, % simply yielding the contents of . (We also do this for % the toc entries.) \toks0 = {#1}\message{(\the\toks0)}% % \unnumbchapmacro {#1}% \gdef\thischapter{#1}\gdef\thissection{#1}% \writetocentry{unnumbchap}{#1}{{\the\chapno}} \unnumbnoderef \global\let\section = \unnumberedsec \global\let\subsection = \unnumberedsubsec \global\let\subsubsection = \unnumberedsubsubsec } % Sections. \outer\def\numberedsec{\parsearg\secyyy} \def\secyyy #1{\numhead1{#1}} % normally calls seczzz \def\seczzz #1{% \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % \gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}% \writetocentry{sec}{#1}{{\the\chapno}{\the\secno}} \donoderef \nobreak } \outer\def\appendixsection{\parsearg\appendixsecyyy} \outer\def\appendixsec{\parsearg\appendixsecyyy} \def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz \def\appendixsectionzzz #1{% \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % \gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}% \writetocentry{sec}{#1}{{\appendixletter}{\the\secno}} \appendixnoderef \nobreak } \outer\def\unnumberedsec{\parsearg\unnumberedsecyyy} \def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz \def\unnumberedseczzz #1{% \plainsecheading {#1}\gdef\thissection{#1}% \writetocentry{unnumbsec}{#1}{{\the\chapno}{\the\secno}} \unnumbnoderef \nobreak } % Subsections. \outer\def\numberedsubsec{\parsearg\numberedsubsecyyy} \def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz \def\numberedsubseczzz #1{% \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % \subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}% \writetocentry{subsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}} \donoderef \nobreak } \outer\def\appendixsubsec{\parsearg\appendixsubsecyyy} \def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz \def\appendixsubseczzz #1{% \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % \subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}% \writetocentry{subsec}{#1}{{\appendixletter}{\the\secno}{\the\subsecno}} \appendixnoderef \nobreak } \outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy} \def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz \def\unnumberedsubseczzz #1{% \plainsubsecheading {#1}\gdef\thissection{#1}% \writetocentry{unnumbsubsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}} \unnumbnoderef \nobreak } % Subsubsections. \outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy} \def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz \def\numberedsubsubseczzz #1{% \gdef\thissection{#1}\global\advance \subsubsecno by 1 % \subsubsecheading {#1} {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}% \writetocentry{subsubsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}} \donoderef \nobreak } \outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy} \def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz \def\appendixsubsubseczzz #1{% \gdef\thissection{#1}\global\advance \subsubsecno by 1 % \subsubsecheading {#1} {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}% \writetocentry{subsubsec}{#1}{{\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}} \appendixnoderef \nobreak } \outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy} \def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz \def\unnumberedsubsubseczzz #1{% \plainsubsubsecheading {#1}\gdef\thissection{#1}% \writetocentry{unnumbsubsubsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}} \unnumbnoderef \nobreak } % These are variants which are not "outer", so they can appear in @ifinfo. % Actually, they should now be obsolete; ordinary section commands should work. \def\infotop{\parsearg\unnumberedzzz} \def\infounnumbered{\parsearg\unnumberedzzz} \def\infounnumberedsec{\parsearg\unnumberedseczzz} \def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz} \def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz} \def\infoappendix{\parsearg\appendixzzz} \def\infoappendixsec{\parsearg\appendixseczzz} \def\infoappendixsubsec{\parsearg\appendixsubseczzz} \def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz} \def\infochapter{\parsearg\chapterzzz} \def\infosection{\parsearg\sectionzzz} \def\infosubsection{\parsearg\subsectionzzz} \def\infosubsubsection{\parsearg\subsubsectionzzz} % These macros control what the section commands do, according % to what kind of chapter we are in (ordinary, appendix, or unnumbered). % Define them by default for a numbered chapter. \global\let\section = \numberedsec \global\let\subsection = \numberedsubsec \global\let\subsubsection = \numberedsubsubsec % Define @majorheading, @heading and @subheading % NOTE on use of \vbox for chapter headings, section headings, and such: % 1) We use \vbox rather than the earlier \line to permit % overlong headings to fold. % 2) \hyphenpenalty is set to 10000 because hyphenation in a % heading is obnoxious; this forbids it. % 3) Likewise, headings look best if no \parindent is used, and % if justification is not attempted. Hence \raggedright. \def\majorheading{\parsearg\majorheadingzzz} \def\majorheadingzzz #1{% {\advance\chapheadingskip by 10pt \chapbreak }% {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\penalty 200} \def\chapheading{\parsearg\chapheadingzzz} \def\chapheadingzzz #1{\chapbreak % {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\penalty 200} % @heading, @subheading, @subsubheading. \def\heading{\parsearg\plainsecheading} \def\subheading{\parsearg\plainsubsecheading} \def\subsubheading{\parsearg\plainsubsubsecheading} % These macros generate a chapter, section, etc. heading only % (including whitespace, linebreaking, etc. around it), % given all the information in convenient, parsed form. %%% Args are the skip and penalty (usually negative) \def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} \def\setchapterstyle #1 {\csname CHAPF#1\endcsname} %%% Define plain chapter starts, and page on/off switching for it % Parameter controlling skip before chapter headings (if needed) \newskip\chapheadingskip \def\chapbreak{\dobreak \chapheadingskip {-4000}} \def\chappager{\par\vfill\supereject} \def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi} \def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} \def\CHAPPAGoff{% \global\let\contentsalignmacro = \chappager \global\let\pchapsepmacro=\chapbreak \global\let\pagealignmacro=\chappager} \def\CHAPPAGon{% \global\let\contentsalignmacro = \chappager \global\let\pchapsepmacro=\chappager \global\let\pagealignmacro=\chappager \global\def\HEADINGSon{\HEADINGSsingle}} \def\CHAPPAGodd{ \global\let\contentsalignmacro = \chapoddpage \global\let\pchapsepmacro=\chapoddpage \global\let\pagealignmacro=\chapoddpage \global\def\HEADINGSon{\HEADINGSdouble}} \CHAPPAGon \def\CHAPFplain{ \global\let\chapmacro=\chfplain \global\let\unnumbchapmacro=\unnchfplain \global\let\centerchapmacro=\centerchfplain} % Plain chapter opening. % #1 is the text, #2 the chapter number or empty if unnumbered. \def\chfplain#1#2{% \pchapsepmacro {% \chapfonts \rm \def\chapnum{#2}% \setbox0 = \hbox{#2\ifx\chapnum\empty\else\enspace\fi}% \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright \hangindent = \wd0 \centerparametersmaybe \unhbox0 #1\par}% }% \nobreak\bigskip % no page break after a chapter title \nobreak } % Plain opening for unnumbered. \def\unnchfplain#1{\chfplain{#1}{}} % @centerchap -- centered and unnumbered. \let\centerparametersmaybe = \relax \def\centerchfplain#1{{% \def\centerparametersmaybe{% \advance\rightskip by 3\rightskip \leftskip = \rightskip \parfillskip = 0pt }% \chfplain{#1}{}% }} \CHAPFplain % The default \def\unnchfopen #1{% \chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\nobreak } \def\chfopen #1#2{\chapoddpage {\chapfonts \vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% \par\penalty 5000 % } \def\centerchfopen #1{% \chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt \hfill {\rm #1}\hfill}}\bigskip \par\nobreak } \def\CHAPFopen{ \global\let\chapmacro=\chfopen \global\let\unnumbchapmacro=\unnchfopen \global\let\centerchapmacro=\centerchfopen} % Section titles. \newskip\secheadingskip \def\secheadingbreak{\dobreak \secheadingskip {-1000}} \def\secheading#1#2#3{\sectionheading{sec}{#2.#3}{#1}} \def\plainsecheading#1{\sectionheading{sec}{}{#1}} % Subsection titles. \newskip \subsecheadingskip \def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}} \def\subsecheading#1#2#3#4{\sectionheading{subsec}{#2.#3.#4}{#1}} \def\plainsubsecheading#1{\sectionheading{subsec}{}{#1}} % Subsubsection titles. \let\subsubsecheadingskip = \subsecheadingskip \let\subsubsecheadingbreak = \subsecheadingbreak \def\subsubsecheading#1#2#3#4#5{\sectionheading{subsubsec}{#2.#3.#4.#5}{#1}} \def\plainsubsubsecheading#1{\sectionheading{subsubsec}{}{#1}} % Print any size section title. % % #1 is the section type (sec/subsec/subsubsec), #2 is the section % number (maybe empty), #3 the text. \def\sectionheading#1#2#3{% {% \expandafter\advance\csname #1headingskip\endcsname by \parskip \csname #1headingbreak\endcsname }% {% % Switch to the right set of fonts. \csname #1fonts\endcsname \rm % % Only insert the separating space if we have a section number. \def\secnum{#2}% \setbox0 = \hbox{#2\ifx\secnum\empty\else\enspace\fi}% % \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright \hangindent = \wd0 % zero if no section number \unhbox0 #3}% }% % Add extra space after the heading -- either a line space or a % paragraph space, whichever is more. (Some people like to set % \parskip to large values for some reason.) Don't allow stretch, though. \nobreak \ifdim\parskip>\normalbaselineskip \kern\parskip \else \kern\normalbaselineskip \fi \nobreak } \message{toc,} % Table of contents. \newwrite\tocfile % Write an entry to the toc file, opening it if necessary. % Called from @chapter, etc. We supply {\folio} at the end of the % argument, which will end up as the last argument to the \...entry macro. % % Usage: \writetocentry{chap}{The Name of The Game}{{\the\chapno}} % We open the .toc file for writing here instead of at @setfilename (or % any other fixed time) so that @contents can be anywhere in the document. % \newif\iftocfileopened \def\writetocentry#1#2#3{% \iftocfileopened\else \immediate\openout\tocfile = \jobname.toc \global\tocfileopenedtrue \fi % \iflinks \toks0 = {#2}% \edef\temp{\write\tocfile{\realbackslash #1entry{\the\toks0}#3{\folio}}}% \temp \fi % % Tell \shipout to create a page destination if we're doing pdf, which % will be the target of the links in the table of contents. We can't % just do it on every page because the title pages are numbered 1 and % 2 (the page numbers aren't printed), and so are the first two pages % of the document. Thus, we'd have two destinations named `1', and % two named `2'. \ifpdf \pdfmakepagedesttrue \fi } \newskip\contentsrightmargin \contentsrightmargin=1in \newcount\savepageno \newcount\lastnegativepageno \lastnegativepageno = -1 % Finish up the main text and prepare to read what we've written % to \tocfile. % \def\startcontents#1{% % If @setchapternewpage on, and @headings double, the contents should % start on an odd page, unlike chapters. Thus, we maintain % \contentsalignmacro in parallel with \pagealignmacro. % From: Torbjorn Granlund \contentsalignmacro \immediate\closeout\tocfile % % Don't need to put `Contents' or `Short Contents' in the headline. % It is abundantly clear what they are. \unnumbchapmacro{#1}\def\thischapter{}% \savepageno = \pageno \begingroup % Set up to handle contents files properly. \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11 % We can't do this, because then an actual ^ in a section % title fails, e.g., @chapter ^ -- exponentiation. --karl, 9jul97. %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi \raggedbottom % Worry more about breakpoints than the bottom. \advance\hsize by -\contentsrightmargin % Don't use the full line length. % % Roman numerals for page numbers. \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi } % Normal (long) toc. \def\contents{% \startcontents{\putwordTOC}% \openin 1 \jobname.toc \ifeof 1 \else \closein 1 \input \jobname.toc \fi \vfill \eject \contentsalignmacro % in case @setchapternewpage odd is in effect \pdfmakeoutlines \endgroup \lastnegativepageno = \pageno \global\pageno = \savepageno } % And just the chapters. \def\summarycontents{% \startcontents{\putwordShortTOC}% % \let\chapentry = \shortchapentry \let\appendixentry = \shortappendixentry \let\unnumbchapentry = \shortunnumberedentry % We want a true roman here for the page numbers. \secfonts \let\rm=\shortcontrm \let\bf=\shortcontbf \let\sl=\shortcontsl \let\tt=\shortconttt \rm \hyphenpenalty = 10000 \advance\baselineskip by 1pt % Open it up a little. \def\secentry ##1##2##3##4{} \def\subsecentry ##1##2##3##4##5{} \def\subsubsecentry ##1##2##3##4##5##6{} \let\unnumbsecentry = \secentry \let\unnumbsubsecentry = \subsecentry \let\unnumbsubsubsecentry = \subsubsecentry \openin 1 \jobname.toc \ifeof 1 \else \closein 1 \input \jobname.toc \fi \vfill \eject \contentsalignmacro % in case @setchapternewpage odd is in effect \endgroup \lastnegativepageno = \pageno \global\pageno = \savepageno } \let\shortcontents = \summarycontents \ifpdf \pdfcatalog{/PageMode /UseOutlines}% \fi % These macros generate individual entries in the table of contents. % The first argument is the chapter or section name. % The last argument is the page number. % The arguments in between are the chapter number, section number, ... % Chapters, in the main contents. \def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}} % % Chapters, in the short toc. % See comments in \dochapentry re vbox and related settings. \def\shortchapentry#1#2#3{% \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#3\egroup}% } % Appendices, in the main contents. \def\appendixentry#1#2#3{% \dochapentry{\appendixbox{\putwordAppendix{} #2}\labelspace#1}{#3}} % % Appendices, in the short toc. \let\shortappendixentry = \shortchapentry % Typeset the label for a chapter or appendix for the short contents. % The arg is, e.g., `Appendix A' for an appendix, or `3' for a chapter. % We could simplify the code here by writing out an \appendixentry % command in the toc file for appendices, instead of using \chapentry % for both, but it doesn't seem worth it. % \newdimen\shortappendixwidth % \def\shortchaplabel#1{% % This space should be enough, since a single number is .5em, and the % widest letter (M) is 1em, at least in the Computer Modern fonts. % But use \hss just in case. % (This space doesn't include the extra space that gets added after % the label; that gets put in by \shortchapentry above.) \dimen0 = 1em \hbox to \dimen0{#1\hss}% } % Unnumbered chapters. \def\unnumbchapentry#1#2#3{\dochapentry{#1}{#3}} \def\shortunnumberedentry#1#2#3{\tocentry{#1}{\doshortpageno\bgroup#3\egroup}} % Sections. \def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}} \def\unnumbsecentry#1#2#3#4{\dosecentry{#1}{#4}} % Subsections. \def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}} \def\unnumbsubsecentry#1#2#3#4#5{\dosubsecentry{#1}{#5}} % And subsubsections. \def\subsubsecentry#1#2#3#4#5#6{% \dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}} \def\unnumbsubsubsecentry#1#2#3#4#5#6{\dosubsubsecentry{#1}{#6}} % This parameter controls the indentation of the various levels. \newdimen\tocindent \tocindent = 3pc % Now for the actual typesetting. In all these, #1 is the text and #2 is the % page number. % % If the toc has to be broken over pages, we want it to be at chapters % if at all possible; hence the \penalty. \def\dochapentry#1#2{% \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip \begingroup \chapentryfonts \tocentry{#1}{\dopageno\bgroup#2\egroup}% \endgroup \nobreak\vskip .25\baselineskip plus.1\baselineskip } \def\dosecentry#1#2{\begingroup \secentryfonts \leftskip=\tocindent \tocentry{#1}{\dopageno\bgroup#2\egroup}% \endgroup} \def\dosubsecentry#1#2{\begingroup \subsecentryfonts \leftskip=2\tocindent \tocentry{#1}{\dopageno\bgroup#2\egroup}% \endgroup} \def\dosubsubsecentry#1#2{\begingroup \subsubsecentryfonts \leftskip=3\tocindent \tocentry{#1}{\dopageno\bgroup#2\egroup}% \endgroup} % Final typesetting of a toc entry; we use the same \entry macro as for % the index entries, but we want to suppress hyphenation here. (We % can't do that in the \entry macro, since index entries might consist % of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.) \def\tocentry#1#2{\begingroup \vskip 0pt plus1pt % allow a little stretch for the sake of nice page breaks % Do not use \turnoffactive in these arguments. Since the toc is % typeset in cmr, characters such as _ would come out wrong; we % have to do the usual translation tricks. \entry{#1}{#2}% \endgroup} % Space between chapter (or whatever) number and the title. \def\labelspace{\hskip1em \relax} \def\dopageno#1{{\rm #1}} \def\doshortpageno#1{{\rm #1}} \def\chapentryfonts{\secfonts \rm} \def\secentryfonts{\textfonts} \let\subsecentryfonts = \textfonts \let\subsubsecentryfonts = \textfonts \message{environments,} % @foo ... @end foo. % @point{}, @result{}, @expansion{}, @print{}, @equiv{}. % % Since these characters are used in examples, it should be an even number of % \tt widths. Each \tt character is 1en, so two makes it 1em. % \def\point{$\star$} \def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} \def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}} \def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} \def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}} % The @error{} command. % Adapted from the TeXbook's \boxit. % \newbox\errorbox % {\tentt \global\dimen0 = 3em}% Width of the box. \dimen2 = .55pt % Thickness of rules % The text. (`r' is open on the right, `e' somewhat less so on the left.) \setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt} % \global\setbox\errorbox=\hbox to \dimen0{\hfil \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. \advance\hsize by -2\dimen2 % Rules. \vbox{ \hrule height\dimen2 \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. \kern3pt\vrule width\dimen2}% Space to right. \hrule height\dimen2} \hfil} % \def\error{\leavevmode\lower.7ex\copy\errorbox} % @tex ... @end tex escapes into raw Tex temporarily. % One exception: @ is still an escape character, so that @end tex works. % But \@ or @@ will get a plain tex @ character. \def\tex{\begingroup \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie \catcode `\%=14 \catcode `\+=\other \catcode `\"=\other \catcode `\==\other \catcode `\|=\other \catcode `\<=\other \catcode `\>=\other \escapechar=`\\ % \let\b=\ptexb \let\bullet=\ptexbullet \let\c=\ptexc \let\,=\ptexcomma \let\.=\ptexdot \let\dots=\ptexdots \let\equiv=\ptexequiv \let\!=\ptexexclam \let\i=\ptexi \let\indent=\ptexindent \let\{=\ptexlbrace \let\+=\tabalign \let\}=\ptexrbrace \let\/=\ptexslash \let\*=\ptexstar \let\t=\ptext % \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% \def\@{@}% \let\Etex=\endgroup} % Define @lisp ... @end lisp. % @lisp does a \begingroup so it can rebind things, % including the definition of @end lisp (which normally is erroneous). % Amount to narrow the margins by for @lisp. \newskip\lispnarrowing \lispnarrowing=0.4in % This is the definition that ^^M gets inside @lisp, @example, and other % such environments. \null is better than a space, since it doesn't % have any width. \def\lisppar{\null\endgraf} % Make each space character in the input produce a normal interword % space in the output. Don't allow a line break at this space, as this % is used only in environments like @example, where each line of input % should produce a line of output anyway. % {\obeyspaces % \gdef\sepspaces{\obeyspaces\let =\tie}} % Define \obeyedspace to be our active space, whatever it is. This is % for use in \parsearg. {\sepspaces% \global\let\obeyedspace= } % This space is always present above and below environments. \newskip\envskipamount \envskipamount = 0pt % Make spacing and below environment symmetrical. We use \parskip here % to help in doing that, since in @example-like environments \parskip % is reset to zero; thus the \afterenvbreak inserts no space -- but the % start of the next paragraph will insert \parskip. % \def\aboveenvbreak{{% % =10000 instead of <10000 because of a special case in \itemzzz, q.v. \ifnum \lastpenalty=10000 \else \advance\envskipamount by \parskip \endgraf \ifdim\lastskip<\envskipamount \removelastskip % it's not a good place to break if the last penalty was \nobreak % or better ... \ifnum\lastpenalty>10000 \else \penalty-50 \fi \vskip\envskipamount \fi \fi }} \let\afterenvbreak = \aboveenvbreak % \nonarrowing is a flag. If "set", @lisp etc don't narrow margins. \let\nonarrowing=\relax % @cartouche ... @end cartouche: draw rectangle w/rounded corners around % environment contents. \font\circle=lcircle10 \newdimen\circthick \newdimen\cartouter\newdimen\cartinner \newskip\normbskip\newskip\normpskip\newskip\normlskip \circthick=\fontdimen8\circle % \def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth \def\ctr{{\hskip 6pt\circle\char'010}} \def\cbl{{\circle\char'012\hskip -6pt}} \def\cbr{{\hskip 6pt\circle\char'011}} \def\carttop{\hbox to \cartouter{\hskip\lskip \ctl\leaders\hrule height\circthick\hfil\ctr \hskip\rskip}} \def\cartbot{\hbox to \cartouter{\hskip\lskip \cbl\leaders\hrule height\circthick\hfil\cbr \hskip\rskip}} % \newskip\lskip\newskip\rskip \def\cartouche{% \par % can't be in the midst of a paragraph. \begingroup \lskip=\leftskip \rskip=\rightskip \leftskip=0pt\rightskip=0pt %we want these *outside*. \cartinner=\hsize \advance\cartinner by-\lskip \advance\cartinner by-\rskip \cartouter=\hsize \advance\cartouter by 18.4pt % allow for 3pt kerns on either % side, and for 6pt waste from % each corner char, and rule thickness \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip % Flag to tell @lisp, etc., not to narrow margin. \let\nonarrowing=\comment \vbox\bgroup \baselineskip=0pt\parskip=0pt\lineskip=0pt \carttop \hbox\bgroup \hskip\lskip \vrule\kern3pt \vbox\bgroup \hsize=\cartinner \kern3pt \begingroup \baselineskip=\normbskip \lineskip=\normlskip \parskip=\normpskip \vskip -\parskip \def\Ecartouche{% \endgroup \kern3pt \egroup \kern3pt\vrule \hskip\rskip \egroup \cartbot \egroup \endgroup }} % This macro is called at the beginning of all the @example variants, % inside a group. \def\nonfillstart{% \aboveenvbreak \inENV % This group ends at the end of the body \hfuzz = 12pt % Don't be fussy \sepspaces % Make spaces be word-separators rather than space tokens. \let\par = \lisppar % don't ignore blank lines \obeylines % each line of input is a line of output \parskip = 0pt \parindent = 0pt \emergencystretch = 0pt % don't try to avoid overfull boxes % @cartouche defines \nonarrowing to inhibit narrowing % at next level down. \ifx\nonarrowing\relax \advance \leftskip by \lispnarrowing \exdentamount=\lispnarrowing \let\exdent=\nofillexdent \let\nonarrowing=\relax \fi } % Define the \E... control sequence only if we are inside the particular % environment, so the error checking in \end will work. % % To end an @example-like environment, we first end the paragraph (via % \afterenvbreak's vertical glue), and then the group. That way we keep % the zero \parskip that the environments set -- \parskip glue will be % inserted at the beginning of the next paragraph in the document, after % the environment. % \def\nonfillfinish{\afterenvbreak\endgroup} % @lisp: indented, narrowed, typewriter font. \def\lisp{\begingroup \nonfillstart \let\Elisp = \nonfillfinish \tt \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. \gobble % eat return } % @example: Same as @lisp. \def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp} % @smallexample and @smalllisp: use smaller fonts. % Originally contributed by Pavel@xerox. \def\smalllisp{\begingroup \def\Esmalllisp{\nonfillfinish\endgroup}% \def\Esmallexample{\nonfillfinish\endgroup}% \smallexamplefonts \lisp } \let\smallexample = \smalllisp % @display: same as @lisp except keep current font. % \def\display{\begingroup \nonfillstart \let\Edisplay = \nonfillfinish \gobble } % % @smalldisplay: @display plus smaller fonts. % \def\smalldisplay{\begingroup \def\Esmalldisplay{\nonfillfinish\endgroup}% \smallexamplefonts \rm \display } % @format: same as @display except don't narrow margins. % \def\format{\begingroup \let\nonarrowing = t \nonfillstart \let\Eformat = \nonfillfinish \gobble } % % @smallformat: @format plus smaller fonts. % \def\smallformat{\begingroup \def\Esmallformat{\nonfillfinish\endgroup}% \smallexamplefonts \rm \format } % @flushleft (same as @format). % \def\flushleft{\begingroup \def\Eflushleft{\nonfillfinish\endgroup}\format} % @flushright. % \def\flushright{\begingroup \let\nonarrowing = t \nonfillstart \let\Eflushright = \nonfillfinish \advance\leftskip by 0pt plus 1fill \gobble } % @quotation does normal linebreaking (hence we can't use \nonfillstart) % and narrows the margins. % \def\quotation{% \begingroup\inENV %This group ends at the end of the @quotation body {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip \parindent=0pt % We have retained a nonzero parskip for the environment, since we're % doing normal filling. So to avoid extra space below the environment... \def\Equotation{\parskip = 0pt \nonfillfinish}% % % @cartouche defines \nonarrowing to inhibit narrowing at next level down. \ifx\nonarrowing\relax \advance\leftskip by \lispnarrowing \advance\rightskip by \lispnarrowing \exdentamount = \lispnarrowing \let\nonarrowing = \relax \fi } % LaTeX-like @verbatim...@end verbatim and @verb{...} % If we want to allow any as delimiter, % we need the curly braces so that makeinfo sees the @verb command, eg: % `@verbx...x' would look like the '@verbx' command. --janneke@gnu.org % % [Knuth]: Donald Ervin Knuth, 1996. The TeXbook. % % [Knuth] p.344; only we need to do the other characters Texinfo sets % active too. Otherwise, they get lost as the first character on a % verbatim line. \def\dospecials{% \do\ \do\\\do\{\do\}\do\$\do\&% \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~% \do\<\do\>\do\|\do\@\do+\do\"% } % % [Knuth] p. 380 \def\uncatcodespecials{% \def\do##1{\catcode`##1=12}\dospecials} % % [Knuth] pp. 380,381,391 % Disable Spanish ligatures ?` and !` of \tt font \begingroup \catcode`\`=\active\gdef`{\relax\lq} \endgroup % % Setup for the @verb command. % % Eight spaces for a tab \begingroup \catcode`\^^I=\active \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }} \endgroup % \def\setupverb{% \tt % easiest (and conventionally used) font for verbatim \def\par{\leavevmode\endgraf}% \catcode`\`=\active \tabeightspaces % Respect line breaks, % print special symbols as themselves, and % make each space count % must do in this order: \obeylines \uncatcodespecials \sepspaces } % Setup for the @verbatim environment % % Real tab expansion \newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount % \def\starttabbox{\setbox0=\hbox\bgroup} \begingroup \catcode`\^^I=\active \gdef\tabexpand{% \catcode`\^^I=\active \def^^I{\leavevmode\egroup \dimen0=\wd0 % the width so far, or since the previous tab \divide\dimen0 by\tabw \multiply\dimen0 by\tabw % compute previous multiple of \tabw \advance\dimen0 by\tabw % advance to next multiple of \tabw \wd0=\dimen0 \box0 \starttabbox }% } \endgroup \def\setupverbatim{% % Easiest (and conventionally used) font for verbatim \tt \def\par{\leavevmode\egroup\box0\endgraf}% \catcode`\`=\active \tabexpand % Respect line breaks, % print special symbols as themselves, and % make each space count % must do in this order: \obeylines \uncatcodespecials \sepspaces \everypar{\starttabbox}% } % Do the @verb magic: verbatim text is quoted by unique % delimiter characters. Before first delimiter expect a % right brace, after last delimiter expect closing brace: % % \def\doverb'{'#1'}'{#1} % % [Knuth] p. 382; only eat outer {} \begingroup \catcode`[=1\catcode`]=2\catcode`\{=12\catcode`\}=12 \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next] \endgroup % \def\verb{\begingroup\setupverb\doverb} % % % Do the @verbatim magic: define the macro \doverbatim so that % the (first) argument ends when '@end verbatim' is reached, ie: % % \def\doverbatim#1@end verbatim{#1} % % For Texinfo it's a lot easier than for LaTeX, % because texinfo's \verbatim doesn't stop at '\end{verbatim}': % we need not redefine '\', '{' and '}'. % % Inspired by LaTeX's verbatim command set [latex.ltx] %% Include LaTeX hack for completeness -- never know %% \begingroup %% \catcode`|=0 \catcode`[=1 %% \catcode`]=2\catcode`\{=12\catcode`\}=12\catcode`\ =\active %% \catcode`\\=12|gdef|doverbatim#1@end verbatim[ %% #1|endgroup|def|Everbatim[]|end[verbatim]] %% |endgroup % \begingroup \catcode`\ =\active \obeylines % % ignore everything up to the first ^^M, that's the newline at the end % of the @verbatim input line itself. Otherwise we get an extra blank % line in the output. \gdef\doverbatim#1^^M#2@end verbatim{#2\end{verbatim}}% \endgroup % \def\verbatim{% \def\Everbatim{\nonfillfinish\endgroup}% \begingroup \nonfillstart \advance\leftskip by -\defbodyindent \begingroup\setupverbatim\doverbatim } % @verbatiminclude FILE - insert text of file in verbatim environment. % % Allow normal characters that we make active in the argument (a file name). \def\verbatiminclude{% \begingroup \catcode`\\=\other \catcode`~=\other \catcode`^=\other \catcode`_=\other \catcode`|=\other \catcode`<=\other \catcode`>=\other \catcode`+=\other \parsearg\doverbatiminclude } \def\setupverbatiminclude{% \begingroup \nonfillstart \advance\leftskip by -\defbodyindent \begingroup\setupverbatim } % \def\doverbatiminclude#1{% % Restore active chars for included file. \endgroup \begingroup \let\value=\expandablevalue \def\thisfile{#1}% \expandafter\expandafter\setupverbatiminclude\input\thisfile \endgroup \nonfillfinish \endgroup } % @copying ... @end copying. % Save the text away for @insertcopying later. Many commands won't be % allowed in this context, but that's ok. % % We save the uninterpreted tokens, rather than creating a box. % Saving the text in a box would be much easier, but then all the % typesetting commands (@smallbook, font changes, etc.) have to be done % beforehand -- and a) we want @copying to be done first in the source % file; b) letting users define the frontmatter in as flexible order as % possible is very desirable. % \def\copying{\begingroup % Define a command to swallow text until we reach `@end copying'. % \ is the escape char in this texinfo.tex file, so it is the % delimiter for the command; @ will be the escape char when we read % it, but that doesn't matter. \long\def\docopying##1\end copying{\gdef\copyingtext{##1}\enddocopying}% % % We must preserve ^^M's in the input file; see \insertcopying below. \catcode`\^^M = \active \docopying } % What we do to finish off the copying text. % \def\enddocopying{\endgroup\ignorespaces} % @insertcopying. Here we must play games with ^^M's. On the one hand, % we need them to delimit commands such as `@end quotation', so they % must be active. On the other hand, we certainly don't want every % end-of-line to be a \par, as would happen with the normal active % definition of ^^M. On the third hand, two ^^M's in a row should still % generate a \par. % % Our approach is to make ^^M insert a space and a penalty1 normally; % then it can also check if \lastpenalty=1. If it does, then manually % do \par. % % This messes up the normal definitions of @c[omment], so we redefine % it. Similarly for @ignore. (These commands are used in the gcc % manual for man page generation.) % % Seems pretty fragile, most line-oriented commands will presumably % fail, but for the limited use of getting the copying text (which % should be quite simple) inserted, we can hope it's ok. % {\catcode`\^^M=\active % \gdef\insertcopying{\begingroup % \parindent = 0pt % looks wrong on title page \def^^M{% \ifnum \lastpenalty=1 % \par % \else % \space \penalty 1 % \fi % }% % % Fix @c[omment] for catcode 13 ^^M's. \def\c##1^^M{\ignorespaces}% \let\comment = \c % % % Don't bother jumping through all the hoops that \doignore does, it % would be very hard since the catcodes are already set. \long\def\ignore##1\end ignore{\ignorespaces}% % \copyingtext % \endgroup}% } \message{defuns,} % @defun etc. % Allow user to change definition object font (\df) internally \def\setdeffont#1 {\csname DEF#1\endcsname} \newskip\defbodyindent \defbodyindent=.4in \newskip\defargsindent \defargsindent=50pt \newskip\deflastargmargin \deflastargmargin=18pt \newcount\parencount % We want ()&[] to print specially on the defun line. % \def\activeparens{% \catcode`\(=\active \catcode`\)=\active \catcode`\&=\active \catcode`\[=\active \catcode`\]=\active } % Make control sequences which act like normal parenthesis chars. \let\lparen = ( \let\rparen = ) {\activeparens % Now, smart parens don't turn on until &foo (see \amprm) % Be sure that we always have a definition for `(', etc. For example, % if the fn name has parens in it, \boldbrax will not be in effect yet, % so TeX would otherwise complain about undefined control sequence. \global\let(=\lparen \global\let)=\rparen \global\let[=\lbrack \global\let]=\rbrack \gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 } \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} % This is used to turn on special parens % but make & act ordinary (given that it's active). \gdef\boldbraxnoamp{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb\let&=\ampnr} % Definitions of (, ) and & used in args for functions. % This is the definition of ( outside of all parentheses. \gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested \global\advance\parencount by 1 } % % This is the definition of ( when already inside a level of parens. \gdef\opnested{\char`\(\global\advance\parencount by 1 } % \gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0. % also in that case restore the outer-level definition of (. \ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi \global\advance \parencount by -1 } % If we encounter &foo, then turn on ()-hacking afterwards \gdef\amprm#1 {{\rm\}\let(=\oprm \let)=\clrm\ } % \gdef\normalparens{\boldbrax\let&=\ampnr} } % End of definition inside \activeparens %% These parens (in \boldbrax) actually are a little bolder than the %% contained text. This is especially needed for [ and ] \def\opnr{{\sf\char`\(}\global\advance\parencount by 1 } \def\clnr{{\sf\char`\)}\global\advance\parencount by -1 } \let\ampnr = \& \def\lbrb{{\bf\char`\[}} \def\rbrb{{\bf\char`\]}} % Active &'s sneak into the index arguments, so make sure it's defined. { \catcode`& = \active \global\let& = \ampnr } % \defname, which formats the name of the @def (not the args). % #1 is the function name. % #2 is the type of definition, such as "Function". % \def\defname#1#2{% % How we'll output the type name. Putting it in brackets helps % distinguish it from the body text that may end up on the next line % just below it. \ifempty{#2}% \def\defnametype{}% \else \def\defnametype{[\rm #2]}% \fi % % Get the values of \leftskip and \rightskip as they were outside the @def... \dimen2=\leftskip \advance\dimen2 by -\defbodyindent % % Figure out values for the paragraph shape. \setbox0=\hbox{\hskip \deflastargmargin{\defnametype}}% \dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line \dimen1=\hsize \advance \dimen1 by -\defargsindent % size for continuations \parshape 2 0in \dimen0 \defargsindent \dimen1 % % Output arg 2 ("Function" or some such) but stuck inside a box of % width 0 so it does not interfere with linebreaking. \noindent % {% Adjust \hsize to exclude the ambient margins, % so that \rightline will obey them. \advance \hsize by -\dimen2 \dimen3 = 0pt % was -1.25pc \rlap{\rightline{\defnametype\kern\dimen3}}% }% % % Allow all lines to be underfull without complaint: \tolerance=10000 \hbadness=10000 \advance\leftskip by -\defbodyindent \exdentamount=\defbodyindent {\df #1}\enskip % output function name % \defunargs will be called next to output the arguments, if any. } % Common pieces to start any @def... % #1 is the \E... control sequence to end the definition (which we define). % #2 is the \...x control sequence (which our caller defines). % #3 is the control sequence to process the header, such as \defunheader. % \def\parsebodycommon#1#2#3{% \begingroup\inENV % If there are two @def commands in a row, we'll have a \nobreak, % which is there to keep the function description together with its % header. But if there's nothing but headers, we want to allow a % break after all. Check for penalty 10002 (inserted by % \defargscommonending) instead of 10000, since the sectioning % commands insert a \penalty10000, and we don't want to allow a break % between a section heading and a defun. \ifnum\lastpenalty=10002 \penalty0 \fi \medbreak % % Define the \E... end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% % \parindent=0in \advance\leftskip by \defbodyindent \exdentamount=\defbodyindent } % Common part of the \...x definitions. % \def\defxbodycommon{% % As with \parsebodycommon above, allow line break if we have multiple % x headers in a row. It's not a great place, though. \ifnum\lastpenalty=10000 \penalty1000 \fi % \begingroup\obeylines } % Process body of @defun, @deffn, @defmac, etc. % \def\defparsebody#1#2#3{% \parsebodycommon{#1}{#2}{#3}% \def#2{\defxbodycommon \activeparens \spacesplit#3}% \catcode\equalChar=\active \begingroup\obeylines\activeparens \spacesplit#3% } % #1, #2, #3 are the common arguments (see \parsebodycommon above). % #4, delimited by the space, is the class name. % \def\defmethparsebody#1#2#3#4 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 {\defxbodycommon \activeparens \spacesplit{#3{##1}}}% \begingroup\obeylines\activeparens % The \empty here prevents misinterpretation of a construct such as % @deffn {whatever} {Enharmonic comma} % See comments at \deftpparsebody, although in our case we don't have % to remove the \empty afterwards, since it is empty. \spacesplit{#3{#4}}\empty } % Used for @deftypemethod and @deftypeivar. % #1, #2, #3 are the common arguments (see \defparsebody). % #4, delimited by a space, is the class name. % #5 is the method's return type. % \def\deftypemethparsebody#1#2#3#4 #5 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 ##2 {\defxbodycommon \activeparens \spacesplit{#3{##1}{##2}}}% \begingroup\obeylines\activeparens \spacesplit{#3{#4}{#5}}% } % Used for @deftypeop. The change from \deftypemethparsebody is an % extra argument at the beginning which is the `category', instead of it % being the hardwired string `Method' or `Instance Variable'. We have % to account for this both in the \...x definition and in parsing the % input at hand. Thus also need a control sequence (passed as #5) for % the \E... definition to assign the category name to. % \def\deftypeopparsebody#1#2#3#4#5 #6 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 ##2 ##3 {\def#4{##1}% \defxbodycommon \activeparens \spacesplit{#3{##2}{##3}}}% \begingroup\obeylines\activeparens \spacesplit{#3{#5}{#6}}% } % For @defop. \def\defopparsebody #1#2#3#4#5 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 ##2 {\def#4{##1}% \defxbodycommon \activeparens \spacesplit{#3{##2}}}% \begingroup\obeylines\activeparens \spacesplit{#3{#5}}% } % These parsing functions are similar to the preceding ones % except that they do not make parens into active characters. % These are used for "variables" since they have no arguments. % \def\defvarparsebody #1#2#3{% \parsebodycommon{#1}{#2}{#3}% \def#2{\defxbodycommon \spacesplit#3}% \catcode\equalChar=\active \begingroup\obeylines \spacesplit#3% } % @defopvar. \def\defopvarparsebody #1#2#3#4#5 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 ##2 {\def#4{##1}% \defxbodycommon \spacesplit{#3{##2}}}% \begingroup\obeylines \spacesplit{#3{#5}}% } \def\defvrparsebody#1#2#3#4 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 {\defxbodycommon \spacesplit{#3{##1}}}% \begingroup\obeylines \spacesplit{#3{#4}}% } % This loses on `@deftp {Data Type} {struct termios}' -- it thinks the % type is just `struct', because we lose the braces in `{struct % termios}' when \spacesplit reads its undelimited argument. Sigh. % \let\deftpparsebody=\defvrparsebody % % So, to get around this, we put \empty in with the type name. That % way, TeX won't find exactly `{...}' as an undelimited argument, and % won't strip off the braces. % \def\deftpparsebody #1#2#3#4 {% \parsebodycommon{#1}{#2}{#3}% \def#2##1 {\defxbodycommon \spacesplit{#3{##1}}}% \begingroup\obeylines \spacesplit{\parsetpheaderline{#3{#4}}}\empty } % Fine, but then we have to eventually remove the \empty *and* the % braces (if any). That's what this does. % \def\removeemptybraces\empty#1\relax{#1} % After \spacesplit has done its work, this is called -- #1 is the final % thing to call, #2 the type name (which starts with \empty), and #3 % (which might be empty) the arguments. % \def\parsetpheaderline#1#2#3{% #1{\removeemptybraces#2\relax}{#3}% }% % Split up #2 (the rest of the input line) at the first space token. % call #1 with two arguments: % the first is all of #2 before the space token, % the second is all of #2 after that space token. % If #2 contains no space token, all of it is passed as the first arg % and the second is passed as empty. % {\obeylines % \gdef\spacesplit#1#2^^M{\endgroup\spacesplitx{#1}#2 \relax\spacesplitx}% \long\gdef\spacesplitx#1#2 #3#4\spacesplitx{% \ifx\relax #3% #1{#2}{}% \else % #1{#2}{#3#4}% \fi}% } % Define @defun. % This is called to end the arguments processing for all the @def... commands. % \def\defargscommonending{% \interlinepenalty = 10000 \advance\rightskip by 0pt plus 1fil \endgraf \nobreak\vskip -\parskip \penalty 10002 % signal to \parsebodycommon. } % This expands the args and terminates the paragraph they comprise. % \def\defunargs#1{\functionparens \sl % Expand, preventing hyphenation at `-' chars. % Note that groups don't affect changes in \hyphenchar. % Set the font temporarily and use \font in case \setfont made \tensl a macro. {\tensl\hyphenchar\font=0}% #1% {\tensl\hyphenchar\font=45}% \ifnum\parencount=0 \else \errmessage{Unbalanced parentheses in @def}\fi% \defargscommonending } \def\deftypefunargs #1{% % Expand, preventing hyphenation at `-' chars. % Note that groups don't affect changes in \hyphenchar. % Use \boldbraxnoamp, not \functionparens, so that & is not special. \boldbraxnoamp \tclose{#1}% avoid \code because of side effects on active chars \defargscommonending } % Do complete processing of one @defun or @defunx line already parsed. % @deffn Command forward-char nchars \def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader} \def\deffnheader #1#2#3{\doind {fn}{\code{#2}}% \begingroup\defname {#2}{#1}\defunargs{#3}\endgroup % \catcode\equalChar=\other % Turn off change made in \defparsebody } % @defun == @deffn Function \def\defun{\defparsebody\Edefun\defunx\defunheader} \def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{\putwordDeffunc}% \defunargs {#2}\endgroup % \catcode\equalChar=\other % Turn off change made in \defparsebody } % @deftypefun int foobar (int @var{foo}, float @var{bar}) \def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader} % #1 is the data type. #2 is the name and args. \def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax} % #1 is the data type, #2 the name, #3 the args. \def\deftypefunheaderx #1#2 #3\relax{% \doind {fn}{\code{#2}}% Make entry in function index \begingroup\defname {\defheaderxcond#1\relax$.$#2}{\putwordDeftypefun}% \deftypefunargs {#3}\endgroup % \catcode\equalChar=\other % Turn off change made in \defparsebody } % @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar}) \def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader} % \defheaderxcond#1\relax$.$ % puts #1 in @code, followed by a space, but does nothing if #1 is null. \def\defheaderxcond#1#2$.${\ifx#1\relax\else\code{#1#2} \fi} % #1 is the classification. #2 is the data type. #3 is the name and args. \def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax} % #1 is the classification, #2 the data type, #3 the name, #4 the args. \def\deftypefnheaderx #1#2#3 #4\relax{% \doind {fn}{\code{#3}}% Make entry in function index \begingroup \normalparens % notably, turn off `&' magic, which prevents % at least some C++ text from working \defname {\defheaderxcond#2\relax$.$#3}{#1}% \deftypefunargs {#4}\endgroup % \catcode\equalChar=\other % Turn off change made in \defparsebody } % @defmac == @deffn Macro \def\defmac{\defparsebody\Edefmac\defmacx\defmacheader} \def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{\putwordDefmac}% \defunargs {#2}\endgroup % \catcode\equalChar=\other % Turn off change made in \defparsebody } % @defspec == @deffn Special Form \def\defspec{\defparsebody\Edefspec\defspecx\defspecheader} \def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{\putwordDefspec}% \defunargs {#2}\endgroup % \catcode\equalChar=\other % Turn off change made in \defparsebody } % @defop CATEGORY CLASS OPERATION ARG... % \def\defop #1 {\def\defoptype{#1}% \defopparsebody\Edefop\defopx\defopheader\defoptype} % \def\defopheader#1#2#3{% \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% function index entry \begingroup \defname{#2}{\defoptype\ \putwordon\ #1}% \defunargs{#3}% \endgroup } % @deftypeop CATEGORY CLASS TYPE OPERATION ARG... % \def\deftypeop #1 {\def\deftypeopcategory{#1}% \deftypeopparsebody\Edeftypeop\deftypeopx\deftypeopheader \deftypeopcategory} % % #1 is the class name, #2 the data type, #3 the operation name, #4 the args. \def\deftypeopheader#1#2#3#4{% \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index \begingroup \defname{\defheaderxcond#2\relax$.$#3} {\deftypeopcategory\ \putwordon\ \code{#1}}% \deftypefunargs{#4}% \endgroup } % @deftypemethod CLASS TYPE METHOD ARG... % \def\deftypemethod{% \deftypemethparsebody\Edeftypemethod\deftypemethodx\deftypemethodheader} % % #1 is the class name, #2 the data type, #3 the method name, #4 the args. \def\deftypemethodheader#1#2#3#4{% \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index \begingroup \defname{\defheaderxcond#2\relax$.$#3}{\putwordMethodon\ \code{#1}}% \deftypefunargs{#4}% \endgroup } % @deftypeivar CLASS TYPE VARNAME % \def\deftypeivar{% \deftypemethparsebody\Edeftypeivar\deftypeivarx\deftypeivarheader} % % #1 is the class name, #2 the data type, #3 the variable name. \def\deftypeivarheader#1#2#3{% \dosubind{vr}{\code{#3}}{\putwordof\ \code{#1}}% entry in variable index \begingroup \defname{\defheaderxcond#2\relax$.$#3} {\putwordInstanceVariableof\ \code{#1}}% \defvarargs{#3}% \endgroup } % @defmethod == @defop Method % \def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader} % % #1 is the class name, #2 the method name, #3 the args. \def\defmethodheader#1#2#3{% \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% entry in function index \begingroup \defname{#2}{\putwordMethodon\ \code{#1}}% \defunargs{#3}% \endgroup } % @defcv {Class Option} foo-class foo-flag \def\defcv #1 {\def\defcvtype{#1}% \defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype} \def\defcvarheader #1#2#3{% \dosubind{vr}{\code{#2}}{\putwordof\ \code{#1}}% variable index entry \begingroup \defname{#2}{\defcvtype\ \putwordof\ #1}% \defvarargs{#3}% \endgroup } % @defivar CLASS VARNAME == @defcv {Instance Variable} CLASS VARNAME % \def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader} % \def\defivarheader#1#2#3{% \dosubind{vr}{\code{#2}}{\putwordof\ \code{#1}}% entry in var index \begingroup \defname{#2}{\putwordInstanceVariableof\ #1}% \defvarargs{#3}% \endgroup } % @defvar % First, define the processing that is wanted for arguments of @defvar. % This is actually simple: just print them in roman. % This must expand the args and terminate the paragraph they make up \def\defvarargs #1{\normalparens #1% \defargscommonending } % @defvr Counter foo-count \def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader} \def\defvrheader #1#2#3{\doind {vr}{\code{#2}}% \begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup} % @defvar == @defvr Variable \def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader} \def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index \begingroup\defname {#1}{\putwordDefvar}% \defvarargs {#2}\endgroup % } % @defopt == @defvr {User Option} \def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader} \def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index \begingroup\defname {#1}{\putwordDefopt}% \defvarargs {#2}\endgroup % } % @deftypevar int foobar \def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader} % #1 is the data type. #2 is the name, perhaps followed by text that % is actually part of the data type, which should not be put into the index. \def\deftypevarheader #1#2{% \dovarind#2 \relax% Make entry in variables index \begingroup\defname {\defheaderxcond#1\relax$.$#2}{\putwordDeftypevar}% \defargscommonending \endgroup} \def\dovarind#1 #2\relax{\doind{vr}{\code{#1}}} % @deftypevr {Global Flag} int enable \def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader} \def\deftypevrheader #1#2#3{\dovarind#3 \relax% \begingroup\defname {\defheaderxcond#2\relax$.$#3}{#1} \defargscommonending \endgroup} % Now define @deftp % Args are printed in bold, a slight difference from @defvar. \def\deftpargs #1{\bf \defvarargs{#1}} % @deftp Class window height width ... \def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader} \def\deftpheader #1#2#3{\doind {tp}{\code{#2}}% \begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup} % These definitions are used if you use @defunx (etc.) % anywhere other than immediately after a @defun or @defunx. % \def\defcvx#1 {\errmessage{@defcvx in invalid context}} \def\deffnx#1 {\errmessage{@deffnx in invalid context}} \def\defivarx#1 {\errmessage{@defivarx in invalid context}} \def\defmacx#1 {\errmessage{@defmacx in invalid context}} \def\defmethodx#1 {\errmessage{@defmethodx in invalid context}} \def\defoptx #1 {\errmessage{@defoptx in invalid context}} \def\defopx#1 {\errmessage{@defopx in invalid context}} \def\defspecx#1 {\errmessage{@defspecx in invalid context}} \def\deftpx#1 {\errmessage{@deftpx in invalid context}} \def\deftypefnx#1 {\errmessage{@deftypefnx in invalid context}} \def\deftypefunx#1 {\errmessage{@deftypefunx in invalid context}} \def\deftypeivarx#1 {\errmessage{@deftypeivarx in invalid context}} \def\deftypemethodx#1 {\errmessage{@deftypemethodx in invalid context}} \def\deftypeopx#1 {\errmessage{@deftypeopx in invalid context}} \def\deftypevarx#1 {\errmessage{@deftypevarx in invalid context}} \def\deftypevrx#1 {\errmessage{@deftypevrx in invalid context}} \def\defunx#1 {\errmessage{@defunx in invalid context}} \def\defvarx#1 {\errmessage{@defvarx in invalid context}} \def\defvrx#1 {\errmessage{@defvrx in invalid context}} \message{macros,} % @macro. % To do this right we need a feature of e-TeX, \scantokens, % which we arrange to emulate with a temporary file in ordinary TeX. \ifx\eTeXversion\undefined \newwrite\macscribble \def\scanmacro#1{% \begingroup \newlinechar`\^^M % Undo catcode changes of \startcontents and \doprintindex \catcode`\@=0 \catcode`\\=\other \escapechar=`\@ % Append \endinput to make sure that TeX does not see the ending newline. \toks0={#1\endinput}% \immediate\openout\macscribble=\jobname.tmp \immediate\write\macscribble{\the\toks0}% \immediate\closeout\macscribble \let\xeatspaces\eatspaces \input \jobname.tmp \endgroup } \else \def\scanmacro#1{% \begingroup \newlinechar`\^^M % Undo catcode changes of \startcontents and \doprintindex \catcode`\@=0 \catcode`\\=\other \escapechar=`\@ \let\xeatspaces\eatspaces\scantokens{#1\endinput}\endgroup} \fi \newcount\paramno % Count of parameters \newtoks\macname % Macro name \newif\ifrecursive % Is it recursive? \def\macrolist{} % List of all defined macros in the form % \do\macro1\do\macro2... % Utility routines. % Thisdoes \let #1 = #2, except with \csnames. \def\cslet#1#2{% \expandafter\expandafter \expandafter\let \expandafter\expandafter \csname#1\endcsname \csname#2\endcsname} % Trim leading and trailing spaces off a string. % Concepts from aro-bend problem 15 (see CTAN). {\catcode`\@=11 \gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }} \gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@} \gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @} \def\unbrace#1{#1} \unbrace{\gdef\trim@@@ #1 } #2@{#1} } % Trim a single trailing ^^M off a string. {\catcode`\^^M=\other \catcode`\Q=3% \gdef\eatcr #1{\eatcra #1Q^^MQ}% \gdef\eatcra#1^^MQ{\eatcrb#1Q}% \gdef\eatcrb#1Q#2Q{#1}% } % Macro bodies are absorbed as an argument in a context where % all characters are catcode 10, 11 or 12, except \ which is active % (as in normal texinfo). It is necessary to change the definition of \. % It's necessary to have hard CRs when the macro is executed. This is % done by making ^^M (\endlinechar) catcode 12 when reading the macro % body, and then making it the \newlinechar in \scanmacro. \def\macrobodyctxt{% \catcode`\~=\other \catcode`\^=\other \catcode`\_=\other \catcode`\|=\other \catcode`\<=\other \catcode`\>=\other \catcode`\+=\other \catcode`\{=\other \catcode`\}=\other \catcode`\@=\other \catcode`\^^M=\other \usembodybackslash} \def\macroargctxt{% \catcode`\~=\other \catcode`\^=\other \catcode`\_=\other \catcode`\|=\other \catcode`\<=\other \catcode`\>=\other \catcode`\+=\other \catcode`\@=\other \catcode`\\=\other} % \mbodybackslash is the definition of \ in @macro bodies. % It maps \foo\ => \csname macarg.foo\endcsname => #N % where N is the macro parameter number. % We define \csname macarg.\endcsname to be \realbackslash, so % \\ in macro replacement text gets you a backslash. {\catcode`@=0 @catcode`@\=@active @gdef@usembodybackslash{@let\=@mbodybackslash} @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname} } \expandafter\def\csname macarg.\endcsname{\realbackslash} \def\macro{\recursivefalse\parsearg\macroxxx} \def\rmacro{\recursivetrue\parsearg\macroxxx} \def\macroxxx#1{% \getargs{#1}% now \macname is the macname and \argl the arglist \ifx\argl\empty % no arguments \paramno=0% \else \expandafter\parsemargdef \argl;% \fi \if1\csname ismacro.\the\macname\endcsname \message{Warning: redefining \the\macname}% \else \expandafter\ifx\csname \the\macname\endcsname \relax \else \errmessage{Macro name \the\macname\space already defined}\fi \global\cslet{macsave.\the\macname}{\the\macname}% \global\expandafter\let\csname ismacro.\the\macname\endcsname=1% % Add the macroname to \macrolist \toks0 = \expandafter{\macrolist\do}% \xdef\macrolist{\the\toks0 \expandafter\noexpand\csname\the\macname\endcsname}% \fi \begingroup \macrobodyctxt \ifrecursive \expandafter\parsermacbody \else \expandafter\parsemacbody \fi} \def\unmacro{\parsearg\dounmacro} \def\dounmacro#1{% \if1\csname ismacro.#1\endcsname \global\cslet{#1}{macsave.#1}% \global\expandafter\let \csname ismacro.#1\endcsname=0% % Remove the macro name from \macrolist: \begingroup \expandafter\let\csname#1\endcsname \relax \let\do\unmacrodo \xdef\macrolist{\macrolist}% \endgroup \else \errmessage{Macro #1 not defined}% \fi } % Called by \do from \dounmacro on each macro. The idea is to omit any % macro definitions that have been changed to \relax. % \def\unmacrodo#1{% \ifx#1\relax % remove this \else \noexpand\do \noexpand #1% \fi } % This makes use of the obscure feature that if the last token of a % is #, then the preceding argument is delimited by % an opening brace, and that opening brace is not consumed. \def\getargs#1{\getargsxxx#1{}} \def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} \def\getmacname #1 #2\relax{\macname={#1}} \def\getmacargs#1{\def\argl{#1}} % Parse the optional {params} list. Set up \paramno and \paramlist % so \defmacro knows what to do. Define \macarg.blah for each blah % in the params list, to be ##N where N is the position in that list. % That gets used by \mbodybackslash (above). % We need to get `macro parameter char #' into several definitions. % The technique used is stolen from LaTeX: let \hash be something % unexpandable, insert that wherever you need a #, and then redefine % it to # just before using the token list produced. % % The same technique is used to protect \eatspaces till just before % the macro is used. \def\parsemargdef#1;{\paramno=0\def\paramlist{}% \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,} \def\parsemargdefxxx#1,{% \if#1;\let\next=\relax \else \let\next=\parsemargdefxxx \advance\paramno by 1% \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname {\xeatspaces{\hash\the\paramno}}% \edef\paramlist{\paramlist\hash\the\paramno,}% \fi\next} % These two commands read recursive and nonrecursive macro bodies. % (They're different since rec and nonrec macros end differently.) \long\def\parsemacbody#1@end macro% {\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% \long\def\parsermacbody#1@end rmacro% {\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% % This defines the macro itself. There are six cases: recursive and % nonrecursive macros of zero, one, and many arguments. % Much magic with \expandafter here. % \xdef is used so that macro definitions will survive the file % they're defined in; @include reads the file inside a group. \def\defmacro{% \let\hash=##% convert placeholders to macro parameter chars \ifrecursive \ifcase\paramno % 0 \expandafter\xdef\csname\the\macname\endcsname{% \noexpand\scanmacro{\temp}}% \or % 1 \expandafter\xdef\csname\the\macname\endcsname{% \bgroup\noexpand\macroargctxt \noexpand\braceorline \expandafter\noexpand\csname\the\macname xxx\endcsname}% \expandafter\xdef\csname\the\macname xxx\endcsname##1{% \egroup\noexpand\scanmacro{\temp}}% \else % many \expandafter\xdef\csname\the\macname\endcsname{% \bgroup\noexpand\macroargctxt \noexpand\csname\the\macname xx\endcsname}% \expandafter\xdef\csname\the\macname xx\endcsname##1{% \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% \expandafter\expandafter \expandafter\xdef \expandafter\expandafter \csname\the\macname xxx\endcsname \paramlist{\egroup\noexpand\scanmacro{\temp}}% \fi \else \ifcase\paramno % 0 \expandafter\xdef\csname\the\macname\endcsname{% \noexpand\norecurse{\the\macname}% \noexpand\scanmacro{\temp}\egroup}% \or % 1 \expandafter\xdef\csname\the\macname\endcsname{% \bgroup\noexpand\macroargctxt \noexpand\braceorline \expandafter\noexpand\csname\the\macname xxx\endcsname}% \expandafter\xdef\csname\the\macname xxx\endcsname##1{% \egroup \noexpand\norecurse{\the\macname}% \noexpand\scanmacro{\temp}\egroup}% \else % many \expandafter\xdef\csname\the\macname\endcsname{% \bgroup\noexpand\macroargctxt \expandafter\noexpand\csname\the\macname xx\endcsname}% \expandafter\xdef\csname\the\macname xx\endcsname##1{% \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% \expandafter\expandafter \expandafter\xdef \expandafter\expandafter \csname\the\macname xxx\endcsname \paramlist{% \egroup \noexpand\norecurse{\the\macname}% \noexpand\scanmacro{\temp}\egroup}% \fi \fi} \def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} % \braceorline decides whether the next nonwhitespace character is a % {. If so it reads up to the closing }, if not, it reads the whole % line. Whatever was read is then fed to the next control sequence % as an argument (by \parsebrace or \parsearg) \def\braceorline#1{\let\next=#1\futurelet\nchar\braceorlinexxx} \def\braceorlinexxx{% \ifx\nchar\bgroup\else \expandafter\parsearg \fi \next} % We mant to disable all macros during \shipout so that they are not % expanded by \write. \def\turnoffmacros{\begingroup \def\do##1{\let\noexpand##1=\relax}% \edef\next{\macrolist}\expandafter\endgroup\next} % @alias. % We need some trickery to remove the optional spaces around the equal % sign. Just make them active and then expand them all to nothing. \def\alias{\begingroup\obeyspaces\parsearg\aliasxxx} \def\aliasxxx #1{\aliasyyy#1\relax} \def\aliasyyy #1=#2\relax{\ignoreactivespaces \edef\next{\global\let\expandafter\noexpand\csname#1\endcsname=% \expandafter\noexpand\csname#2\endcsname}% \expandafter\endgroup\next} \message{cross references,} % @xref etc. \newwrite\auxfile \newif\ifhavexrefs % True if xref values are known. \newif\ifwarnedxrefs % True if we warned once that they aren't known. % @inforef is relatively simple. \def\inforef #1{\inforefzzz #1,,,,**} \def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, node \samp{\ignorespaces#1{}}} % @node's job is to define \lastnode. \def\node{\ENVcheck\parsearg\nodezzz} \def\nodezzz#1{\nodexxx #1,\finishnodeparse} \def\nodexxx#1,#2\finishnodeparse{\gdef\lastnode{#1}} \let\nwnode=\node \let\lastnode=\relax % The sectioning commands (@chapter, etc.) call these. \def\donoderef{% \ifx\lastnode\relax\else \expandafter\expandafter\expandafter\setref{\lastnode}% {Ysectionnumberandtype}% \global\let\lastnode=\relax \fi } \def\unnumbnoderef{% \ifx\lastnode\relax\else \expandafter\expandafter\expandafter\setref{\lastnode}{Ynothing}% \global\let\lastnode=\relax \fi } \def\appendixnoderef{% \ifx\lastnode\relax\else \expandafter\expandafter\expandafter\setref{\lastnode}% {Yappendixletterandtype}% \global\let\lastnode=\relax \fi } % @anchor{NAME} -- define xref target at arbitrary point. % \newcount\savesfregister \gdef\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} \gdef\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} \gdef\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} % \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an % anchor), namely NAME-title (the corresponding @chapter/etc. name), % NAME-pg (the page number), and NAME-snt (section number and type). % Called from \foonoderef. % % We have to set \indexdummies so commands such as @code in a section % title aren't expanded. It would be nicer not to expand the titles in % the first place, but there's so many layers that that is hard to do. % % Likewise, use \turnoffactive so that punctuation chars such as underscore % and backslash work in node names. % \def\setref#1#2{{% \atdummies \pdfmkdest{#1}% % \turnoffactive \dosetq{#1-title}{Ytitle}% \dosetq{#1-pg}{Ypagenumber}% \dosetq{#1-snt}{#2}% }} % @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is % the node name, #2 the name of the Info cross-reference, #3 the printed % node name, #4 the name of the Info file, #5 the name of the printed % manual. All but the node name can be omitted. % \def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} \def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} \def\ref#1{\xrefX[#1,,,,,,,]} \def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup \unsepspaces \def\printedmanual{\ignorespaces #5}% \def\printednodename{\ignorespaces #3}% \setbox1=\hbox{\printedmanual}% \setbox0=\hbox{\printednodename}% \ifdim \wd0 = 0pt % No printed node name was explicitly given. \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax % Use the node name inside the square brackets. \def\printednodename{\ignorespaces #1}% \else % Use the actual chapter/section title appear inside % the square brackets. Use the real section title if we have it. \ifdim \wd1 > 0pt % It is in another manual, so we don't have it. \def\printednodename{\ignorespaces #1}% \else \ifhavexrefs % We know the real title if we have the xref values. \def\printednodename{\refx{#1-title}{}}% \else % Otherwise just copy the Info node name. \def\printednodename{\ignorespaces #1}% \fi% \fi \fi \fi % % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not % insert empty discretionaries after hyphens, which means that it will % not find a line break at a hyphen in a node names. Since some manuals % are best written with fairly long node names, containing hyphens, this % is a loss. Therefore, we give the text of the node name again, so it % is as if TeX is seeing it for the first time. \ifpdf \leavevmode \getfilename{#4}% {\turnoffactive \otherbackslash \ifnum\filenamelength>0 \startlink attr{/Border [0 0 0]}% goto file{\the\filename.pdf} name{#1}% \else \startlink attr{/Border [0 0 0]}% goto name{#1}% \fi }% \linkcolor \fi % \ifdim \wd1 > 0pt \putwordsection{} ``\printednodename'' \putwordin{} \cite{\printedmanual}% \else % _ (for example) has to be the character _ for the purposes of the % control sequence corresponding to the node, but it has to expand % into the usual \leavevmode...\vrule stuff for purposes of % printing. So we \turnoffactive for the \refx-snt, back on for the % printing, back off for the \refx-pg. {\turnoffactive \otherbackslash % Only output a following space if the -snt ref is nonempty; for % @unnumbered and @anchor, it won't be. \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi }% % output the `[mynode]' via a macro. \xrefprintnodename\printednodename % % But we always want a comma and a space: ,\space % % output the `page 3'. \turnoffactive \otherbackslash \putwordpage\tie\refx{#1-pg}{}% \fi \endlink \endgroup} % This macro is called from \xrefX for the `[nodename]' part of xref % output. It's a separate macro only so it can be changed more easily, % since not square brackets don't work in some documents. Particularly % one that Bob is working on :). % \def\xrefprintnodename#1{[#1]} % \dosetq is called from \setref to do the actual \write (\iflinks). % \def\dosetq#1#2{% {\let\folio=0% \edef\next{\write\auxfile{\internalsetq{#1}{#2}}}% \iflinks \next \fi }% } % \internalsetq{foo}{page} expands into % CHARACTERS @xrdef{foo}{...expansion of \page...} \def\internalsetq#1#2{@xrdef{#1}{\csname #2\endcsname}} % Things to be expanded by \internalsetq. % \def\Ypagenumber{\folio} \def\Ytitle{\thissection} \def\Ynothing{} \def\Ysectionnumberandtype{% \ifnum\secno=0 \putwordChapter@tie \the\chapno \else \ifnum\subsecno=0 \putwordSection@tie \the\chapno.\the\secno \else \ifnum\subsubsecno=0 \putwordSection@tie \the\chapno.\the\secno.\the\subsecno \else \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno \fi\fi\fi } \def\Yappendixletterandtype{% \ifnum\secno=0 \putwordAppendix@tie @char\the\appendixno{}% \else \ifnum\subsecno=0 \putwordSection@tie @char\the\appendixno.\the\secno \else \ifnum\subsubsecno=0 \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno \else \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno \fi\fi\fi } % Use TeX 3.0's \inputlineno to get the line number, for better error % messages, but if we're using an old version of TeX, don't do anything. % \ifx\inputlineno\thisisundefined \let\linenumber = \empty % Pre-3.0. \else \def\linenumber{\the\inputlineno:\space} \fi % Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. % If its value is nonempty, SUFFIX is output afterward. % \def\refx#1#2{% {% \indexnofonts \otherbackslash \expandafter\global\expandafter\let\expandafter\thisrefX \csname X#1\endcsname }% \ifx\thisrefX\relax % If not defined, say something at least. \angleleft un\-de\-fined\angleright \iflinks \ifhavexrefs \message{\linenumber Undefined cross reference `#1'.}% \else \ifwarnedxrefs\else \global\warnedxrefstrue \message{Cross reference values unknown; you must run TeX again.}% \fi \fi \fi \else % It's defined, so just use it. \thisrefX \fi #2% Output the suffix in any case. } % This is the macro invoked by entries in the aux file. % \def\xrdef#1{\expandafter\gdef\csname X#1\endcsname} % Read the last existing aux file, if any. No error if none exists. \def\readauxfile{\begingroup \catcode`\^^@=\other \catcode`\^^A=\other \catcode`\^^B=\other \catcode`\^^C=\other \catcode`\^^D=\other \catcode`\^^E=\other \catcode`\^^F=\other \catcode`\^^G=\other \catcode`\^^H=\other \catcode`\^^K=\other \catcode`\^^L=\other \catcode`\^^N=\other \catcode`\^^P=\other \catcode`\^^Q=\other \catcode`\^^R=\other \catcode`\^^S=\other \catcode`\^^T=\other \catcode`\^^U=\other \catcode`\^^V=\other \catcode`\^^W=\other \catcode`\^^X=\other \catcode`\^^Z=\other \catcode`\^^[=\other \catcode`\^^\=\other \catcode`\^^]=\other \catcode`\^^^=\other \catcode`\^^_=\other % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc. % in xref tags, i.e., node names. But since ^^e4 notation isn't % supported in the main text, it doesn't seem desirable. Furthermore, % that is not enough: for node names that actually contain a ^ % character, we would end up writing a line like this: 'xrdef {'hat % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first % argument, and \hat is not an expandable control sequence. It could % all be worked out, but why? Either we support ^^ or we don't. % % The other change necessary for this was to define \auxhat: % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter % and then to call \auxhat in \setq. % \catcode`\^=\other % % Special characters. Should be turned off anyway, but... \catcode`\~=\other \catcode`\[=\other \catcode`\]=\other \catcode`\"=\other \catcode`\_=\other \catcode`\|=\other \catcode`\<=\other \catcode`\>=\other \catcode`\$=\other \catcode`\#=\other \catcode`\&=\other \catcode`\%=\other \catcode`+=\other % avoid \+ for paranoia even though we've turned it off % % Make the characters 128-255 be printing characters {% \count 1=128 \def\loop{% \catcode\count 1=\other \advance\count 1 by 1 \ifnum \count 1<256 \loop \fi }% }% % % Turn off \ as an escape so we do not lose on % entries which were dumped with control sequences in their names. % For example, @xrdef{$\leq $-fun}{page ...} made by @defun ^^ % Reference to such entries still does not work the way one would wish, % but at least they do not bomb out when the aux file is read in. \catcode`\\=\other % % @ is our escape character in .aux files. \catcode`\{=1 \catcode`\}=2 \catcode`\@=0 % \openin 1 \jobname.aux \ifeof 1 \else \closein 1 \input \jobname.aux \global\havexrefstrue \global\warnedobstrue \fi % Open the new aux file. TeX will close it automatically at exit. \openout\auxfile=\jobname.aux \endgroup} % Footnotes. \newcount \footnoteno % The trailing space in the following definition for supereject is % vital for proper filling; pages come out unaligned when you do a % pagealignmacro call if that space before the closing brace is % removed. (Generally, numeric constants should always be followed by a % space to prevent strange expansion errors.) \def\supereject{\par\penalty -20000\footnoteno =0 } % @footnotestyle is meaningful for info output only. \let\footnotestyle=\comment \let\ptexfootnote=\footnote {\catcode `\@=11 % % Auto-number footnotes. Otherwise like plain. \gdef\footnote{% \let\indent=\ptexindent \global\advance\footnoteno by \@ne \edef\thisfootno{$^{\the\footnoteno}$}% % % In case the footnote comes at the end of a sentence, preserve the % extra spacing after we do the footnote number. \let\@sf\empty \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi % % Remove inadvertent blank space before typesetting the footnote number. \unskip \thisfootno\@sf \dofootnote }% % Don't bother with the trickery in plain.tex to not require the % footnote text as a parameter. Our footnotes don't need to be so general. % % Oh yes, they do; otherwise, @ifset and anything else that uses % \parseargline fail inside footnotes because the tokens are fixed when % the footnote is read. --karl, 16nov96. % % The start of the footnote looks usually like this: \gdef\startfootins{\insert\footins\bgroup} % % ... but this macro is redefined inside @multitable. % \gdef\dofootnote{% \startfootins % We want to typeset this text as a normal paragraph, even if the % footnote reference occurs in (for example) a display environment. % So reset some parameters. \hsize=\pagewidth \interlinepenalty\interfootnotelinepenalty \splittopskip\ht\strutbox % top baseline for broken footnotes \splitmaxdepth\dp\strutbox \floatingpenalty\@MM \leftskip\z@skip \rightskip\z@skip \spaceskip\z@skip \xspaceskip\z@skip \parindent\defaultparindent % \smallfonts \rm % % Because we use hanging indentation in footnotes, a @noindent appears % to exdent this text, so make it be a no-op. makeinfo does not use % hanging indentation so @noindent can still be needed within footnote % text after an @example or the like (not that this is good style). \let\noindent = \relax % % Hang the footnote text off the number. Use \everypar in case the % footnote extends for more than one paragraph. \everypar = {\hang}% \textindent{\thisfootno}% % % Don't crash into the line above the footnote text. Since this % expands into a box, it must come within the paragraph, lest it % provide a place where TeX can split the footnote. \footstrut \futurelet\next\fo@t } }%end \catcode `\@=11 % @| inserts a changebar to the left of the current line. It should % surround any changed text. This approach does *not* work if the % change spans more than two lines of output. To handle that, we would % have adopt a much more difficult approach (putting marks into the main % vertical list for the beginning and end of each change). % \def\|{% % \vadjust can only be used in horizontal mode. \leavevmode % % Append this vertical mode material after the current line in the output. \vadjust{% % We want to insert a rule with the height and depth of the current % leading; that is exactly what \strutbox is supposed to record. \vskip-\baselineskip % % \vadjust-items are inserted at the left edge of the type. So % the \llap here moves out into the left-hand margin. \llap{% % % For a thicker or thinner bar, change the `1pt'. \vrule height\baselineskip width1pt % % This is the space between the bar and the text. \hskip 12pt }% }% } % For a final copy, take out the rectangles % that mark overfull boxes (in case you have decided % that the text looks ok even though it passes the margin). % \def\finalout{\overfullrule=0pt} % @image. We use the macros from epsf.tex to support this. % If epsf.tex is not installed and @image is used, we complain. % % Check for and read epsf.tex up front. If we read it only at @image % time, we might be inside a group, and then its definitions would get % undone and the next image would fail. \openin 1 = epsf.tex \ifeof 1 \else \closein 1 % Do not bother showing banner with epsf.tex v2.7k (available in % doc/epsf.tex and on ctan). \def\epsfannounce{\toks0 = }% \input epsf.tex \fi % % We will only complain once about lack of epsf.tex. \newif\ifwarnednoepsf \newhelp\noepsfhelp{epsf.tex must be installed for images to work. It is also included in the Texinfo distribution, or you can get it from ftp://tug.org/tex/epsf.tex.} % \def\image#1{% \ifx\epsfbox\undefined \ifwarnednoepsf \else \errhelp = \noepsfhelp \errmessage{epsf.tex not found, images will be ignored}% \global\warnednoepsftrue \fi \else \imagexxx #1,,,,,\finish \fi } % % Arguments to @image: % #1 is (mandatory) image filename; we tack on .eps extension. % #2 is (optional) width, #3 is (optional) height. % #4 is (ignored optional) html alt text. % #5 is (ignored optional) extension. % #6 is just the usual extra ignored arg for parsing this stuff. \newif\ifimagevmode \def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup \catcode`\^^M = 5 % in case we're inside an example \normalturnoffactive % allow _ et al. in names % If the image is by itself, center it. \ifvmode \imagevmodetrue \nobreak\bigskip % Usually we'll have text after the image which will insert % \parskip glue, so insert it here too to equalize the space % above and below. \nobreak\vskip\parskip \nobreak \line\bgroup\hss \fi % % Output the image. \ifpdf \dopdfimage{#1}{#2}{#3}% \else % \epsfbox itself resets \epsf?size at each figure. \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi \epsfbox{#1.eps}% \fi % \ifimagevmode \hss \egroup \bigbreak \fi % space after the image \endgroup} \message{localization,} % and i18n. % @documentlanguage is usually given very early, just after % @setfilename. If done too late, it may not override everything % properly. Single argument is the language abbreviation. % It would be nice if we could set up a hyphenation file here. % \def\documentlanguage{\parsearg\dodocumentlanguage} \def\dodocumentlanguage#1{% \tex % read txi-??.tex file in plain TeX. % Read the file if it exists. \openin 1 txi-#1.tex \ifeof1 \errhelp = \nolanghelp \errmessage{Cannot read language file txi-#1.tex}% \let\temp = \relax \else \def\temp{\input txi-#1.tex }% \fi \temp \endgroup } \newhelp\nolanghelp{The given language definition file cannot be found or is empty. Maybe you need to install it? In the current directory should work if nowhere else does.} % @documentencoding should change something in TeX eventually, most % likely, but for now just recognize it. \let\documentencoding = \comment % Page size parameters. % \newdimen\defaultparindent \defaultparindent = 15pt \chapheadingskip = 15pt plus 4pt minus 2pt \secheadingskip = 12pt plus 3pt minus 2pt \subsecheadingskip = 9pt plus 2pt minus 2pt % Prevent underfull vbox error messages. \vbadness = 10000 % Don't be so finicky about underfull hboxes, either. \hbadness = 2000 % Following George Bush, just get rid of widows and orphans. \widowpenalty=10000 \clubpenalty=10000 % Use TeX 3.0's \emergencystretch to help line breaking, but if we're % using an old version of TeX, don't do anything. We want the amount of % stretch added to depend on the line length, hence the dependence on % \hsize. We call this whenever the paper size is set. % \def\setemergencystretch{% \ifx\emergencystretch\thisisundefined % Allow us to assign to \emergencystretch anyway. \def\emergencystretch{\dimen0}% \else \emergencystretch = .15\hsize \fi } % Parameters in order: 1) textheight; 2) textwidth; 3) voffset; % 4) hoffset; 5) binding offset; 6) topskip; 7) physical page height; 8) % physical page width. % % We also call \setleading{\textleading}, so the caller should define % \textleading. The caller should also set \parskip. % \def\internalpagesizes#1#2#3#4#5#6#7#8{% \voffset = #3\relax \topskip = #6\relax \splittopskip = \topskip % \vsize = #1\relax \advance\vsize by \topskip \outervsize = \vsize \advance\outervsize by 2\topandbottommargin \pageheight = \vsize % \hsize = #2\relax \outerhsize = \hsize \advance\outerhsize by 0.5in \pagewidth = \hsize % \normaloffset = #4\relax \bindingoffset = #5\relax % \ifpdf \pdfpageheight #7\relax \pdfpagewidth #8\relax \fi % \setleading{\textleading} % \parindent = \defaultparindent \setemergencystretch } % @letterpaper (the default). \def\letterpaper{{\globaldefs = 1 \parskip = 3pt plus 2pt minus 1pt \textleading = 13.2pt % % If page is nothing but text, make it come out even. \internalpagesizes{46\baselineskip}{6in}% {\voffset}{.25in}% {\bindingoffset}{36pt}% {11in}{8.5in}% }} % Use @smallbook to reset parameters for 7x9.5 (or so) format. \def\smallbook{{\globaldefs = 1 \parskip = 2pt plus 1pt \textleading = 12pt % \internalpagesizes{7.5in}{5in}% {\voffset}{.25in}% {\bindingoffset}{16pt}% {9.25in}{7in}% % \lispnarrowing = 0.3in \tolerance = 700 \hfuzz = 1pt \contentsrightmargin = 0pt \defbodyindent = .5cm }} % Use @afourpaper to print on European A4 paper. \def\afourpaper{{\globaldefs = 1 \parskip = 3pt plus 2pt minus 1pt \textleading = 13.2pt % % Double-side printing via postscript on Laserjet 4050 % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm. % To change the settings for a different printer or situation, adjust % \normaloffset until the front-side and back-side texts align. Then % do the same for \bindingoffset. You can set these for testing in % your texinfo source file like this: % @tex % \global\normaloffset = -6mm % \global\bindingoffset = 10mm % @end tex \internalpagesizes{51\baselineskip}{160mm} {\voffset}{\hoffset}% {\bindingoffset}{44pt}% {297mm}{210mm}% % \tolerance = 700 \hfuzz = 1pt \contentsrightmargin = 0pt \defbodyindent = 5mm }} % Use @afivepaper to print on European A5 paper. % From romildo@urano.iceb.ufop.br, 2 July 2000. % He also recommends making @example and @lisp be small. \def\afivepaper{{\globaldefs = 1 \parskip = 2pt plus 1pt minus 0.1pt \textleading = 12.5pt % \internalpagesizes{160mm}{120mm}% {\voffset}{\hoffset}% {\bindingoffset}{8pt}% {210mm}{148mm}% % \lispnarrowing = 0.2in \tolerance = 800 \hfuzz = 1.2pt \contentsrightmargin = 0pt \defbodyindent = 2mm \tableindent = 12mm }} % A specific text layout, 24x15cm overall, intended for A4 paper. \def\afourlatex{{\globaldefs = 1 \afourpaper \internalpagesizes{237mm}{150mm}% {\voffset}{4.6mm}% {\bindingoffset}{7mm}% {297mm}{210mm}% % % Must explicitly reset to 0 because we call \afourpaper. \globaldefs = 0 }} % Use @afourwide to print on A4 paper in landscape format. \def\afourwide{{\globaldefs = 1 \afourpaper \internalpagesizes{241mm}{165mm}% {\voffset}{-2.95mm}% {\bindingoffset}{7mm}% {297mm}{210mm}% \globaldefs = 0 }} % @pagesizes TEXTHEIGHT[,TEXTWIDTH] % Perhaps we should allow setting the margins, \topskip, \parskip, % and/or leading, also. Or perhaps we should compute them somehow. % \def\pagesizes{\parsearg\pagesizesxxx} \def\pagesizesxxx#1{\pagesizesyyy #1,,\finish} \def\pagesizesyyy#1,#2,#3\finish{{% \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi \globaldefs = 1 % \parskip = 3pt plus 2pt minus 1pt \setleading{\textleading}% % \dimen0 = #1 \advance\dimen0 by \voffset % \dimen2 = \hsize \advance\dimen2 by \normaloffset % \internalpagesizes{#1}{\hsize}% {\voffset}{\normaloffset}% {\bindingoffset}{44pt}% {\dimen0}{\dimen2}% }} % Set default to letter. % \letterpaper \message{and turning on texinfo input format.} % Define macros to output various characters with catcode for normal text. \catcode`\"=\other \catcode`\~=\other \catcode`\^=\other \catcode`\_=\other \catcode`\|=\other \catcode`\<=\other \catcode`\>=\other \catcode`\+=\other \catcode`\$=\other \def\normaldoublequote{"} \def\normaltilde{~} \def\normalcaret{^} \def\normalunderscore{_} \def\normalverticalbar{|} \def\normalless{<} \def\normalgreater{>} \def\normalplus{+} \def\normaldollar{$}%$ font-lock fix % This macro is used to make a character print one way in ttfont % where it can probably just be output, and another way in other fonts, % where something hairier probably needs to be done. % % #1 is what to print if we are indeed using \tt; #2 is what to print % otherwise. Since all the Computer Modern typewriter fonts have zero % interword stretch (and shrink), and it is reasonable to expect all % typewriter fonts to have this, we can check that font parameter. % \def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi} % Same as above, but check for italic font. Actually this also catches % non-italic slanted fonts since it is impossible to distinguish them from % italic fonts. But since this is only used by $ and it uses \sl anyway % this is not a problem. \def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi} % Turn off all special characters except @ % (and those which the user can use as if they were ordinary). % Most of these we simply print from the \tt font, but for some, we can % use math or other variants that look better in normal text. \catcode`\"=\active \def\activedoublequote{{\tt\char34}} \let"=\activedoublequote \catcode`\~=\active \def~{{\tt\char126}} \chardef\hat=`\^ \catcode`\^=\active \def^{{\tt \hat}} \catcode`\_=\active \def_{\ifusingtt\normalunderscore\_} % Subroutine for the previous macro. \def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em } \catcode`\|=\active \def|{{\tt\char124}} \chardef \less=`\< \catcode`\<=\active \def<{{\tt \less}} \chardef \gtr=`\> \catcode`\>=\active \def>{{\tt \gtr}} \catcode`\+=\active \def+{{\tt \char 43}} \catcode`\$=\active \def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix % Set up an active definition for =, but don't enable it most of the time. {\catcode`\==\active \global\def={{\tt \char 61}}} \catcode`+=\active \catcode`\_=\active % If a .fmt file is being used, characters that might appear in a file % name cannot be active until we have parsed the command line. % So turn them off again, and have \everyjob (or @setfilename) turn them on. % \otherifyactive is called near the end of this file. \def\otherifyactive{\catcode`+=\other \catcode`\_=\other} \catcode`\@=0 % \rawbackslashxx outputs one backslash character in current font, % as in \char`\\. \global\chardef\rawbackslashxx=`\\ % \rawbackslash defines an active \ to do \rawbackslashxx. % \otherbackslash defines an active \ to be a literal `\' character with % catcode other. {\catcode`\\=\active @gdef@rawbackslash{@let\=@rawbackslashxx} @gdef@otherbackslash{@let\=@realbackslash} } % \realbackslash is an actual character `\' with catcode other. {\catcode`\\=\other @gdef@realbackslash{\}} % \normalbackslash outputs one backslash in fixed width font. \def\normalbackslash{{\tt\rawbackslashxx}} \catcode`\\=\active % Used sometimes to turn off (effectively) the active characters % even after parsing them. @def@turnoffactive{% @let"=@normaldoublequote @let\=@realbackslash @let~=@normaltilde @let^=@normalcaret @let_=@normalunderscore @let|=@normalverticalbar @let<=@normalless @let>=@normalgreater @let+=@normalplus @let$=@normaldollar %$ font-lock fix } % Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of % the literal character `\'. (Thus, \ is not expandable when this is in % effect.) % @def@normalturnoffactive{@turnoffactive @let\=@normalbackslash} % Make _ and + \other characters, temporarily. % This is canceled by @fixbackslash. @otherifyactive % If a .fmt file is being used, we don't want the `\input texinfo' to show up. % That is what \eatinput is for; after that, the `\' should revert to printing % a backslash. % @gdef@eatinput input texinfo{@fixbackslash} @global@let\ = @eatinput % On the other hand, perhaps the file did not have a `\input texinfo'. Then % the first `\{ in the file would cause an error. This macro tries to fix % that, assuming it is called before the first `\' could plausibly occur. % Also back turn on active characters that might appear in the input % file name, in case not using a pre-dumped format. % @gdef@fixbackslash{% @ifx\@eatinput @let\ = @normalbackslash @fi @catcode`+=@active @catcode`@_=@active } % Say @foo, not \foo, in error messages. @escapechar = `@@ % These look ok in all fonts, so just make them not special. @catcode`@& = @other @catcode`@# = @other @catcode`@% = @other @c Set initial fonts. @textfonts @rm @c Local variables: @c eval: (add-hook 'write-file-hooks 'time-stamp) @c page-delimiter: "^\\\\message" @c time-stamp-start: "def\\\\texinfoversion{" @c time-stamp-format: "%:y-%02m-%02d.%02H" @c time-stamp-end: "}" @c End: lyskom-server-2.1.2/scripts/.cvsignore0000664000015100472110000000002506551006351013502 Makefile Makefile.in lyskom-server-2.1.2/scripts/unprefix0000775000015100472110000000031107717403716013301 #!/bin/sh # usage: unprefix prefix path # # Print path, but if it starts with prefix, first remove the prefix. echo "$2" \ | sed -e 's%^'"`echo $1|sed 's%//*$%%'`"'%%' -e tn -e q -e ':n' -e 's%^//*%%' lyskom-server-2.1.2/scripts/definepath0000775000015100472110000000042007717403716013551 #!/bin/sh # usage: definepath top_srcdir prefix pp-symbol path # # Emit '#define pp-symbol "path"', where a leading prefix of path is removed. echo '#define '$3' "'"`$1/scripts/unprefix "$2" "$4"`"'"' \ | sed 's/\(........................... \) *"/\1"/' lyskom-server-2.1.2/scripts/lyskomd-copyrights0000775000015100472110000001620507723670035015322 #!/bin/bash # $Id: lyskomd-copyrights,v 1.20 2003/08/29 15:21:53 ceder Exp $ # Copyright (C) 1995-1996, 1999, 2002-2003 Lysator Academic Computer Association. # # 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 2, 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, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. if [ ! -f src/server/fncdef.txt ]; then echo $0: must be invoked from base of lyskomd source >&2; exit 1 fi if [ ! -f scripts/CVS/Entries ]; then echo $0: must be invoked in a CVS working copy of the sources >&2; exit 1 fi find . \( -type f -print \) -o \( -name CVS -prune \) \ | sed \ -e '/#/d' \ -e '/\.bb$/d' \ -e '/\.bbg$/d' \ -e '/\.da$/d' \ -e '/\.deps\//d' \ -e '/\.elc$/d' \ -e '/\.log$/d' \ -e '/\.o$/d' \ -e '/\.orig$/d' \ -e '/\.rej$/d' \ -e '/\.sum$/d' \ -e '/\.tar\.gz$/d' \ -e '/\.tmp$/d' \ -e '/\/.cvsignore$/d' \ -e '/\/ChangeLog/d' \ -e '/\/Makefile$/d' \ -e '/\/Makefile.in$/d' \ -e '/\/TAGS$/d' \ -e '/\/\.gdbinit$/d' \ -e '/\/\site.exp/d' \ -e '/\/autom4te.cache\//d' \ -e '/\/lib[^/]*\.a$/d' \ -e '/^\.\/AUTHORS$/d' \ -e '/^\.\/COPYING$/d' \ -e '/^\.\/HACKING$/d' \ -e '/^\.\/NEWS$/d' \ -e '/^\.\/README\.FSF$/d' \ -e '/^\.\/TODO$/d' \ -e '/^\.\/aclocal\.m4/d' \ -e '/^\.\/config.h$/d' \ -e '/^\.\/config\.cache$/d' \ -e '/^\.\/config\.h\.in/d' \ -e '/^\.\/config\.log$/d' \ -e '/^\.\/config\.status$/d' \ -e '/^\.\/configure$/d' \ -e '/^\.\/db-crypt\//d' \ -e '/^\.\/db-nocrypt\//d' \ -e '/^\.\/doc\/.*\.am$/d' \ -e '/^\.\/doc\/.*\.aux$/d' \ -e '/^\.\/doc\/.*\.cp$/d' \ -e '/^\.\/doc\/.*\.dvi$/d' \ -e '/^\.\/doc\/.*\.fn$/d' \ -e '/^\.\/doc\/.*\.fns$/d' \ -e '/^\.\/doc\/.*\.info$/d' \ -e '/^\.\/doc\/.*\.info-[0-9]$/d' \ -e '/^\.\/doc\/.*\.info-[0-9][0-9]$/d' \ -e '/^\.\/doc\/.*\.ky$/d' \ -e '/^\.\/doc\/.*\.pdf$/d' \ -e '/^\.\/doc\/.*\.pg$/d' \ -e '/^\.\/doc\/.*\.toc$/d' \ -e '/^\.\/doc\/.*\.tp$/d' \ -e '/^\.\/doc\/.*\.tps$/d' \ -e '/^\.\/doc\/.*\.vr$/d' \ -e '/^\.\/doc\/IDEAS$/d' \ -e '/^\.\/doc\/Protocol-A\.notab$/d' \ -e '/^\.\/doc\/cmsltt12\.mf$/d' \ -e '/^\.\/doc\/constructs\.expected$/d' \ -e '/^\.\/doc\/help\.swe$/d' \ -e '/^\.\/doc\/kom-style\.el$/d' \ -e '/^\.\/doc\/lyskomd\.notab$/d' \ -e '/^\.\/doc\/protocol-a-current\.txt$/d' \ -e '/^\.\/doc\/protocol-a-full\.txt$/d' \ -e '/^\.\/doc\/protocol-a-recommended\.txt$/d' \ -e '/^\.\/doc\/protocol-a\.html$/d' \ -e '/^\.\/doc\/protocol-a\.texi$/d' \ -e '/^\.\/doc\/protocol-a\.xml$/d' \ -e '/^\.\/doc\/protocol-a\//d' \ -e '/^\.\/doc\/stamp-vti$/d' \ -e '/^\.\/doc\/stamp-vti1$/d' \ -e '/^\.\/doc\/version\.texi$/d' \ -e '/^\.\/run-support\/config$/d' \ -e '/^\.\/run-support\/savecore-lyskom$/d' \ -e '/^\.\/scripts\/definepath$/d' \ -e '/^\.\/scripts\/install-sh/d' \ -e '/^\.\/scripts\/lyskomd-copyrights$/d' \ -e '/^\.\/scripts\/mkinstalldirs$/d' \ -e '/^\.\/scripts\/unprefix$/d' \ -e '/^\.\/scripts\/update-copyright$/d' \ -e '/^\.\/scripts\/warnings\.sed$/d' \ -e '/^\.\/src\/libraries\/adns\//d' \ -e '/^\.\/src\/libraries\/libcommon\/README$/d' \ -e '/^\.\/src\/libraries\/libeintr\/eintr\.h$/d' \ -e '/^\.\/src\/libraries\/libeintr\/fclose\.c$/d' \ -e '/^\.\/src\/libraries\/libeintr\/fopen\.c$/d' \ -e '/^\.\/src\/libraries\/libeintr\/funcs\.txt$/d' \ -e '/^\.\/src\/libraries\/libeintr\/rename\.c$/d' \ -e '/^\.\/src\/libraries\/libisc-new\//d' \ -e '/^\.\/src\/libraries\/libmisc\/README$/d' \ -e '/^\.\/src\/libraries\/liboop\//d' \ -e '/^\.\/src\/libraries\/regex\//d' \ -e '/^\.\/src\/server\/.*\.gdb$/d' \ -e '/^\.\/src\/server\/Magics$/d' \ -e '/^\.\/src\/server\/aux-item-def-parse\.[hc]$/d' \ -e '/^\.\/src\/server\/aux-item-def-scan\.c$/d' \ -e '/^\.\/src\/server\/aux-no\.h$/d' \ -e '/^\.\/src\/server\/cache-database\.c$/d' \ -e '/^\.\/src\/server\/cache-database\.h$/d' \ -e '/^\.\/src\/server\/call-switch\.incl$/d' \ -e '/^\.\/src\/server\/com\.h$/d' \ -e '/^\.\/src\/server\/dbck$/d' \ -e '/^\.\/src\/server\/fnc-def-init\.incl$/d' \ -e '/^\.\/src\/server\/fncdef-no-str-limit\.txt$/d' \ -e '/^\.\/src\/server\/komrunning$/d' \ -e '/^\.\/src\/server\/lyskomd$/d' \ -e '/^\.\/src\/server\/paths\.h$/d' \ -e '/^\.\/src\/server\/prot-a-is-legal-fnc\.incl$/d' \ -e '/^\.\/src\/server\/prot-a-parse-arg\.c$/d' \ -e '/^\.\/src\/server\/prot-a-parse-arg\.h$/d' \ -e '/^\.\/src\/server\/splitkomdb$/d' \ -e '/^\.\/src\/server\/testsuite\/bignum$/d' \ -e '/^\.\/src\/server\/testsuite\/config\/localcfg\.exp$/d' \ -e '/^\.\/src\/server\/testsuite\/config\/lyskomd-config$/d' \ -e '/^\.\/src\/server\/testsuite\/core$/d' \ -e '/^\.\/src\/server\/testsuite\/db\//d' \ -e '/^\.\/src\/server\/testsuite\/etc\//d' \ -e '/^\.\/src\/server\/testsuite\/get-time-often$/d' \ -e '/^\.\/src\/server\/testsuite\/leaks\.0\/no-aux-items\.conf$/d' \ -e '/^\.\/src\/server\/testsuite\/lyskomd\.0\/15\.exp$/d' \ -e '/^\.\/src\/server\/testsuite\/lyskomd\.0\/19\.exp$/d' \ -e '/^\.\/src\/server\/testsuite\/lyskomd\.0\/aux-items-18\.conf$/d' \ -e '/^\.\/src\/server\/testsuite\/lyskomd\.0\/aux-items-35\.conf$/d' \ -e '/^\.\/src\/server\/testsuite\/lyskomd\.0\/aux-items-46\.conf$/d' \ -e '/^\.\/src\/server\/testsuite\/lyskomd\.0\/aux-items-bad\.conf$/d' \ -e '/^\.\/src\/server\/testsuite\/lyskomd\.0\/aux-items\.leaks$/d' \ -e '/^\.\/src\/server\/testsuite\/lyskomd\.0\/bug-1121\.data$/d' \ -e '/^\.\/src\/server\/testsuite\/lyskomd\.0\/bug-1121\.texts$/d' \ -e '/^\.\/src\/server\/testsuite\/lyskomd\.0\/bug-52\.data$/d' \ -e '/^\.\/src\/server\/testsuite\/lyskomd\.0\/bug-52\.texts$/d' \ -e '/^\.\/src\/server\/testsuite\/lyskomd\.0\/internal-connections-cov\.exp$/d' \ -e '/^\.\/src\/server\/testsuite\/lyskomd\.0\/isc-parse-cov\.exp$/d' \ -e '/^\.\/src\/server\/testsuite\/lyskomd\.0\/log-cov\.exp$/d' \ -e '/^\.\/src\/server\/testsuite\/lyskomd\.0\/memory-cov\.exp$/d' \ -e '/^\.\/src\/server\/testsuite\/lyskomd\.supp$/d' \ -e '/^\.\/src\/server\/testsuite\/test-l2g$/d' \ -e '/^\.\/src\/server\/testsuite\/test-select$/d' \ -e '/^\.\/src\/server\/testsuite\/test-sigjmp$/d' \ -e '/^\.\/src\/server\/testsuite\/testfd$/d' \ -e '/^\.\/src\/server\/testsuite\/timeval-overflow$/d' \ -e '/^\.\/src\/server\/testsuite\/usage\.all/d' \ -e '/^\.\/src\/server\/testsuite\/valgrind\.wrap$/d' \ -e '/^\.\/src\/server\/timewrap\.h$/d' \ -e '/^\.\/src\/server\/updateLysKOM$/d' \ -e '/^\.\/src\/server\/version-info\.c$/d' \ -e '/^\.\/src\/server\/version\.incl$/d' \ -e '/^\.\/stamp-depend$/d' \ -e '/^\.\/stamp-h$/d' \ -e '/^\.\/stamp-h1$/d' \ -e '/^\.\/stamp-h\.in/d' \ -e '/~$/d' \ | scripts/update-copyright lyskom-server-2.1.2/scripts/update-copyright0000775000015100472110000000443507721707025014737 #!/bin/bash # $Id: update-copyright,v 1.9 2003/08/23 13:39:59 ceder Exp $ # Copyright (C) 1994-1996, 1999, 2003 Lysator Academic Computer Association. # # 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 2, 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, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # This file updates the copyright lines found in the programs, making # sure that every year that the file is edited appears in the # copyright line. while read file do if grep '[C]opyright' $file > /tmp/$$.yc ; then : ; else echo "$file:1: no Copy"right" line found" >&2 ; continue; fi tr , '\012' < /tmp/$$.yc \ | sed -n \ -e 's/.*\([12][0-9][0-9][0-9]\)-\([12][0-9][0-9][0-9]\).*/\1 \2/p' \ -e 's/.*\([12][0-9][0-9][0-9]\).*/\1/p' \ | awk 'NF == 2 { for(i=$1; i<=$2; ++i) print i } NF == 1' \ > /tmp/$$.year if cvs log $file > /tmp/$$.yc ; then : ; else echo "$file:1: cvs log failed" >&2 ; continue; fi cat /tmp/$$.yc \ | sed -n 's/^date: \([0-9][0-9][0-9][0-9]\).*author.*state.*$/\1/p' \ | sort | uniq >> /tmp/$$.year y=`sort /tmp/$$.year \ | uniq \ | (read first ; echo -n $first; next=\`expr $first + 1\`; rest=; \ while read second; \ do \ if [ $second = $next ]; \ then \ rest="-$next"; \ else \ echo -n $rest, $second; \ rest=; \ fi; \ next=\`expr $second + 1\`; \ done; \ echo -n $rest)` sed 's/\([C]opyright[^0-9]*\)[---0-9 ,]*[0-9]\([^0-9]*\)/\1'"$y"'\2/' \ < $file > /tmp/$$.file cmp /tmp/$$.file $file >/dev/null if [ $? = 1 ]; then if [ -x $file ]; then cat /tmp/$$.file > $file; chmod +x $file else cat /tmp/$$.file > $file; fi echo $file updated fi rm /tmp/$$.file /tmp/$$.yc /tmp/$$.year done lyskom-server-2.1.2/scripts/xenofarm.sh0000664000015100472110000002023207721716116013666 #!/bin/sh # Perform a test compilation of the LysKOM server under Xenofarm. # Copyright (C) 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # To understand this file, you should look at the xenofarm file # projects/lyskom-server/source-transform.sh (see ). It will attempt to unpack # the distribution, configure it, compile, run tests, and collect # information in the "r" directory. # # How can this file unpack the distribution when it is part of the # distribution? Read source-transform.sh and find out. # # Why is this file present here, and not in the Xenofarm CVS module? # Because whenever anything here changes, we probably want to re-run # the tests on the Xenofarm, and committing anything to the # lyskom-server CVS module will trigger the creation of a source # distribution. cfgargs= makeargs= while [ $# -gt 0 ] do case "$1" in --cfg) shift; cfgargs="$1"; shift;; --make) shift; makeargs="$1"; shift;; *) echo $0: unsupported argument $1 >&2; exit 1;; esac done rm -rf r mkdir r exec > r/packlog.txt 2> r/packwarn.txt # For some unknown reason, crond on asmodean has file descriptor 21 # open to /dev/null. This interferes with the test suite, so we close # that file descriptor. It isn't portable to manipulate file # descriptor 10 and above from a shell script, so do this only on the # affected host (that is running bash). if test "`hostname`" = asmodean.lysator.liu.se then exec 21<&- fi VERS=`echo lyskom-server*tar.gz|sed s/lyskom-server-//|sed s/.tar.gz//` BASE=lyskom-server-$VERS timeecho () { echo `TZ=UTC date|awk '{print $6 "-" $2 "-" $3 " " $4}'\ |sed -e s/Jan/01/ -e s/Feb/02/ -e s/Mar/03/ -e s/Apr/04/ \ -e s/May/05/ -e s/Jun/06/ -e s/Jul/07/ -e s/Aug/08/ \ -e s/Sep/09/ -e s/Oct/10/ -e s/Nov/11/ -e s/Dec/12/ `: "$@" } log () { echo "$@" >> r/mainlog.txt TZ=GMT LC_ALL=C date >> r/mainlog.txt } logstart () { log "BEGIN $1" } logpass () { log "PASS" } logfail () { log "FAIL" } logwarn () { log "WARN $1" } dotask () { important="$1" task="$2" warnfunc="$3" cmd="$4" if test $status = good then logstart $task timeecho Begin $task if sh -c "$cmd" > r/${task}log.txt 2>&1 then if [ -z "$warnfunc" ] then logpass else $warnfunc fi else timeecho FAIL: $task if [ $important = 1 ] then status=${task}-failed fi logfail fi else echo status $status makes it impossible to perform this step \ > r/${task}log.txt fi } cfgwarn () { egrep -i 'warning|\(w\)' r/cfglog.txt \ > r/cfgwarn.txt warnings=`wc -l < r/cfgwarn.txt` if test $warnings -gt 0 then logwarn $warnings else rm r/cfgwarn.txt logpass fi } makewarn () { egrep -i 'warning|\(w\)' r/makelog.txt \ | sed -f $BASE/scripts/warnings.sed \ > r/makewarn.txt # Special case for a suspect gcc installation on fonda.roxen.com # as of 2003-07-16. if grep '/i/gcc/2\.95\.2/lib/gcc-lib/hppa1\.1-hp-hpux11\.00/2\.95\.2/include/stddef\.h:165: warning: this is the location of the previous definition' r/makewarn.txt >/dev/null 2>&1 then grep -v '/usr/include/.*warning: `__size_t. redefined' r/makewarn.txt \ | grep -v '2\.95\.2/include/stddef.h:165: warning: this is the' \ | grep -v '/i/gcc/.*/string\.h:.*conflicting types for built-in func' \ > r/makewarn2.txt mv r/makewarn2.txt r/makewarn.txt fi warnings=`wc -l < r/makewarn.txt` if test $warnings -gt 0 then logwarn $warnings else rm r/makewarn.txt logpass fi } ckprgwarn () { egrep -i 'warning|\(w\)|error' r/ckprglog.txt \ |grep -v 'WARNING: Couldn.t find the global config file.' \ |grep -v 'WARNING: Couldn.t find tool init file' \ > r/ckprgwarn.txt warnings=`wc -l < r/ckprgwarn.txt` if test $warnings -gt 0 then egrep -i 'error' r/ckprgwarn.txt \ > r/ckprgfail.txt if test `wc -l < r/ckprgfail.txt` -gt 0 then logfail else rm r/ckprgfail.txt logwarn $warnings fi else rm r/ckprgwarn.txt logpass fi } pfx=`pwd`/pfx status=good echo 'FORMAT 2' > r/mainlog.txt ulimit -c unlimited dotask 1 "unzip" "" "gzip -d $BASE.tar.gz" dotask 1 "unpack" "" "tar xf $BASE.tar" dotask 1 "cfg" "cfgwarn" "cd $BASE && ./configure -C --prefix=$pfx $cfgargs" dotask 0 "fds" "" "cd $BASE/src/server/testsuite && make check-testfd" dotask 0 "id_cc" "" "cd $BASE && make ident-cc" dotask 0 "id_tx" "" "cd $BASE/doc && make ident-makeinfo" dotask 1 "make" "makewarn" "cd $BASE && make $makeargs" dotask 0 "sigjmp" "" "cd $BASE/src/server/testsuite && make check-test-sigjmp" # # "make check" requirements # pdfok=true dviok=true checkprgok=true # We need "runtest". if (runtest -V) 2>&1 then : else echo runtest not found >> r/ckprglog.txt checkprgok=false fi # runtest on taylor is broken. if test "`hostname`" = taylor && test "`domainname`" = lysator.liu.se then echo runtest is broken on taylor >> r/ckprglog.txt checkprgok=false fi # We need "pdftex" if (pdftex --version) 2>&1 then : else echo pdftex not found >> r/pdflog.txt pdfok=false fi # We need "texi2dvi" if (texi2dvi --version) 2>&1 then : else echo texi2dvi not found >> r/dvilog.txt dviok=false fi # We need "tex" if (tex --version) 2>&1 then : else echo tex not found >> r/dvilog.txt dviok=false fi # No use to run pdf and dvi if check-doc fails. oldstatus=$status dotask 1 "ckdoc" "" "cd $BASE/doc && make check-doc" if $dviok then dotask 0 "dvi" "" "cd $BASE/doc && make dvi" fi if $pdfok then dotask 0 "pdf" "" "cd $BASE/doc && make pdf" fi # Restore status: check is useful even if check-doc failed. status=$oldstatus if $checkprgok then dotask 0 "ckprg" "" "cd $BASE/src && make check" fi dotask 1 "install" "" "cd $BASE && make install" # FIXME: run distcheck. # FIXME: compare the contents of the distcheck-generated tar file # with the one we distributed. # Collect stuff. timeecho Collecting results logstart pack find pfx -type f -print | sort > r/installedfiles.txt if test `wc -l < r/installedfiles.txt` -eq 0 then rm r/installedfiles.txt fi mv $BASE/config.cache r/configcache.txt mv $BASE/config.log r/configlog.txt mv $BASE/src/libraries/libisc-new/config.log r/iscconfiglog.txt mv $BASE/src/libraries/liboop/config.log r/oopconfiglog.txt mv $BASE/src/libraries/adns/config.log r/adnsconfiglog.txt mv $BASE/src/libraries/adns/src/config.h r/adnsconfig-h.txt mv $BASE/config.h r/config-h.txt for file in $BASE/src/server/testsuite/*.log do if test -f $file then mv $file r/`basename $file`.txt fi done find $BASE -name core\* -print > r/corefiles.txt if test `wc -l < r/corefiles.txt` -eq 0 then rm r/corefiles.txt else # FIXME (bug 1066): Since the test suite produces a core file this # is not a good thing to do. : echo core files found >&2 fi env > r/environ.txt echo $PATH > r/path.txt makeinfo --version > r/makeinfo.txt type makeinfo >> r/makeinfo.txt 2>&1 mv buildid.txt r/buildid.txt warnings=`wc -l < r/packwarn.txt` if test $warnings -gt 0 then logwarn $warnings else rm r/packwarn.txt logpass fi echo END >> r/mainlog.txt (cd r && tar cf - *) > xenofarm_result.tar gzip -1 xenofarm_result.tar exit 0 lyskom-server-2.1.2/scripts/warnings.sed0000664000015100472110000001370207721712460014042 # This sed script removes known warnings for the benefit of Xenofarm. # Placed in the public domain by Per Cederqvist 2003-08-23. # NOTE: the "?" and "|" operators are not portable. Don't use them. # FIXME (bug 976): Lots of warnings from regex.c. /regex\.c/d # glibc-2.1.2/gcc-2.95.2 on gratia. /\/usr\/include\/inttypes.h:427: warning: function returns an aggregate/d /\/usr\/include\/inttypes.h:428: warning: function call has aggregate value/d /\/usr\/include\/bits\/string2.h:.*: warning: pointer of type `void \*' used in arithmetic/d # Linux on alpha. egcs-2.91.66. asmodean.lysator.liu.se as of 2003-07-16. /\/usr\/include\/inttypes.h:342: warning: function returns an aggregate/d /\/usr\/include\/inttypes.h:343: warning: function call has aggregate value/d # egcs-2.91.66 produces this false warning. asmodean.lysator.liu.se as # of 2003-07-16. /aux-item-def-scan.c:711: warning: `yy_cp' might be used uninitialized in this function/d # The Intel C++ compiler doesn't like the -M options that # automake-1.7.2 uses to create dependency information. /icc: Command line warning: ignoring option '-M'; no argument required/d /icc: Command line warning: no action performed for specified object file(s)/d # flex-2.5.4 generates some unused stuff. /aux-item-def-scan.c:.*: warning: label `find_rule' defined but not used/d /aux-item-def-scan.c:.*: warning: `yy_flex_realloc' defined but not used/d /aux-item-def-scan.c:.*: warning: `yyunput' defined but not used/d # Quoted from src/server/getopt.h: # /* Many other libraries have conflicting prototypes for getopt, with # differences in the consts, in stdlib.h. To avoid compilation # errors, only prototype getopt for the GNU C library. */ /getopt\.h:104: warning: function declaration isn't a prototype/d # When compiling on a system that doesn't use the GNU C library, # getopt.c and getopt1.c uses non-prototype declarations of several # library functions. # # Examples: AIX 4.2 on hal.lysator.liu.se, AIX 4.3 on # dupond.lysator.liu.se. /getopt\.c:.*: warning: function declaration isn't a prototype/d /getopt1\.c:.*: warning: function declaration isn't a prototype/d # This is a harmless comparison of the return value of strlen() and # a difference between two pointers. Warning created on AIX 4.3 with # gcc 3.2 (castafiore.lysator.liu.se). /getopt\.c:461: warning: comparison between signed and unsigned/d # This is a false warning from gcc 3.2 (seen oon AIX 4.3, # castafiore.lysator.liu.se). /getopt\.c:451: warning: `indfound' might be used uninitialized in this function/d # On AIX 4.3, with the /usr/vac/bin/cc compiler, sig_atomic_t is # apparently a volatile type. The lyskom-server code uses "volatile # sig_atomic_t", since many systems exists where sig_atomic_t isn't # volatile, and this results in the warnings below. # Seen on dupond.lysator.liu.se. /"sys\.c", line .*: 1506-112 (W) Duplicate type qualifier "volatile" ignored\./d /"signal\.c", line .*: 1506-112 (W) Duplicate type qualifier "volatile" ignored\./d # Linux on ia64. gcc-2.96. soyokaze.roxen.com as of 2003-01-18. /\/usr\/include\/bits\/socket\.h:271: warning: cast increases required alignment of target type/d # Linux on ia64. gcc-2.96. gosroth.roxen.com as of 2003-07-16. /\/usr\/include\/bits\/socket\.h:268: warning: cast increases required alignment of target type/d # Linux on alpha. egcs-2.91.66. asmodean.lysator.liu.se as of 2003-07-16. /\/usr\/include\/bits\/socket\.h:261: warning: cast increases required alignment of target type/d # Linux on ia64 with the ecc compiler. soyokaze.roxen.com as of 2003-01-18. /warning #688: "format" is an unrecognized __declspec attribute/d # HP-UX 11.0 with gcc and without GAS does not support -g. # taylor.lysator.liu.se as of 2003-07-16. /cc1: warning: -g is only supported when using GAS on this processor,/d /cc1: warning: -g option disabled/d /as: warning 2: Unknown option "--traditional-format" ignored\./d # Assigning SIG_IGN to sa_handler gives this warning on some systems: # Solaris 2.7 with gcc 2.95.2: stanly as of 2003-07-31. # Solaris 2.8 with gcc 2.95.3: lenin as of 2003-07-31. /ramkomd\.c:156: warning: function declaration isn't a prototype/d # Solaris 2.7 with gcc 2.95.2. # stanly as of 2003-07-31. /\/usr\/include\/sys\/vnode\.h:382: warning: declaration of `free' shadows global declaration/d # Including gives this warning on Linux. gcc-2.96, libc-2.2.5. # paragon as of 2003-07-31. /\/usr\/include\/bits\/mathinline\.h:.*: warning: comparing floating point with == or != is unsafe/d # Including gives these warning on Linux. egcs-2.91.66. # asmodean as of 2003-07-31. /\/usr\/include\/bits\/mathinline\.h:.*: warning: no previous prototype for `__fdim'/d /\/usr\/include\/bits\/mathinline\.h:.*: warning: no previous prototype for `fdim'/d /\/usr\/include\/bits\/mathinline\.h:.*: warning: no previous prototype for `__fdimf'/d /\/usr\/include\/bits\/mathinline\.h:.*: warning: no previous prototype for `fdimf'/d # -Wwrite-strings causes this warning on HP-UX 11.0. # fonda.roxen.com as of 2003-07-31. /prot-a-output\.c:.*: warning: passing arg 3 of `snprintf' discards qualifiers from pointer target type/d # Lenin has a dubious float.h header as of 2003-08-03. /\/usr\/include\/limits\.h:165: warning: `DBL_MAX' redefined/d /\/i\/gcc\/2\.95\.3\/lib\/gcc-lib\/i386-pc-solaris2\.8\/2\.95\.3\/include\/float\.h:63: warning: this is the location of the previous definition/d /\/usr\/include\/limits\.h:167: warning: `DBL_MIN' redefined/d /\/i\/gcc\/2\.95\.3\/lib\/gcc-lib\/i386-pc-solaris2\.8\/2\.95\.3\/include\/float\.h:54: warning: this is the location of the previous definition/d /\/usr\/include\/limits\.h:170: warning: `FLT_MAX' redefined/d /\/i\/gcc\/2\.95\.3\/lib\/gcc-lib\/i386-pc-solaris2\.8\/2\.95\.3\/include\/float\.h:35: warning: this is the location of the previous definition/d /\/usr\/include\/limits\.h:171: warning: `FLT_MIN' redefined/d /\/i\/gcc\/2\.95\.3\/lib\/gcc-lib\/i386-pc-solaris2\.8\/2\.95\.3\/include\/float\.h:26: warning: this is the location of the previous definition/d lyskom-server-2.1.2/README0000664000015100472110000002420107723671335010711 1. What is LysKOM? ================== LysKOM has a lot in common with netnews, but LysKOM is intended for local discussions (instead of worldwide). LysKOM consists of a server process and several client programs. The server process maintains a data base of persons, conferences and articles. The clients connect to the server and let the users browse the database for unread articles. LysKOM is much faster than netnews - almost as fast as irc or ICQ! - but like in netnews the articles are saved so that you don't have to be logged in to receive the news. As mentioned above, you need a client to be able to do something useful with LysKOM. At this time there are several clients available. The most popular client is written in elisp and requires Gnu Emacs or XEmacs to run. There are also web clients and a MS Windows client. See for availability of clients. A LysKOM server has been running at Lysator since July 25th 1990. You can connect to it and test it out if you like to get a feel for what LysKOM is. The hostname of the server is kom.lysator.liu.se. Of course, you need a client to test it. On that particular server most of the discussions are done in Swedish. See the file NEWS for information about changes, or the various ChangeLogs for more detailed information. The lyskom-server distribution, of which this README file is a part, only contains the server. You must obtain the clients separately. 2. Documentation ================ doc/lyskomd.texi Instructions for maintaining a LysKOM server. Also contains a chapter for hackers that want to extend or modify the server. doc/Protocol-A.texi Documentation of the protocol used between the clients and the LysKOM server. NEWS What is new in this release? README This file. INSTALL Generic install instructions (see below for lyskomd-specific instructions). HACKING Information that may be useful if you want to change lyskomd. COPYING The license for lyskomd (GNU GPL). AUTHORS List of authors. 3. Installing or upgrading a LysKOM installation ================================================ 1. Select a location where you want the LysKOM database and server binaries to reside. We recommend something like /usr/lyskom (the default), /usr/local/lyskom or /opt/lyskom. WARNING: Do not place the database on an NFS-mounted directory that is mounted with "intr"! If you do, the system calls that writes the database may return a failure and set errno to EINTR. lyskomd does not yet handle that appropriately. See bug 847 for more details and the current status of this problem. . 2. From the top directory of the server sources, run configure: $ ./configure -C --prefix=/usr/local/lyskom The prefix defaults to /usr/lyskom. There are many other options that you can give to the configure script. Most of them are documented in the generic INSTALL file. There are a few LysKOM-specific options, but except for --with-language they are only useful if you want to debug lyskomd. See the HACKING file for more information about them. You can use --with-language=sv to select that a Swedish database should be installed (if no previous database exists). By default, an English database will be installed. This only affects the names of a few conferences and the administrator. You can rename them manually once the server is running. The "-C" option tells configure to cache configuration values in config.cache. Since the lyskomd distribution uses more than one configure scripts, this will speed up the configure process. 3. Compile it: $ make 4. If you like, you can run the test suite: $ make check There should be no unexpected errors. It is normal that some unsupported tests and expected errors are reported. You need DejaGnu 1.4.2 and Python to run the test suite. DejaGnu in turn needs TCL and expect. They can be downloaded from: ftp://prep.ai.mit.edu/pub/gnu/dejagnu/dejagnu-1.4.2.tar.gz ftp://ftp.scriptics.com/pub/tcl/tcl8_3/tcl8.3.4.tar.gz http://expect.nist.gov/src/expect-5.38.0.tar.gz http://www.python.org/download/ 5. Create a user that should own the database files. This file assumes that the user is named "lyskom". 6. If you are upgrading, you must stop the running lyskomd, using the installed "komrunning" program: $ su lyskom $ /usr/lyskom/sbin/komrunning stop (If you are upgrading from a version older than 2.1.0, the komrunning program will be residing in /usr/lyskom/bin.) 7. If you are upgrading from 2.0.7 or older to 2.1.0 or newer, run these commands to adjust to the new filesystem layout (see NEWS for a complete list of everything that changed; this only moves the database, config file and log files from the old to the new layout): $ su lyskom $ cd /usr/lyskom $ mv etc/config etc/lyskomd.conf $ mkdir -p var/lyskomd/db $ mv db/* var/lyskomd/db/ $ rmdir db $ mv etc/server-log var/lyskomd.log $ mv etc/lyskomd-log var/lyskomd.stats $ mv etc/memory-usage var/lyskomd.memory $ cp etc/status var/lyskomd/db/status It might be a good idea to remove the old files in bin, or at least move them to a location where you won't run them by mistake. 8. As "lyskom", install it: $ su lyskom $ make install This will install the server and documentation. It will also install an empty database, unless it finds an old database. The empty database will contain four standard conferences and one privileged user, "Administrator (for) LysKOM", with password "gazonk". See "Database versions" below if you have an old database -- you may have to convert it. A sample config file will be installed in etc/lyskomd.conf, unless it already exists. If you are upgrading to a new version of lyskomd you may have to edit the config file. The current sample config file is in run-support/config. The configuration for aux-items will be installed in etc/aux-items.conf. It will be overwritten even if it has been edited locally. 9. If you are upgrading from 2.0.7 or older to 2.1.0 or newer you need to update the cron entries, so that they run the binaries from sbin instead of bin. Once that is done, you can remove the old etc/status file. 10. Make sure updateLysKOM is run regularly by user lyskom. The recommended way is to add a line such as this to the cron file of the lyskom user: 0,10,20,30,40,50 * * * * /usr/lyskom/sbin/updateLysKOM If your cron does not support per-user cron files you will have to arrange this in some other way. The updateLysKOM will occasionally output a message to stderr and exit with a non-zero exit status. It expects the cron to send a mail to a LysKOM administrator with the output from the program. Most sane cron systems does so. You may want to create a .forward file for user "lyskom". 11. If you are upgrading, you must run komrunning again to remove the lock it created: $ su lyskom $ /usr/lyskom/sbin/komrunning start (Despite its name, this does not actually start lyskomd. See the next step.) 12. Wait for updateLysKOM to start the server, or run updateLysKOM manually (as user "lyskom"). You are ready. If you are upgrading from 2.1.0 or 2.1.1 you might see entries similar to this in the log: fparse_read_range_0: discarded out-of-order local number 8 probably introduced by bug 1121 This means that the server has detected an error in the database introduced by 2.1.0 or 2.1.1. The error will be fixed automatically once the affected person logs on. This message is harmless. 13. Read the documentation in doc/lyskomd.info, especially the Administration chapter. It tells you how to shut down and restart lyskomd. LysKOM needs your attention once in a while. Here at Lysator we expunge old texts (with "dbck -g") approximately twice a year. 14. We would like to know about where LysKOM servers are running. If you start a server, please mail "kom@lysator.liu.se", and tell us that you are running a server. (You are very welcome to tell more about you, but that's not necessary). 4. Database Versions -- you may have to convert the database ============================================================ The database format has not changed in the 2.0.1 through 2.0.6 releases. However, there was a bug in the 2.0.0 release that may have caused the database to contain errors. Most of them can be fixed by dbck, but some cannot yet be fixed; a release with an improved dbck might be created in the future. Please run this command if you are upgrading from the 2.0.0 release: dbck -i lyskomd version 2.0.0 uses a new file format for the database. If you have been running earlier versions of lyskomd you must convert the database by issuing the following command: dbck -o 2 -F You must, of course, use version 2.0.0 or later of dbck to do the conversion. You can convert back the database to the old format with dbck -o 1 -F (for lyskomd version 1.9.0) dbck -o 0 -F (for ancient lyskomd versions) 5. Contact information ====================== If you find a bug, please take a moment to check the bug database at http://bugzilla.lysator.liu.se/ to make sure that it isn't an old bug. If you find your bug there, and feel that you have more information about it, please make an "additional comment". If the bug is important for you, please tell us so by voting for it. If you cannot find the bug, please enter a bug report there. If you are unable to use Bugzilla, or if you don't want the information you have to be public knowledge, you can send your bug report to the email address bug-lyskom@lysator.liu.se. The latest release of the server can always be found from ftp://ftp.lysator.liu.se/pub/lyskom/server/ This file and almost the entire lyskomd server is Copyright (C) 1991-2003 Lysator Academic Computer Association See also the AUTHORS file. lyskom-server-2.1.2/AUTHORS0000664000015100472110000000256307704727562011113 Various authors have contributed to the LysKOM server through the years. This list was constructed in 1998, over 8 years after the project started, so it may be incomplete. Lars Aronsson Thomas Bellman David Byers Per Cederqvist Pär Emanuelsson Peter Eriksson Thorild Selén (IPv6 support in libisc) Linus Tolke Inge Wallin Lars Willför In addition to the above authors, several other persons have contributed feedback, ideas, criticism and bug reports. The server wouldn't be what it is unless we got that. You know who you are. Thanks. The sources includes third-party software which was released under GPL and/or LGPL by other authors than the above. The details are given below. liboop ====== License: GNU LESSER GENERAL PUBLIC LICENSE, version 2.1 Copyright owner: Dan Egnor, Ian Jackson More info: see src/libraries/liboop regex ===== We use a very old version of the GNU regex matcher. Sooner or later we should update this... License: GNU GENERAL PUBLIC LICENSE, version 2 Copyright owner: Free Software Foundation Authors: See src/libraries/regex/AUTHORS getopt ====== License: GNU GENERAL PUBLIC LICENSE, version 2 Copyright owner: Free Software Foundation More info: See src/server/getopt.* autoconf and automake ===================== Various files in this distribution are created and/or inserted by automake and autoconf. They have very varying licenses. lyskom-server-2.1.2/COPYING0000664000015100472110000004307605065176264011075 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy 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 2 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, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. lyskom-server-2.1.2/ChangeLog0000664000015100472110000175734607723706606011633 2003-08-30 Per Cederqvist * Release 2.1.2. 2003-08-29 Per Cederqvist Spelling fixes. * doc/Protocol-A.texi: Spelling errors fixed. Makefile fix. * doc/Makefile.am (DISTCLEANFILES): Added protocol-a-current.txt, protocol-a-recommended.txt and protocol-a-full.txt. Release administrativa. * configure.in: Set version 2.1.2. * versions (SERVER-VERSION): Set to 2.1.2. (SERVER-COMPAT-VERSION): Set to 20102. * doc/Protocol-A.texi (PROTOEDITION): Set to 11.1. (VERSION): Set to 2.1.2. (Document Edition History): Added an entry for 11.1. Added missing "Distributed with" line for 11.0. (Top): Say that this was "first distributed with" a certain lyskomd release, not that it "corresponds to" a release. This way, the text is more accurate if a bug-fix release of lyskomd is made without updating the Protocol-A.texi file. * NEWS: Updated for the 2.1.2 release. * README: Mention that the bug 1121 fix will write stuff to the log. Update the year in the copyright notice. * scripts/lyskomd-copyrights: The top-level README file has a copyright statement, so don't forget to update that file. Don't update the generated machine-readable grammars. Don't update the data files for bug-1121.exp. Don't allow the garb thread to be starved. Tune the garb parameters. (Bug 1129). * src/server/text-garb.c (garb_callback): Always run the garb, so that it cannot be completely starved. * src/server/server-config.c (parameters): Changed "Garb busy postponement" from 20 to 50 milliseconds. Changed "Garb timeout" from 100 to 0 milliseconds. * src/include/kom-types.h (Text_stat): Remove swedish in a comment. * doc/lyskomd.texi (Parameters): Updated "Garb busy postponement" and "Garb timeout". * src/server/testsuite/lyskomd.0/37.exp: Updated the expected timeouts for the garb tuning. Document the garb. (Bug 194). * doc/Protocol-A.texi (Garb): New chapter. Check for a potential memory leak when killing a client. (Bug 149). * src/server/internal-connections.c (kill_client): Check that no aux_item_list remains. Don't produce overlapping ranges in the read-ranges part of a membership. (Bug 1121). Make lyskomd fix the errors introduced by bug 1121. * src/server/membership.c (insert_loc_no): Handle the case where adjoining ranges exists properly instead of producing overlapping ranges. * src/server/ram-parse.c (fparse_read_range_0): Handle the errors introduced by bug 1121. Log an error message if any damage was repaired. * src/server/testsuite/config/unix.exp (lyskomd_start): New argument: db_messages. (dbck_run): New argument: extra_lines. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added bug-1121.exp, bug-1121.data and bug-1121.texts. * src/server/testsuite/lyskomd.0/bug-1121.exp: Test for bug 1121: mark-as-read mishandles read texts in some circumstances. Also test that lyskomd can repair the problems introduced by this bug. * src/server/testsuite/lyskomd.0/bug-1121.texts: New file. * src/server/testsuite/lyskomd.0/bug-1121.data: New file. 2003-08-28 Per Cederqvist Reduce the noise in the log. * src/server/connections.c (read_from_connection): Don't report ETIMEDOUT errors, as they seem to be quite common. Generate two now forms of extracted grammars. Publish them on the web. Mention them in Protocol-A.texi. * doc/Protocol-A.texi (Extracted grammar): New appendix that discusses the extracted files. * doc/Makefile.am (update-www): Depend on protocol-a-full.txt, so that checkargs.py is run first. Copy the generated grammars to the web dir. (protocol-a-full.txt): New target. * doc/checkargs.py: Generate protocol-a-recommended.txt and protocol-a-current.txt. (prot_a_type.__init__): Initialize __recommended to 0. (prot_a_type.use): New argument: recommended. All callers updated. Set the __recommended flag once a recommended request or async uses this type. (prot_a_builtin.use_recurse): Ditto. (prot_a_type.recommended): New method. (lexer.__parse_type): Replaced the protover arguemnt with a request object. All callers updated. (lexer.__parse_request_arg): Ditto. (generate_stable_output): New argument: filename, only_recommended. (generate_summary_output): New function. * doc/constructs.expected: Updated. 2003-08-28 Kent Engström Add support for the "html" alternative of mx-refuse-import. * run-support/aux-items.conf: Update validation regexp. Also set the unique flag to false. * doc/Protocol-A.texi (Aux-Item Types): Document "html". * doc/constructs.expected: Add @code{html}. 2003-08-28 Per Cederqvist Don't crash if a person has read more than 65535 texts after the first unread. * src/server/ram-parse.c (fparse_read_range_0): Use int, not short, in case a person has read many texts after the first unread text. Complete the renaming of aux.h. * scripts/lyskomd-copyrights: src/server/aux.h has been renamed to src/server/aux-no.h. Fix several minor errors in Protocol-A.texi. * doc/Protocol-A.texi (Protocol Requests): The status codes for who-is-on-ident and get-session-info-ident were "r" but should have been "O". (login-old): Added info about when this request became obsolete in the section. (get-person-stat-old): Ditto. (lookup-name): Ditto. (get-conf-stat-older): Ditto. (mark-text-old): Ditto. (who-is-on-old): Ditto. (broadcast): Ditto. (get-session-info): Ditto. (re-lookup-person): Ditto. (re-lookup-conf): Ditto. (lookup-person): Ditto. (lookup-conf): Ditto. (query-read-texts-10): Ditto. (get-membership-10): Ditto. (set-connection-time-format): Fixed typo in the @section heading. (Asynchronous Messages): The status codes for async-new-text-old was "r" but should have been "O". (async-new-text-old): Added async number to the @section heading. (async-i-am-off): Ditto. (async-i-am-on-obsolete): Ditto. (async-new-name): Ditto. (async-i-am-on): Ditto. (async-sync-db): Ditto. (async-leave-conf): Ditto. (async-login): Ditto. (async-broadcast): Ditto. (async-rejected-connection): Ditto. (async-send-message): Ditto. (async-logout): Ditto. (async-deleted-text): Ditto. (async-new-text): Ditto. (async-new-recipient): Ditto. (async-sub-recipient): Ditto. (async-new-membership): Ditto. (async-new-user-area): Ditto. (async-new-presentation): Ditto. (async-new-motd): Ditto. (async-text-aux-changed): Ditto. Generate a stable machine-readable file with the syntax of Protocol A. * doc/checkargs.py (defined_request_names): New variable. (defined_request_names): New variable. (defined_async_names): New variable. (set_values): New variable. (tt): New variable. (tr): New variable. (rt): New variable. (rr): New variable. (at): New variable. (ar): New variable. (has_suffix): New function. (remove_suffix): New function. (prot_a_type.__init__): Initialize __protover. (prot_a_type.line_no): Renamed from line(). (prot_a_type.use): New argument: protover. All callers and derived methods updated. (prot_a_builtin.use_recurse): Ditto. (prot_a_type.protover): New method. (prot_a_simple.base_type): New method. (prot_a_simple.array): New method. (prot_a_alternate.type_a): New method. (prot_a_alternate.type_b): New method. (prot_a_struct.fields): New method. (prot_a_bitstring.add_field): Store the bits in the order they are defined. (prot_a_bitstring.bits): New method. (prot_a_selection.fields): New method. (prot_a_enumeration_of.base_type): New method. (prot_a_msg): New class. (prot_a_request): New class. (prot_a_async): New class. (menu): New class. (reader.menu_re): New constant. (reader.getc_eofok): If a menu line for a request or async message is found, store the information. (reader.menu): New method. (lexer.section_re): New method. (lexer.__init__): __implemented_conftypes and __implemented_privbits both maps to None, not a random number. (lexer.run): If __toplevel_at() returns a non-None value, return it. (lexer.__toplevel_at): Return the result of the called "toplevel_" method instead of always returning None. (lexer.toplevel_set): New method. (lexer.toplevel_section): New method. (lexer.toplevel_findex): Store information about the request in a prot_a_request instance. Check the corresponding @section heading and @menu item. (lexer.toplevel_amindex): Ditto for asyncs. (lexer.__parse_async): New API. (lexer.toplevel_bye): Generate stable names. Return the error flag instead of calling sys.exit(). (lexer.__parse_request): New API. (lexer.__parse_type): New argument: protover. (lexer.__parse_request_arg): Ditto. Return the parsed info. (lexer.__bad_arg): Fixed minor typo. (lexer.generate_stable_names): New method. (generate_stable_output): New function. 2003-08-26 Per Cederqvist * Release 2.1.1. 2003-08-25 Per Cederqvist Release administrativa. * versions (SERVER-VERSION): Set to 2.1.1. (SERVER-COMPAT-VERSION): Set to 20101. * configure.in: Set version 2.1.1. * NEWS: Updated for the 2.1.1 release. Fix the installation instructions. * README: Tell the admin to run "komrunning start" if upgrading. Create var/lyskomd/exportdb during install. (Bug 1119). * run-support/Makefile.am (install-data-local): Create var/lyskomd/exportdb. Rename aux.h to aux-no.h. (Bug 1116). * src/server/Makefile.am (aux-no.h): New name for former "aux.h". The name "aux.h" isn't legal on the operating systems Cygwin runs on top of. All references to aux.h in this file updated. * src/server/.cvsignore: aux.h has been renamed aux-no.h. * src/server/aux-items.c: Ditto. * src/server/text.c: Ditto. Added some missing auxiliary files to the distribution. * src/libraries/adns/Makefile.am (EXTRA_DIST): Added changelog. * src/libraries/adns/client/Makefile.am (EXTRA_DIST): Added .cvsignore. * src/libraries/adns/src/Makefile.am: Ditto. * src/libraries/liboop/Makefile.am: Ditto. Added test cases for write errors. * src/server/testsuite/lyskomd.0/49.exp: New file, that tests client disconnect immediately before a write(). * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added 49.exp. * src/include/services.h (server_sleep): New debug request. * src/server/fncdef.txt: Added the debug call server_sleep. * src/server/debug.c (server_sleep): New request. Testsuite cleanup. * src/server/testsuite/lyskomd.0/bug-52.exp: Fixed typo in never-executed code. * src/server/testsuite/lyskomd.0/47.exp: Fixed a typo in a comment. 2003-08-24 Per Cederqvist * Release 2.1.0. 2003-08-23 Per Cederqvist Fixes for the web publication of Protocol A. * doc/Makefile.am (protocol-a.info): Updated the rule to what automake-1.7.6 would have generated. Don't generate the info file in $(srcdir). 2003-08-23 Per Cederqvist Set the release date. * HACKING: Mention that the release date should be set. * NEWS: Set the release date to tomorrow. * doc/Protocol-A.texi (Document Edition History): Set the release date to tomorrow. Update copyright headers. * : update the year in the copyright notice. * scripts/lyskomd-copyrights: Ignore public domain files: doc/kom-style.el scripts/warnings.sed Ignore tiny files: scripts/definepath scripts/unprefix src/server/timewrap.h Ignore generated files: src/server/paths.h doc/version.texi Ignore user-supplied files: src/server/testsuite/config/localcfg.exp Ignore binaries: src/server/testsuite/get-time-often src/server/testsuite/test-sigjmp src/server/testsuite/timeval-overflow Ignore temporary files: src/server/testsuite/lyskomd.0/aux-items-35.conf src/server/testsuite/lyskomd.0/aux-items-46.conf src/server/testsuite/lyskomd.0/aux-items-bad.conf Ignore run-support/savecore-lyskom, not run-support/savecore. Don't claim copyright on a collection of compiler error messages. * scripts/warnings.sed: Placed in the public domain. Make all requests that takes a BOOL argument return bad-bool if something besides 0 or 1 is sent by the client. * doc/Protocol-A.texi (get-membership-old): Added error code bad-bool. (login): Ditto. (re-z-lookup): Ditto. (lookup-z-name): Ditto. (who-is-on-dynamic): Ditto. (get-membership-10): Ditto. (query-read-texts): Ditto. (get-membership): Ditto. (set-connection-time-format): Ditto. (Error Codes): Document error code bad-bool. (Protocol Version History): Mention bad-bool. (Document Edition History): Mention bad-bool. * NEWS: Added info about bad-bool. * src/include/kom-errno.h (enum kom_err): Added KOM_BAD_BOOL. * src/server/manipulate.h (CHK_BOOL): New macro. * src/server/session.c (login): Call CHK_BOOL for invisible. (who_is_on_dynamic): Call CHK_BOOL for want_visible and want_invisible. (set_connection_time_format): Call CHK_BOOL for use_utc. Don't use KOM_INDEX_OUT_OF_RANGE for that error. * src/server/regex-match.c (re_z_lookup): Call CHK_BOOL for want_persons and want_confs. * src/server/person.c (query_read_texts): Call CHK_BOOL for want_read_ranges. * src/server/membership.c (get_membership_old): Call CHK_BOOL for want_read_texts. (get_membership_10): Ditto. (get_membership): Call CHK_BOOL for want_read_ranges. * src/server/conference.c (lookup_z_name): Call CHK_BOOL for want_persons and want_confs. * src/server/testsuite/lyskomd.0/01.exp: Expect bad-bool, not index-out-of-range, from set-connection-time-format(2). * src/server/testsuite/lyskomd.0/03.exp: Ditto. * src/server/testsuite/lyskomd.0/48.exp: New file: Test the bad-bool error code. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added 48.exp. Make statement-like macros more robust. * src/server/manipulate.h (CHK_CONNECTION): Use the "do ... while (0)" construct to make this macro expand to exactly one statement. (CHK_LOGIN): Ditto. (CONF_ZERO): Ditto. (CHK_EXIST): Ditto. (GET_P_STAT): Ditto. (VOID_GET_P_STAT): Ditto. (GET_C_STAT): Ditto. (VOID_GET_C_STAT): Ditto. (GET_T_STAT): Ditto. (VOID_GET_T_STAT): Ditto. "make distcheck" lint. * src/server/testsuite/lyskomd.0/Makefile.am (MOSTLYCLEANFILES): Added aux-items-35.conf and aux-items-46.conf. * doc/Makefile.am (MOSTLYCLEANFILES): Added Protocol-A.dvi. * src/server/testsuite/lyskomd.0/35.exp: Store the temporary aux-item file in lyskomd.0/aux-items-35.conf, instead of 35-aux.conf, just like other test files already do. * src/server/testsuite/.cvsignore: Don't ignore 35-aux.conf. * src/server/testsuite/lyskomd.0/.cvsignore: Ignore aux-items-35.conf. * src/server/testsuite/lyskomd.0/46.exp: Remove the temporary file before copying files to it, to avoid permission problems if the files in the source tree has read-only permissions. Updated the copyright-updating scripts. * scripts/update-copyright: Updated copyright heading. * scripts/lyskomd-copyrights: Updated copyright heading. Don't update copyright headers of adns or liboop. Update version numbers. * HACKING: Updated where version numbers are found. * configure.in: Set version 2.1.0. * versions (PROTOCOL-A-LEVEL): 11. (SERVER-VERSION): 2.1.0. (SERVER-COMPAT-VERSION): 20100. * doc/Protocol-A.texi (PROTOEDITION): Set to 11.0. (PROTOVER): Set to 11. (VERSION): Set to 2.1.0. (Client-Server Dialog): Talk about "version 10 or newer", not only "version 10". Release administrativa. * NEWS: Updated for the 2.1.0 release. * HACKING: Mention that our automake patch is obsolete. * README: Some minor errors fixed. Ask the reader to vote for the bugs he considers important. Update the protocol and document history of Protocol A. * doc/Protocol-A.texi (Future changes): Don't mention bugs that are closed. Mention that the list of included bugs is incomplete. (Protocol Version History): Document version 11. (Document Edition History): Document edition 11.0. * doc/constructs.expected: Updated. Revert the Xenofarm automount workaround. * src/server/connections.c (dump_connections): Revert the automount workaround attempt. It didn't work, and it also introduced an endless loop. 2003-08-22 Per Cederqvist Keep track of clients that are beind killed, and don't re-add them to the kill list. (Bug 1100). * src/server/internal-connections.h (get_conn_by_number): Document that it returns NULL if the session doesn't exist. * src/server/internal-connections.c (init_connection): Set the new kill_status field of Connection instead of the old kill_pending field. (new_client): Ditto. (check_conn_exists): Dead code removed. (get_conn_by_number): Don't crash if no connections exist. It isn't abnormal if the supplied connection number doesn't exist, so remove code inside NDEFENSIVE_CHECKS that assumed it was. Whitespace fixes. * src/server/connections.h (enum kill_state): New enum. (Connection): Replaced the "Bool kill_pending" field with a "enum kill_stat kill_status" field. * src/server/connections.c (check_kill_flg): Use the new kill_status field of Connection instead of the old kill_pending field. (read_from_connection): Ditto. (add_to_kill_list): Ditto. Don't add the client if it is dying. Update var/lyskomd.clients when the handshake completes by a DNS response. * src/server/connections.c (dns_resolution): If the DNS resolution completed the handshake, dump out the connections again to reflect that fact. Test for bug 1100. * src/server/testsuite/lyskomd.0/47.exp: New file: Test client disconnect while logged in and receiving async-logout. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added 47.exp. Xenofarm automount workaround. * src/server/connections.c (dump_connections): If the rename of the file fails with ENOENT, retry it a few times before giving up. This is an attempt to work around an automount problem on the Xenofarm at Lysator. Fixed an error in the new function l2gi_prev(). * src/server/local-to-global.c (l2gi_prev): Don't read memory before the start of an array. Make dump_connections() static. * src/server/internal-connections.h (dump_connections): Removed. * src/server/connections.c (dump_connections): Now static. New requests: local-to-global-reverse and map-created-texts-reverse. (Bug 1092). * doc/Protocol-A.texi (Mapping Local to Global Text Numbers): Renamed the field "later-texts-exists" in "Text-Mapping" to "more-texts-exists", so that it is useful for the new requests defined below. Updated the descriptions of some fields for the same purpose. (local-to-global): Added a link to local-to-global-reverse. (map-created-texts): Added a link to map-created-texts-reverse. (set-connection-time-format): Added a missing protocol number. (local-to-global-reverse): New request. (map-created-texts-reverse): New request. * src/server/fncdef.txt: Added local_to_global_reverse and map_created_texts_reverse. * src/include/services.h (map_created_texts_reverse): New request. (local_to_global_reverse): New request. * src/server/text.c (local_to_global_reverse): New function. * src/server/person.c (map_created_texts_reverse): New request. * src/include/kom-types.h (Text_mapping_reverse): New struct. * src/server/prot-a.c (prot_a_reply): Handle rt_text_mapping_reverse. * src/server/prot-a-output.h, src/server/prot-a-output.c (prot_a_output_text_mapping_reverse): New function. * src/server/connections.h (enum res_type): Added rt_text_mapping_reverse. (union result_holder): Added text_mapping_reverse. * src/server/testsuite/renumber.el (renumber-lyskom-send-simple-expect-indented): New function. * src/server/testsuite/lyskomd.0/00.exp: Added test cases for local-to-global-reverse and map-created-texts-reverse. * src/server/testsuite/lyskomd.0/01.exp: Ditto. * src/server/testsuite/lyskomd.0/03.exp: Ditto. Added support for reverse local-to-global iterators. * src/include/kom-types.h (L2g_reverse_iterator): New struct. * src/server/local-to-global.h (l2gi_searchsome_reverse): New function. (l2gi_prev): New function. * src/server/Makefile.am (check-l2g): New target. * src/server/local-to-global.c (find_block_index_key_reverse): New static function. (l2gi_searchsome_reverse): New function. (l2gi_prev): New function. * src/server/testsuite/test-l2g.c (main): Handle command "b", for testing backwards iterators. ("r", "R", and "I" were all taken). * src/server/testsuite/l2g.0/07.exp: Added test cases for reverse iterators. * src/server/testsuite/l2g.0/10.exp: Ditto. * src/server/testsuite/l2g.0/11.exp: Ditto. 2003-08-20 Per Cederqvist Code cleanup. (Bug 1097). * src/server/aux-items.c (find_linked_aux_item_list): Removed all traces of PERS_OBJECT_TYPE. (mark_linked_object_as_changed): Ditto. * src/include/kom-types.h (enum object_type): Removed all traces of PERS_OBJECT_TYPE. Don't explicitly specify the values of the constants, since they don't matter. Fix output of linefeed in Protocol A examples. (Bug 376). * doc/Protocol-A.texi (Connecting to the Server): Say "linefeed", not "newline" or "line feed". (create-text): Ditto. (Reformattable Text (text/x-kom-basic)): Ditto. (The User Area): Ditto. (Text formatting): Ditto. (Protocol Version History): Ditto. (get-text): Use "@bullet{}" to represent linefeed characters inside hollerith strings. (create-text-old): Ditto. (create-anonymous-text-old): Ditto. * doc/constructs.expected: Updated. Return the error code long-array instead of a protocol error if a too long array is sent to mark-as-read. (Bug 836). Get rid of c_local_text_no_p -- use Number_list instead. * src/server/fncdef.txt (mark_as_read): Changed the argument from "num num c_local_text_no_p" to the more modern "num num_list". * src/include/services.h (mark_as_read): Changed the arguments "int no_of_text; const Local_text_no *text_arr" into a single more modern-style Number_list argument. * src/server/membership.c (mark_as_read): Changed the arguments "int no_of_text; const Local_text_no *text_arr" into a single more modern-style Number_list argument. Return KOM_LONG_ARRAY if the array is too long. Simplified the code. (set_read_ranges): Call CHK_CONNECTION before checking the supplied read_ranges. * src/server/prot-a.c (prot_a_init): Removed handling of c_local_text_no_p. (prot_a_destruct): Ditto. * src/server/prot-a-parse-arg-c.awk: Removed handling of c_local_text_no_p. * src/server/internal-connections.c (init_connection): Removed handling of c_local_text_no_p. (kill_client): Ditto. But do check for left-over data in num_list. * src/server/connections.h (Connection): Removed c_local_text_no_p. * src/server/connections.c (free_parsed): Removed handling of c_local_text_no_p. * src/server/call-switch.awk: Removed handling of c_local_text_no_p. * src/server/testsuite/lyskomd.0/29.exp: Don't expect bug 836. Send mail using sendmail, to avoid malformed mails. (Bug 185). Make the path to sendmail configurable. Make it possible to turn off mail delivery completely. * configure.in: Search for a sendmail binary. * doc/lyskomd.texi (Parameters): Document "sendmail path". * src/server/param.h (struct kom_par): Added sendmail_path. * src/server/server-config.c (parameters): Added "sendmail path". (read_configuration): Handle it. * src/server/updateLysKOM.c (checkstatus): Send mail by opening a pipe to "sendmail -t". That is more portable than pipeing a message into "mail". Turn off mail delivery completely if "sendmail path" is set to ":". * src/server/Makefile.am (paths.h): Write SENDMAIL_PATH. Test suite: Don't forget to distribute aux-items-bad.conf. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added aux-items-bad.conf. Fix text_read_access() so that it uses the privileges of the supplied connection, and never uses active_connection. (Bug 178). Fixing this also required me to remove the ability to specify an faq-text for a freshly created person on a session where nobody is logged on; this could be considered a security fix. * src/server/text.c (person_text_read_access): Removed. Integrate the functionality inteo text_read_access. (text_read_access): Use the supplied Connection for all checks. Don't use active_connection, ENA, ACTPERS or ACT_P. Fail and log an error message if the Connection is NULL. Use is_supervisor() instead of is_supervisor_2(). * src/server/manipulate.h (is_supervisor_2): Removed. (person_text_read_access): Removed. * src/server/conference.c (is_supervisor_2): Removed. * src/server/aux-items.c (aux_item_validate_existing_text): Don't allow access to texts if you are not logged in. This change means that create-person cannot accept aux-items with the existing-readable-text validator if nobody is logged in. I think this is more reasonable than the number of special cases in the code that were needed to support the old functionality. * src/server/testsuite/lyskomd.0/40.exp: Don't expect bug 178. * src/server/testsuite/lyskomd.0/41.exp: Don't expect bug 178. * src/server/testsuite/lyskomd.0/03.exp: Don't expect to be able to create a person with an faq-text. Add the faq-text using a modify-conf-info request instead. Test that creation of a new person with a faq-text item really fails. Keep track of the connection that is creating an aux-item, so that ENA_C() and text_read_access() can be used. Get rid of broken concept "owner", and introduced "subordinate" instead. (Bug 334). Some other aux-item-related code cleanup. * src/server/aux-items.h (Aux_item_validation_data): Removed item_creator, object_creator and owner_check. Added creating_conn and subordinate. Placed add_to_list, start_looking_at and object_type inside #if 0..#endif, since they are not currently used. (aux_inherit_items):Removed arguments target_creator, creating and object_type. Added argument subordinate. Changed type of arguments object_no and object, since we know that they are a Text_no and Text_stat, respectively. (check_delete_aux_item_list): Renamed the "owner" argument "subordinate". (text_stat_check_add_aux_item): Removed the item_creator and creating arguments. Added the creating_conn argument. (conf_stat_check_add_aux_item_list): Ditto. (system_check_add_aux_item_list): Ditto. (conf_stat_check_add_aux_item): Declaration for undefined and unused function removed. (conf_stat_add_aux_item): Ditto. * src/server/aux-items.c (aux_item_validate): Return Success, not Bool. All callers updated. (aux_item_add_perm): Removed the arguments item_creator, object_creator and owner_check. Added the arguments creating_conn and subordinate. All callers updated. Simplified the code. Use is_supervisor() instead of is_strictly_supervisor() where appropriate. Use the supplied connection instead of checking that ACTPERS is the item_creator. Adjusted for the new contents of Aux_item_validation_data. (aux_inherit_items): Removed arguments target_creator, creating and object_type. Added argument subordinate. Changed type of arguments object_no and object, since we know that they are a Text_no and Text_stat, respectively. (filter_aux_item_list): Assert that the viewer_conn argument is non-NULL. (check_delete_aux_item_list): Renamed the "owner" argument "subordinate". (text_stat_check_add_aux_item_list): Removed the item_creator and creating arguments. Added the creating_conn argument, and assert it is non-NULL. (conf_stat_check_add_aux_item_list): Replaced the "creator" argument with "creating_conn". Argument assertions added. (system_check_add_aux_item_list): Ditto. (aux_item_validate_existing_text): Changed return type from Bool to Success. Use person_text_read_access() only when necessary, and add a comment explaining why it might happen. * src/server/text.c (create_text_add_aux): Adjusted to new API of aux_inherit_items(). (do_create_text): Adjusted to new API of text_stat_check_add_aux_item_list(). (modify_text_info): Ditto. * src/server/person.c (create_person_generic): Adjusted to new API of conf_stat_check_add_aux_item_list(). * src/server/manipulate.h (text_read_access): Docstring updated. (person_text_read_access): Docstring added. * src/server/conference.c (do_create_conf): New argument: creating_connection. All callers updated. (modify_conf_info): Adjusted to new API of check_delete_aux_item_list() and conf_stat_check_add_aux_item_list(). * src/server/admin.c (modify_system_info): Adjusted to new API of system_check_add_aux_item_list(). * src/server/testsuite/lyskomd.0/24.exp: Use good_bad_expect instead of a "if {0}" construct. Don't expect it to fail. Fixed a broken test outcome. Added code to diagnose Success vs. Bool mixups. * HACKING (Release generation): Use TYPE_CHECK_COMPILATION for increased quality assurance. * src/include/misc-types.h (TYPE_CHECK_COMPILATION): New compilation switch. (SUCCESS_AS_PTR): Ditto. (Bool): Provide a pointer-based non-working implementation, that can be used for compile-time checks, but not for running code. (Success): Provide a pointer-based implementation. Switch to using it, at least for now; this might give us good warnings from the compilers. * src/server/misc-types.c: New file. Implementation of the types in misc-type.h. * src/server/Makefile.am (libcheck_a_SOURCES): Added misc-types.c. (lyskomd_SOURCES): Ditto. (komrunning_SOURCES): Ditto. (updateLysKOM_SOURCES): Ditto. (dbck_SOURCES): Ditto. (splitkomdb_SOURCES): Ditto. * src/server/testsuite/Makefile.am (test_l2g_LDADD): libcheck.a must be linked twice. (get_time_often_LDADD): Ditto. Make etags find our documentation. * Makefile.am (AM_ETAGSFLAGS): Use --declarations, so that the tags command finds the documentation. Include an Emacs indentation style for our code. * doc/kom-style.el ("KOM"): New C style for c-add-style. This sets up proper indentation for Emacs. * doc/Makefile.am (EXTRA_DIST): Added kom-style.el. Added more hacking documentation. * doc/lyskomd.texi (The Database): Mention that untranslated Swedish text exists. (local-to-global): Ditto. (Modifying Stored Types): Mention that dbck needs to be updated. (Coding conventions): New section. Document that send async-deleted-text, async-new-text, async-new-text-old, async-new-recipient and async-sub-recipient are sent to recipients of text linked to the relevant text. The functionality was added 2003-01-13. (Bug 59). * doc/Protocol-A.texi (Aux-Item Inheritance): Added a missing parenthesis. (async-new-text-old): Document that recipients of linked texts also gets this message. (async-deleted-text): Ditto. (async-new-text): Ditto. (async-new-recipient): Ditto. (async-sub-recipient): Ditto. 2003-08-19 Per Cederqvist Test permissons for setting the canonical-name aux-item. * src/server/testsuite/lyskomd.0/45.exp: Test that only an enabled admin can set a canonical-name aux-item on the system. Improve aux-item documentation. * doc/Protocol-A.texi (About Aux-Items): Reduce the amount of text talking about aux-items on persons. (Aux-Item Inheritance): New node. * doc/lyskomd.texi (Aux-Item Definition File): Document that author-only and supervisor-only has no effect on items placed on the system. Speed up the test suite slightly. * src/server/testsuite/lyskomd.0/gen-19.py (DEBUG): Turn it off. Improve documentation on set-connection-time-format, and make it recommended. * doc/Protocol-A.texi (Common Types): Mention that times can be expressed in UTC if the set-connection-time-format request has been used. (get-last-text): Ditto. (set-connection-time-format): Change the status from experimental to recommended. * doc/constructs.expected: Updated. Fixed a crash in setup_timer(). * src/libraries/libmisc/timeval-util.c (setup_timer): Fixed a fence error that triggered an assertion with a probability of one in a million. Warn about using SIGWINCH to read a new aux-item file. If there is a syntax error, the server will abort. * doc/lyskomd.texi (Parameters): Warn about Bug 1095. (Signals): Ditto. Test parsing of broken aux-items at runtime. * src/server/testsuite/lyskomd.0/46.exp: New file: Test parsing a broken aux-item file as a result of SIGWINCH. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added 46.exp. * src/server/testsuite/config/unix.exp (lyskomd_death): New reason: "restart_kom". * src/server/testsuite/lyskomd.0/aux-items-bad.conf: New file with syntax errors. 2003-08-18 Per Cederqvist Write test case for aux-item inheritance. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added 45.exp. * src/server/testsuite/lyskomd.0/45.exp: New file: Test aux-item inheritance. 2003-08-17 Per Cederqvist Simplified the statistics code. Don't crash if the time moves backwards, but log a nice error message including how much the time moved. * src/server/connections.c (set_time): Log how much the time moves backwards when it moves backwards. * src/server/stats.h (check_all_stats): Removed. * src/server/stats.c: Don't attempt to keep a running average. Rounding errors are far too common. Recompute it whenever it is requested instead. This results in simpler code as well. (dump_stats): Removed. (update_one_stat): Check if the time moves backward, to avoid triggering an assertion. (is_nonzero): Removed. (check_all_stats): Removed. * src/server/ramkomd.c (main): Removed calls to check_all_stats(). Simplify handling of the sent_by misc-info. Allow the supervisor of the author and sender to modify or remove a recipient (Bug 966, Bug 181 and Bug 1089). Don't allow a text to be both a footnote and a comment of the same text at the same time (Bug 1090). Code cleanup. * doc/Protocol-A.texi (add-comment): Added error codes already-comment and already-footnote. (add-footnote): Added error codes already-comment. * src/server/text.c (find_textlink): New static function. (is_supervisor_of_sender): New static function. (is_sender): Removed. (is_comm_sender): Removed. (is_comment_to): Removed. (recp_sent_by): Removed. (is_footnote_to): Removed. (sender): Removed. (do_add_footnote): New arguments: the Text_stat objects. All callers updated. (do_add_comment): Ditto. (do_add_recipient): The text_s argument may no longer be NULL. All callers updated. (skip_recp): New simplified API. (filter_secret_info): Use is_supervisor_of_sender() instead of recp_sent_by(). Use the new API of is_supervisor(). (person_text_read_access): Use is_supervisor_2() instead of is_supervisor() until bug 178 is fixed. (create_text_add_miscs): New argument: new_stat. Pass it to do_add_footnote(), do_add_comment() and do_add_recipient() for a slight performance gain. All callers updated. (delete_text): Use new API of is_supervisor(). (add_recipient): Allow the supervisor of the author to modify the recipient (fixes bug 966). Allow the supervisor of the sender to modify the recipient (fixes bug 181). (sub_recipient): Use the new API of is_supervisor(). Allow the supervisor of the sender to remove the recipient (fixes bug 1089). (check_add_textlink): New helper function with the common parts of add_comment() and add_footnote(). Don't allow a text to be both a footnote and a comment of the same text at the same time (fixes bug 1090). (add_comment): Move code to check_add_textlink(). (sub_comment): Use find_textlink() instead of is_comment_to(). Use new API of is_supervisor(). Allow the supervisor of the sender to remove the comment link. (add_footnote): Use check_add_textlink() to simplify the code. (sub_footnote): Use find_textlink() instead of is_footnote_to(). Use new API of is_supervisor(). * src/server/session.c (login_old): Use new API of is_supervisor(). Simplify and reindent code. (login): Ditto. (disconnect): Ditto. * src/server/person.c (set_passwd): Use new API of is_supervisor(). Simplify and reindent code. * src/server/membership.c (access_perm_helper): Use new API of is_supervisor(). Simplify and reindent code. (sub_member): Ditto. (add_member_common): Ditto. (do_get_members): Ditto. * src/server/conference.c (is_supervisor): Replaced the Pers_no and Person arguments with a Connection argument. (is_supervisor_2): New function, with the old API of is_supervisor(). (set_permitted_submitters): Use new API of is_supervisor(). (set_super_conf): Ditto. * src/server/aux-items.c (filter_aux_item_list): Use new API of is_supervisor(). (check_delete_aux_item_list): Ditto. * src/server/manipulate.h (is_supervisor): Replaced the Pers_no and Person arguments with a Connection argument. (is_supervisor_2): New function, with the old API of is_supervisor(). This is only used in one place, and will be removed when bug 178 is fixed. * src/server/testsuite/lyskomd.0/44.exp: Bugs 966, 181, 1089 and 1090 are now fixed. * src/server/testsuite/lyskomd.0/14.exp: Bug 181 is now fixed. Added test cases for bug 1090. * src/server/testsuite/lyskomd.0/44.exp: Added test cases for bug 1090. * src/server/testsuite/config/unix.exp (good_bad_expect): Handle the case where the bad result contains only a success indicator and a refno (such as "=1032"). Allow recipients to be converted in a few more cases. * doc/Protocol-A.texi (add-recipient): The permission-denied error code is given if you are not supervisor of the author, recipient or sender. The condition used to be more restrictive. Test suite fixes. * src/server/testsuite/lyskomd.0/14.exp: Simplified the code by using good_bad_expect. * src/server/testsuite/lyskomd.0/41.exp: Fixed typo in a comment. Added test cases for bug 181, bug 966 and bug 1089. * src/server/testsuite/lyskomd.0/44.exp: New file, that tests conversion of recipients from one type to another. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added 44.exp. Fixed dist error introduced yesterday. * scripts/Makefile.am (EXTRA_DIST): Dont forget to distribute the $(noinst_SCRIPTS). 2003-08-16 Per Cederqvist Send and receive times in UTC, if the clients requests it. (Bug 957). * doc/Protocol-A.texi (set-connection-time-format): New request. * src/include/services.h (set_connection_time_format): New request. * src/server/connections.h (Connection): Added use_utc. * src/server/fncdef.txt: Added set_connection_time_format. * src/server/text.c (get_last_text): Handle use_utc. * src/server/session.c (set_connection_time_format): New function. * src/server/prot-a-output.c (prot_a_output_time): Handle use_utc. * src/server/internal-connections.c (init_connection): Initialize use_utc. (new_client): Ditto. * src/server/prot-a-parse.c (prot_a_parse_misc_info): This code used to convert the broken-down time to a time_t using mktime(). The value was never used. Instead of introducing a portability problem using by calling timelocal(), we now simply store a 0 in the time field of rec_time and sent_at misc-infos. * src/server/testsuite/lyskomd.0/01.exp: Test set_connection_time_format. * src/server/testsuite/lyskomd.0/03.exp: Ditto. Installation fixes. * README: Fixed minor error in upgrade instructions. * run-support/Makefile.am (install-data-local): Create var/run, which will hold the pid file. New async: async-text-aux-changed. (Bug 910). * doc/Protocol-A.texi (Client-Specific Aux-Item Types): Reserve 10200-10299 for private test use. Refer to Bugzilla. (async-text-aux-changed): New async message. * src/server/async.h (enum async): Added ay_text_aux_changed. * src/server/prot-a-send-async.h, src/server/prot-a-send-async.c (prot_a_async_text_aux_changed): New function. * src/server/send-async.c, src/server/send-async.h (async_text_aux_changed): New function. * src/server/session.c (accept_async): Handle ay_text_aux_changed. * src/server/text.c (send_async_text_aux_changed): New function. (modify_text_info): Call it. * src/server/testsuite/lyskomd.0/03.exp: Handle async-text-aux-changed. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added 43.exp. * src/server/testsuite/lyskomd.0/43.exp: New file. Test async-text-aux-changed. Code cleanup. * src/server/aux-items.c: Fixed indentation of bool operators. (commit_aux_item_list_internal): Removed a redundant "continue". (delete_aux_item_list): Fixed cut-n-paste errors in comments. (aux_item_list_add_items): Simplified the code. * src/server/prot-a-parse.c (prot_a_parse_misc_info_list): Fixed a cut-n-paste error: wrong function name in log message. * src/server/testsuite/lyskomd.0/00.exp: Removed the "test" argument to one of the simple_expect, to help diagnose problems where 127.0.0.1 isn't properly resolved. The man-pages will stay. * HACKING: It is good to have man-pages that refer to the real documentation, so don't remove them. (Bug 77). Refer to Bugzilla, not email. (Bug 724). * All files: Change the phrase "Please mail bug reports to bug-lyskom@lysator.liu.se." to "Please report bugs at http://bugzilla.lysator.liu.se/." Make config files refer to their documentation. * run-support/aux-items.conf: Added a reference to the documentation. * run-support/config: Added a reference to the documentation. Use better file names, so that lyskomd can be installed in /usr or /usr/local. (Bug 66 and Bug 132). * NEWS: Documented all changed path names. * README: Removed the warning not to use /usr/local as the prefix. Document how an upgrade should be made. Document what needs to be done when upgrading from pre-2.1.0 to 2.1.0. The binaries are now in "sbin", not "bin". * Makefile.am (SUBDIRS): Moved scripts before doc. * src/server/server-config.c (assign_path): New define for assign_string. (unassign_path): New define for unassign_string. (parameters): Use assign_path and unassign_path for all path parameters, to make them easier to find. Use default values from paths.h instead of hardcoding the defaults in the file. A lot of values have changed; see the summary in the NEWS file. (CONFIG_FILE): Removed. This is now a define in paths.h. (compiled_config_file): New constant. (get_default_config_file_name): Use compiled_config_file instead of CONFIG_FILE. (free_default_config_file_name): Ditto. * src/server/connections.h: Updated a comment. * src/server/Makefile.am (MOSTLYCLEANFILES): Added paths.h. (AM_CPPFLAGS): Removed the DEFAULT_PREFIX define. Use paths.h instead. (sbin_PROGRAMS): Was: bin_PROGRAMS. (BUILT_SOURCES): Added paths.h. (.gdbinit): Removed redundant "-f" option to $(RM). (DEFP): New constant. (paths.h): New target. (server-config.o): Added explicit dependency on paths.h. * scripts/unprefix: New script. * scripts/definepath: New script. * scripts/common.make (dbdir): Moved here from db-crypt/db/Makefile.am. (exportdir): New constant. * scripts/Makefile.am (noinst_SCRIPTS): Added unprefix and definepath. Moved lyskomd-copyrights and update-copyright here from EXTRA_DIST. * run-support/config: Mention that this is installed as lyskomd.conf. * run-support/Makefile.am (sbin_SCRIPTS): Renamed savecore to savecore-lyskom, to avoid confusion with the /usr/bin/savecore program on Solaris. (MOSTLYCLEANFILES): Track the change. (savecore-lyskom): Track the change. (install-data-local): Install the config file as lyskomd.conf, not config. Create the lyskomd.cores directory. (uninstall-local): Track the name change of lyskomd.conf. * src/server/testsuite/config/unix.exp (lyskomd_start): Use the old path names, so that we don't have to update the entire test suite. * doc/lyskomd.texi: Updated the default paths to the new world order. * db-crypt/db/Makefile.am (dbdir): Moved to common.make. Added man pages that refer to the Texinfo documentation for all installed programs. Made the man pages static. * doc/man/splitkomdb.8: New file. * doc/man/savecore-lyskom.8: New file. * doc/man/lyskomd.8: Removed the version number. * doc/man/updateLysKOM.8: Removed the version number. * doc/man/Makefile.am (man_MANS): Added savecore-lyskom.8 and splitkomdb.8. 2003-08-15 Per Cederqvist Distribution fix. * mkmi: Always regenerate scripts/depcomp. Xenofarm fix. * src/server/testsuite/lyskomd.0/person-cov.exp: Added "DNS log threshold: 3600" to support a certain slow Xenofarm computer. Calculate the file name of the configuration file in a single place. Related code cleanup. * src/server/updateLysKOM.c (main): Use get_default_config_file_name() to find the config file. * src/server/splitkomdb.c (main): Ditto. * src/server/komrunning.c (main): Ditto. * src/server/dbck.c (main): Ditto. * src/server/ramkomd.c (main): Ditto. Don't set read_config_file -- nothing used the value. * src/server/server-config.c (read_config_file): Variable removed. (CONFIG_FILE): Now static. (default_config): New static variable. (get_default_config_file_name): New function. (free_default_config_file_name): New function. (DEFAULT_DBASE_DIR): Removed. * src/server/param.h (read_config_file): Variable removed. * src/include/kom-config.h (DEFAULT_DBASE_DIR): Removed. (CONFIG_FILE): Removed. (get_default_config_file_name): New function. (free_default_config_file_name): New function. Handle scheduling of different weights. The scheduling priority must still be 0. * doc/lyskomd.texi (Parameters): Document "Default priority", "Max priority", "Default weight" and "Max weight". * src/server/connections.h (Connection): New field: schedule. * src/server/server-config.c (parameters): Added "Default priority", "Max priority", "Default weight" and "Max weight". (require_less_eq): New static function. (read_configuration): Check the new parameters. For now, max_priority must be set to 0, since connections.c can only handle a single priority. * src/server/param.h (struct kom_par): New fields: default_priority, max_priority, default_weight, max_weight. * src/server/internal-connections.c (init_connection): Initialize the schedule. * src/server/connections.c (login_request): Set the priority and weight from param.default_priority and param.default_weight. (adjust_penalty): Use the weight to reduce the penalty. (get_scheduling): Return the actual scheduling information from the connection. (set_scheduling): Check the priority and weight against param.max_priority and param.max_weight. Allow the user to change them, as long as it is done within those limits. Store the new values in the connection. Note: the current implementation cannot handle more than one priority. The check for that is made in server-config.c. * src/server/testsuite/get-time-often.c (longopts): Added --priority and --weight. (main): Handle the new options. * src/server/testsuite/lyskomd.0/01.exp: The new default weight is 20. The new maximum weight is 100. * src/server/testsuite/lyskomd.0/03.exp: Ditto. 2003-08-14 Per Cederqvist Added the set-scheduling and get-scheduling requests. The current implementation only supports priority==0 and weight==1. * doc/Protocol-A.texi (Session Information): Added Scheduling-Info. (get-scheduling): New request. (set-scheduling): New request. (Error Codes): Added priority-denied, weight-denied and weight-zero. * src/server/prot-a.c (prot_a_reply): Handle rt_scheduling_info. * src/server/prot-a-output.h, src/server/prot-a-output.c (prot_a_output_scheduling_info): New function. * src/server/fncdef.txt: Added get_scheduling and set_scheduling. * src/server/connections.h (enum res_type): Added rt_scheduling_info. (union result_holder): Added scheduling_info. * src/server/connections.c (get_scheduling): New request. (may_change_scheduling): New static function. (set_scheduling): New request. * src/include/services.h (set_scheduling): New request. (get_scheduling): New request. * src/include/kom-types.h (Scheduling_info): New struct. * src/include/kom-errno.h (enum kom_err): Added KOM_PRIORITY_DENIED, KOM_WEIGHT_DENIED and KOM_WEIGHT_ZERO. * src/server/testsuite/lyskomd.0/01.exp: Test get-scheduling and set-scheduling. * src/server/testsuite/lyskomd.0/03.exp: Ditto. Test suite improvement. * src/server/testsuite/Makefile.am (../../libraries/adns/client/adnshost): New target. (site.exp): Depend on adnshost, so that "make check" works even if "make check" has not been run in the adns directory. Minor doc fixes. * doc/lyskomd.texi (Parameters): Document the default value of "Low penalty". Removed some text that was left behind a cut-n-paste operation. (Adding a New Protocol Request): Added a CHK_CONNECTION call to the example. Changed status of set-keep-commented from experimental to recommended. * doc/Protocol-A.texi (Protocol Requests): Changed the status of set-keep-commented from experimental to recommended. (set-keep-commented): Ditto. Clarify the description of get-stats-description and get-stats. * doc/Protocol-A.texi (get-stats-description): State that this always returns the same during a session, so clients can cache this value aggressively. (get-stats): Elaborate on the access-denied error code. 2003-08-13 Per Cederqvist Use AM_PATH_PYTHON to find the Python interpreter. (Bug 329). * configure.in: Use AM_PATH_PYTHON. (HAVE_PYTHON): New automake conditional. * HACKING: Use Automake 1.7.6 with a patch for better Python handling. * doc/Makefile.am (check-doc): Only perform the tests if HAVE_PYTHON is set. Use $(PYTHON) instead of python. Print a warning if HAVE_PYTHON isn't set. * src/server/testsuite/Makefile.am (check-lyskomd): Only perform the tests if HAVE_PYTHON is set. Use $(PYTHON) instead of python. Print a warning if HAVE_PYTHON isn't set. (check-leaks): Ditto. (site.exp): Set python to the Python interpreter found by configure. * src/server/testsuite/lyskomd.0/Makefile.am ($(srcdir)/15.exp): Use $(PYTHON) instead of python. Use the HAVE_PYTHON Automake conditional. ($(srcdir)/19.exp): Ditto. * src/server/testsuite/config/unix.exp (obtain_lock): Use $python from site.exp instead of hardcoding "python". (client_start): Ditto. (client_start_fail): Ditto. * scripts/xenofarm.sh: Removed tests for python. We should get a warning message from "make check" if python is missing, but it should still succeed. Testsuite improvement. * src/server/testsuite/lyskomd.0/37.exp: Added "DNS log threshold" entries so that a slow DNS server won't interfere with this test. Protocol-A.texi was incompatible with the texinfo.tex supplied with Automake 1.7.6. * doc/Protocol-A.texi (\tensltt): Define this command using TeX syntax, and add a \global. I have only a vague idea what this does, but it seems to work with texinfo.tex 2003-05-04.08. Create scripts/common.make, and include it from all LysKOM Makefile.am files. Move the RM setting to it. (Bug 851). * scripts/common.make: New file, which contains makefile fragments that all makefiles should include. (RM): Moved this variable to this file. * db-crypt/db/Makefile.am: Include common.make instead of setting RM. * doc/Makefile.am: Ditto. * run-support/Makefile.am: Ditto. * src/libraries/libeintr/Makefile.am: Ditto. * src/server/testsuite/Makefile.am: Ditto. * src/server/testsuite/lyskomd.0/Makefile.am: Ditto. * Makefile.am: Include common.make. * db-crypt/Makefile.am: Ditto. * scripts/Makefile.am: Ditto. * src/Makefile.am: Ditto. * src/include/Makefile.am: Ditto. * src/include/server/Makefile.am: Ditto. * src/libraries/Makefile.am: Ditto. * src/libraries/libansi/Makefile.am: Ditto. * src/libraries/libcommon/Makefile.am: Ditto. * src/libraries/libmisc/Makefile.am: Ditto. * src/server/Makefile.am: Ditto. * src/server/testsuite/config/Makefile.am: Ditto. * doc/man/Makefile.am: Ditto. Automake lint. * configure.in: Use new-style call to AM_INIT_AUTOMAKE. Implement find-next-conf-no and find-previous-conf-no. (Bug 123). * doc/Protocol-A.texi (Server Information): Refer to find-previous-conf-no. (find-next-conf-no): New request. (find-previous-conf-no): New request. * src/server/fncdef.txt: Added find_next_conf_no and find_previous_conf_no. * src/include/services.h, src/server/conference.c (find_next_conf_no): New function. (find_previous_conf_no): New function. * src/server/testsuite/lyskomd.0/01.exp: Test find_next_conf_no and find_previous_conf_no. * src/server/testsuite/lyskomd.0/03.exp: Ditto. * src/server/testsuite/lyskomd.0/41.exp: Ditto. The test suite failed on really really slow computers. * src/server/testsuite/config/unix.exp (lyskomd_start): Increase the "Connect timeout" and "Login timeout" to 1 day, unless the test specifies them. I suspect that the "Connect timeout" interfered with a test on one of the slower members of the Xenofarm. * src/server/testsuite/lyskomd.0/38.exp: Fixed a race condition: if the client was killed at the wrong time, the test would crash. * src/server/testsuite/lyskomd.0/37.exp: Pass a $base_config to lyskomd_start in the other place as well. The fix made on 2003-08-07 was incomplete. Implement first-unused-conf-no and first-unused-text-no. (Bug 121). * doc/Protocol-A.texi (first-unused-conf-no): New request. (first-unused-text-no): New request. (Server Information): Refer to the new requests instead of inferior ways to get the same information. * src/include/services.h (first_unused_conf_no): New function. (first_unused_text_no): New function. * src/server/text.c (first_unused_text_no): New function. * src/server/simple-cache.c (query_next_conf_no): New function. * src/server/prot-a.c (prot_a_reply): Handle rt_conf_no. * src/server/prot-a-output.h, src/server/prot-a-output.c (prot_a_output_conf_no): New function. * src/server/fncdef.txt: Added first_unused_conf_no and first_unused_text_no. * src/server/connections.h (enum res_type): Aded rt_conf_no. (union result_holder): Added conf_no. * src/server/conference.c (first_unused_conf_no): New function. * src/server/cache.h (query_next_conf_no): New function. * src/server/testsuite/lyskomd.0/01.exp: Test 114:first-unused-conf-no and 115:first-unused-text-no. * src/server/testsuite/lyskomd.0/03.exp: Ditto. * src/server/testsuite/lyskomd.0/41.exp: Ditto. Makefile improvements that might help portability to CYGWIN_NT-5.0. * src/server/testsuite/Makefile.am (AM_CPPFLAGS): Added ../../.., so that config.h is properly found. * src/server/Makefile.am (aux.h): Don't append to a non-existing file; use ">" instead of ">>" to create it. 2003-08-12 Per Cederqvist Implement and use has_access() to simplify code. (Bug 723). * src/server/manipulate.h, src/server/membership.c (has_access): New function. This is a simple wrapper around access_perm that simplifies the code. * src/server/membership.c (filter_conf_no): Use has_access() instead of access_perm() to simplify code. (sub_member): Ditto. (add_member_common): Ditto. * src/server/text.c (filter_secret_info): Ditto. (add_recipient): Ditto. (sub_recipient): Ditto. * src/server/send-async.c (async_new_name): Ditto. (async_new_user_area): Ditto. * src/server/regex-match.c (lookup_regexp): Ditto. * src/server/person.c (do_query_read_texts): Ditto. * src/server/conference.c (set_conf_errno): Ditto. (lookup_name): Ditto. (lookup_z_name): Ditto. (do_lookup): Ditto. (send_async_new_presentation): Ditto. (send_async_new_motd): Ditto. (modify_conf_info): Ditto. * src/server/admin.c (send_message): Ditto. * doc/lyskomd.texi (Adding a New Protocol Request): Fixed broken code example. Use has_access() instead of access_perm(). lyskomd is now officially shut down via SIGTERM. (SIGHUP still works, and SIGINT also shuts it down.) (Bug 808). * doc/lyskomd.texi (Parameters): lyskomd is now officially shut down by SIGTERM, not SIGHUP. (Signals): Ditto. However, SIGHUP and SIGINT also works. (Administration): Recommend SIGTERM, not SIGHUP. (Bugs): Removed entry about terminating on SIGINT and SIGTERM. * src/server/testsuite/config/unix.exp (lyskomd_death): The reason "signal" now means SIGTERM. Also handle "sighup" and "sigint". * src/server/updateLysKOM.c (checkstatus): Use SIGTERM, not SIGHUP. * src/server/sigflags.h: Updated a comment: SIGTERM is now the official way to shut down lyskomd. * src/server/ramkomd.c (server_init): Handle SIGTERM and SIGINT the same way as SIGHUP: shut down. (main): Ditto. (sighandler_term): New name for former sighandler_hup. Log proper message depending on which signal was used to shut down the server. * src/server/komrunning.c (shutdown_lyskom): Use SIGTERM, not SIGHUP, to shut down lyskomd. * src/server/connections.c: Updated a comment: SIGTERM is now the official way to shut down lyskomd. * src/server/testsuite/lyskomd.0/31.exp: Test to shut down the server by both SIGTERM, SIGHUP and SIGINT. * src/server/testsuite/lyskomd.0/07.exp: Use TERM instead of HUP to shut down lyskomd. * src/server/testsuite/lyskomd.0/11.exp: Ditto. * src/server/testsuite/lyskomd.0/30.exp: Ditto. * src/server/testsuite/lyskomd.0/37.exp: Ditto. * src/server/testsuite/lyskomd.0/38.exp: Ditto. * src/server/testsuite/lyskomd.0/39.exp: Ditto. * src/server/testsuite/lyskomd.0/bug-48.exp: Ditto. * src/server/testsuite/lyskomd.0/bug-52.exp: Ditto. * src/server/testsuite/lyskomd.0/bug-810.exp: Ditto. The same text can no longer be FAQ for the same conference twice. (Bug 572). * run-support/aux-items.conf (faq-conf): Added unique-data, so that the same text cannot be faq for a conference more than once. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added bug-572.exp. * src/server/testsuite/lyskomd.0/bug-572.exp: New file. Test that the same text cannot be FAQ for the same conference more than once. Added support for aux-items that must contain a unique piece of data. * doc/lyskomd.texi (Aux-Item Definition File): Document unique-data. * src/server/aux-items.h (struct Aux_item_definition_s): Added unique_data. * src/server/aux-items.c (empty_aux_item_definition): Added unique-data. (simple_aux_item): Ditto. (aux_item_add_perm): If aux_item_check_unique sets kom_errno, don't override it. (aux_item_check_unique): Check for unique_data violations. * src/server/aux-item-def-parse.y (assign): Handle unique-data. (parse_aux_item_definitions): Handle unique-data in the debug code that prints the parsed aux-item. "./configure && make install" no longer fails. (Bug 856). * src/server/Makefile.am (connections.o): Add an explicit dependency on prot-a-parse-arg.h so that "./configure&&make install" works. * HACKING: Before a release, a "./configure&&make install" check should be made. Test suite fix. * src/server/testsuite/lyskomd.0/regexp-match-cov.exp: Re-updated expected leak count. Since the leak due to bug 689 is now suppressed, it only shows up among the suppressions. The get-boottime-info implementation caused compilation errors unless DEBUG_CALLS was defined. * src/server/simple-cache.c: services.h and manipulate.h are always needed. Added get-boottime-info. (Bug 6). * src/server/testsuite/lyskomd.0/03.exp, src/server/testsuite/lyskomd.0/01.exp: Test get-boottime-info. * src/server/stats.h, src/server/stats.c (read_stat_value): New function. * src/server/simple-cache.c (boottime_info): New static variable. (init_cache): Initialize boottime_info. (get_boottime_info): New request. * src/server/prot-a.c (prot_a_reply): Handle rt_static_server_info. * src/server/prot-a-output.h, src/server/prot-a-output.c (prot_a_output_static_server_info): New function. * src/server/fncdef.txt: Added get_boottime_info. * src/server/connections.h (enum res_type): Added rt_static_server_info. (union result_holder): Added static_server_info. * src/include/services.h (get_boottime_info): New request. * src/include/kom-types.h (Static_server_info): New type. * doc/constructs.expected: Updated. * doc/Protocol-A.texi (Server Information): Document Static-Server-Info. (get-boottime-info): New request. Measure the number of existing conferences and persons. * src/server/testsuite/lyskomd.0/03.exp, src/server/testsuite/lyskomd.0/01.exp: Test STAT_CONFS and STAT_PERSONS. * src/server/stats.h (enum stat_type): Added STAT_CONFS and STAT_PERSONS. * src/server/stats.c (name): Handle STAT_CONFS and STAT_PERSONS. * src/server/simple-cache.c (init_cache): Update STAT_CONFS and STAT_PERSONS. * src/server/person.c (do_delete_pers): Update STAT_PERSONS. (create_person_generic): Update STAT_PERSONS and STAT_CONFS. * src/server/conference.c (do_delete_conf): Update STAT_CONFS. (do_create_conf): Ditto. * doc/Protocol-A.texi (Measured Properties): Added "confs" and "persons". 2003-08-11 Per Cederqvist Testsuite fixes. * src/server/testsuite/lyskomd.0/41.exp: Code cleanup. * src/server/testsuite/lyskomd.0/regexp-match-cov.exp: Updated expected suppressed leak count. Test handling of the keep-commented field and its interaction with the garb. Added the debug request backdate_comment_link. (Bug 902). * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added 42.exp. * src/server/testsuite/lyskomd.0/42.exp: New file. Test keep-commented handling. * src/server/fncdef.txt: Added backdate_comment_link. * src/server/debug.c (backdate_comment_link): New debug request. * src/include/services.h (backdate_comment_link): New debug request. Comments and footnotes now protect the parent text from being garbed until the comment is keep_commented days old. (Bug 902). * src/include/kom-types.h (Small_conf): Added keep_commented. * src/server/cache.h (cached_get_keep_commented): New function. * src/server/text-garb.c (saved_by_recipient): Code cleanup. (find_comment_limit_and_age): New static function. (saved_by_keep_commented): New static function. (saved): Call saved_by_keep_commented. * src/server/simple-cache.c (mark_conference_as_changed): Copy the keep_commented field to the small_conf. (setup_small_conf): Ditto. (init_small_conf): Initialize keep_commented. (cached_get_keep_commented): New function. * src/server/dbck-cache.c (cached_get_keep_commented): New function. Code cleanup. * src/server/conference.c: Fixed a cut-n-paste comment error. Add a valgrind suppression. * src/server/testsuite/lyskomd.supp: Added a suppression for a known leak in regex_compile(). Reorganized text-garb.c for readability. * src/server/text-garb.c (day_to_sec): New constant. (default_save): New constant. (saved_by_aux): New static helper function. (saved_by_recipient): Ditto. (saved_by_comment): Ditto. (saved): Ditto. (garb_text): Use the saved() function to simplify code. 2003-08-10 Per Cederqvist Use valgrind-20030725. Use leak suppression to ignore harmless leaks we cannot fix. (Bug 974). * scripts/warnings.sed: Adjusted a line number. * src/server/testsuite/lyskomd.0/regexp-match-cov.exp: Updated for valgrind-20030725. * src/server/testsuite/lyskomd.0/aux-items-cov.exp: The possible leaks are now suppressed. * src/server/testsuite/config/unix.exp (check_valgrind): The expected_leaks argument should now include the number of suppressed memory leaks. Ignore up to 25 suppressed leaks. Don't ignore any reachable leaks. * src/server/testsuite/lyskomd.supp: Updated for valgrind-20030725. Add suppressions of known harmless memory leaks. 2003-08-08 Per Cederqvist Implement async-new-motd. (Bug 906). * doc/Protocol-A.texi (async-new-motd): New async message. * src/server/async.h (enum async): Added ay_new_motd. * src/server/session.c (accept_async): Handle ay_new_motd. * src/server/send-async.h, src/server/send-async.c (async_new_motd): New function. * src/server/prot-a-send-async.h, src/server/prot-a-send-async.c (prot_a_async_new_motd): New function. * src/server/conference.c (send_async_new_motd): New function. (do_set_etc_motd): Call it. Clean up variable names. * src/server/testsuite/lyskomd.0/conference-cov.exp: Track change in error message from do_set_etc_motd. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added 41.exp. * src/server/testsuite/lyskomd.0/41.exp: Test async-new-motd. * src/server/testsuite/lyskomd.0/03.exp: Handle ay-new-motd. * src/server/testsuite/lyskomd.0/40.exp: Fixed a broken comment. Implement async-new-presentation. (Bug 904). * src/server/session.c (accept_async): Handle ay_new_presentation. * src/server/send-async.h, src/server/send-async.c (async_new_presentation): New function. * src/server/prot-a-send-async.h, src/server/prot-a-send-async.c (prot_a_async_new_presentation): New function. * src/server/conference.c (send_async_new_presentation): New function. (do_set_presentation): Call it. Clean up variable names, and remember the text statuses of the old and new presentation so they can be passed to send_async_new_presentation(). Include the text number of the old presentation in the error message that is printed if the old presentation lacks a mark. * src/server/testsuite/config/unix.exp (client_good_bad_expect): New proc. (client_extracting_expect): New proc. * src/server/testsuite/lyskomd.0/03.exp: Handle async-new-presentation. * src/server/testsuite/lyskomd.0/40.exp: async-new-presentation is now implemented. Expect bug 178. * src/server/testsuite/lyskomd.0/conference-cov.exp: Track change in error message from do_set_presentation. Document async-new-presentation and write a test suite for it. (Bug 904). * doc/Protocol-A.texi (async-presentation-changed): New async. * src/server/async.h (enum async): Added ay_new_presentation. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added 40.exp. * src/server/testsuite/lyskomd.0/40.exp: Test async-new-presentation. * src/server/testsuite/config/unix.exp (client_expect): New proc. 2003-08-07 Per Cederqvist The test suite failed on really really slow computers. * src/server/testsuite/lyskomd.0/37.exp: Pass a $base_config to lyskomd_start, since we don't want lyskomd_start to modifiy the compiled-in default of "Sync interval". * src/server/testsuite/config/unix.exp (lyskomd_start): Set the "Sync interval" to 1 day, so that it doesn't interfere with the tests. Added a colon to the strings that extra_config is checked against, so that parameters that are prefixes of other parameters are handled correctly. Stats improvements. * src/server/stats.c: The "updates" field now counts incremental updates of avenrun. (update_history): Adjusted. (update_one_stat): Adjusted. (check_one_stat): Adjusted. Make it easier to change the file descriptor reserved for valgrind. Don't use a file descriptor that interferes with the test suite. * src/server/testsuite/config/unix.exp (PROTECTED_FDS): Added a comment that refers to ../Makefile.am. Check that valgrind_fd is set properly. (lyskomd_host): This is now set in site.exp, not here. (l2g_start): Use valgrind_fd instead of hardcoding the value. (spawn_lyskomd): Ditto. (dbck_run): Ditto. * src/server/testsuite/Makefile.am (VALGRIND_FD): New constant, set to 21. Added a comment that refers to PROTECTED_FDS in unix.exp. (site.exp): Set lyskomd_host to whatever 127.0.0.1 resolves to, or 127.0.0.1 if it cannot be looked up at all. Set valgrind_fd to the constant defined in VALGRIND_FD. (valgrind.wrap): Use VALGRIND_FD, instead of hardcoding the value in two places. Changed the valgrind file descriptor to 21, which is currently the highest reserved file descriptor. (check_DATA): Was: noinst_DATA. site.exp should not be built until adnshost is built, and the other stuff in noinst_DATA was also not needed until check time. Don't log simple reverse lookup errors for localhost, since they interfere with the test suite and are fairly common and harmless. * src/server/connections.c (dns_resolution): Don't log errors if the lookup of localhost fails due to "nxdomain" or "inconsistent". The AIX 4.2 and 4.3 builds have failed the tests for max open clients since we enabled ADNS. Attempt to fix. But can they really have an extra overhead of 8-9 file descriptors? * src/include/kom-config.h (PROTECTED_FDS): Account for the two file descriptors used by ADNS. * src/server/testsuite/config/unix.exp: Ditto. Send async-rejected-connection even to sessions where the reverse DNS lookup hasn't completed yet. * src/server/internal-connections.c (handshake_ok): Actually ignore the dns_done field when told to do so. 2003-08-06 Per Cederqvist Don't crash if shut down with a pending reverse DNS lookup. * src/server/connections.c (dns_resolution): Don't re-enable idle check during shutdown. Simplify code. (toploop): Simplify code by using enable_idle_check(). Test suite: Obtain the name "localhost" using adns. * src/server/testsuite/config/unix.exp (lyskomd_host): Use adnshost to set it, so that it is set the same way as when lyskomd is running. Compile the adnshost program during "make check". * src/libraries/adns/Makefile.am (SUBDIRS): Added client. * src/libraries/adns/configure.in: Generate client/Makefile. * src/libraries/adns/client/Makefile.am: New file. Compile adnshost as part of the "make check" phase. * src/libraries/adns/client/Makefile.in: Removed. Document undocumented TeX code. (Bug 195). * doc/Protocol-A.texi: Document some TeX code. Fix the "make check" target in liboop. * src/libraries/liboop/test-oop.c (get_name): Adjusted the call to oop_adns_submit. Use ADNS, so that IPv4 reverse DNS lookups are non-blocking. Since ADNS does not yet support IPv6, reverse lookups of IPv6 addresses are still blocking. (Bug 627). * src/server/prot-a.c (prot_a_parse_packet): Skip whitespace when blocking the client waiting for a DNS reply. * src/server/connections.c (parse_unparsed): Return immediately if the session became blocked by DNS. (dns_resolution): Schedule an idle check, as a client may have become unblocked. Don't call isc_enable() here. Instead, add the session to the run-queue. There may be pending input in the input buffer. Handle ADNS errors. (login_request): Check the return value of isc_resolve_remote(). (read_from_connection): Return if the session is blocked by DNS. * src/server/testsuite/lyskomd.0/regexp-match-cov.exp: After the adns integration, we need to ignore 25 unreachable blocks. * src/server/testsuite/lyskomd.0/aux-items-cov.exp: After the adns integration, we need to ignore 25 unreachable blocks. * src/server/testsuite/config/unix.exp (check_valgrind): After the adns integration, we need to ignore 25 unreachable blocks. Added the ability to do reverse queries to the oop adns adapter. * src/libraries/liboop/oop-adns.h, src/libraries/liboop/adns.c (oop_adns_submit): New argument: errcode. (oop_adns_submit_reverse): New function. 2003-08-05 Per Cederqvist Update testsuite: clients that hasn't completed the handshake should be invisible. * src/server/testsuite/lyskomd.0/connections-cov.exp: Disconnecting a client that hasn't declared a protocol yet now should fail. "make clean" fix. * src/server/testsuite/Makefile.am (MOSTLYCLEANFILES): Added memory-usage-*.log. Use a callback-based API for DNS lookup, in preparation for ADNS integration. Block clients, and make them invisible for all other clients, until the DNS lookup has completed. * doc/lyskomd.texi (Files): Document the handshake_ok field of connections.txt. (Function Templates for send-async.c): Include a call to handshake_ok() in prototype code. (Traversing Connections): Ditto. * src/server/session.c: All users of the hostname updated to get it from the isc_scb. (who_is_on): Removed dead code. (who_is_on_ident): Ditto. (who_is_on_dynamic): Removed dead code. Don't include sessions until the handshake is completed. (get_session_info): Don't include sessions until the handshake is completed. (get_static_session_info): Don't include sessions until the handshake is completed. (get_session_info_ident): Ditto. (disconnect): Don't include sessions until the handshake is completed. (get_client_name): Ditto. (get_client_version): Ditto. * src/server/send-async.c (async_new_text_old): Use handshake_ok() to check if it is OK to send the message to the client. As a result, the message will not be sent until the DNS lookup has completed. (async_new_text): Ditto. (async_i_am_on): Ditto. (async_logout): Ditto. (async_new_name): Ditto. (async_forced_leave_conf): Ditto. (async_login): Ditto. (async_deleted_text): Ditto. (async_new_recipient): Ditto. (async_sub_recipient): Ditto. (async_new_membership): Ditto. (async_new_user_area): Ditto. (async_garb_ended): Ditto. (async_sync_db): Ditto, but ignore the DNS lookup. (async_rejected_connection): Ditto. * src/server/prot-a.c (prot_a_parse_packet): Disable the session after the initial handshake if the dns resolution hasn't completed yet. * src/server/membership.c (send_async_new_membership): Indentation fixed. * src/server/internal-connections.h (enum ignored_conditions): New enum. (handshake_ok): New function. * src/server/internal-connections.c (init_connection): Updated to initialize all fields. Several were forgotten. (kill_client): Clear the remote_ip. (handshake_ok): New function. * src/server/connections.h (Connection): Removed the hostname field, since that is now stored as isc_session->remote. Added dns_done, blocked_by_dns, and remote_ip. * src/server/connections.c (dump_connections): Include a flag that tells if the session has completed the handshake or not. (dns_resolution): New function. (get_host_name): Removed. (login_request): Reorganized the code to use the new callback-driven API of ISC host lookups. * src/server/admin.c (shutdown_kom): Get the host name from the isc_scb, now that the information is no longer stored in the connection. * src/libraries/libmisc/timeval-util.h, src/libraries/libmisc/timeval-util.c (timeval_diff_d): New function. The session_start field of a Connection was used both to record the connect time and the login/logout time. As a result, the connection-time of a Static-Session-Info was not actually static. Fixed by keeping track of the connect time and the login/logout time separately. * src/server/connections.h (Connection): Replaced the session_start field with connect_time and login_time. All users updated. * src/server/session.c: (login_old): Set login_time, not connect_time. (login): Ditto. (logout): Use login_time, not connect_time. (get_session_info): Use connect_time, not login_time, as the connection_time. (get_static_session_info): Use connect_time, not login_time, as the connection_time. (get_session_info_ident): Ditto. * src/server/internal-connections.c (new_client): Set both connect_time and login_time. * src/server/connections.c (handle_accept_event): Call set_time(), so that the connect_time is set correctly. 2003-08-04 Per Cederqvist Don't leave whitespace in the input buffers. * src/server/prot-a.c (prot_a_parse_packet): Delete leading and trailing whitespace, to avoid having it linger in the input buffer. * src/server/prot-a-parse.h, src/server/prot-a-parse.c (prot_a_parse_skip_whitespace): New function. Code cleanup. * src/server/isc-parse.c (parse_nonwhite_char): Use WHITESPACE instead of hardcoding the string. Xenofarm: warnings from . * scripts/warnings.sed: Ignore warnings from lenin. Track the simplified API of ISC callback functions. * src/server/ramkomd.c (handle_accept_event): Added a forward declaration using the isc_accept_callback typedef. * src/server/connections.h (handle_accept_event): Adjusted to the new API of ISC callback functions. * src/server/connections.c (write_err_cb): Adjusted to the new API of ISC callback functions. (stale_cb): Ditto. (idle_cb): Ditto. (login_request): Ditto. (data_available_callback): Ditto. (handle_accept_event): Ditto. Slow DNS servers could interfere with the test suite. * src/server/testsuite/config/unix.exp (lyskomd_start): Set the "DNS log threshold" to one hour, to avoid that it interferes with the test suite. 2003-08-03 Per Cederqvist Track some minor cleanup of ISC. (Bug 916). * src/server/ramkomd.c (server_init): Use the address stored in listen_client->laddr instead of calling isc_getladdress(). * src/server/testsuite/lyskomd.supp: Removed a suppressions for calling accept() with NULL pointers. ISC no longer does that. Plug a memory leak in a test program. * src/server/testsuite/get-time-often.c (tcp_connect): Plugged a memory leak. The idle timeouts interfered with some tests on slow computers. Fix. * src/server/testsuite/lyskomd.0/29.exp (startup): Set the idle timeouts to 6 hours, to make sure that they do not interfere with the test. Bug fixes for the idle client disconnect. * src/server/server-config.c (parameters): Changed "Connect timeout" to 30 seconds. Changed "Login timout" to 30 minutes. (read_configuration): Don't require the various idle timeouts to be longer than the stale timeout. * doc/lyskomd.texi (Parameters): Updated the description of the idle timeouts. * src/server/testsuite/lyskomd.0/39.exp: Extended: test each timeout by itself. Removed the test that "Stale timeout" should be less than the idle timeouts, since that is no longer required. * src/server/testsuite/lyskomd.0/37.exp: Updated the expected values for "Connect timeout" and "Login timeout", and fixed the expected default suffix of "Active timeout". Bug fixes for get-stats. (Bug 1072). * src/server/stats.c (update_one_stat): The accumulator was not updated in a proper way. (update_stat): Update the ascending and descending values even when the delta is 0, so that they are updated when the get-stats request is issued. 2003-08-02 Per Cederqvist Disconnect idle clients after a few days. (Bug 11). * doc/lyskomd.texi (Parameters): Document "Connect timeout", "Login timeout" and "Active timeout". * src/server/server-config.c (parameters): Added "Connect timeout", "Login timeout" and "Active timeout". (require_less): New static function. (read_configuration): Check that "Stale timeout" is smaller than the three new timeouts. * src/server/param.h (struct param): Added connect_timeout, login_timeout and active_timeout. * src/server/session.c (login_old): Set the idle timeout to param.active_timeout. (login): Ditto. (logout): Set the idle timeout to param.login_timeout. * src/server/ramkomd.c (server_init): Set the default idle timeout to param.connect_timeout. * src/server/prot-a.c (prot_a_parse_packet): Set the idle timeout to param.login_timeout once the handshake is done. * src/server/connections.c (idle_cb): New static function. (login_request): Pass idle_cb() to isc_set_read_callback(). * src/server/testsuite/lyskomd.0/37.exp: Expect the new timeval settings: "Connect timeout", "Login timeout" and "Active timeout". * src/server/testsuite/lyskomd.0/39.exp: New file, with tests for idle client disconnect. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added 39.exp. Fixed a race condition in the test suite. * src/server/testsuite/config/unix.exp (client_start_fail): Don't add an expect_always handler for eof. In some tests two or more clients are supposed to die "at once", and this would lead to a race condition. (get_time_client_start): Ditto. Test suite framework improvement. * src/server/testsuite/config/unix.exp (extracting_expect): Report the value that was found in the "pass" message. This may help debugging. Test suite: Made the "stalled client" test more robust. * src/server/testsuite/lyskomd.0/38.exp: Set the sync interval to 1 day, to avoid spurious save async messages on slow hosts. Don't change the timeout. Keep waiting as long as the server processes new requests, even if it is so slow that it takes a long while for the output queue to start filling up. (req_rate): New proc. * src/server/testsuite/lyskomd.0/38.exp: Made the test for a stalled client more robust. (monitor_progress): Shut down the client if a timeout occurs. (send_queue_size): New proc. * src/server/testsuite/get-time-often.c (reading_from_server): New variable. (request_limit): New variable. (start_writing): New static function. (start_reading): Ditto. (stop_reading): Ditto. (read_stdin): New command: start-reading. (read_server): If do_write_only, just return OOP_HALT when eof, EPIPE or ECONNRESET on the server is seen--don't print anything. Print a message if more than request_limit replies are received. (write_server): Made a log message unique. (main): Use start_reading(), start_writing() and stop_reading() to simplify the code. Don't do a final write; different Unixes handles this in various strange ways, and we don't want to test *them*. Test suite fix. * src/server/testsuite/lyskomd.0/38.exp: Use a small message size and transmit queue. Make the packet sizes and output queue parameters configurable. * doc/lyskomd.texi (Parameters): Document "Max client message size", "Max client transmit queue messages" and "Max client transmit queue bytes". * src/server/server-config.c (parameters): Renamed "Max client transmit queue" to "Max client transmit queue messages". Added "Max client message size" and "Max client transmit queue bytes". * src/server/ramkomd.c (server_init): Call isc_cfg_queue_size(). Actually *use* param.maxqueuedsize and param.maxdequeuelen. * src/server/param.h (struct param): Added maxmsgsize and maxqueuedsize_bytes. 2003-08-01 Per Cederqvist get-stats should never return a negative number. * src/server/stats.c (check_one_stat): Fix the value if it has become negative, even if the error isn't large enough to fix. 2003-08-01 Per Cederqvist Fix struct timeval overflow problems on Linux/Alpha. * src/libraries/libmisc/timeval-util.h, src/libraries/libmisc/timeval-util.c (timeval_ctor): Changed type of the sec argument from int to time_t. * src/server/testsuite/lyskomd.0/37.exp: Handle the %g format now created by timeval-overflow. * src/server/testsuite/timeval-overflow.c (main): Use %g instead of %f to print the numbers, to avoid overflow problems in the %f representation. 2003-08-01 Per Cederqvist More fixes to the test of stalled clients. * src/server/testsuite/get-time-often.c (main): Actually retry after a EAGAIN, EWOULDBLOCK or EINTR result from the final write. Retry if it succeeds as well -- the server may just be slow closing the socket. Collect statistics of the read and write queues. * doc/Protocol-A.texi (Measured Properties): Document send-queue-bytes and recv-queue-bytes. * src/server/stats.h (enum stat_type): Added STAT_SEND_QUEUE and STAT_RECV_QUEUE. * src/server/stats.c (name): Handle STAT_SEND_QUEUE and STAT_RECV_QUEUE. * src/server/ramkomd.c (write_queue_change_callback): New static function. Update STAT_SEND_QUEUE. (server_init): Register write_queue_change_callback with isc. * src/server/internal-connections.c (kill_client): Update STAT_RECV_QUEUE. * src/server/connections.c (read_from_connection): Update STAT_RECV_QUEUE. * src/server/testsuite/lyskomd.0/01.exp: Test send-queue-bytes and recv-queue-bytes. * src/server/testsuite/lyskomd.0/03.exp: Ditto. * src/server/testsuite/lyskomd.0/38.exp: Ditto. Bug fix. * src/server/connections.c (toploop): Cancel the timer for check_kill_flag if needed during shutdown. Don't be too efficient... (Back out part of the "ignore clients" patch.) * src/server/connections.c (read_from_connection): Revert part of last change: flush the output even if the client is disconnecting. We want it to have a chance see the reply to the disconnect or shutdown request. Test suite fix. * src/server/testsuite/lyskomd.0/38.exp: Increased the timeout for stalled client detection even further. Fixed a memory leak during shutdown. Ignore clients that are being killed more efficiently. * src/server/connections.h (Connection): New field: kill_pending. * src/server/internal-connections.c (init_connection): Initialize kill_pending. (new_client): Ditto. * src/server/connections.c (add_to_kill_list): Check and update kill_pending. (check_kill_flg): Ditto. (read_from_connection): Ignore connections with a pending kill. (toploop): Call check_kill_flg() during shutdown if any kill is pending, so that the kill list is freed. Test suite fixes. * src/server/testsuite/lyskomd.0/37.exp: Handle "Stale timeout". * src/server/testsuite/lyskomd.0/38.exp: Use --write-only without the --time-abort. Use the new "shutdown" command of get-time-client. Allow the server half a minute to fill the output queue for the --write-only test. * src/server/testsuite/config/unix.exp (client_start_fail): Don't call wait from expect_always code. It would wait on the wrong process. (client_start_fail): Ditto. (get_time_client_start): Ditto. * src/server/testsuite/get-time-often.c (read_stdin): Implement the commands "ping" and "shutdown". (write_server): Don't return OOP_HALT just because the socket to the server is reset, but stop writing in that case. (main): Allow --write-only without --time-abort. Retry the final write up to 3 times if it fails with EPIPE, ECONNRESET or EINTR. (main): Write more than a single byte in the final write. Xenofarm: ignore more warnings. * scripts/warnings.sed: Allow line numbers in floating point comparison warnings from mathinline.h to differ. Disconnect stale clients. * doc/lyskomd.texi (Parameters): Document "Stale timeout". * src/server/server-config.c (parameters): Added "Stale timeout". * src/server/ramkomd.c (server_init): Configure the stale timeout of ISC. * src/server/param.h (struct kom_par): Added stale_timeout. * src/server/connections.c (stale_cb): New static function. (login_request): Pass stale_cb to isc_set_read_callback(). (setup_timer): Moved to timeval-util.h, and added a return value. All callers updated to check it. * src/server/testsuite/lyskomd.0/38.exp: Set the "Stale timeout" to 10 seconds, so that we can test disconnection of a stalled client in a reasonable time. Don't expect that test to fail. * src/server/testsuite/get-time-often.c (abort_pending): New static variable. (do_write_only): Now global static, not a local variable in main. (setup_timer): Removed. Use the one from libmisc instead. (write_server): Handle ECONNRESET, EPIPE and end-of-file when only writing. (arm_timer): Check return value of setup_timer. (end_it): Clear abort_pending. (main): Set abort_pending if we are about to abort. Cancel the timer if the top loop returns before the abort timer fires. Treat ECONNRESET the same way as EPIPE. Moved setup_timer() to libmisc. * src/server/connections.h: (setup_timer): Moved to timeval-util.h, and added a return value. All callers updated to check it. * src/libraries/libmisc/timeval-util.h, src/libraries/libmisc/timeval-util.c (setup_timer): New function. * src/libraries/libmisc/Makefile.am (AM_CPPFLAGS): Search liboop. * src/server/text-garb.c (garb_callback): Check return value of setup_timer. 2003-07-31 Per Cederqvist Xenofarm tweak for asmodean. * scripts/xenofarm.sh: Close file descriptor 21 on asmodean. Don't access internal structures of isc. * src/server/connections.c (add_to_kill_list): Use the new isc_getoopsource() function instead of accessing the internals of the isc_mcb structure. (data_available_callback): Ditto. Don't report expected rounding errors (near zero). * src/server/stats.c (struct avg_status): New field: max_seen. (dump_stats): Print the max_seen field. (init_stats): Initialize it. (update_history): Update it. (check_one_stat): Take max_seen into account when deciding if a message should be logged or not. Reset max_seen if a new value is stored. Test suite fix. * src/server/testsuite/lyskomd.0/38.exp: Handle the "Resource temporarily unavailable" error properly. Xenofarm: ignore more warnings. * scripts/warnings.sed: Ignore warnings from mathinline.h on Linux. Port to HP-UX 11.0. * src/server/Makefile.am (lyskomd_LDADD): Add -lm, which is needed for fpclassify on HP-UX 11.0. Test handling of write-only clients. They should be disconnected after a timeout, but that isn't implemented yet. * src/server/testsuite/lyskomd.0/38.exp: Test handling of a write-only client. It should be disconnected after a while. * src/server/testsuite/config/unix.exp (get_time_client_start): Replaced the "mode" argument with an "args" argument, that is a list of arguments to pass to get-time-often. * src/server/testsuite/get-time-often.c (main): Implement --write-only. Don't round stats too often. * src/server/stats.c (check_one_stat): Fixed the logic that determines if we need to fix a rounding error. Report the values using %g instead of %f. (is_nonzero): New static function. (check_one_stat): Don't report very small rounding errors when the correct value is 0. Port to Solaris 2.4, which lacks snprintf. * configure.in: Check for snprintf. * src/server/prot-a-output.c (prot_a_output_float): Fall back to using sprintf if snprintf isn't available. Fix "pack" warnings in Xenofarm. * scripts/xenofarm.sh: When searching for a program, put the program in a subshell, so that we can reliably divert the "program not found" error message to stdout. Use "find ... -print" instead of "find ... -ls", since -ls is a GNU extension. Xenofarm: ignore more warnings. * scripts/warnings.sed: Ignore some Solars warnings. Solaris stores ar in /usr/ccs/bin. * src/libraries/adns/configure.in: Use the same check for the ``ar'' program that lyskom-server uses. Fix Xenofarm error. * scripts/xenofarm.sh: The log file from the "pack" task should be named "packwarn.txt", not "sherr.txt". 2003-07-30 Per Cederqvist Fixed link error in test suite. * src/server/testsuite/Makefile.am (get_time_often_LDADD): Added libcheck.a, to get getopt_long(). Improve test suite for busy clients. * src/server/Makefile.am (libcheck_a_SOURCES): Added getopt.c and getopt1.c. * src/server/testsuite/lyskomd.0/38.exp: Test two simultaneous get-time-client clients. (slow): Removed. (fast): Removed. (monitor_progress): New proc. * src/server/testsuite/get-time-often.c (last_progress_status): New variable. (parse_async): Fixed off-by-one parse error. Report parse errors more verbosely. (report_progress): New function. Report progress, but print nothing unless we have received a new reply from the server since the last time we were called. (longopts): New constant. (main): Use getopt_long to parse the arguments. Enable progress report. Fixed a broken printf format string. Don't crash if a client with queued request closes the connection. Improve handling of busy clients. * src/server/connections.c (write_err_cb): Increase the penalty, so we don't process anything more from this client. (read_from_connection): isc_disable() can fail. Handle that case. (check_idle_callback): Make sure the same connection is never processed more than once during a call to this function. 2003-07-30 Per Cederqvist The statistics was broken on platforms where sizeof(int) != sizeof(long). * src/server/stats.c (dump_stats): Updated to cope with the introduction of enum value_type. (ind): Changed sign of the "offset" argument, since it is a bad idea to store a negative number in an "unsigned int". All callers updated. (update_one_stat): Fixed the call to check_stat when DEBUG_STATS is true. (check_one_stat): If a rounding error occurs, log which enum value_type that is responsible. 2003-07-28 Per Cederqvist Fixed printf argument type. * src/server/testsuite/get-time-often.c (main): The argument to a "*" printf format string modifier should be an int, not an ssize_t. Revert last change to text-garb.c. Fixed the libisc API instead. * src/server/text-garb.c: Don't include . isc.h no longer uses socklen_t in the exported API. Increase timeout during the stress test. * src/server/testsuite/lyskomd.0/38.exp: Use a very long timeout, but only for a short while. Use client id 1, to avoid having to clients with id 0 if the first one doesn't die. (fast): New proc. (slow): New proc. Collect info about leaked memory even when valgrind isn't in use. * src/server/testsuite/config/unix.exp (memix): New variable. (check_memory_usage): Save the memroy-usage file if it indicates a leak. Don't log failure to write to a client that has closed the socket. * src/server/connections.c (write_err_cb): Don't log EPIPE errors. Include before isc.h. * src/server/text-garb.c: Include , since isc.h now needs it due to its use of socklen_t. Added the beginnings of a stress test. This is work in progress, but it already seems to expose a server bug... * src/server/testsuite/lyskomd.0/38.exp: New test. * src/server/testsuite/config/unix.exp (client_death): Removed unneeded global statements for clientport, nl and deep_any. (get_time_client_start): New proc. (get_time_client_death): New proc. (talk_to): Handle get_time_client. * src/server/testsuite/get-time-often.c: New program, that generates a *lot* of get-time requests. * src/server/testsuite/Makefile.am (check_PROGRAMS): Added get-time-often. (get_time_often_SOURCES): New variable. (get_time_often_LDADD): New variable. (AM_CPPFLAGS): Make "oop.h" accessible. (.gdbinit): Added oop and isc directories. (EXTRA_DIST): Added 38.exp. 2003-07-27 Per Cederqvist Measure statistics for the number of existing texts. * doc/Protocol-A.texi (Measured Properties): Document "texts". * src/server/stats.h (enum stat_type): Added STAT_TEXTS. * src/server/stats.c (name): Handle STAT_TEXTS. * src/server/text.c (do_delete_text): Update STAT_TEXTS. (do_create_text): Ditto. * src/server/simple-cache.c (init_cache): Call update_stat with STAT_TEXTS to updated the number of existing texts. * src/server/ramkomd.c (main): Moved the call to init_stats earlier, so that we can count the existing texts while reading the database. * src/server/testsuite/lyskomd.0/01.exp: Check the "texts" stat. * src/server/testsuite/lyskomd.0/03.exp: Ditto. Fix a potential denial-of-service scenario. * src/server/connections.c (login_request): Give the new client maximum penalty to start with. It has to be connected a while to earn the right to do anything. Code cleanup. * src/server/simple-cache.c (init_cache): Use a new local variable, "record", to count the records in the database file. Don't reuse the "ic" variable for that purpose. 2003-07-25 Per Cederqvist Fixed "make check" for the documentation. * doc/constructs.expected: Added @code{printf("%g", val);}. * doc/checkargs.py (lexer.__init__): Added builtin type FLOAT. (lexer.pushback): Pushback @cite. * doc/Protocol-A.texi (Statistics): Fixed markup so that checkargs.py likes it. Changed 112=get_stats so that it returns average, ascent rate and descent rate for each measured value. Return the values as FLOAT, not a fixed-point value stored in an INT32. * src/server/testsuite/lyskomd.0/01.exp: Updated for the new look of get-stats and the new members of enum stat_type. * src/server/testsuite/lyskomd.0/03.exp: Ditto. * src/server/testsuite/config/unix.exp (any_float): New constant. * src/server/stats.h (enum stat_type): Removed STAT_FIRST_EVENT, STAT_PROCESSED_CALLS, STAT_PROCESSED_DNS, STAT_PROCESSED_IDENT, STAT_RUN_QUEUE_ENTER, STAT_RUN_QUEUE_LEAVE. Added STAT_REQUESTS. * src/server/stats.c (enum value_type): New enum. (status): Added a new dimension: the type of the value (average, ascending rate, or descending rate. (copy): Ditto. (init_stats): Handle the new dimension. (update_one_stat): New static function, that updates a single dimension. (update_stat): Update the proper dimensions. (check_one_stat): New static function, that checks a single dimension. (check_stat): Check all dimensions. (name): Removed STAT_PROCESSED_CALLS, STAT_PROCESSED_DNS, STAT_PROCESSED_IDENT, STAT_RUN_QUEUE_ENTER, STAT_RUN_QUEUE_LEAVE. Added STAT_REQUESTS. (get_stats): Now returns a Stats_list. Don't multiply the result by 100. * src/server/prot-a.c (prot_a_reply): Handle rt_stats_list. * src/server/prot-a-output.h (prot_a_output_stats_list): New function. * src/server/prot-a-output.c (prot_a_output_float): New static function. (prot_a_output_stats): Ditto. (prot_a_output_stats_list): New function. * src/server/fncdef.txt: Changed return type of get_stats to Stats_list. * src/server/connections.h (enum res_type): Added rt_stats_list. (union result_holder): Added stats_list. * src/server/connections.c (queue_add): Don't update STAT_RUN_QUEUE_ENTER. (queue_remove): Don't update STAT_RUN_QUEUE_LEAVE. (parse_unparsed): Update STAT_REQUESTS instead of STAT_PROCESSED_CALLS. (get_host_name): Don't update STAT_PROCESSED_DNS. * src/include/services.h (get_stats): Changed return type to Stats_list. * src/include/kom-types.h (Stats): New struct. (Stats_list): New struct. * doc/Protocol-A.texi (Simple Data Types): New datatype: FLOAT. (Statistics): Added the "Stats" data type. Updated the description of the "when" field of "Stats-Description". (get-stats): Return an array of Stats, not INT32. (Measured Properties): There are no longer two kinds of values. 2003-07-24 Per Cederqvist Implement 111=get_stats_description and 112=get_stats. * src/server/stats.h (check_all_stats): New name for former check_stat. * src/server/stats.c (check_stat): Only check a single statistics. Now static. (check_all_stats): New name for former check_stat. All callers updated. (name): New static function. (get_stats_description): New protocol request. (get_stats): New protocol request. * doc/lyskomd.texi (Parameters): Documented "Statistic name length". * src/server/server-config.c (parameters): Added "Statistic name length". * src/server/ramkomd.c (main): Use check_all_stats instead of check_stat. * src/server/prot-a.c (prot_a_reply): Handle rt_stats_description. * src/server/prot-a-output.h, src/server/prot-a-output.c (prot_a_output_stats_description): New function. * src/server/param.h (struct kom_par): Added stat_name_len. * src/server/fncdef.txt: Added 111=get_stats_description and 112=get_stats. * src/server/connections.h (enum res_type): Added rt_stats_description. (union result_holder): Added stats_description. * src/include/services.h (get_stats_description): New request. (get_stats): New request. * src/include/kom-types.h (Stats_description): New data type. * src/include/kom-errno.h (enum kom_err): Added KOM_UNDEFINED_MEASUREMENT. * doc/constructs.expected: Added @code{when} and @samp{X-}. * doc/Protocol-A.texi (Statistics): New section. (get-stats-description): New request. (get-stats): New request. (Error Codes): Documented undefined-measurement. (Measured Properties): New chapter. * src/server/testsuite/lyskomd.0/01.exp: Test get-stats-description and get-stats. * src/server/testsuite/lyskomd.0/03.exp: Ditto. Collect more statistics. * src/server/rfc931.c (get_real_username): Update the STAT_IDENT_QUEUE and STAT_PROCESSED_IDENT statistics. * src/server/stats.h (enum stat_type): Added STAT_DNS_QUEUE, STAT_IDENT_QUEUE, STAT_PROCESSED_DNS and STAT_PROCESSED_IDENT. * src/server/connections.c (logout_client): Update the STAT_CLIENTS statistics. (login_request): Ditto. (get_host_name): Update the STAT_DNS_QUEUE and STAT_PROCESSED_DNS statistics. 2003-07-23 Per Cederqvist Fixed the overflow checking of timeval configuration parameters. * src/server/conf-file.c (assign_timeval): The logic for detecting overflow was wrong. Code cleanup. * src/server/aux-item-def-parse.y: Don't include twice. Gather statistics on the run queue length and the number of processed requests. * src/server/Makefile.am (lyskomd_SOURCES): Added stats.h and stats.c. * src/server/stats.h, src/server/stats.c: New file, that collects some statistical information about the operation of the server. * src/server/ramkomd.c (main): Initialize the statistics subsystem, and check the integrity of it during shutdown. * src/server/connections.c (queue_add): Update statistics. (queue_remove): Ditto. (parse_unparsed): Ditto. 2003-07-22 Per Cederqvist Don't redefine LIST_INIT on FreeBSD 4.8. * src/libraries/adns/src/dlist.h (ADNS_LIST_INIT, ADNS_LINK_INIT) (ADNS_LIST_UNLINK_PART, ADNS_LIST_LINK_TAIL_PART, ADNS_LIST_UNLINK) (ADNS_LIST_LINK_TAIL): Appended the "ADNS_" prefix to make the macro names more unique. LIST_INIT is already defined in /usr/include/sys/queue.h:291 on FreeBSD 4.8. All users updated. Added overflow checking of timeval configuration parameters, and test cases for the error checking. * src/server/conf-file.c (assign_timeval): Added overflow checking. * src/server/testsuite/lyskomd.0/37.exp: Check for overflow, bad suffixes, and negative values for time parameters. * src/server/testsuite/timeval-overflow.c: New program that creates a broken lyskomd config file with timeval overflows. * src/server/testsuite/Makefile.am (check_PROGRAMS): Added timeval-overflow. (timeval_overflow_SOURCES): New target. (check-lyskomd): Depend on timeval-overflow. 2003-07-18 Per Cederqvist Find the included adns.h from liboop. * src/libraries/liboop/Makefile.am (AM_CPPFLAGS): Added -I option for adns. Fix enum mis-match detected by the AIX 5.1 compiler. * src/libraries/adns/src/parse.c (adns__parse_domain): The flags argument should be a parsedomain_flags, not adns_queryflags. I think. Port adns to FreeBSD (and many others). * src/libraries/adns/configure.in: Include before . Xenofarm improvements. * scripts/xenofarm.sh: Save config.log and config.h from the adns library. Link lyskom-server against adns. * configure.in: Added src/libraries/adns to AC_CONFIG_SUBDIRS. * mkmi: Recreate configure and Makefile.in in adns. * src/libraries/Makefile.am (SUBDIRS): Added adns. * src/libraries/liboop/configure.ac: Unconditionally define HAVE_ADNS. * src/libraries/liboop/Makefile.am (liboop_a_SOURCES): Added adns.c. (test_oop_LDADD): Added libadns.a. * src/server/Makefile.am (AM_CPPFLAGS): Include adns files. (lyskomd_LDADD): Link with libadns.a. Removed adns files that are generated by autoconf or automake. * src/libraries/adns/Makefile.in: Removed. * src/libraries/adns/acconfig.h: Removed. * src/libraries/adns/aclocal.m4: Removed. * src/libraries/adns/configure: Removed. * src/libraries/adns/src/Makefile.in: Removed. * src/libraries/adns/src/config.h.in: Removed. * src/libraries/adns/src/.cvsignore: Added more files to ignore. * src/libraries/adns/.cvsignore: Added more files to ignore. Use Automake in adns for better integration with lyskoms-server. Only re-implement what we need (no shared libraries, no programs, no testsuite...) * src/libraries/adns/configure.in: Updated for automake-1.5.1 and autoconf-2.57. Removed DPKG_CACHED_TRY_COMPILE. Removed all dynamic linking support. Removed support for client programs. Use AC_C_INLINE instead of a hand-coded test for the same thing. Add AH_VERBATIM for config.h. Only output Makefile and src/Makefile. * src/libraries/adns/acinclude.m4: New name for former aclocal.m4. * src/libraries/adns/Makefile.am: New Makefile template, which compiles (and distributes) only the parts of adns that are needed by the LysKOM server. * src/libraries/adns/src/Makefile.am: Ditto. * src/libraries/adns/settings.make.in: Removed. Use automake instead. Import adns-1.0. * src/libraries/adns/README: Mention where the lyskom-server ChangeLog can be found. Mention that only parts of the full adns distribution is included here. * src/libraries/adns/changelog: Ditto. * src/libraries/adns: Imported adns-1.0. 2003-07-16 Per Cederqvist Xenofarm: ignore more warnings. * scripts/xenofarm.sh (makewarn): Remove spurious warnings from fonda.roxen.com. * scripts/warnings.sed: More updates. Fixed all calls to isspace(). * src/server/conf-file.c (assign_timeval): Fixed the type of the argument to isspace(). is obsolete and produces a warning on FreeBSD 4.8. Avoid including it. * src/server/aux-item-def-parse.y: Include instead of . * src/server/admin.c: Don't needlessly include . * src/server/debug.c: Include only if we really need it; we must be configured with --with-debug-calls and mallinfo() must be found. Second attempt to get rid of warnings about bzero(). * src/libraries/liboop/configure.ac: Check for . * src/libraries/liboop/adns.c: Include to get rid of a warning on AIX 4.3. * src/libraries/liboop/glib.c: Ditto. * src/libraries/liboop/select.c: Ditto. * src/libraries/liboop/sys.c: Ditto. * scripts/warnings.sed: More updates. 2003-07-15 Per Cederqvist Fix some portability issues in liboop. * src/libraries/liboop/read.c: Undefine MIN before defining it. * src/libraries/liboop/configure.ac: Check for . * src/libraries/liboop/adns.c: Include to get rid of a warning on AIX 4.3. * src/libraries/liboop/glib.c: Ditto. * src/libraries/liboop/select.c: Ditto. * src/libraries/liboop/sys.c: Ditto. Update the warnings filter. * scripts/warnings.sed: Updated. Reduce the number of false warnings from Xenofarm. * scripts/xenofarm.sh: Don't produce output on stderr when checking for the existence of certain programs. Liboop integration. * AUTHORS: Add info about liboop. Build warnings in Xenofarm were broken. Added a warning if the xenofarm script produces any output to stderr. * scripts/warnings.sed: Added a missing "d". * scripts/xenofarm.sh: Store the stderr output generated during the build in a separate file. Introduce a final "pack" task that will result in a warning if any output to stderr exists. Enable core files. Recognize core files even when the file name includes a pid. Store the config.log file from liboop. 2003-07-14 Per Cederqvist Fixed a recently introduced typo. * src/server/connections.c (queue_remove): Fixed a typo that caused a broken pointer structure on the queue of pending clients. Improve liboop error checking. * src/libraries/liboop/signal.c (add_flag): New static function, that checks the return values from fcntl properly. (oop_signal_new): Use add_flag() to simplify code. Fail (return NULL) if any of the fcntl calls on the new pipe fails. Increase PROTECTED_FDS, since liboop uses internal file descriptors. * src/include/kom-config.h (PROTECTED_FDS): Increased from 12 to 20. Document that liboop uses a couple of file descriptors, and that this setting is also present in unix.exp. * src/server/testsuite/config/unix.exp (PROTECTED_FDS): New constant. * src/server/testsuite/lyskomd.0/07.exp: Use PROTECTED_FDS. * src/server/testsuite/lyskomd.0/connections-cov.exp: Ditto. * src/server/testsuite/lyskomd.0/prot-a-send-async-cov.exp: Ditto. * src/server/testsuite/lyskomd.0/send-async-cov.exp: Ditto. Flush the output less often. This fixes the non-controversial parts of bug 107. * src/server/prot-a.c (prot_a_reply): Don't call isc_flush() here. Doing so was redundant. * src/server/connections.c (parse_unparsed): Return true if anything was sent back to the client. Don't call isc_flush(). (read_from_connection): Call isc_flush() once if parse_unparsed() returned true at least once. * src/server/prot-a-send-async.c (async_trailer): Added a comment about the controversial parts of bug 107. 2003-07-13 Per Cederqvist Don't call select() with a very large timeout. This could possibly fix bug 1065. * src/libraries/liboop/sys.c (oop_sys_run): Clamp the value of the tv_sec field of the select timeout argument to 3600 seconds, to check if very large values is the reason that FreeBSD returns EINVAL here. (Bug 1065). Reverted the change of 1999-04-03: go_and_die is now a Bool once again. It is no longer manipulated from a signal handler. * src/server/admin.c (shutdown_kom): Use TRUE instead of 1 as value of go_and_die. * src/server/connections.c (go_and_die): Now a Bool, once again. * src/server/ramkomd.c (sighandler_hup): Use TRUE instead of 1 as value of go_and_die. * src/server/sigflags.h (go_and_die): Now a Bool, once again. Terminate at once if go_and_die becomes set while the queue of pending requests is processed. * src/server/connections.c (check_idle_callback): Break out of the loop and return OOP_HALT if go_and_die is true. Header file cleanup. * src/server/sigflags.h (intr_syscalls_on_intr): Removed. (restart_syscalls_on_intr): Removed. (do_statistics): Removed. 2003-07-13 Per Cederqvist Actually distribute all test cases... * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added 37.exp. 2003-07-13 Per Cederqvist Tweak testsuite timeouts. * src/server/testsuite/config/unix.exp (timeout): Increase the timeout 2 more seconds. Move garb timers around so that the debug request start_garb() can actually start the garb. Fixes breakage in lyskomd.0/09.exp. * src/server/text-garb.h (garb_text): This function is now static. (start_garb_thread): New function. (stop_garb_thread): New function. * src/server/text-garb.c (garb_timer): New static variable. (garb_timer_running): Ditto. (garb_text): Added static qualifier. (garb_callback): Moved here from connections.c. Some minor modifications made to make it compiler in its new environment. (start_garb_thread): New function. (stop_garb_thread): New function. (start_garb): Restart the garb "thread". * src/server/connections.h (set_time): Now exported. (setup_timer): Ditto. (server_idle): New function. * src/server/connections.c (set_time): No longer static. (setup_timer): Ditto. (garb_callback): Moved to text-garb.c. (saver_callback): The source argument is actually used. (toploop): Moved the garb timer to text-garb.c. (server_idle): New function. Use the liboop signal adapter; avoid using siglongjmp from signal handlers. Ignore signals during shutdown. * src/server/ramkomd.c (kom_signal_adapter): New static variable. (server_init): Use oop_signal_new, since I don't trust the way liboop uses siglongjmp to break out of a signal handler. Ignore the signals before registering them with liboop, to get a proper behaviour on shutdown. (main): Adjusted to use the signal adapter. Fix errors in ths liboop signal adapter. * src/libraries/liboop/signal.c (use_sa_restart): New static variable. (sig_on_signal): Add SA_RESTART if appropriate. (oop_signal_new): Don't just blindly set FD_CLOEXEC and O_NONBLOCK. Read the old settings first. (oop_signal_use_sa_restart): New function. * src/libraries/liboop/oop.h (oop_signal_use_sa_restart): New function. Updated documentation for the configuration file for "timeval" parameters and penalty points/client scheduling. * doc/lyskomd.texi (Parameter Types): Document "timeval". (Parameters): Updated the documentation for "timeval" parameters and the parameters relating to penalty points. Added test cases for parsing of timeval values. * src/include/services.h (dump_cfg_timevals): New debug request. * src/server/fncdef.txt: Added 1006=dump_cfg_timevals. * src/server/server-config.c (dump_timeval): New static function. (dump_cfg_timevals): New request. * src/server/testsuite/lyskomd.0/37.exp: New file: Test the parsing of "timeval" entries in the configuration file. Improved timeval parsing. * src/server/conf-file.c (assign_timeval): Skip whitespace between the number and the suffix. Round the tv_usec field properly. Improve config file checking. * src/server/server-config.c (read_configuration): Give an error message if low_penalty isn't lower than max_penalty. Fixed more compilation errors. * src/server/simple-cache.c (cache_sync_finish): Added a missing parenthesis. * src/server/aux-item-def-parse.y: Include timewrap.h, since connections.h now needs it. * src/server/debug.c: Ditto. * src/server/standalone.c: Ditto. Added more liboop assertions. * src/libraries/liboop/sys.c (oop_sys_run): Added a few assertions to try to figure out why select still returns EINVAL sometimes. Fixed compilation error when compiled for coverage measurements. * src/server/simple-cache.c (cache_sync_finish): Adjusted to new API of sync_part(). Include and in a proper way. * src/server/Makefile.am (lyskomd_SOURCES): Added timewrap.h. * src/server/timewrap.h: New include file; a wrapper around and . All files that needs to include either file now does so via this wrapper. 2003-07-12 Per Cederqvist Code cleanup. * src/server/server-config.c: (parameters): Added default_suffix initializers for all parameters. Break overly long lines. All configuration parameters that are time periods can now have an optional suffix such as "hours" appended. Store them as a struct timeval, not as an int, so that the bulk of the code doesn't have to take the unit into account. * src/server/param.h (struct kom_par): Changed the type of the following fields from int to struct timeval: garb_busy_postponement, garbtimeout, synctimeout, garb_interval, sync_interval, sync_retry_interval. * src/server/server-config.c: (parameters): Changed the assigner of "Garb busy postponement", "Garb timeout", "Sync timeout", "Garb interval", "Sync interval" and "Sync retry interval" from int to timeval, and added appropriate default suffixes to those configuration parameters. * src/server/conf-file.h (struct parameter): New field: default_suffix. (assign_timeval): New assigner. * src/server/conf-file.c (struct suffix_conversion): New struct. (suffix_table): New table. (assign_timeval): New assigner. Use "struct timeval" instead of a number of milliseconds or seconds in several places. This fixes a number of potential and actual overflows. * src/server/connections.h (Connection): Change the type of the session_start and active_time fields from time_t to struct timeval. * src/server/server-time.h (current_time): Now a struct timeval, not a time_t. * src/server/disk-end-of-atomic.c, src/server/end-of-atomic.h (end_of_atomic): Now returns a struct timeval, not a long. * src/server/cache.h (sync_part): Now returns a struct timeval. * src/server/text.c (add_text_in_conf): Extract the seconds from the current_time. (create_text_add_miscs): Ditto. (do_create_text): Ditto. (add_recipient): Ditto. (add_comment): Ditto. (add_footnote): Ditto. * src/server/text-garb.c (garb_text): Extract the seconds from the current_time. * src/server/simple-cache.c (sync_output_header): Extract the seconds from the current_time. (sync_part): Return a struct timeval instead of a long. Use struct timeval instead of a time_t. Use timeval_remaining() to simplify the code. (init_cache): Use a struct timeval instead of time_t. (cache_sync_all): Adjusted to new API of sync_part(). * src/server/session.c (leave_conf): Extract the seconds from the current_time. (login_old): Ditto. (login): Ditto. (get_static_session_info): Ditto. (get_time): Ditto. (logout): Ditto. Use timeval_diff_sec instead of ldifftime. (who_is_on_dynamic): Use timeval_diff_sec instead of ldifftime. (get_session_info): Ditto. (get_session_info_ident): Ditto. * src/server/send-async.c (async_rejected_connection): Use struct timeval instead of time_t. * src/server/ramkomd.c (current_time): Now a struct timeval, not a time_t. (main): Adjusted for the new type of current_time. * src/server/person.c (create_person_generic): Extract the seconds from the current_time. * src/server/membership.c (do_add_rec_time): Extract the seconds from the current_time. (do_add_member): Ditto. * src/server/internal-connections.c (init_connection): Use struct timeval instead of time_t. * src/server/connections.c (set_time): Use struct timeval instead of time_t. (dump_statistics): Ditto. (saver_callback): Ditto. (setup_timer): Replaced the milliseconds argument with a struct timeval argument. (garb_callback): Simplified the code. * src/server/conference.c (do_create_conf): Extract the seconds from the current_time. * src/server/aux-items.c (prepare_aux_item): Extract the seconds from the current_time. Added utility functions for struct timeval. * src/libraries/libmisc/Makefile.am (libmisc_a_SOURCES): Added timeval-util.h and timeval-util.c. * src/libraries/libmisc/timeval-util.h, * src/libraries/libmisc/timeval-util.c: New files. (timeval_subtract): New static function. (timeval_nonzero): New function. (timeval_zero): Ditto. (timeval_ctor): Ditto. (timeval_remaining): Ditto. (timeval_greater): Ditto. (timeval_less): Ditto. (timeval_diff_sec): Ditto. Don't store garbage in struct timevals passed to liboop. * src/server/connections.c (setup_timer): Fixed an error that caused the tv_usec field to be out-of-range. 2003-07-12 Per Cederqvist Make liboop refuse bad timestamps early on. * src/libraries/liboop/sys.c (sys_on_time): Trigger an assertion if a broken tv_usec is entered. Make gdb find the liboop sources. * src/server/Makefile.am (.gdbinit): Added liboop. 2003-07-12 Per Cederqvist Attempt to fix a bug that caused the testsuite to hang. * src/server/testsuite/config/unix.exp (kill_client): Fixed broken logic that caused the "looking for stray output" never to emit a pass message. Look for eof on the client. Update valgrind suppressions. * src/server/testsuite/lyskomd.supp: Track the name change of isc_tcp_accept_fn() to isc_tcp_accept(). Reduce the number of log messages. * src/server/connections.c (add_to_kill_list): Don't write a log message when the connection is already present on the kill list. With the liboop callbacks that can happen and is not an error. (write_err_cb): Don't log an error for ECONNRESET. Fixed compilation errors. * src/server/connections.c (read_from_connection): Removed left-over debug code. (enable_idle_check): Ditto. (check_idle_callback): Ditto. * src/libraries/liboop/www.c (reg): Don't use //-style comments. (unreg): Ditto. Fixed liboop compilation errors introduced by me. * src/libraries/liboop/sys.c (sys_on_time): Moved the assert statement to after all variable declarations. (sys_on_signal): Ditto. Make it easier to run all the tests that don't require dejagnu. * src/server/testsuite/Makefile.am (check-nondejagnu): New target. (check-dejagnu): New target. (check): Depend on check-dejagnu and check-nondejagnu, and move all dependencies to one of those targets. Add scheduling of clients, so that one client cannot starve other clients for resources. (Bug 102). * src/server/server-config.c (parameters): Added "Penalty per call", "Penalty per read", "Max penalty" and "Low penalty". * src/server/testsuite/lyskomd.0/conf-file-cov.exp: Check the parameter "Garb timeout" instead of "Idle timeout", since the latter no longer exists. * src/server/param.h (struct kom_par): Removed timeout. Added garb_busy_postponement, penalty_per_call, penalty_per_read, max_penalty and low_penalty. * src/server/internal-connections.c (init_connection): Initialize penalty, penalty_generation, queue_next, queue_prev, on_queue. (kill_client): Assert that on_queue is false. * src/server/connections.h (Connection): New fields: penalty, penalty_generation, queue_prev, queue_next, on_queue. (handle_accept_event): New function. * src/server/connections.c (penalty_generation): New static variable. (work_done): Ditto. (is_idle): Ditto. (queue_first): Ditto. (queue_last): Ditto. (queue_add): New static function. (queue_remove): Ditto. (logout_client): Remove the client from the queue of pending clients. (parse_unparsed): Add penalty points for finished calls and protocol errors. Don't delete the parsed part of unparsed. (adjust_penalty): New static function. (enable_idle_check): Ditto. (check_idle_callback): Ditto. Run the database save, garb, and check for killed clients from three separate liboop timer callbacks. * src/server/connections.c (kill_pending): New static variable. (add_to_kill_list): Add an oop timer event callback to check_kill_flg when a client is added to the kill list. (check_kill_flg): Changed API: this is now an oop timer callback function. (garb_callback): New static function. (saver_callback): Ditto. * src/server/text-garb.c (last_start): Static variable removed. (garb_text): Expect the caller to wait long enough when the garb shouldn't be running. Return true when the garb is completed, instead of when the garb shouldn't be running. * src/server/cache.h (sync_part): Return the number of seconds to wait instead of a Bool. * src/server/simple-cache.c (sync_part): Return the number of seconds to wait instead of a Bool. All callers updated. * src/server/server-config.c (parameters): Removed "Idle timeout". Added "Garb busy postponement" * src/server/end-of-atomic.h (end_of_atomic): Removed the idle argument. * src/server/disk-end-of-atomic.c (end_of_atomic): Removed the idle argument. Don't call the garb. Adjusted to the new API of sync_part(). Use liboop for signal dispatching. * src/server/ramkomd.c (sighandler_usr1): Now an liboop signal callback, not a real signal handler. Do the real work here. (sighandler_winch): Ditto. (sighandler_hup): Now an liboop signal callback, not a real signal handler. (sighandler_quit): Ditto. (sighandler_usr2): Ditto. (setup_sighandlers): Removed. (restart_syscalls_on_intr): Removed. (intr_syscalls_on_intr): Removed. * src/server/param.h (reread_param): Variable removed. * src/server/server-config.c (reread_param): Removed. * src/server/connections.c (do_statistics): Variable removed. Use liboop. (Bug 106). * src/server/Makefile.am (AM_CPPFLAGS): Added an -I flag for liboop. (lyskomd_SOURCES): Added oop-malloc.h and oop-malloc.c. (lyskomd_LDADD): Link against liboop.a. * src/server/oop-malloc.c, src/server/oop-malloc.h (oop_malloc_wrapper): New function. (oop_free_wrapper): New function. (oop_realloc_wrapper): New function. (dump_oop_alloc_counts): New function. * src/server/ramkomd.c (listen_client): Static variable removed. (server_init): Initialize liboop. Adjusted to the new isc API:s. (main): Clean up liboop structures on shutdown. * src/server/rfc931.h: Adjusted to new libisc API. * src/server/rfc931.c: Include liboop.h. * src/server/prot-a.c: Include oop.h. * src/server/prot-a-send-async.c: Include oop.h. * src/server/prot-a-parse.c: Include oop.h. * src/server/prot-a-parse-arg-c.awk: Include oop.h. * src/server/prot-a-output.c: Include oop.h. * src/server/isc-interface.h (kom_server_oop_src): New global variable. * src/server/connections.c (kom_server_oop_src): New variable. (set_time): New static function. (parse_message): Function removed. (logout_request): Function removed. (parse_forgotten): Ditto. (message_request): Ditto. (write_err_cb): New static function. (read_from_connection): Ditto. (setup_timer): Ditto. (data_available_callback): Ditto. (handle_accept_event): New function. (login_request): Take an isc_scb as argument instead of an isc event. Add read and write error callback functions for the new client. (toploop): Rewritten to use liboop. Code cleanup. * src/server/internal-connections.c (init_connection): Added static const qualifiers to the default_want_async variable. Renamed a few constants that have nothing to do with ISC. * src/server/isc-parse.h (KOM_PROTOCOL_ERR): New name for former ISC_PROTOCOL_ERR. All users updated. (KOM_MSG_INCOMPLETE): New name for former ISC_MSG_INCOMPLETE. All users updated. (KOM_LOGOUT): New name for former ISC_LOGOUT. All users updated. * src/server/isc-parse.c (parse_char): Use KOM_MSG_INCOMPLETE instead of ISC_MSG_INCOMPLETE. Make it possible to read an unsigned int from the config file. * src/server/conf-file.h (assign_uint): New function. (union param_value): Unused union removed. * src/server/conf-file.c (assign_uint): New function. Add SA_RESTART support to liboop. (This has been sent to the liboop maintainer.) (Fixes bug 845). * src/libraries/liboop/oop.h (oop_sys_use_sa_restart): New function. * src/libraries/liboop/sys.c (sys_sig_owner): Added static qualifier. (use_sa_restart): New static variable. (sys_on_fd): Require the callback to be non-NULL. (sys_on_time): Ditto. (sys_on_signal): Ditto. (sys_on_signal): Use SA_RESTART if use_sa_restart is true. (oop_sys_use_sa_restart): New function. Add a few utility string functions. * src/libraries/libmisc/s-string.h, src/libraries/libmisc/s-string.c (s_trim_left): New function. (s_reserve): New function. (s_reserve_done): New function. 2003-07-10 Per Cederqvist Solaris stores ar in /usr/ccs/bin. * src/libraries/liboop/configure.ac: Use the same check for the ``ar'' program that lyskom-server uses. libisc will soon depend on liboop. * src/libraries/Makefile.am (SUBDIRS): Compile liboop before libisc-new, since isc is about to use liboop. 2003-07-09 Per Cederqvist Link-time fix for liboop test program. * src/libraries/liboop/Makefile.am (test_oop_LDADD): Link against liboop.a, not -loop, to ensure that we get the local copy. Build liboop (but don't use it yet). * configure.in: Added src/libraries/liboop to AC_CONFIG_SUBDIRS. * mkmi: Recreate configure and Makefile.in in liboop. * src/libraries/Makefile.am (SUBDIRS): Added liboop. Using libtool isn't worth the effort for our copy of liboop. Don't include adapters for things we are never going to use. * src/libraries/liboop/configure.ac: Removed checks for readline, glib, Tcl and libwww, since they are not used by lyskom-server. (AM_PROG_LIBTOOL): Removed. (PROG_LDCONFIG): Don't set it. (no_wacky_libs): Don't set it. (AC_PROG_RANLIB): Added. * src/libraries/liboop/Makefile.am (noinst_LIBRARIES): Added. (liboop_a_SOURCES): New name for former liboop_la_SOURCES. (noinst_HEADERS): New name for former include_HEADERS. (lib_LTLIBRARIES): Removed. (liboop_la_LDFLAGS): Removed. (liboop_adns_la_LDFLAGS): Removed. (liboop_adns_la_LIBADD): Removed. (liboop_adns_la_SOURCES): Removed. (liboop_glib_la_LDFLAGS): Removed. (liboop_glib_la_LIBADD): Removed. (liboop_glib_la_SOURCES): Removed. (liboop_tcl_la_LDFLAGS): Removed. (liboop_tcl_la_LIBADD): Removed. (liboop_tcl_la_SOURCES): Removed. (liboop_www_la_LDFLAGS): Removed. (liboop_www_la_LIBADD): Removed. (liboop_www_la_SOURCES): Removed. (liboop_rl_la_LDFLAGS): Removed. (liboop_rl_la_LIBADD): Removed. (liboop_rl_la_SOURCES): Removed. (check_PROGRAMS): New name for former noinst_PROGRAMS. (test_oop_LDADD): Removed $(lib_LTLIBRARIES) and added -loop. (install-exec-local): Removed. There is no need to run ldconfig. Removed liboop files that are generated by autoconf or automake. * src/libraries/liboop/aclocal.m4: Removed. * src/libraries/liboop/Makefile.in: Removed. * src/libraries/liboop/configure: Removed. * src/libraries/liboop/install-sh: Removed. * src/libraries/liboop/missing: Removed. * src/libraries/liboop/mkinstalldirs: Removed. Import liboop-0.9. * src/libraries/liboop/README: File created. * src/libraries/liboop/*: Import version 0.9 of liboop to the lyskom-server repository. Liboop calls siglongjmp from a signal handler. Check if that is really portable. * scripts/xenofarm.sh: Run the test-sigjmp program as a separate task. * src/server/testsuite/Makefile.am (check_PROGRAMS): Added test-sigjmp. (test_sigjmp_SOURCES): New variable. (test_sigjmp_LDADD): New variable. (check-test-sigjmp): New target. * src/server/testsuite/test-sigjmp.c: New test program. Verify that select can be broken by a siglongjmp call from a signal handler. 2003-07-03 Per Cederqvist Turn on the -Wfloat-equal gcc warning. * configure.in: Added -Wfloat-equal to CFLAGS. Update the test suite for the denial-of-service fix. * src/server/testsuite/lyskomd.0/01.exp: Expect the get-last-text, find-next-text-no and find-previous-text-no requests to fail when the user isn't logged in. 2003-05-09 Per Cederqvist Require that the user is logged in before allowing him to do get-last-text, find-next-text-no or find-previous-text-no. This fixes a denial-of-service attack reported by Calle Dybedahl. * src/server/text.c (get_last_text): Require the user to be logged in. (find_next_text_no): Ditto. (find_previous_text_no): Ditto. * doc/Protocol-A.texi (get-last-text): This request now requires that the user is logged in. (find-next-text-no): Ditto. (find-previous-text-no): Ditto. 2003-03-23 Per Cederqvist Don't copy zero-length arrays. (Bug 1005). * src/server/memory.c (copy_membership): Don't allocate a copy of read_ranges if read_ranges is NULL. Test for bug 1005. * src/server/testsuite/lyskomd.0/36.exp: New file that triggers an assertion. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added 36.exp. Don't copy zero-length arrays. * src/server/membership.c (read_ranges_precondition): Don't allocate a copy of read_ranges if read_ranges is NULL. Code cleanup. * src/server/prot-a-output.c (prot_a_output_read_texts): Coding standards issue: compare the pointer read_ranges against NULL, not 0. 2003-03-15 Per Cederqvist Remove the "magic" field of Connection. Valgrind provides a better and less intrusive way to find memory allocation errors. * src/server/connections.h (CONN_MAGIC_ALLOC): Removed. (CONN_MAGIC_FREE): Removed. (Connection): Removed the magic field. * src/server/internal-connections.c (init_connection): Don't set the magic field. (new_client): Ditto. (kill_client): Ditto. * src/server/connections.c (logout_client): Don't check the magic field. Allow test suite configuration (such as the timeout) to be overridden in localcfg.exp. * src/server/testsuite/config/unix.exp: Source config/localcfg.exp if it exists. * src/server/testsuite/config/.cvsignore: Ignore localcfg.exp. 2003-03-08 Per Cederqvist Port 4894 is official. * doc/Protocol-A.texi (Connecting to the Server): Mention that port 4894 is registered with IANA. 2003-02-09 Per Cederqvist Minor makefile fix. * src/libraries/libeintr/Makefile.am (eintr.h $(funcs)): Use $(AWK) and not @AWK@. 2003-02-08 Per Cederqvist Port to FreeBSD 4.7. * doc/Makefile.am (check-doc): Make sed pattern more portable by not using "[---a-z0-9]". FreeBSD 4.7 said "RE error: invalid character range". 2003-01-18 Per Cederqvist Xenofarm: use TZ=GMT to work around buggy dwim_time(). * scripts/xenofarm.sh (log): Set TZ to GMT, and LC_ALL to C, before calling date. The Pike function Calendar.ISO.dwim_time does very buggy things when a time zone it doesn't understand is encountered, so force everybody to use the well-known GMT time zone. Disable the test suite on taylor. * scripts/xenofarm.sh: Don't run the test suite on taylor. Runtest is broken there. Xenofarm: move warning filtering to a separate file. * scripts/xenofarm.sh: Moved large sed script to warnings.sed. * scripts/warnings.sed: New file. This sed script removes all false warnings. New coding standard rule: each (group of) removed warning(s) should be preceded by a comment that gives an example of where the warning occurs. I'm starting with an almost empty file, and will add back the filters and collect info on from where they originate. * scripts/Makefile.am (EXTRA_DIST): Distribute warnings.sed. 2003-01-17 Per Cederqvist Complete testing of async-deleted-text et c. (Bug 59). * src/server/testsuite/.cvsignore: Ignore 35-aux.conf. * src/server/testsuite/lyskomd.0/35.exp: Test case completed. 2003-01-17 Per Cederqvist Xenofarm warnings. * scripts/xenofarm.sh: Ignore glibc-2.1.2/gcc-2.95.2 warnings. 2003-01-17 Per Cederqvist Fixed cut-n-paste error. * src/server/text.c (report_bad_aux): Don't declare variables in the middle of a function! Minor testsuite fixes. * src/server/testsuite/lyskomd.0/30.exp: Specify a long sync interval, to avoid spurious async-sync-db messages. * src/server/testsuite/config/unix.exp (epoch_time): New constant. * src/server/testsuite/lyskomd.0/05.exp: Use epoch_time. This test used to fail when run west of London. Continue testing async-deleted-text et c. Fix bugs found. (Bug 59). * src/server/text.c (report_bad_aux): New static function. (is_member_in_linked_recpt): New argument: tno. All callers updated. For now, do nothing special with cross-reference; until but 23 is fixed that would be pointless. Report bad aux-items with report_bad_aux. Added missing breaks. (interested_party): New argument: tno. All callers updated. * src/server/testsuite/lyskomd.0/35.exp: Commit of work in progress. Still needs more work. Stricter checking on aux-item cross-reference. * run-support/aux-items.conf (cross-reference): If anything follows the reference, it must begin with a space. Typos fixed. * src/libraries/libmisc/s-string.h: Fixed typo in a comment. * README: Typo fixed. 2003-01-14 Per Cederqvist Start testing async-deleted-text et c. (Bug 59). * src/server/testsuite/lyskomd.0/35.exp: New file. Test sending of async-deleted-text, async-new-text, async-new-text-old, async-add-recipient and async-sub-recipient to recipients of texts that are linked to the text. Needs more work. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added 35.exp. 2003-01-13 Per Cederqvist Xenofarm tweaking. * scripts/xenofarm.sh: Remove installedfiles.txt if it is empty. Use mv instead of cp to move files into the result package, to preserve time stamps. Create corefiles.txt if any core files are found. Cut-n-paste error introduced in last commit fixed. * src/server/text.c (is_member_in_linked_recpt): Fixed cut-n-paste error. 2003-01-13 Per Cederqvist Send async-deleted-text, async-new-text, async-new-text-old, async-add-recipient and async-sub-recipient to recipients of text linked to the relevant text. (Bug 59). * src/server/text.c (is_member_in): New static function. (is_member_in_recpt): Use is_member_in to simplify code. (is_member_in_recpt_of): New static function. (is_member_in_linked_recpt): New static function. (interested_party): New static function. This also considers if the potential message recipient is a member of a recipient of a text that is linked to the text, via a misc-info or a aux-item. (send_async_sub_recipient): Use interested_party to determine if the asynchronous message should be sent. (send_async_deleted_text): Ditto. (send_async_new_text_old): Ditto. (send_async_new_text): Ditto. (send_async_add_recipient): Ditto. (text_read_access): Added const qualifiers. * src/server/manipulate.h (text_read_access): Added const qualifiers. (person_text_read_access): Ditto. Port to DejaGnu 1.2. * scripts/xenofarm.sh: DejaGnu 1.2 doesn't understand --version, so use "runtest -V" instead when detecting runtest. 2003-01-12 Per Cederqvist Fix too restrictive validation on content-type. * run-support/aux-items.conf (content-type): Allow anything after a semicolon. Implemented passive-message-invert. (Bug 827). * doc/Protocol-A.texi (Membership Information): Renamed the reserved1 bit of Membership-Type to passive-message-invert. Document it. (async-send-message): Mention that the passive and passive-message-invert bits of the Membership-Type influences if messages are sent or not. (send-message): Mention passive and passive-message-invert. Mention async-send-message. (Error Codes): Don't say "group message". * src/include/kom-types.h (Membership_type): Renamed reserved1 to passive_message_invert. * src/server/admin.c (send_message): Handle passive_message_invert. * src/server/ram-parse.c (fparse_membership_type): Handle passive_message_invert. * src/server/ram-output.c (foutput_membership_type): Handle passive_message_invert. * src/server/prot-a-parse.c (prot_a_parse_membership_type): Handle passive_message_invert. * src/server/prot-a-output.c (prot_a_output_membership_type): Handle passive_message_invert. * src/server/person.c (create_person_generic): Handle passive_message_invert. * src/server/memory.c (init_membership_type): Handle passive_message_invert. * src/server/membership.c (set_membership_type_bits): Handle passive_message_invert. * src/server/dbck.c (check_membership): Handle passive_message_invert. * src/server/testsuite/lyskomd.0/34.exp: New file. Test the passive-message-invert bit of Membership-Type. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added 34.exp. Made aux-items.conf more strict. (Bug 451). * run-support/aux-items.conf (content-type): Don't allow more than one "/". (no-comment): This must be unique and contain no data. (personal-comment): Ditto. (request-confirmation): Ditto. (read-confirm): This must contain no data. (redirect): Clear inherit, secret and hide-creator. (mx-author): Clear inherit, secret, hide-creator and dont-garb. (mx-from): Ditto. (mx-reply-to): Ditto. (mx-message-id): Ditto. (mx-in-reply-to): Ditto. (mx-misc): Ditto. (mx-allow-filter): Ditto. (mx-reject-forward): Ditto. (mx-to): Clear inherit and dont-garb. (mx-cc): Ditto. (canonical-name): Ditto. (mx-date): Clear hide-creator, secret and dont-garb. (notify-comments): Clear inherit, hide-creator and dont-garb. (recommended-conf): Clear inherit and dont-garb. (allowed-content-type): Clear inherit and dont-garb. Require a priority number before the content type, and don't allow more than one "/" or " ". (mx-list-name): Set owner-delete. Clear dont-garb and inherit. (mx-refuse-import): Set unique. Clear dont-garb and inherit. (mx-mime-misc): Set unique. (mx-envelope-sender): Set unique. * src/server/testsuite/lyskomd.0/20.exp: Adjusted for the new, stricter aux-items.conf. * src/server/testsuite/lyskomd.0/03.exp: Adjusted for the new, stricter aux-items.conf. 2003-01-10 Per Cederqvist Document undocumented files. (Bug 852). * doc/lyskomd.texi (Parameters): Documented the default values of "Connection status file" and "Connection status temp file". (Files): Documented db/number.txt and etc/connections.txt. Use mark_person_as_changed properly in mark_as_read. (Bug 877). * src/server/membership.c (mark_as_read): The list of read texts is part of the person, so use mark_person_as_changed, not mark_conference_as_changed. (Bug 877). (mark_as_unread): FIXME comment removed. (set_read_ranges): Ditto. Write a test case for bug 877. * src/server/testsuite/lyskomd.0/bug-877.exp: New file. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added bug-877.exp. * src/server/simple-cache.c: All these changes are only in effect if DEBUG_CALLS is defined: Include services.h and manipulate.h. (block_after_pre_sync): New static variable. (save_one_conf): Return immediately if block_after_pre_sync is true. (cache_sync_all): Crash if block_after_pre_sync is true. (cache_sync_start): New request. (cache_sync_finish): New request. * src/server/fncdef.txt (cache_sync_start): New DEBUG_CALLS request. (cache_sync_finish): Ditto. * src/include/services.h (cache_sync_start): New DEBUG_CALLS request. (cache_sync_finish): Ditto. Code cleanup. * src/server/connections.c (kill_list): Now static. (kill_list_size): Now static. 2003-01-07 Per Cederqvist Port to IRIX64, where "unsigned long" isn't large enough to avoid alignment problems. * src/server/ram-smalloc.c: Include or . (union overhead): New union. Use two of these instead of two unsigned ints as the overhead at the front of a malloced block. This ensures we get the alignment that we need. (smalloc): Updated to use union overhead. Some useless casts removed. (sfree): Ditto. (srealloc): Ditto. * configure.in: Check for , intptr_t, intmax_t and size_t. 2003-01-07 Per Cederqvist Xenofarm cleanup. * scripts/xenofarm.sh: Don't create .pass-, .warn- and .fail files. The information is present in mainlog.txt, and the Xenofarm scripts no longer need them. Upgrade to valgrind-1.9.2. * src/server/testsuite/lyskomd.supp: Valgrind 1.9.2 detects the isc_tcp_accept_fn in the calltrace, so we have to update the suppressions for bug 916. 2003-01-07 Per Cederqvist Note a bug. * src/server/text.c (add_recipient): FIXME comment added. 2003-01-06 Per Cederqvist Change to Xenofarm log file format version 2. * scripts/xenofarm.sh (logstart, logpass, logfail, logwarn): New functions. (dotask): New argument: warnfunc. All callers updated. Convert to Xenofarm log format version 2. (cfgwarn, makewarn, ckprgwarn): New functions that hunt for warnings. Extracted from the top level. (Top Level): Removed special-caseing for taylor. 2003-01-06 Per Cederqvist Xenofarm tweaking. * scripts/xenofarm.sh: Use sed -e instead of multiple grep -v. This should scale better. Implemented async-new-user-area. (Bug 7). * doc/Protocol-A.texi (async-new-user-area): New async message. * src/server/async.h (enum async): Added ay_new_user_area. * src/server/person.c (do_set_user_area): Renamed a few local variables. Call async_new_user_area when the user area changes. * src/server/session.c (accept_async): Handle ay_new_user_area. * src/server/send-async.h, src/server/send-async.c (async_new_user_area): New function. * src/server/prot-a-send-async.h, src/server/prot-a-send-async.c (prot_a_async_new_user_area): New function. * src/server/person.c (do_set_user_area): Indentation fixes. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added 33.exp. * src/server/testsuite/lyskomd.0/33.exp: New file: test async-new-user-area. * src/server/testsuite/lyskomd.0/03.exp: Expect asynchronous message 19 to exist. Improve the description on how to add an async message. * doc/lyskomd.texi (Adding Asynchronous Messages): Mention sesion.c, 03.exp and that new test cases should be written. Test deletion of a person that is logged in on another session. * src/server/testsuite/lyskomd.0/32.exp: New file. Test deletion of a person that is logged in on another session. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added 32.exp. Don't state that async-leave-conf is sent when the person is deleted. * doc/Protocol-A.texi (async-leave-conf): This is not sent when the person is deleted, so don't say that it is. Update the testsuite for the new semantics of "Max conferences". * src/server/testsuite/lyskomd.0/person-cov.exp: Lower "Max conferences" from 18 to 17, to compensate for the bugfix of 2003-01-04. * src/server/testsuite/lyskomd.0/conference-cov.exp: Lower "Max conferences" from 20 to 19, to compensate for the bugfix of 2003-01-04. 2003-01-04 Per Cederqvist Make it easier to reduce the DejaGnu timeout. * src/server/testsuite/config/unix.exp: Moved the setting of timeout around so that people with a fast machine can reduce the timeout simply by removing a has sign. Document what happens when a text, person or conference cannot be created because of the "Max texts"/"Max conferences" parameters. * doc/Protocol-A.texi (create-person-old): Document the error code index-out-of-range. (create-person): Ditto. (create-conf-old): Ditto. (create-conf): Ditto. (create-text-old): Ditto. (create-text): Document what error-status is set to when index-out-of-range is returned. The "Max texts" and "Max conferences" parameters was off by one. * src/server/server-config.c (read_configuration): Increase param.max_text and param.max_conf. This fixes an off-by-one error in the documentation and parameter naming. Test the "Max texts" and "Max conferences" parameters. * src/server/testsuite/lyskomd.0/31.exp: Test the "Max texts" and "Max conferences" parameters. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added 31.exp. The error code anonymous-rejected was not documented under create-text. * doc/Protocol-A.texi (create-text). Document the error code anonymous-rejected. 2002-12-30 Per Cederqvist Port to autoconf 2.57. * configure.in: Require autoconf 2.57. Use AC_CONFIG_HEADERS instead of AM_CONFIG_HEADER. Update copyright headers. * : update the year in the copyright notice. * scripts/lyskomd-copyrights: Added bug-52.data and bug-52.texts to the list of files that should not have a copyright header. Clarify the faq-text item in aux-items.conf. * run-support/aux-items.conf (faq-text): Changed the regexp validation to explicitly forbid linking to text number 0. Minor doc fix. * doc/Protocol-A.texi (add-footnote): The description for the error code index-out-of-range was wrong. Autoconf: better check for "attribute unused" support. * configure.in: Use CMOD_C_WORKING_ATTRIBUTE_UNUSED instead of CMOD_C_ATTRIBUTE_UNUSED. * acinclude.m4 (CMOD_C_ATTRIBUTE_UNUSED): Removed. (CMOD_C_WORKING_ATTRIBUTE_UNUSED): New defun. 2002-11-28 Per Cederqvist Added IPv6 support, coded by Thorild Selén . (Bug 563). * configure.in: Added --enable-ipv6 switch. * AUTHORS: Added Thorild Selén. Stop mark-as-read from leaking info about secret conferences. (Bug 48). * src/server/membership.c (mark_as_read): Don't leak info about secret conferences. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added bug-48.exp. * src/server/testsuite/lyskomd.0/bug-48.exp: New file. Removed redundant dbck runs from the test suite. * src/server/testsuite/lyskomd.0/bug-52.exp (stop): Removed a redundant call to dbck_run. Update documentation. * doc/lyskomd.texi (Adding New Input Types): Test for client disconnect during parsing. * doc/Protocol-A.texi (set-read-ranges): Added error code conference-zero. 2002-11-27 Per Cederqvist Test set-read-ranges. (Bug 54). * src/server/testsuite/lyskomd.0/30.exp: Test set-read-ranges. * src/server/testsuite/lyskomd.0/29.exp: Added test cases for client disconnect while parsing a read_range_list. Test mark-as-unread. (Bug 53). * src/server/testsuite/lyskomd.0/30.exp: Test mark-as-unread. 2002-11-26 Per Cederqvist Use valgrind-1.1.0 instead of valgrind-1.0.0. * src/server/testsuite/lyskomd.supp: Adjusted to valgrind-1.1.0. Added suppressions for bug 916. Fixed a broken log message. * src/server/membership.c (read_ranges_postcondition): Added a missing newline in the log message. Plugged a memory leak in mark-as-unread. * src/server/membership.c (remove_loc_no): srealloc() or sfree() the read_ranges if we remove a range. Test mark-as-unread and set-read-ranges a little. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added 30.exp. * src/server/testsuite/lyskomd.0/30.exp: New file. Test mark-as-unread and set-read-ranges. This is not complete yet. 2002-11-25 Per Cederqvist Upgraded for autoconf-2.56 and automake-1.7.1. * HACKING: Updated version numbers of autoconf and automake. * src/server/Makefile.am (AM_YFLAGS): Set AM_YFLAGS instead of YFLAGS. The latter is reserved for the user. * doc/Protocol-A.texi: Use @c instead of @ignore..@end ignore inside the @copying command, since @ignore..@end ignore no longer works there with the texinfo.tex supplied with automake-1.7.1. * configure.in: Upgraded for autoconf-2.56 and automake-1.7.1: Use AC_COMPILE_IFELSE instead of AC_TRY_COMPILE. Use AC_LANG_PROGRAM. Use AC_LINK_IFELSE instead of AC_TRY_LINK. Use AC_RUN_IFELSE instead of AC_TRY_RUN. 2002-11-25 Per Cederqvist Bug 93 has been split into several bugs. Update the FIXME comments that refered to bug 93. * src/server/text.c (modify_text_info): Update FIXME comment. * src/server/person.c (create_person): Update FIXME comment. * src/server/connections.c (logout_client): Update FIXME comment. * src/server/conference.c (do_delete_conf): Update FIXME comment. (set_etc_motd): Ditto. (modify_conf_info): Ditto. * src/server/admin.c (set_motd_of_lyskom): Update FIXME comment. 2002-11-15 Per Cederqvist Minor doc fixes. * doc/Protocol-A.texi (mark-as-read): Added markup. (set-unread): Ditto. (get-membership): This was introduced in protocol version 11, not 10. Added new requests 109=mark-as-unread and 110=set-read-ranges. * doc/Protocol-A.texi (mark-as-unread): New request. (set-read-ranges): New request. (Error Codes): Added invalid-range and invalid-range-list. * src/include/services.h (mark_as_unread): New request. (set_read_ranges): New request. * src/server/fncdef.txt: Added mark_as_unread and set_read_ranges. * src/server/membership.c (remove_loc_no): New static function. (read_ranges_precondition): New static function. (read_ranges_postcondition): New static function. (mark_as_read): Extracted debug code to read_ranges_precondition and read_ranges_postcondition. (mark_as_unread): New function. (check_range_list): New static function. (set_read_ranges): New function. * src/server/testsuite/lyskomd.0/01.exp: Test 109=mark-as-unread and 110=set-read-ranges. * src/server/testsuite/lyskomd.0/03.exp: Ditto. Added parsing of "ARRAY Read-Range", aka read_range_list, needed by request 110=set-read-ranges. * doc/lyskomd.texi (Parameters): Document "Max read_ranges per call". * src/server/param.h (struct kom_par): Added max_read_ranges. * src/server/server-config.c (parameters): Added "Max read_ranges per call". * src/server/prot-a.c (prot_a_destruct): Free read_range_list. * src/server/prot-a-parse.h (prot_a_parse_read_range_list): New function. * src/server/prot-a-parse.c (prot_a_parse_read_range): New static function. (prot_a_parse_read_range_list): New function. * src/server/prot-a-parse-arg-c.awk: Handle read_range_list. * src/server/internal-connections.c (init_connection): Initialize read_range_list. * src/server/connections.h (Connection): Added read_range_list. * src/server/connections.c (free_parsed): Free read_range_list. * src/server/call-switch.awk: Handle read_range_list. * src/include/kom-types.h (struct read_range_list): New struct. * src/include/kom-errno.h (enum kom_err): Added KOM_INVALID_RANGE and KOM_INVALID_RANGE_LIST. 2002-11-14 Per Cederqvist Release administrativa. * HACKING: Publish the NEWS file on the web when doing a release. Test 107=query-read-texts and 108=get-membership even more. (Bug 590). * src/server/testsuite/lyskomd.0/bug-37.exp: Test 107=query-read-texts and 108=get-membership. * src/server/testsuite/lyskomd.0/bug-37-2.exp: Ditto. * src/server/testsuite/lyskomd.0/bug-37-3.exp: Ditto. * src/server/testsuite/lyskomd.0/bug-37-4.exp: Ditto. 2002-11-13 Per Cederqvist Release administrativa. * HACKING: Make sure no closed bugs are left on the TODO list. Test 107=query-read-texts and 108=get-membership. * src/server/testsuite/lyskomd.0/bug-52.exp: Fixed a couple of errors in the range-based test cases. (checkit): Test 107=query-read-texts and 108=get-membership. (checktrunc): New proc. Use it a few times to check that the new requests can truncate the ranges of read texts. * src/server/testsuite/lyskomd.0/03.exp: Be prepared that query-read-texts-old now adjusts the read ranges. Test 107=query-read-texts and 108=get-membership. Renumber. * src/server/testsuite/lyskomd.0/01.exp: Test 107=query-read-texts and 108=get-membership. Renumber. Implement 107=query-read-texts and 108=get-membership. * src/server/prot-a.c (prot_a_reply): Handle rt_membership and rt_membership_list. * src/server/prot-a-output.h, src/server/prot-a-output.c (prot_a_output_membership): New function. (prot_a_output_membership_list): New function. * src/server/person.c (do_query_read_texts): New arguments: want_read_ranges and max_ranges. All callers updated. Call adjust_read() if want_read_ranges is true. (query_read_texts): New function. * src/server/membership.c (copy_public_confs): New arguments: keep_read and max_ranges. All callers updated. (adjust_read): Now has external linkage. Changed return type from void to Bool; return true if the membership was modified. (do_get_membership): New arguments: keep_ranges and max_ranges. Renamed the want_read_texts argument to want_read_ranges. All callers updated. (get_membership): New function. * src/server/manipulate.h (adjust_read): Now has external linkage. * src/server/fncdef.txt: Added query_read_texts and get_membership. * src/server/connections.h (Connection): Added num4. (enum res_type): Added rt_membership and rt_membership_list. (union result_holder): Added membership and membership_list. * src/include/services.h (get_membership): New function. (query_read_texts): New function. Documented new range-based requests get-membership and query-read-texts. Renamed the old versions by adding a "-10" suffix. * doc/constructs.expected: Removed references to bug 52. * doc/Protocol-A.texi (Membership and Reading): Talk about read-ranges, not last-text-read and read-texts. (Person Status Types): Mention read-ranges. (Membership Information): Mention that obsolete versions of Membership exists. (Membership Information): Renamed Membership to Membership-10, and added new Membership and Read-Range types. (Protocol Requests): Flag 98=query-read-texts-10 and 99=get-membership-10 as obsolete. Added 107=query-read-texts and 108=get-membership. (sub-member): Changed get-membership to get-membership-old, since that is was the example uses. Added markup. (mark-as-read): Changed query-read-texts to query-read-texts-old, since that is what the example uses. Added markup. (set-unread): Ditto. (set-last-read): Ditto. (query-read-texts-10): New name for former request query-read-texts. Mark it as obsolete and refer to the new query-read-texts request. Changed return type to Membership-10. (get-membership-10): New name for former request get-membership. Mark it as obsolete and refer to the new get-membership request. Changed return type to ARRAY Membership-10. (query-read-texts): New request. (get-membership): New request. (Membership visibility): Added get-membership-10 and query-read-texts-10. (What do I have unread): Added markup. (Future changes): Removed references to bug 52. (Document Edition History): Tracked the renaming of query-read-texts-10 and get-membership-10. 2002-11-12 Per Cederqvist Added a "_10" suffix to type Membership and all derived types and functions, in preparation of writing range-based replacements. * src/server/fncdef.txt: Renamed functions: query_read_texts -> query_read_texts_10 get_membership -> get_membership_10 Renamed types: membership -> membership_10 membership_list -> membership_list_10 * src/include/services.h: Renamed functions: query_read_texts -> query_read_texts_10 get_membership -> get_membership_10 * src/server/connections.h (enum res_type): Renamed: rt_membership -> rt_membership_10 rt_membership_list -> rt_membership_list_10 (union result_holder): Renamed: membership -> membership_10 membership_list -> membership_list_10 * src/server/prot-a.c (prot_a_reply): Use membership_old instead of membership where appropriate. Track rename of *membership* to *membership*_10. * src/server/person.c (query_read_texts_10): Renamed from query_read_texts. * src/server/membership.c (get_membership_10): Renamed from get_membership. * src/server/prot-a-output.h, src/server/prot-a-output.c (prot_a_output_membership_10): Renamed from prot_a_output_membership. (prot_a_output_membership_list_10): Renamed from prot_a_output_membership_list. Allow types in Protocol A to end in a number suffix. * doc/checkargs.py (lexer.__bad_type): Allow types that ends in a number, such as "Membership-10". Testsuite: work on even slower computers. * src/server/testsuite/config/unix.exp (timeout): Increase the timeout even further. Log message fixed. * src/server/ram-parse.c (fparse_read_range_0): Fixed wrong function name in a log message. Ignore gcov-generated files in libeintr. * src/libraries/libeintr/.cvsignore: Ignore *.bb, *.bbg and *.da. Doc typo fixed. * doc/lyskomd.texi (Modifying Output Types): Typo fixed. Fixed all known bugs in the range-based read-texts implementation. * src/server/ram-parse.c (fparse_read_range_0): Don't forget the first interval that is created based on last-text-read. * src/server/membership.c (adjust_read): Aim at setting first_read of the first range to 1, even if that is lower than the first currently existing text in the conference. Make the code that tries to extend ranges towards higher numbers more efficient -- no loop is needed, since l2g_next_key can be used. Removed some dead code. * src/server/testsuite/lyskomd.0/bug-52.exp (start): Use serial number 999 instead of 1000 to ease debugging. 2002-11-11 Per Cederqvist Finish the test-suite for range-based representation. This reveals at least two errors in the implementation. * src/server/testsuite/lyskomd.0/bug-52.exp: Renumber and extend. (do_restart): Set to 1. (check_unread_confs): New proc. Use it several times. 2002-11-10 Kent Engström Add support for the mx-refuse-import aux item. * run-support/aux-items.conf: Add mx-refuse-import [35]. * doc/Protocol-A.texi (Aux-Item Types): Ditto. * doc/constructs.expected: Add @code{all}, @code{spam}. * src/server/testsuite/lyskomd.0/01.exp: Fix to accept the added aux item. * src/server/testsuite/lyskomd.0/03.exp: Ditto. * src/server/testsuite/lyskomd.0/18.exp: Ditto. Add information about dependence on texinfo version. * HACKING: Add entry about texinfo. 2002-11-10 Per Cederqvist Make do_get_members() look nicer. * src/server/membership.c (do_get_members): Minor code cleanup and indentation fixes. Use init_member() to set all fields, and then explicitly set (only) the secret bit. 2002-11-09 Per Cederqvist Even more tests for the range-based representation. * src/server/testsuite/lyskomd.0/bug-52.exp: Expand the test suite and prepare it for range-based information commands. (lazy_expand): New variable. (mark_as_read_atomic): New variable. (do_restart): New variable. This is currently set to 0 to hide known errors... (restart): New proc. (checkit): New argument: ranges. Added more tests of the range-based representation for read texts. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added bug-52.data, bug-52.texts and bug-52.exp. * src/server/testsuite/lyskomd.0/bug-52.exp: New file. * src/server/testsuite/lyskomd.0/bug-52.data: New file. * src/server/testsuite/lyskomd.0/bug-52.texts: New file. * src/server/testsuite/config/unix.exp (unpack_db): New proc. (lyskomd_start): New args: confs, texts and nogarb. 2002-11-06 Per Cederqvist Use a range-based representation in core for the texts a user has read. The external representation is not yet affected. (Bug 52). * src/include/kom-types.h (struct read_range): New struct. (Membership): Removed fields last_text_read, no_of_read and read_texts. Added fields no_of_read_ranges, read_ranges and skip_read_texts. * src/server/ram-parse.c (fparse_read_range_0): New static function that handles the new range-based representation of memberships. (fparse_membership_2): Use it. (fparse_membership_0): Use it. (fparse_membership_list_0): Handle the new range-based representation of memberships. (fparse_membership_list_2): Ditto. * src/server/ram-output.c (foutput_read_ranges_0): New static function that handles the new range-based representation of memberships. (foutput_membership_0): Use it. (foutput_membership_2): Use it. * src/server/prot-a-output.c (prot_a_output_read_texts): New static function that handles the new range-based representation of memberships. (prot_a_output_membership_old): Use it. * src/server/person.c (do_query_read_texts): Handle new range-based representation of memberships. * src/server/memory.c (clear_membership): Handle new range-based representation of memberships. (copy_membership): Ditto. (init_membership): Ditto. * src/server/membership.c (copy_public_confs): Handle new range-based representation of memberships. (adjust_read): Ditto. (insert_loc_no): Ditto. (do_add_member): Ditto. (do_sub_member): Ditto. (check_membership): Ditto. (mark_as_read): Ditto. (do_get_membership): Ditto. (get_unread_confs): Ditto. (set_unread): Ditto. (set_last_read): Ditto. (last_text_read): New static inline function. * src/server/dbck.c (check_membership): Handle range-based representation of memberships. Xenofarm warnings. * scripts/xenofarm.sh: Ignore warnings about reduced hard ulimit. 2002-11-05 Per Cederqvist Spell-check Protocol-A.texi. * HACKING: Spell-check Protocol-A.texi when a release is made. * doc/Protocol-A.texi: A few spelling errors fixed. Testsuite: timeout handling was broken. * src/server/testsuite/config/unix.exp (fix_expect_after): Don't unconditionally add a timeout pattern. Contrary to my belief, a timeout pattern seems to refer to a specific spawn id. If we add it here when there are no spawned processes, the timeout will refer to stdin, and this will cause expect to detect eof on stdin when run from Xenofarm. Instead, everything that spawns a process must add timeout patterns to the expect_active variable. (l2g_start): Add a timeout pattern to expect_active. (lyskomd_start): Ditto. (lyskomd_start_fail): Ditto. (client_start): Ditto. (client_start_fail): Ditto. Test suite fixes. * src/server/testsuite/config/unix.exp (dbck_run): Added missing "global spawn_id". * src/server/testsuite/lyskomd.0/12.exp: After dbck_run has finished, we must re-specify which client we want to talk to. The test suite didn't stop listening to lyskomd when it died. * src/server/testsuite/config/unix.exp (lyskomd_death): Don't listen to the lyskomd spawn id once it has died. (kill_lyskomd): Ditto. * src/server/testsuite/lyskomd.0/11.exp: Match all output. Somehow this test didn't fail even though there were unmatched output from lyskomd. Strange. Never reuse text or conference numbers. (Bug 810). * doc/lyskomd.texi (Parameters): New parameters: "Number file:" and "Number temp file:". * src/server/param.h (struct kom_par): Added numberfile_name and numberfile_tmp_name. * src/server/server-config.c (parameters): Added "Number file" and "Number temp file". (read_configuration): Handle them. * src/server/simple-cache.c (highest_conf_no): Explicitly initialize to 0. (highest_text_no): Ditto. (write_number_file): New static function. (read_number_file): Ditto. (cached_create_conf): Call write_number_file, and return KOM_TEMPFAIL if it fails. (cached_create_text): Ditto. (init_cache): Don't set highest_conf_no and highest_text_no. They are only used during the save phase. Call read_number_file. * db-crypt/db/number.txt: New file. * db-crypt/db/Makefile.am (EXTRA_DIST): Added number.txt. (install-data-local): Install number.txt. (uninstall-local): Remove number.txt. Don't remove anything if number.txt is altered. * src/server/testsuite/config/unix.exp (lyskomd_start): New optional arguments: log_messages, init_db and want_stale. Copy number.txt. Don't copy the database if init_db is 0. Expect a log message about a removal of a stale lock file if want_stale is 1. Expect log_messages after the startup messages but before the garb messages. (lyskomd_fail_start): Copy number.txt. * src/server/testsuite/lyskomd.0/bug-810.exp: Expect messages about lost texts and conferences in the log. Don't expect any failures. 2002-11-04 Per Cederqvist Write test case for bug 810: retain text, person and conference numbers after a crash. * src/server/testsuite/config/unix.exp (kill_lyskomd): New proc. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added bug-810.exp. * src/server/testsuite/lyskomd.0/bug-810.exp: Test that text, person and conference number are never reused, not even when the server crashes. 2002-11-04 Per Cederqvist Xenofarm: ignore warnings from assignment of SIG_IGN. * scripts/xenofarm.sh: Updated list of warnings to ignore. * src/server/ramkomd.c (set_handler_sig_ign): New function. (server_init): Use it. (go_daemon): Use it. This reduces the number of warnings on some platforms. 2002-11-04 Per Cederqvist Fixed a grammar error. * doc/Protocol-A.texi (Document Edition History): Fixed grammar error. Reported by Hans Persson. Fixed typo. * src/server/ram-smalloc.c: Fixed a typo in a comment. Release administrativa that missed the deadline. * README: Recommend the "-C" option of "./configure". * HACKING: Updated with stuff found while performing the 2.0.7 release. 2002-11-03 Per Cederqvist * Release 2.0.7. 2002-11-02 Per Cederqvist Disable the extended tests for the release. * src/server/testsuite/lyskomd.0/gen-19.py (EXTENDED): Reset to 0. * src/server/testsuite/lyskomd.0/gen-15.py (EXTENDED): Reset to 0. Not all makes sets RM, so do it manually in all Makefile.am. * src/libraries/libeintr/Makefile.am (RM): Set it. * run-support/Makefile.am (RM): Set it. * db-crypt/db/Makefile.am (RM): Set it. A few files lacked a copyright header. * src/server/testsuite/lyskomd.0/summarize.sh: Added copyright header. * src/server/testsuite/bignum.c: Added copyright header. * src/libraries/libeintr/gen-wrapper.awk: Added copyright header. * src/libraries/libeintr/eintr.h.pre: Added copyright header. Update the copyright updater. * scripts/lyskomd-copyrights: Ignore generated files in libeintr and the testsuite. Run extended tests on the Xenofarm. * src/server/testsuite/lyskomd.0/gen-19.py (EXTENDED): Set to 1. * src/server/testsuite/lyskomd.0/gen-15.py (EXTENDED): Set to 1. Fix the distribution. * src/libraries/libeintr/Makefile.am (nodist_libeintr_a_SOURCES): Added the nodist_ prefix, to avoid distributing these generated files. (MOSTLYCLEANFILES): Added the generated files. Release administrativa. * scripts/lyskomd-copyrights: Updated the copyright statement. * README: Updated version numbers for TCL and expect. Updated copyright statement. * NEWS: Updated. * HACKING: We actually use Python 2.1 for the release generation, not 2.2.1. Extract the release from the Xenofarm build package. * doc/Protocol-A.texi (Document Edition History): Updated with all made changes. Fixed a few minor problems with Protocol-A.texi. * doc/Protocol-A.texi(Some Client-specific Aux-Item Types): New name for the appendix formerly known as "Client-specific Aux-Item Types". Another node of that name already exists! (LysKOM Content Types): Fixed a typo. (Membership visibility): Fixed typos. (Order of misc-info groups): Fixed a typo. 2002-11-01 Per Cederqvist The timeout of the test suite was too low. * src/server/testsuite/config/unix.exp (timeout): Increase the timeout further. Hal apparently needs it. 2002-10-31 Per Cederqvist NFS-mounted databases may fail. Warn the administrator. * README: Added a warning that NFS-mounted databases may fail due to EINTR. Added a library of wrapper functions that checks for EINTR. * configure.in: Generate src/libraries/libeintr/Makefile. * src/libraries/Makefile.am (SUBDIRS): Added libeintr. * src/libraries/libeintr/gen-wrapper.awk: New file. Generate simple wrappers that check for EINTR. * src/libraries/libeintr/funcs.txt: New file. Use wrappers for fopen, fclose and rename. * src/libraries/libeintr/eintr.h.pre: New file. * src/libraries/libeintr/Makefile.am: New file. Use the libeintr wrappers instead of fopen, fclose and rename. * src/server/Makefile.am (AM_CPPFLAGS): Added libeintr. (lyskomd_LDADD): Ditto. (dbck_LDADD): Ditto. (LDADD): Ditto. * src/server/updateLysKOM.c (main): Use i_fopen instead of fopen. Don't forget to close the status file. * src/server/splitkomdb.c (copy_file, copy_db_file): Use i_fopen and i_fclose instead of fopen and fclose. * src/server/simple-cache.c (is_clean, get_version, post_sync) (save_one_text, sync_part, init_cache, free_all_cache): Use i_fopen and i_fclose instead of fopen and fclose. (pre_sync): Ditto, and i_rename instead of rename. * src/server/ramkomd.c (save_pid, dump_exit_statistics): Use i_fopen and i_fclose instead of fopen and fclose. * src/server/ram-smalloc.c (trace_alloc_file): Use f_fopen intstead of fopen. * src/server/pidfile.c (read_pid_file): Use i_fopen and i_fclose instead of fopen and fclose. * src/server/komrunning.c (create_status): Use i_fopen and i_fclose instead of fopen and fclose. * src/server/dbck.c (garb_text_file): Use i_rename instead of rename. Check the return value. * src/server/dbck-cache.c (get_version, is_clean, cache_sync_all) (cache_open_new_text_file, init_cache): Use i_fopen, i_fclose and i_rename instead of fopen, fclose and rename. * src/server/connections.c (dump_statistics): Use i_fopen and i_fclose instead of fopen and fclose. (dump_connections): Ditto, and i_rename instead of rename. * src/server/conf-file.c (read_config): Use i_fopen and i_fclose instead of fopen and fclose. * src/server/aux-item-def-parse.y (parse_aux_item_definitions): Use i_fopen and i_fclose instead of fopen and fclose. 2002-10-28 Per Cederqvist Check if rename really sets errno to EINTR. * src/server/connections.c (dump_connections): Set errno to 0 before the rename that strangely returns with EINTR during the Xenofarm tests. * NEWS: Updated. 2002-10-28 Per Cederqvist Make dump_connections more robust. * src/server/connections.c (dump_connections): Call fflush() and ferror(). This might help track down spurious errors from the rename that I don't understand. Release administrativa. * HACKING: Mention "make distcheck". Test suite cleanup. * scripts/xenofarm.sh: Removed the "eintr" task. 2002-10-28 Per Cederqvist Port to AIX 4.2: limit the number of open file descriptors properly. * src/server/connections.c (toploop) [!USING_RLIMIT_NOFILE]: Fixed a off-by-one error. Fixed compile error on systems lacking SA_RESTART. * src/server/ramkomd.c (setup_sighandlers): Added a missing semicolon. 2002-10-27 Per Cederqvist Testsuite fixes. Don't use __FILE__ in log messages, as it isn't very useful, and makes the test suite more complex. * src/server/testsuite/lyskomd.0/connections-cov.exp: Don't expect the "connections.c" file name in the log message, as that broke when doing an srcdir build. * src/server/text.c (is_member_in_recpt): Don't use __FILE__. (do_sub_recpt): Ditto. (check_double_subm): Ditto. (check_double_comm): Ditto. Fix the function name in a log message. * src/server/memory.c (clear_text_stat): Don't use __FILE__. Fix the function name in a log message. * src/server/connections.c (dump_statistics): Don't use __FILE__. Don't require bison/yacc when compiling. (Bug 843). * src/server/Makefile.am: The explicit dependencies added 2002-10-21 to fix "make clean; make check" was broken: the ".c" extension was used instead of ".o" in several cases. This resulted in bison being run on the client. Consider FD_SETSIZE. * src/server/ramkomd.c (initialize): Don't allow the number of open files to be larger than FD_SETSIZE. * src/server/testsuite/testfd.c (find_limits): Report FD_SETSIZE. 2002-10-27 Per Cederqvist Testsuite fixes. * src/server/testsuite/lyskomd.0/11.exp: Fixed a race condition in the test. * src/server/testsuite/config/unix.exp (obtain_lock): Search for locksuite.py in $srcdir. (lyskomd_start): Removed unused global declaration of srcdir. (lyskomd_fail_start): Ditto. (client_death): Ditto. 2002-10-27 Per Cederqvist Port to AIX 4.2: limit the number of open file descriptors in a more portable way. * src/include/kom-config.h (PROTECTED_FDS): Added parenthesis around the number. (MAX_NO_OF_CONNECTIONS): Removed. (USING_RLIMIT_NOFILE): Define if we have a good setrlimit. (fd_ceiling): New variable. * src/server/server-config.c (MAX_NO_OF_CONNECTIONS): Removed. (fd_ceiling): New variable. * src/server/connections.c (toploop): Transform ISC_EVENT_LOGIN to ISC_EVENT_LOGIN_UNRELOCATED if the file descriptor is above fd_ceiling. This can only happen if USING_RLIMIT_NOFILE is undefined, so ifdef out this code. * src/server/ramkomd.c (go_daemon): Close everything below fd_ceiling instead of using MAX_NO_OF_CONNECTIONS + PROTECTED_FDS. (initialize): Use getrlimit/setrlimit if USING_RLIMIT_NOFILE is defined. Check that getrlimit after setrlimit returns a sane value. Don't use sysconf(_SC_OPEN_MAX), since getrlimit provides a better value. Set fd_ceiling instead of MAX_NO_OF_CONNECTIONS. Make it possible to lower the ceiling even when we don't have a working setrlimit. Removed the final sanity checks; the world ain't sane. * src/server/testsuite/testfd.c (main): Adjusted logic for error checks to be similar to the code now used. In particular, don't test sysconf(_SC_OPEN_MAX), and don't test getrlimit if HAVE_BROKEN_NOFILE. 2002-10-26 Per Cederqvist Prepare for more portable handling of the number of file descriptors used. * configure.in: Define HAVE_BROKEN_NOFILE if setrlimit(RLIMIT_NOFILE) fails. 2002-10-26 Per Cederqvist Update the testsuite so that it doesn't fail because of SA_RESTART/select() on HP-UX. * src/server/testsuite/Makefile.am (check-test-select): Pass --no-sa-restart to test-select, so that we test the code the way we actually use it. * src/server/testsuite/test-select.c (main): New argument: --no-sa-restart. Don't use SA_RESTART if given. Port to HP-UX: Use SA_RESTART except while calling select(). * src/server/sigflags.h (restart_syscalls_on_intr): New function. (intr_syscalls_on_intr): New function. * src/server/ramkomd.c (setup_sighandlers): New function. Use SA_RESTART if the "restartable" argument is true. (restart_syscalls_on_intr): New function. (intr_syscalls_on_intr): New function. (main): Move signal handler setup to setup_sighandlers(). * src/server/connections.c (toploop): Call intr_syscalls_on_intr() before calling isc_getnextevent, and restart_syscalls_on_intr() immediately after its return. 2002-10-26 Per Cederqvist Port to SunOS 4.1.1_U1 that lacks SA_RESTART. * src/server/testsuite/test-select.c (main): Call link_ansi(). Only set SA_RESTART if it is available. * src/server/testsuite/Makefile.am (test_select_LDADD): New variable. 2002-10-26 Per Cederqvist Use SA_RESTART. * src/server/ramkomd.c (main): Use SA_RESTART, even though it potentially will cause lyskomd to block in select() instead of responding promptly to signals. Check that SA_RESTART can interrupt select(). * src/server/testsuite/test-select.c: Test if select() can be interrupted by a signal even when SA_RESTART is specified. * src/server/testsuite/Makefile.am (check_PROGRAMS): Added test-select. (test_select_SOURCES): New variable. (check): Added check-test-select. (check-test-select): New target. * scripts/xenofarm.sh: Added eintr test, to check the select/SA_RESTART in a separate task. Fixed a race condition in the test suite. * src/server/testsuite/tcpconnect.py: Flush stdout more often. Give feedback on "#supsend socket" and "#resume socket" to avoid a race condition. * src/server/testsuite/config/unix.exp (kill_client): Include the client number in the test name when testing for stray output. This makes it easier to see which client that misbehaves. (suspend_client): Expect a response from the client. (resume_client): Ditto. 2002-10-25 Per Cederqvist The test suite now test for buffer overflow in the proper way. (Bug 844). * src/server/testsuite/config/unix.exp (l2g_start): Test for "full_buffer". An old expect document has fooled us to test for "buffer_full" instead; that doesn't work. (simple_expect): Ditto. (good_bad_expect): Ditto. (extracting_expect): Ditto. (unanchored_expect): Ditto. (lyskomd_start): Ditto. (lyskomd_fail_start): Ditto. (client_start): Ditto. (client_start_fail): Ditto. The test suite failed when configured with --with-debug-calls. * src/server/testsuite/config/unix.exp (lyskomd_fail_start): Handle --with-debug-calls compilations. * src/server/testsuite/lyskomd.0/09.exp: Handle --with-debug-calls compilations. * src/server/testsuite/lyskomd.0/admin-cov.exp: Ditto. * src/server/testsuite/lyskomd.0/conference-cov.exp: Ditto. * src/server/testsuite/lyskomd.0/person-cov.exp: Ditto. Improve a few log messages. * src/server/person.c (do_set_user_area): Improve the "Old user_area X unmarked" message. * src/server/conference.c (do_set_presentation): Improve the "Old presentation not marked" message. (do_set_etc_motd): Improve the "New motd has X marks" and "Old motd not marked" messages. * src/server/admin.c (set_motd_of_lyskom): The "Old motd not marked" message used the wrong function name. Log the reason why the connection status file cannot be renamed. (Bug 841). * src/server/connections.c (dump_connections): Emit strerror(errno) when file operations fails. 2002-10-23 Per Cederqvist Plugged a memory leak. (Bug 816). * src/server/prot-a.c (prot_a_destruct): Clear dummy_aux_item, to plug a memory leak. To trigger this leak, you had to send an oversized aux-item-list, that contained an oversized string in the last part of the oversized array, and disconnect while sending the last part of the string. Test client disconnect more thoroughly. (Bug 63). * src/server/testsuite/lyskomd.0/29.exp: Several more test cases added. We now trigger bug 816. (startup): Reduce "Max aux_item length" and "Max links per text". Test suite fixes. * src/server/testsuite/lyskomd.0/03.exp: Wait for a third tick. This test failed on computers that were too fast, due to the script waiting too short a time. * src/server/testsuite/config/unix.exp (lyskomd_start): Added a missing dot that caused --with-debug-calls tests to fail. Clients should offer to add the letterbox of the author if he isn't a member of any of the recipients. * doc/Protocol-A.texi (Recipients of comments): Added a description of what to do when the author of a new comment isn't a member of any of the recipients. Added option "-f" (stay in foreground) to lyskomd. "-d" no longer implies "stay in foreground". * src/server/ramkomd.c (foreground): New static variable. (go_daemon): Stay in foreground if given -f, not -d. (initialize): Prompt the operator for confirmation when given -f, not -d. (main): Ditto. Handle -f: stay in foreground. * doc/lyskomd.texi (Invoking lyskomd): Documented the new -f option. Let the test suite check all output from lyskomd. * src/server/testsuite/config/unix.exp (maxint): Unused constant removed. (lyskomd_expect): New proc. (spawn_lyskomd): Use -f, not -d. (lyskomd_start): Check all output from lyskomd. (lyskomd_fail_start): Ditto. (lyskomd_death): New argument: reason. Check all output from lyskomd. (talk_to): Set current_talk_what and current_talk_nr, so that lyskomd_expect can restore the old settings. Set proper line_leader for lyskomd. * src/server/testsuite/lyskomd.0/03.exp: Check all output from lyskomd. * src/server/testsuite/lyskomd.0/05.exp: Ditto. * src/server/testsuite/lyskomd.0/06.exp: Ditto. * src/server/testsuite/lyskomd.0/24.exp: Ditto. * src/server/testsuite/lyskomd.0/25.exp: Ditto. * src/server/testsuite/lyskomd.0/27.exp: Ditto. * src/server/testsuite/lyskomd.0/admin-cov.exp: Ditto. * src/server/testsuite/lyskomd.0/aux-items-cov.exp: Ditto. * src/server/testsuite/lyskomd.0/bug-349.exp: Ditto. * src/server/testsuite/lyskomd.0/bug-37-2.exp: Ditto. * src/server/testsuite/lyskomd.0/bug-37-3.exp: Ditto. * src/server/testsuite/lyskomd.0/bug-37-4.exp: Ditto. * src/server/testsuite/lyskomd.0/bug-37.exp: Ditto. * src/server/testsuite/lyskomd.0/bug-612.exp: Ditto. * src/server/testsuite/lyskomd.0/conf-file-cov.exp: Ditto. * src/server/testsuite/lyskomd.0/conference-cov.exp: Ditto. * src/server/testsuite/lyskomd.0/connections-cov.exp: Ditto. * src/server/testsuite/lyskomd.0/gen-15.py: Ditto. * src/server/testsuite/lyskomd.0/gen-19.py: Ditto. * src/server/testsuite/lyskomd.0/membership-cov.exp: Ditto. * src/server/testsuite/lyskomd.0/person-cov.exp: Ditto. * src/server/testsuite/lyskomd.0/send-async-cov.exp: Ditto. * src/server/testsuite/lyskomd.0/session-cov.exp: Ditto. * src/server/testsuite/lyskomd.0/text-cov.exp: Ditto. * src/server/testsuite/lyskomd.0/11.exp: Use the -f argument of lyskomd, not -d. Pass the reason argument to lyskomd_death. * src/server/testsuite/lyskomd.0/07.exp: Pass the reason argument to lyskomd_death. Test suite cleanup. * src/server/testsuite/lyskomd.0/29.exp: Removed spurious newline from the log file. Fixed a race condition in the test suite. (Bug 692). * src/server/testsuite/lyskomd.0/18.exp: Check all output from lyskomd. Closes bug 692. * src/server/ramkomd.c (sighandler_winch): Moved log message to toploop(). * src/server/connections.c (toploop): Log a message when SIGWINCH has been processed and the aux definitions reloaded. Fixed a false log message about a memory leak. (Half of Bug 816). * src/server/prot-a.c (prot_a_destruct): Set c_local_text_no_p to NULL after freeing it, to avoid logging "kill_client(): unexpected local_text_no remains." when a client disconnects while sending a c_local_text_no_p array. Clean up the output from lyskomd. * src/server/conf-file.c (configure_line): Don't add blank lines to the log. * src/server/aux-items.c (aux_item_validate): Added a trailing dot to a log message. * src/server/aux-item-def-parse.y: Fixed typo in a log message. 2002-10-21 Per Cederqvist Don't crash if a client sends the length of an aux-item list and disconnects before sending the "{". Fixed similar code for other arrays. * src/server/prot-a-parse.c (prot_a_parse_num_list): Don't set res->length until res->data is allocated. (prot_a_parse_misc_info_list): Ditto. (prot_a_parse_aux_item_list): Ditto. Without this fix, a client can cause a crash by sending the length of the list, and disconnect before sending the "{". (prot_a_parse_string): Add an additional comment explaining why a client_len field should be added (bug 162). Fix testsuite. * src/server/testsuite/lyskomd.0/29.exp: Expect bug 836: mark-text-as-read gives a protocol error response instead of the error code long-array when an overly long array is sent to the server. "make clean; make check" failed. * src/server/Makefile.am: Added explicit dependencies so that "make clean; make check" no longer fails. Added missing semicolon i bison file. * src/server/aux-item-def-parse.y (action): Inserted a missing semicolon. Fixed a testsuite bug. * src/server/testsuite/lyskomd.0/prot-a-send-async-cov.exp: Use client_death instead of kill_client after receiving the "%% No connections left" message. * src/server/testsuite/lyskomd.0/send-async-cov.exp: Ditto. 2002-10-20 Per Cederqvist Test client disconnect while while the client has sent partial requests. * src/server/testsuite/lyskomd.0/29.exp: New file: test for client disconnect. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added 29.exp. Testsuite: check for unexpected data sent to clients immediately before they are killed. * src/server/testsuite/config/unix.exp (kill_client): Look for stray output before killing the client. Testsuite framework: make it possible to send incomplete lines to the server. * src/server/testsuite/tcpconnect.py: Added support for sending incomplete lines to the server via the "#nocr" instruction. 2002-10-18 Per Cederqvist Minor doc improvement. * doc/Protocol-A.texi (Auxiliary Information): Added a reference to Aux-Item Types. 2002-10-17 Per Cederqvist Fixed a broken lookup-z-name example. * doc/Protocol-A.texi (lookup-z-name): "T C" doesn't match "Trains (-) Discussion", so remove it from the result. Reported by Hans Persson. 2002-10-16 Per Cederqvist Fixed a typo. * doc/Protocol-A.texi (Membership Information): Fixed typo: "added-by", not "added-byp". 2002-10-15 Per Cederqvist Better logging of leaks during client disconnect. * src/server/internal-connections.c (kill_client): Log left-overs from misc_info_list and local_text_no separately. 2002-10-14 Per Cederqvist Port testfd.c to SunOS 5.4. * src/server/testsuite/testfd.c (find_limits): The code failed to compile unless HAVE_GETDTABLESIZE. Flush stdout before writing something to stderr. (main): Flush stdout before writing something to stderr. 2002-10-13 Per Cederqvist Gather more info about file descriptor usage. * src/server/testsuite/testfd.c: Lower the limit using setrlimit and test the limits afterwards as well. Report an error if the assumptions made by lyskomd do not hold. 2002-10-12 Per Cederqvist File descriptor counting on AIX is apparently wrong. Collect some information from the farm. * scripts/xenofarm.sh: Run check-testfd as a separate task, so that the info can be easily collected. * src/server/testsuite/Makefile.am (check_PROGRAMS): Added testfd. (testfd_SOURCES): New variable. (check): Added check-testfd. (check-testfd): New target. * src/server/testsuite/testfd.c: New test program. Handle a failure mode that seems to occur. * src/server/testsuite/lyskomd.0/11.exp: Handle one case of early lyskomd death. Improve testsuite lock handling. * src/server/testsuite/locksuite.py (try_symlink): Break stale lock files. 2002-10-11 Per Cederqvist Removed obsolete Xenofarm compatibility cruft. * scripts/xenofarm.sh: Removed old Xenofarm compatibility stuff, including the --compat argument and the ability to give the compiler to use as an argument. Added the --make argument. 2002-10-09 Per Cederqvist Use AM_CPPFLAGS instead of the obsolete variable INCLUDES. * src/server/testsuite/Makefile.am (AM_CPPFLAGS): New name for former INCLUDES. * src/server/Makefile.am: (AM_CPPFLAGS): New name for former INCLUDES. * src/libraries/libmisc/Makefile.am (AM_CPPFLAGS): New name for former INCLUDES. * src/libraries/libcommon/Makefile.am (AM_CPPFLAGS): New name for former INCLUDES. * src/libraries/libansi/Makefile.am (AM_CPPFLAGS): New name for former INCLUDES. 2002-10-07 Per Cederqvist Xenofarm builds could get stuck forever on a stale lock file. * src/server/testsuite/config/unix.exp (obtain_lock): This failed to break stale locks if the host name contained for instance a dot. So this failed if a FQDN name is used. 2002-10-06 Per Cederqvist Fix the doc fix. * doc/lyskomd.texi (Template for ram-parse.c): Break a too long line. 2002-10-06 Daniel Andersson Doc fix. (Bug 814). * doc/lyskomd.texi (Template for ram-output.c): Corrections to function names etc. (Template for ram-parse.c): Ditto. 2002-10-06 Per Cederqvist Xenofarm cleanup. * scripts/xenofarm.sh: Removed special cases for aristocat, moghedien and lysator. Path setup et c is better handled in the configuration files of the corresponding computer. Fix configure tests for and rlim_t. * configure.in: When checking for rlim_t in , and when checking for itself, include and in the proper way. Both these tests were made too early. 2002-10-05 Per Cederqvist Update Xenofarm configuration of asmodean and moghedien. * scripts/xenofarm.sh: asmodean is no longer used by Xenofarm. moghedien needs runtest, but not a special makeinfo. Also, "uname -n" doesn't return a FQDN there. Send a broadcast message when the server fails to save the database. (Bug 813). * src/server/simple-cache.c (sync_part): Send a broadcast message to everyone if the save failed. Patch from Daniel Andersson, slightly edited. Get rid of some compiler warnings about conversions between char and unsigned char. * src/include/kom-config.h, src/server/server-config.c (WHITESPACE): Changed type from const unsigned char* to const char* to remove some compiler warnings. * src/libraries/libmisc/s-string.h, src/libraries/libmisc/s-string.c (s_usr_strcmp): Changed type of collat_tab argument from char to unsigned char. (s_usr_strhead): Ditto. * src/libraries/libcommon/parser.h, src/libraries/libcommon/parser.c (match): Changed type of collat_tab argument from char to unsigned char. (parse): Ditto. * src/server/regex-match.c (lookup_regexp): Cast the "pattern" argument of re_compile_pattern to char* to get rid of a warning. (lookup_regexp): Cast the "string" argument of re_search to char* to get rid of a warning. * src/server/aux-items.c (aux_item_definition_cache_regexp): Don't set the translate field of the pattern buffer to DEFAULT_COLLAT_TAB. That causes a warning. The field is anyhow set to NULL on the next line, as it should be. (aux_item_validate): Cast the "string" argument of re_search to char* to get rid of a warning. 2002-10-04 Per Cederqvist Xenofarm refinements. * scripts/xenofarm.sh: Remove makewarn.txt and ckprgwarn.txt if they are empty. Create ckprgfail.txt and cause the ckprg steg to fail if the string "error" is found in the output (case insensitive). Change s_free() to s_clear() in comments in s-string.h. * src/libraries/libmisc/s-string.h: Two comments mentioned s_free(), but the actual name of the function is s_clear(). Fixed the comments. 2002-10-02 Per Cederqvist Watch for runtest problems. * scripts/xenofarm.sh: Added "error" to the list of strings that should cause ckprg to flag a warning. Remove warnings about unused libraries from the test suite. * src/server/testsuite/test-l2g.c (main): Call link_ansi(). * src/server/testsuite/Makefile.am (test_l2g_LDADD): Removed $(LDADD). Added libmisc.a, liblyskom-server.a and libansi.a. (LDADD): Removed. The bignum program doesn't need any of this, and test-l2g only needs parts of it. (INCLUDES): Added libansi. 2002-10-02 Per Cederqvist Port to the ecc compiler. * acinclude.m4 (CMOD_C_ATTRIBUTE_UNUSED): Improve the test, by checking that __attribute__((unused)) is accepted in a function declaration. The ecc compiler on Linux/ia64 seems to accept it and give a warning when used on a local variable, but chokes on it when used in a function declaration. * scripts/xenofarm.sh: Ignore a warning created by __attribute__((format)) when compiling with ecc. Get more info from Xenofarm builds. * scripts/xenofarm.sh: Retrieve config.log and src/libraries/libisc-new/config.log. 2002-10-01 Per Cederqvist Doc fix. * doc/man/dbck.8: Refer to lyskomd.info, not dbck.info. 2002-09-28 Per Cederqvist Xenofarm warning handling. * scripts/xenofarm.sh: Fixed a warning regexp. 2002-09-19 Per Cederqvist Get rid of a warning. Xenofarm warning handling. * src/server/conference.c (do_lookup): Introduce a new variable letterflag to get rid of a compiler warning from gcc-2.7.2.2 on AIX. * scripts/xenofarm.sh: Check for warnings during configure and ckprg. Ignore a few more warnings during make. 2002-09-10 Per Cederqvist Remove warnings about unused libraries. * src/server/updateLysKOM.c (main): Call link_ansi(). * src/server/splitkomdb.c (main): Call link_ansi(). * src/server/ramkomd.c (main): Call link_ansi(). * src/server/komrunning.c (main): Call link_ansi(). * src/server/dbck.c (main): Call link_ansi(). * src/server/Makefile.am (INCLUDES): Added libansi. (lyskomd_LDADD): New variable. (dbck_LDADD): New variable. (LDADD): Removed several libraries that the other programs don't use. * src/libraries/libansi/empty.c (link_ansi): New function. (neveruse): Removed. * src/libraries/libansi/Makefile.am (libansi_a_SOURCES): Added linkansi.h. * src/libraries/libansi/linkansi.h: New file. (link_ansi): New function. Ignore a warning from . * scripts/xenofarm.sh: Ignore a harmless warning from /usr/include/sys/vnode.h. 2002-09-09 Per Cederqvist Port to SunOS 4.1.1_U1 which lacks rlim_t. * configure.in: Check for rlim_t. * src/server/ramkomd.c [!HAVE_RLIM_T]: typedef rlim_t to int. No wonder locksuite.py failed: it wasn't distributed! * src/server/testsuite/Makefile.am (EXTRA_DIST): Added locksuite.py. Sorted the lines. Xenofarm went amok on some computers, where locksuite.py fails. * src/server/testsuite/config/unix.exp (obtain_lock): Don't loop forever if we get an unexpected eof from locksuite.py. 2002-09-09 Per Cederqvist Lock the test suite so that only one run at a time is performed. * src/server/testsuite/config/unix.exp (lock_count): New variable. (obtain_lock): New proc. (release_lock): New proc. (l2g_start): Get the lock. (l2g_stop): Release it. (lyskomd_start): Get the lock. (lyskomd_fail_start): Get and release the lock. (lyskomd_death): Release it. (client_start_fail): Get and release the lock * src/server/testsuite/lyskomd.0/11.exp: Release the lock. 2002-09-08 Per Cederqvist Prepare for locking the test suite. * src/server/testsuite/config/unix.exp (clientport): Comment updated. * src/server/testsuite/locksuite.py: New file. This is a basic building block for preventing simultaneous test runs on the same computer or in the same directory. Get rid of some compiler warnings. * src/include/kom-types.h (Info): Change highest_aux_no from long to unsigned long, since that is what aux_item_list_add_items() wants it to be. * configure.in: Check for crypt only if crypt isn't found in libc. More Xenofarm improvements. * scripts/xenofarm.sh: Include config.h in the result package. Ignore warnings about duplicate volatile. These are due to AIX apparently including volatile in sig_atomic_t. 2002-09-07 Per Cederqvist Better support for building multiple configurations under Xenofarm. * scripts/xenofarm.sh: Implement --cfg option. Removed special setup for moria. Tweak types and add a few casts to get rid of several gcc warnings. * src/server/splitkomdb.c (copy_file): Changed type of sz from int to size_t to get rid of compiler warnings. * src/server/simple-cache.c (init_cache): Replaced "i" with "ic" and "it" to get rid of warnings when the wrong type was used. * src/server/ramkomd.c (initialize): Added casts to remove warnings. * src/server/ram-parse.c (fparse_aux_item_link): Added cast to remove warning. * src/server/prot-a.c (prot_a_parse_packet): Added cast to remove warning. * src/server/local-to-global.h (l2g_set_block_size): Comment updated. * src/server/local-to-global.c (l2g_append): Added cast to remove warning. (l2g_expensive_set): Ditto. (l2g_expensive_set): Ditto. * src/server/dbck.c (motd_of_lyskom): Now a Text_no, not int. (main): Use atol, not atoi, when setting motd_of_lyskom. * src/server/dbck-cache.c (next_free_num): Change type to Conf_no. Added static qualifier. (cache_sync_all): Replaced the local variable "i" with "ic" and "it", for loops over conferences and texts. (init_cache): Changed type of "i" to unsigned long. Changed type of motd_of_lyskom to Text_no. * src/server/connections.h, src/server/connections.c (num_fnc_defs): Change type to int. Make Xenofarm ignore a few warnings in code that we didn't write. * scripts/xenofarm.sh: Ignore warnings from aux-item-def-scan.c about defined stuff that isn't used. This is an auto-generated file, and we can't help that it includes a few unused labels and functions. Ignore warning from getopt about a function declaration that isn't a prototype. Ignore cast warnings in . 2002-09-04 Per Cederqvist Fix bugs in last commit. * scripts/xenofarm.sh: More portable handling of "(W)". Process all options, not just the first. 2002-09-03 Per Cederqvist Xenofarm improves. Adapt. * scripts/xenofarm.sh: Handle the --compat option. Handle compilers that flag warnings with the string "(W)". 2002-08-25 Per Cederqvist Create Xenofarm warning indications. * scripts/xenofarm.sh: Check for warnings during the build. 2002-08-24 Per Cederqvist * NEWS: Updated. 2002-08-23 Per Cederqvist Remove false xenofarm failures. * scripts/xenofarm.sh: Run without optimization and with an old version of gcc, to make valgrind more happy. Port to Solaris 2.4. * src/server/connections.c (login_request): Don't use snprintf. It's not portable. 2002-08-22 Per Cederqvist Compile with more than one compiler on Xenofarm. * scripts/xenofarm.sh: Take an optional argument: the name of the compiler to use. Include it in machineid.txt, and pass it to the configure script. Solaris 2.4 porting. * src/libraries/libmisc/s-collat-tabs.c, src/libraries/libmisc/s-collat-tabs.h: (swedish_collate_tab, english_collate_tab): Use unsigned char, not signed char, to get rid of a warning from SparcWorks 5.1 under Solaris 2.4. The info about elisp-client-specific aux-items is informative only. (Bug 726). * doc/Protocol-A.texi (Aux-Item Types): Moved elisp-client-read-faq [10000] and elisp-client-rejected-recommendation [10001] to an appendix. (Client-specific Aux-Item Types): New appendix. (Document Edition History): Fixed broken @xref usage. * doc/Makefile.am (check-doc): Handle the "Client-specific Aux-Item Types" appendix. 2002-08-20 Per Cederqvist Release administrativa. * doc/Protocol-A.texi (Order of misc-info groups): Fix typo. (Document Edition History): Updated edition 10.7 according to the NEWS file from 2002-08-17. * NEWS: "common block", not "common area". 2002-08-20 Per Cederqvist Document how lines in a text are separated. Document the order of misc-info groups. * doc/Protocol-A.texi (create-text): Say "Misc-Info items", not "misc-items". (LysKOM Content Types): There should be no linefeed after the last line. (Reformattable Text (text/x-kom-basic)): Ditto. (Order of misc-info groups): New node. The test suite failed on certain slow machines. * src/server/testsuite/config/unix.exp: Increase the timeout. 2002-08-20 Per Cederqvist Code cleanup. * src/server/testsuite/config/unix.exp (lyskomd_start): Removed an unused global declaration. The test suite failed on 64-bit platforms. * src/server/testsuite/bignum.c: New program. * src/server/testsuite/Makefile.am (check_PROGRAMS): Added bignum. (bignum_SOURCES): New variable. (check-lyskomd): Depend on bignum. * src/server/testsuite/lyskomd.0/prot-a-parse-cov.exp: Use bignum to find a suitable big number. Don't include when it isn't available. * src/server/connections.c: Fix include guards for and . * src/server/ramkomd.c: Ditto. Xenofarm tweaks. * scripts/xenofarm.sh: Store error message from "import socket" in the proper log file. Run valgrind on moria. 2002-08-19 Per Cederqvist Increase test suite portability. * src/server/testsuite/lyskomd.0/18.exp (copy_aux): Don't use "file copy", since that isn't portable to old TCL versions. Fixed test suite typos. * src/server/testsuite/config/unix.exp (l2g_start): Fixed typo: ";wait" should not be part of the fail string. (lyskomd_fail_start): Ditto. (client_start): Ditto. (client_start_fail): Ditto. Xenofarm refinements. * scripts/xenofarm.sh: Don't bother running the tests of python cannot import socket. 2002-08-18 Per Cederqvist Increase test suite portability. * src/server/testsuite/lyskomd.0/18.exp (copy_aux): Don't use "file delete", since that isn't portable to old TCL versions. Make the Xenofarm result pages more readable. * scripts/xenofarm.sh: Shorten the header names. Break out "dvi" and "pdf" from Xenofarm task "checkdoc". * scripts/xenofarm.sh: Make check-doc, pdf and dvi separately, instead of using the "make check" target of the doc subdirectory. Don't attempt to "make pdf" unless we find pdftex. Don't attempt to "make dvi" unless we find texi2dvi and tex. 2002-08-17 Per Cederqvist Don't require "grep -f" and "tac" to check the documentation. * doc/filterlines.py: New file, that we can use instead of the non-portable "grep -v -f ...". * doc/tac.py: New file, that replaces the "tac" program. * doc/Makefile.am (check-doc): Use filterlines.py instead of "grep -v -f ...". Adjust the contents of several temporary files accordingly: they now contains lines to ignore, not regexp patterns to ignore. Use tac.py instead of tac; not everybody has GNU textutils installed. (EXTRA_DIST): Added filterlines.py and tac.py. * scripts/xenofarm.sh (checkdocok): "grep -f" and tac are no longer required to "make check" in the doc subdirectory. Xenofarm refinements. * scripts/xenofarm.sh: Attempt to identify the version of the C compiler and the makeinfo program. Flag automatically generated files. * src/server/testsuite/lyskomd.0/gen-15.py: Insert a warning in the output that the result is automatically generated. * src/server/testsuite/lyskomd.0/gen-19.py: Ditto. * src/server/Makefile.am (aux.h): Se the mode of this generated file to 444, to avoid accidental edits. Portability fix. * configure.in: Use "test x && test y" instead of "test x -a y", since the -a option is less portable than the "&&" construct. Update copyright headers. * : update the year in the copyright notice. * scripts/lyskomd-copyrights: Updated the list of files to ignore. * src/server/testsuite/renumber.el: Copyright header added. Xenofarm integration. * scripts/xenofarm.sh: New file. This version was taken from revision 1.9 of projects/lyskom-server/source-transform.sh in the xenofarm CVS module, and a copyright header and some initial comments were added. * scripts/Makefile.am (EXTRA_DIST): Added xenofarm.sh. * Makefile.am (ident-cc): New target. * doc/Makefile.am (ident-makeinfo): New target. Release administrativa. * HACKING: Mention gpg, the paths of the FTP an WWW servers, a few web pages, and Freshmeat. * NEWS: Updated for the upcoming 2.0.7 release. This is only a first draft and needs more work. 2002-08-16 Per Cederqvist Portability fixes. * doc/Makefile.am (check-doc): Use "diff -c" instead of "diff -u" for increased portability. * HACKING: Use bison 1.35. Bison 1.28 produces a file that fails on AIX. Fix Texinfo error. * doc/Makefile.am (protocol-a.texi): Use '@"a', not '@"a{}', when substituting IAM. * doc/Protocol-A.texi (IAM): Use '@"a', not '@"a{}'. * doc/constructs.expected: @"a{} is no longer used. "make check" / Python 1.5 compatibility fixes. * doc/checkargs.py (lexer.__init__): Use string.split for Python 1.5 compatibility. (number_suffixed): Don't use "".startswith. (isalpha): New function. Use it instead of "".isalpha. (isdigit): New function. Use it instead of "".isdigit. (isupper): New function. Use it instead of "".isupper. (islower): New function. Use it instead of "".islower. (isspace): New function. Use it instead of "".isspace. (prot_a_bitstring.check_implemented): Old Python versions cannot loop over a dictionary; add an explicit call to the .keys() method. (lexer.__init__): Use string.strip instead of "".strip. Dump info about existing sessions to a file specified by "Connection status file:". (Bug 706). * src/server/connections.h (Connection): Added the "peer" field. * src/server/connections.c (dump_connections): New function. (check_kill_flg): Call dump_connections if any connection was killed. (login_request): Set the "peer" field. * src/server/internal-connections.h (dump_connections): New function. * src/server/internal-connections.c (kill_client): Free the "peer" field. * src/server/server-config.c (parameters): Added "Connection status file" and "Connection status temp file". (read_configuration): Handle them. * src/server/param.h (struct kom_par): Added connection_status_file and connection_status_file_tmp. * doc/lyskomd.texi (Parameters): New parameters: "Connection status file:" and "Connection status temp file:". 2002-08-15 Per Cederqvist "make check" may now work with Python 1.5. * doc/checkargs.py (prot_a_type.use): Don't use +=. (reader.getc_eofok): Ditto. (lexer.toplevel_rarg): Ditto. (lexer.toplevel_aarg): Ditto. "make check" should no longer require gawk. * doc/Makefile.am (.texi.notab): Use $(AWK), not gawk. At least some other awk implementations supports this script. 2002-08-14 Per Cederqvist Makefile bug fixed. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Fixed a makefile syntax error. 2002-08-13 Per Cederqvist * HACKING: Updated version number of automake. Mention Xenofarm. 2002-08-11 Per Cederqvist Distribution cleanup. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added 21.exp, 22.exp, 23.exp, 24.exp, 25.exp, 26.exp, 27.exp, 28.exp, bug-145.exp, bug-225.exp, bug-349.exp, bug-37-2.exp, bug-37-3.exp, bug-37-4.exp, bug-37.exp, bug-38.exp, bug-598-2.exp, bug-598.exp, bug-612.exp and bug-84.exp. * doc/Makefile.am (MOSTLYCLEANFILES): Added TeX temp file regarding protocol-a.texi, and protocol-a.texi. (DISTCLEANFILES): Added Protocol-A.pdf. (Protocol-A.dvi): Fix the TEXINPUTS setting so that a VPATH compile works. (Protocol-A.pdf): Ditto. Update version numbers. * configure.in: Set version 2.0.7. * versions (SERVER-VERSION): 2.0.7. (SERVER-COMPAT-VERSION): 20007. * doc/Protocol-A.texi (PROTOEDITION): Set to 10.7. (VERSION): Set to 2.0.7. Document "language" in the common area. (Bug 124). Fix grammar of common area. * doc/Protocol-A.texi (The User Area): The description of the common block grammar contained many errors. State that everything is encoded as HOLLERITHs, and that they in turn contain datatypes. Removed "list" and "elems"; added "string-list". Added the "language" setting. * doc/constructs.expected: Updated. * doc/checkargs.py (lexer.toplevel_copying): Ignore. (lexer.toplevel_quotation): Ignore (lexer.toplevel_insertcopying): Ignore. Make it possible to disable DNS lookups. Log DNS lookups that takes too long. (Bug 627). * src/server/server-config.c (parameters): Removed "Y2K Compatibility". Added "Use DNS" and "DNS log threshold". * doc/lyskomd.texi (Parameter Types): Document "double". (Parameters): New parameters: "Use DNS:" and "DNS log threshold:". * src/server/param.h (struct kom_par): Added use_dns and dns_log_threshold. Removed y2k_compat. * src/server/connections.c (get_host_name): New function. (login_request): Use get_host_name. (logout_request): Ditto. * src/server/conf-file.h, src/server/conf-file.c (assign_double): New function. 2002-08-10 Per Cederqvist Fix documentation of privilege bits create-conf and create-pers. (Bug 688). * doc/Protocol-A.texi (Security): create-conf and create-pers are normally not assigned. Added a footnote that says that they are normally not needed, either. * src/server/testsuite/lyskomd.0/27.exp: Removed references to bug 688. Check for ar. (Bug 523). * configure.in: Check for ar. Look in $PATH:/usr/ccs/bin, and stop with an error if no ar can be found. Avoid duplicating the license in Protocol-A.texi. (Bug 441). * doc/Protocol-A.texi: Use the new @copying and @insertcopying commands, to avoid repeating the copyright information. (About this document): New node, that makes the copyright information visible in Info and HTML. Fix the parser so that negative numbers are rejected. Don't pretend that the protocol base will ever be anything but ten. (Bug 225). * src/libraries/libmisc/s-string.h: (s_strtol): Removed the base argument. * src/libraries/libmisc/s-string.c (char2digit): Removed the base argument. Simplified the code. This should be faster now. (s_strtol): Removed the base argument. Don't allow leading '+' or '-' signs. This simplifies the code. * src/server/prot-a-parse.c (prot_a_parse_long): Removed the base argument of s_strtol. (prot_a_parse_string): Ditto. * src/server/aux-items.c (aux_item_trigger_mark_text): Removed the base argument of s_strtol. (aux_item_trigger_unmark_text): Ditto. (aux_item_trigger_mirror_faq): Ditto. (aux_item_validate_existing_text): Ditto. * src/include/kom-config.h (PROTOCOL_NUMBER_BASE): Removed. * src/server/testsuite/lyskomd.0/prot-a-parse-cov.exp: Updated, now that the parser no longer accepts negative numbers. * src/server/testsuite/lyskomd.0/bug-225.exp: Test bug 225. Fix references to dbck documentation. (Bug 386). * doc/lyskomd.texi (Parameters): Don't refer to dbck.info, since that document is now part of lyskomd.texi. (Administration): Ditto. Fix error codes for query-read-texts, query-read-texts-old and sub-member. (Bug 161, Bug 703, Bug 43 and Bug 612). * src/server/person.c: "kom-errno.h" must now be included before "manipulate.h". (do_query_read_texts): Fix error code computations. Previously, ENA(admin,4) was needed. Now, ENA(admin,2) or ENA(wheel,8) is enough. (Bug 161 & Bug 703). * src/server/membership.c (enum memb_visibility): Moved to manipulate.h. (membership_visible): No longer static. (sub_member): Improve error code computations. (Bug 612 & Bug 43). * src/server/manipulate.h (enum memb_visibility): Moved here from membership.c. (membership_visible): Now exported from membership.c. (set_conf_errno): New function. * src/server/conference.c: "kom-errno.h" must now be included before "manipulate.h". (set_conf_errno): New function. * src/server/admin.c: "kom-errno.h" must now be included before "manipulate.h". * src/server/aux-items.c: Ditto. * src/server/dbck.c: Ditto. * src/server/send-async.c: Ditto. * src/server/server-config.c: Ditto. * src/server/session.c: Ditto. * src/server/standalone.c: Ditto. * src/server/text.c: Ditto. * src/server/testsuite/lyskomd.0/27.exp: Bug 703 is fixed. * src/server/testsuite/lyskomd.0/bug-37-4.exp: Bug 703 is fixed. * src/server/testsuite/lyskomd.0/bug-612.exp: Test cases for bug 612. * doc/Protocol-A.texi (sub-member): Document the value of error-status for permission-denied errors. get-membership and get-membership-old didn't always honor unread-is-secret. (Bug 607). (Bug 608). * src/server/membership.c (copy_public_confs): New argument: pers_no. Caller updated. Use membership_visible to simplify code and fix bugs 607 and 607. * src/server/testsuite/lyskomd.0/bug-37-3.exp: Bug 607 and bug 608 are now fixed. * src/server/testsuite/lyskomd.0/bug-37-4.exp: Ditto. get-members and get-members-old leaks secret persons (Bug 705). * src/server/membership.c (membership_visible): New arguments: is_supervisor_of_member, is_supervisor_of_conf. Callers updated. Avoid calling access_perm if possible. Grant full access if ENA(admin,2) or ENA(wheel,8), as do_get_members did. (do_get_members): Use membership_visible to simplify code, and fix bug 705. * src/server/testsuite/lyskomd.0/bug-37.exp: Bug 705 fixed. Minor doc fix. * doc/Protocol-A.texi (Membership visibility): Markup fixed. * doc/constructs.expected: Updated. Fix membership visibility for get-unread-confs. (Bug 597). * src/server/membership.c (enum memb_visibility): New enum. (check_unread): New static function. (membership_visible): New static function, that fully implements the membership visibility rules that were documented 2002-08-07. (get_unread_confs): Use membership_visible to simplify the code and use the correct membership visibility rules. Various code cleanup. * src/server/testsuite/lyskomd.0/bug-37-2.exp: get-unread-confs is now better. Bug 597 fixed. * src/server/testsuite/lyskomd.0/bug-37.exp: get-unread-confs now fails in a different, and better, way for secret persons. * src/server/testsuite/lyskomd.0/27.exp: query-read-texts-old, query-read-texts and get-unread-confs should not censor the secret conference, since the viewer is supervisor of the member. 2002-08-08 Per Cederqvist Comment added. * src/server/membership.c (sub_member): Added comments for bug 612. Code cleanup: remove global define of SMALLOC_MAGIC_ALLOC and SMALLOC_MAGIC_FREE. (Bug 562). * src/server/ram-smalloc.c (SMALLOC_MAGIC_ALLOC): Moved here from smalloc.h. Only define if USE_MALLOC_GUARDS is true. (SMALLOC_MAGIC_FREE): Ditto. * src/include/server/smalloc.h (SMALLOC_MAGIC_ALLOC): Moved to ram-smalloc.c. (SMALLOC_MAGIC_FREE): Ditto. Test membership visibility in get-members-old and get-members. * src/server/testsuite/lyskomd.0/bug-37.exp: Test get-members-old and get-members. * src/server/testsuite/lyskomd.0/bug-37-2.exp: Ditto. * src/server/testsuite/lyskomd.0/bug-37-3.exp: Ditto. * src/server/testsuite/lyskomd.0/bug-37-4.exp: Ditto. 2002-08-07 Per Cederqvist Documented membership visibility. (Bug 693). * doc/Protocol-A.texi (Membership visibility): New chapter. * src/server/testsuite/lyskomd.0/bug-37-3.exp: Updated for new membership visibility rules. * src/server/testsuite/lyskomd.0/bug-37-4.exp: Ditto. 2002-08-06 Per Cederqvist Fix some "make maintainer-clean" lossage. * src/server/Makefile.am (aux-item-def-scan.o): Added an explicit dependency on aux-item-def-parse.h. * Makefile.am (DISTCLEANFILES): Added config.cache. 2002-08-02 Per Cederqvist More valgrind integration. * src/server/testsuite/config/unix.exp (check_valgrind): Remove boring valgrind logfiles. 2002-08-02 David Byers Add missing test cases for bug 84. * src/server/testsuite/config/prot-a.exp (kom_delete_text): New function. Use to delete a text from the test suite. * src/server/testsuite/lyskomd.0/bug-84.exp: Added missing test cases for bug 84 and one xfail for bug 690. 2002-08-02 Per Cederqvist Work around a race condition in the test suite. * src/server/testsuite/lyskomd.0/18.exp: Sleep six seconds to work around a race condition (Bug 692). Suppress errors from regex.c. Handle simultaneous runs of lyskomd and dbck. * src/server/testsuite/lyskomd.supp: New file for valgrind. This contains a suppression for bug 691. * src/server/testsuite/config/unix.exp (l2g_start): Pass a log file name to the valgrind wrapper. (dbck_run): Ditto. (spawn_lyskomd): New argument: log file name. All callers updated. Use the lyskomd.supp valgrind suppressions file. Pass --show-reachable=yes and a log file name to valgrind. (check_valgrind): New arguments: logfile, need_leaks and need_errs. All callers updated. * src/server/testsuite/Makefile.am (valgrind.wrap): Expect the log file name as the first argument. (EXTRA_DIST): Added lyskomd.supp. Make it possible to run lyskomd without malloc guard areas. * configure.in: Added --disable-malloc-guards. This is useful when combined with --with-valgrind, but should not be used in a production setting. * src/server/ram-smalloc.c: Document our guard areas, and make them optional. (OVERHEAD): New macro, that computes a size including the guard area overhead. Two versions, depending on if USE_MALLOC_GUARDS is defined or not. (smalloc): Reindent. Test USE_MALLOC_GUARDS. (sfree): Test USE_MALLOC_GUARDS. (srealloc): Test USE_MALLOC_GUARDS. Fixed a read past the end of a buffer. * src/libraries/libmisc/s-string.c (s_strtol): When a string containing only whitespace was passed to s_strtol, s_strtol would attempt to read the sign ('+' or '-') past the end of the string. Fix the l2g test cases. * src/server/testsuite/l2g.0/00.exp: Destroy all structures before exit, so that the leak check of valgrind works properly. * src/server/testsuite/l2g.0/01.exp: Ditto. * src/server/testsuite/l2g.0/02.exp: Ditto. * src/server/testsuite/l2g.0/03.exp: Ditto. * src/server/testsuite/l2g.0/04.exp: Ditto. * src/server/testsuite/l2g.0/05.exp: Ditto. * src/server/testsuite/l2g.0/06.exp: Ditto. * src/server/testsuite/l2g.0/07.exp: Ditto. * src/server/testsuite/l2g.0/08.exp: Ditto. * src/server/testsuite/l2g.0/09.exp: Ditto. * src/server/testsuite/l2g.0/10.exp: Ditto. Valgrind refinements. * src/server/testsuite/config/unix.exp (spawn_lyskomd): Use valgrind.wrap. (l2g_start): Use valgrind. (l2g_stop): Check valgrind output. (lyskomd_fail_start): Use valgrind. (check_valgrind): Ensure that the memory report is seen. (dbck_run): Use valgrind. * src/server/testsuite/Makefile.am (valgrind.wrap): New target. Since valgrind can only send the log to a specified file descriptor, and expect cannot open a specified file descriptor, we have to use a wrapper for valgrind. (noinst_DATA): Added valgrind.exp. (MOSTLYCLEANFILES): Added valgrind-*.log, valgrind.log and valgrind.wrap. (check-l2g): Depend on valgrind.wrap. (check-lyskomd): Ditto. (check-leaks): Ditto. Plug a memory leak. * src/server/aux-items.c (aux_item_definition_cache_regexp): Call regfree() when a regex compilation fail, since our re_compile_pattern may leave allocated stuff in the buffer. Improved valgrind support. * configure.in: Remove all remnants of the purify support, since it was broken when we switched to automake. Added valgrind support. * src/server/testsuite/.cvsignore: Ignore valgrind-*.log. * src/server/testsuite/Makefile.am (site.exp): Set valgrind. * src/server/testsuite/config/unix.exp: Use the "valgrind" variable from site.exp. It contains a the path name of the valgrind binary to use. (spawn_lyskomd): Adjust accordingly. Don't use -v. (check_valgrind): New argument: expected_leaks. (lyskomd_death): Pass the new optional argument "expected_leaks" to check_valgrind. Note a memory leak. * src/server/testsuite/lyskomd.0/regexp-match-cov.exp: Bug 689 is a hard-to-fix memory leak. Mark it as an expected failure. (shutdown): Pass info about expected leaks to lyskomd_death. * src/server/testsuite/lyskomd.0/aux-items-cov.exp: This triggers a hard-to-fix memory leak (Bug 689). Shut up valgrind. * src/server/memory.c (init_person): Clear the pwd field. This way, we avoid writing junk to the database file, and we make valgrind happy. The junk was never used, so this is not a bugfix. Test suite fix. * src/server/testsuite/lyskomd.0/27.exp: Use idholl where appropriate. Fix a minor memory leak. * src/server/aux-items.c (free_aux_item_definitions): Fixed a memory leak. We have to call regfree() to deallocate stuff within the compiled regular expression. This bug was found with valgrind. Added some valgrind support. (Bug 514). * src/server/testsuite/config/unix.exp: Handle the VALGRIND command line argument. (spawn_lyskomd): New proc, that knows how to use valgrind. (lyskomd_fail_start): Use spawn_lyskomd. (parse_valgrind_leak): New proc. (check_valgrind): New proc. (lyskomd_death): Call check_valgrind. 2002-08-01 Per Cederqvist Minor doc fix. * doc/Protocol-A.texi (Preface): Fix markup. * doc/constructs.expected: Updated. 2002-07-31 Per Cederqvist Updated send-comments-to [33] so that it now allows an optional recipient type. * run-support/aux-items.conf: Updated send-comments-to [33]. * doc/Protocol-A.texi (Aux-Item Types): Ditto. * src/server/testsuite/lyskomd.0/23.exp: Refer to 28.exp. * src/server/testsuite/lyskomd.0/28.exp: Test the aux-item send-comments-to (33) with a specified recipient type. More membership visibility tests. * src/server/testsuite/lyskomd.0/27.exp: Test basic visibility of a secret conference for the supervisor of a member. Version 2.0.6 of lyskomd passes the test as written. 2002-07-22 Per Cederqvist Fix typo in Protocol A example. * doc/Protocol-A.texi (re-z-lookup): Fixed ref-id error in example. Thanks to Joorin for pointing it out. (Preface): Mention that bugs should be reported via Bugzilla. 2002-06-22 Per Cederqvist New membership-related tests. * doc/Protocol-A.texi (Person Status Types): Explicitly say that the supervisor of a person bypasses the unread-is-secret bit. * src/server/testsuite/lyskomd.0/bug-37-4.exp: New test cases. Like bug-37.exp, but let the observer be supervisor of all conferences, and let all memberships be secret. * src/server/testsuite/lyskomd.0/bug-37-3.exp: New test cases. Like bug-37.exp, but let the observer be supervisor of all conferences. * src/server/testsuite/lyskomd.0/bug-37-2.exp: Don't set the flg3 flag of the Personal-Flags. Removed a comment. * src/server/conference.c (set_conf_type): David Byers is no longer a supporter of secret persons, so remove a comment that states that he is. 2002-06-15 Per Cederqvist get_unread_confs no longer censors rd-prot conferences. (Bug 596). * src/server/membership.c (get_unread_confs): It is sufficient that the viewer has read_protected access to a conference for it to be returned. * src/server/testsuite/lyskomd.0/bug-37.exp: Bug 596 is fixed. This also causes two other tests to fail in a different way. * src/server/testsuite/lyskomd.0/bug-37-2.exp: Adjusted to the resolution of bug 596. This only affects how certain tests fails. Don't lose the array size of get-membership and get-membership-old. (Bug 598). * src/server/membership.c (copy_public_confs): Removed the "copy_secret" argument. Simplify the code, and don't lose the array size just because want_read is false. * src/server/testsuite/lyskomd.0/bug-598.exp (want_array_size): Don't expect failure. Added test cases for bug 598: get-membership and get-membership-old sometimes drops the array size. * src/server/testsuite/lyskomd.0/bug-598.exp: New file. Test bug 598. * src/server/testsuite/lyskomd.0/bug-598-2.exp: A version of the bug-598.exp test with unread-is-secret set. Fixed minor doc error. * doc/Protocol-A.texi (get-membership-old): Fixed error in description of index-out-of-range. (get-membership): Ditto. * doc/constructs.expected: Updated. Introduce good_bad_expect, for trapping XFAIL situations nicely. * src/server/testsuite/config/unix.exp (good_bad_expect): New proc. * src/server/testsuite/renumber.el (renumber-lyskom-send-simple-expect): Handle good_bad_expect. Write a test cases for bug 37. * src/server/testsuite/lyskomd.0/bug-37.exp: New test case for bug 37. Bugs 593, 594, 595 and 596 were found while writing this test case... * src/server/testsuite/lyskomd.0/bug-37-2.exp: Like bug-37.exp, but with all memberships being secret. Found bug 597. Document unread-is-secret. (Bug 593). * doc/Protocol-A.texi (Person Status Types): Added a reference to Security, for an explanation of the privileges. Document the bits in Personal-Flags. (Membership Information): Document how unread-is-secret affects some parts of Membership and Membership-Old. Added a test case for bug 349. * src/server/testsuite/lyskomd.0/bug-349.exp: Test case for bug 349: wrong error code from set_supervisor. 2002-06-14 Per Cederqvist Document the Message-ID format of exported texts. (Bug 574). * doc/Protocol-A.texi (Importing and Exporting E-Mail): Document the Message-ID format of exported texts. Remove autoconf-2.53 warning. * configure.in: Use all three arguments of AC_DEFINE. * acinclude.m4 (CMOD_C_ATTRIBUTE_UNUSED): Use all three arguments of AC_DEFINE. * acconfig.h: File removed. 2002-05-20 Per Cederqvist Minor doc fix. * doc/Protocol-A.texi (Client-Server Dialog): Don't mention feature-disabled twice. 2002-05-07 David Byers * Updated message from 2002-04-11. 2002-04-14 David Byers * doc/Protocol-A.texi (Aux-Item Types): Documented elisp-client-read-faq and elisp-client-rejected-recommendation. 2002-04-13 David Byers Test for fix of bug 145: * src/server/testsuite/config/prot-a.exp (kom_delete_conf): New function. (kom_lookup_z_name): New function. 2002-04-12 David Byers Fix bug 145: * src/server/conference.c (do_delete_conf): Removed lines that cleared the name of the conference. That is done in cached_delete_conf. Fix bug 38: * src/server/testsuite/lyskomd.0/bug-38.exp: New file. * src/server/testsuite/config/prot-a.exp (kom_set_user_area): New function. (kom_shutdown_server): New function. (kom_create_text_simple): New function. (cres): The else branch which does eval actually works now. Made ref_no global in this function. * src/server/person.c (do_set_user_area): Copied check for read access to new user area from get_text_stat. Fix bug 331: * src/server/testsuite/lyskomd.0/03.exp: Use idholl and lyskomd_host for hostname-dependend strings. * src/server/testsuite/lyskomd.0/16.exp: Use idholl and lyskomd_host for hostname-dependend strings. * src/server/testsuite/lyskomd.0/01.exp: Use idholl and lyskomd_host for hostname-dependend strings. * src/server/testsuite/lyskomd.0/00.exp: Use idholl and lyskomd_host for hostname-dependend strings. * src/server/testsuite/config/unix.exp (idholl): New function to create hollerith with at sign and name of localhost appended. (lyskomd_server): New variable containing the name of this host. 2002-04-11 David Byers * src/server/aux-items.c (aux_item_trigger_mirror_faq): Don't just return when the object type is INFO_OBJECT_TYPE (which represents server aux-items). Instead, create the mirror aux-item as required by the protocol. * configure.in: Added AC_PREREQ. 2002-04-07 Per Cederqvist Added the world-readable aux item. (Bug 5). * run-support/aux-items.conf: Added world-readable [34]. * src/server/text.c (person_text_read_access): Give everybody read access to texts with a world-readable aux-item. * doc/Protocol-A.texi (Aux-Item Types): New aux-item: world-readable. (get-text): Mention the world-readable aux item under the no-such-text error code. (get-text-stat-old): Ditto. (get-text-stat): Ditto. * src/server/testsuite/lyskomd.0/01.exp: Handle world-readable. * src/server/testsuite/lyskomd.0/03.exp: Ditto. * src/server/testsuite/lyskomd.0/18.exp: Ditto * src/server/testsuite/lyskomd.0/26.exp: Test world-readable. 2002-04-06 Per Cederqvist Use symbolic names for aux item tags. * src/server/aux-items.c (aux_item_trigger_mirror_faq): Use aux_faq_for_conf from aux.h instead of a hardcoded 28. * src/server/Makefile.am (aux.h): New target. (MOSTLYCLEANFILES): Added aux.h. (NODIST_GENOBJS): Added aux.h. (BUILT_SOURCES): Added aux.h. (version.incl): Fixed spelling error. (version-info.c): Ditto. 2002-04-02 Per Cederqvist Fix the documentation of no-of-created-texts (Bug 384). * doc/Protocol-A.texi (Person Status Types): Fix the documentation of no-of-created-texts. (Bug 384). Clarify the description of get-person-stat-old. * doc/Protocol-A.texi (get-person-stat-old): Don't call the "username" field "name". Add markup for it. Clarify that the empty string is returned; dont say that the "name is not returned". Automake improves. * src/server/testsuite/Makefile.am (noinst_DATA): Removed a comment about an Automake deficiency that is no longer there. (Bug 208). 2002-03-29 Per Cederqvist * Release 2.0.6. Release administrativa. * doc/checkargs.py: Copyright header added. * scripts/lyskomd-copyrights: Updated. * HACKING: Updated version numbers. Mention Bugzilla. * configure.in: Set version 2.0.6. * versions (SERVER-VERSION): 2.0.6. (SERVER-COMPAT-VERSION): 20006. * README: Updated for the 2.0.6 release. * NEWS: Updated for the 2.0.6 release. * doc/Protocol-A.texi (PROTOEDITION): Set to 10.6. (VERSION): Set to 2.0.6. (Document Edition History): Document changes in edition 10.6. * doc/constructs.expected: Updated. Create PDF and DVI output from the protocol specification. * doc/Makefile.am (pdf): New target. (html): New target. (Protocol-A.dvi): New target. (Protocol-A.pdf): Use texi2dvi --pdf instead of texi2pdf. (protocol-a.texi): New target. Major hack. Expand a few of the macros so that texinfo.tex can cope with the rest. (protocol-a/index.html): New target. (.texi.notab): Use automake comments instead of /bin/sh comments. (update-www): Also depend on protocol-a/index.html, Protocol-A.dvi and Protocol-A.pdf, and install them. (check): Also depend on the targets pdf and dvi. Doc fixes. * doc/Protocol-A.texi (create-person-old): Moved a misplaced brace to its proper place. (get-text): State that ^J represents a newline in the example. (create-person-old): Move punctuation outside of quotes, according to the Texinfo style guide. 2002-03-26 Per Cederqvist Port to Cygwin. * src/server/Makefile.am (all-recursive): Added the $(EXEEXT) suffix to lyskomd and dbck, so that the makefile works on cygwin. (check-recursive): Ditto. 2002-03-24 Per Cederqvist Allow faq-text to be set on letterboxes. (Bug 423). * run-support/aux-items.conf (faq-text): Allow it on letterboxes as well as conferences and the server. * doc/Protocol-A.texi (Aux-Item Types): Document that faq-text may be set on letterboxes. * src/server/testsuite/lyskomd.0/03.exp: Set an faq-text on the letterbox of person 8. 2002-02-15 Per Cederqvist Added support for the "Jubel: public" parameter, that enforces the policy that certain texts must be created in public conferences. * src/server/testsuite/lyskomd.0/25.exp: Test public jubels. * src/server/text.c (create_text_check_misc): New argument: need_public_jubel. (struct jubel): New field: public. (register_jubel): New argument: public. (ok_to_create_next_text): New result parameter: must_be_public. (do_create_text): Check for jubels that must be public. * src/server/standalone.c (register_jubel): New argument: public. * src/server/server-config.c (jubel): Handle the new "public" form. * src/server/manipulate.h (register_jubel): New argument: public. * doc/lyskomd.texi (Parameter Types): These are standard types, not all legal types. (Parameters): Document the "public" forms of the Jubel parameters. Mention that there may be several Jubel parameters. 2002-02-11 Per Cederqvist Don't emit garbage statistics. (Bug 390). * src/server/connections.c (dump_statistics): Don't emit statistics for the dummy request used to skip unimplemented requests. Initialize the function_index field a little earlier. * src/server/prot-a.c (prot_a_init): Initialize function_index. * src/server/internal-connections.c (init_connection): Initialize function_index. Make fnc-def-init.incl look nicer. (Bug 381). * src/server/fnc-def-init.awk: Make certain that the final entry, that is only used to skip all arguments of requests that are not implemented, gets a unique number. 2002-02-10 Per Cederqvist Bugzilla affects the release procedures. * HACKING: Mention that the version number should be added to Bugzilla when releases are made. 2002-01-23 Per Cederqvist Added missing include statement. (Bug 385). * src/server/log.c: Include stdlib.h. 2002-01-18 Per Cederqvist Quote backslashes properly in Texinfo macro calls. (Bug 376). * doc/Protocol-A.texi (create-text-old): Properly quote \n in macro call. (create-anonymous-text-old): Ditto. 2002-01-03 Per Cederqvist Document that ``last-login'' is also updated on logout. * doc/Protocol-A.texi (Person Status Types): Don't forget to mention that ``last-login'' is also updated on logout. 2002-01-01 Per Cederqvist Check @field{} usage. (Bug 206). * doc/checkargs.py (defined_fields): New variable. (undefined_fields): New variable. (prot_a_struct.add_field): Handle defined_fields and undefined_fields. (prot_a_bitstring.add_field): Ditto. (lexer.toplevel_bye): Check for undefined fields. (lexer.toplevel_field): New method. * doc/Makefile.am (check): Removed a fixed FIXME comment. * doc/Protocol-A.texi (Future changes): Don't use @field{} when talking about stuff that might be a field some day in the future. Check @priv{} usage, and that all implemented Priv-Bits are documented, and vice versa. (Bug 207). * doc/Makefile.am (check): Create privbits.tmp. Check @priv{} usage. * doc/checkargs.py (lexer.__init__): Load "privbits.tmp". (lexer.toplevel_bye): Check Priv-Bits. Document the ``change-name'' capability. * doc/Protocol-A.texi (Security): Document ``change-name''. Remove the unused and undocumented privilege bit ``extern_gw''. * src/include/kom-types.h (Priv_bits): Renamed the unused bit ``extern_gw'' to ``flg7'', and reserve it for future use. * src/server/ram-parse.c (fparse_priv_bits): Parse flg7 instead of extern_gw. * src/server/ram-output.c (foutput_priv_bits): Emit flg7 instead of extern_gw. * src/server/prot-a-parse.c (prot_a_parse_priv_bits): Parse flg7 instead of extern_gw. * src/server/prot-a-output.c (prot_a_output_priv_bits): Emit flg7 instead of extern_gw. * src/server/memory.c (init_priv_bits): Initialize flg7 instead of extern_gw. * src/server/dbck.c (check_persons): Set Priv_bits flg7 instead of extern_gw. 2001-12-31 Per Cederqvist Fix documentation of error code ``client-is-crazy''. * doc/Protocol-A.texi (Error Codes): client-is-crazy is actually used, so don't say it isn't. Check @errorcode usage. * doc/Makefile.am (check): Create files for all error codes that are implemented. Check @errorcode{} usage. (Bug 205). Check that all implemented Conf_type bits are documented, and vice versa. * doc/Makefile.am (check): Don't ignore the reserved bits of Conf_type. * doc/checkargs.py (prot_a_bitstring.__init__): New method. (prot_a_bitstring.add_field): Store the field, and check for duplicates. (prot_a_bitstring.check_implemented): New method. (lexer.__init__): Read conftypes.tmp. (lexer.toplevel_bye): Check Extended-Conf-Type. (lexer.__parse_userdefined_bitstring): Be prepared that prot_a_bitstring.add_field can return an error message. Check that all implemented misc-infos are documented, and vice versa. * doc/Makefile.am (check): Create miscs-numbered.tmp based on the contents of kom-types.h. * doc/checkargs.py (prot_a_selection.check_implemented): New method. (prot_a_selection.all_names): New method. (lexer.__init__): Check that the same number isn't used twice in asyncs-numbered.tmp. Read miscs-numbered.tmp. (lexer.toplevel_bye): Check that all implemented misc-infos are documented, and vice versa. 2001-12-30 Per Cederqvist Code cleanup. (Bug 346). * src/server/aux-items.c (aux_item_default_definition): Removed left-over traces of "extended aux-items", a concept that didn't scale and was abandoned a long time ago. Document supervisors better. * doc/Protocol-A.texi (Conferences): State that a person is a supervisor of himself, except for the set-supervisor call. Fix "make check". * doc/constructs.expected: Updated. * doc/checkargs.py (lexer.pushback): Pushback @cindex. Code cleanup. * src/server/aux-items.c (conf_stat_check_add_aux_item_list): Removed confusing comment. 2001-12-29 Per Cederqvist Code cleanup. * src/server/aux-items.h, src/server/aux-items.c (prepare_aux_item): Now a static function. (filter_aux_item_list): Comment updated. Fixed typos. * doc/Protocol-A.texi (Reformattable Text (text/x-kom-basic)): Removed duplicated "as". * src/server/aux-items.c: Fixed typo in comment. 2001-12-28 Per Cederqvist Talk about character sets. (Bug 339). * doc/Protocol-A.texi (Simple Data Types): Talk a little about character sets under HOLLERITH, without saying anything definite. Check for __attribute__((__noreturn__)) support at configuration time instead of at compile time. (Bug 57). * src/include/compiler.h: Removed. * src/include/Makefile.am (noinst_HEADERS): Removed compiler.h. * configure.in: Check for __attribute__((__noreturn__)). * acconfig.h (HAVE_ATTRIBUTE_NORETURN): Added. * src/server/lyskomd.h: Don't include compiler.h. Use HAVE_ATTRIBUTE_NORETURN instead of the NORETURN symbol, that previously was defined by compiler.h. Don't include config.h twice. * src/libraries/libcommon/kom-errno.c: Don't include both and "config.h". Don't declare kom_errno and err_stat twice. (Bug 343). * src/server/ramkomd.c (kom_errno): Removed, since this is already defined in src/libraries/libcommon/kom-errno.c. (err_stat): Ditto. Use ``union result_holder'' instead of ``Result_holder''. (Bug 337). * src/server/connections.h (union result_holder): Result_holder typedef removed. * src/server/connections.c: Use ``union result_holder'' instead of ``Result_holder''. * src/server/prot-a.h: Ditto. * src/server/prot-a.c: Ditto. * doc/lyskomd.texi (Adding New Result Types): Use ``union result_holder'' instead of ``Result_holder''. (Modifying Output Types): Ditto. Use ``union info_datum instead of ``Info_datum''. (Bug 337). * src/server/manipulate.h (ADD_MISC): Use ``union info_datum instead of ``Info_datum''. * src/include/kom-types.h (union info_datum): Removed Info_datum typedef. Use ``enum kom_err'' instead of ``Kom_err''. (Bug 335). * src/libraries/libcommon/kom-errno.c: Use ``enum kom_err'' instead of ``Kom_err''. * src/server/aux-items.c: Ditto. * src/server/ramkomd.c: Ditto. * src/include/kom-errno.h (enum kom_err): Removed Kom_err typedef. Use ``enum res_type'' instead of ``Res_type''. (Bug 335). * src/server/connections.h (enum res_type): Removed the Res_type typedef. The only user updated. * doc/lyskomd.texi (Adding New Result Types): Use ``enum res_type'' instead of ``Res_type''. (Modifying Output Types): Ditto. Use ``enum log_class'' instead of ``Log_class''. (Bug 335). * src/server/logII.c (enum log_class): Removed the Log_class enum. (log): Use ``enum log_class'' instead of ``Log_class''. Use ``enum log_type'' instead of ``Log_type''. (Bug 335). * src/server/simple-cache.c (enum log_type): Removed the Log_type typedef. (log_access): Use ``enum log_type'' instead of ``Log_type''. Use ``enum aux_item_validation_type'' instead of ``Aux_Item_Validation_Type''. (Bug 335). * src/server/aux-items.h (enum aux_item_validation_type): Removed the Aux_item_validation_type typedef. The only user updated. Use ``enum call_header'' instead of ``Call_header''. (Bug 335). * src/server/connections.h: Use ``enum call_header'' instead of ``Call_header''. * src/server/prot-a.c: Ditto. * src/server/com-h.awk: Don't create the Call_header typedef. Use ``enum access'' instead of ``Access''. (Bug 335). * src/server/manipulate.h: Use ``enum access'' instead of ``Access''. (enum access): Removed ``Access'' typedef. * src/server/conference.c: Use ``enum access'' instead of ``Access''. * src/server/membership.c: Ditto. * src/server/person.c: Ditto. * src/server/text.c: Ditto. Updated a comment. * src/server/session.c (accept_async): Updated a comment that talked about ``Async'' instead of ``enum async''. Use ``enum object_type instead of ``Object_type''. (Bug 335). * src/include/kom-types.h (enum object_type): Removed Object_type typedef. All types that contain an enum object_type updated. * src/server/aux-items.c: Use ``enum object_type'' instead of ``Object_type''. * src/server/aux-items.h: Ditto. * src/server/ram-parse.c: Ditto. Use ``enum info_type instead of ``Info_type''. (Bug 335). * src/include/kom-types.h (enum info_type): Removed Info_type typedef. All types that contain an enum info_type updated. * doc/Makefile.am (check-doc): Extract ``enum info_type'' instead of ``Info_type'' from kom-types.h. * src/server/text.c (do_add_recipient): Use ``enum info_type'' instead of ``Info_type''. (send_async_sub_recipient): Ditto. (remove_misc_item): Ditto. (create_text_add_miscs): Ditto. (send_async_add_recipient): Ditto. (add_recipient): Ditto. * src/server/send-async.h, src/server/send-async.c (async_new_recipient): Use ``enum info_type'' instead of ``Info_type''. (async_sub_recipient): Ditto. * src/server/ram-parse.c (fparse_misc_info): Use ``enum info_type'' instead of ``Info_type''. * src/server/prot-a-send-async.h, src/server/prot-a-send-async.c (prot_a_async_new_recipient): Use ``enum info_type'' instead of ``Info_type''. (prot_a_async_sub_recipient): Ditto. * src/server/memory.c (clear_text_stat): Use ``enum info_type'' instead of ``Info_type''. * src/server/manipulate.h (ADD_MISC): Use ``enum info_type'' instead of ``Info_type''. * src/include/services.h (add_recipient): Use ``enum info_type'' instead of ``Info_type''. Code cleanup. * src/server/conference.c: Removed an obsolete comment. 2001-12-28 Per Cederqvist Fixed the specification of idle-time. (Bug 197). * doc/Protocol-A.texi (Session Information): The idle-time is affected only by the user-active request, not by any request. Use "C" environment when sorting test output (Bug 330). * doc/Makefile.am (check-doc): Set LANG, LC_ALL, LC_COLLATE and LC_CTYPE to "C" when running sort and uniq. BUG and BUGS comments converted into FIXMEs and entered into Bugzilla. (Bug 336). * src/server/membership.c (sub_member): Obsolete BUGS comment removed. * src/server/ram-parse.c: BUGS comment converted into FIXMEs and entered into Bugzilla. * src/server/prot-a-parse.c: BUG comment converted into FIXME and entered into Bugzilla. * src/server/conference.c: BUG and BUGS comments converted into FIXMEs and entered into Bugzilla. 2001-12-22 Per Cederqvist Use ``enum async'' instead of ``Async''. (Bug 335). * src/server/session.c (accept_async): Use ``enum async'' instead of ``Async''. * src/server/prot-a-send-async.c (async_header): Use ``enum async'' instead of ``Async''. * src/server/internal-connections.c (init_connection): Use ``enum async'' instead of ``Async''. * src/server/async.h (enum async): Removed the Async typedef. * doc/lyskomd.texi (Adding Asynchronous Messages): Use ``enum async'' instead of a typedef. The check for supervisor in modify_conf_info was broken. (Bug 309). * src/server/conference.c (modify_conf_info): Fix typo: use conf->supervisor instead of conf->super_conf. * src/server/testsuite/lyskomd.0/24.exp: Check for bug 309. Bug 334 was found while writing this test case; setup_xfail for it. Fix typo in documentation. * doc/Protocol-A.texi (modify-conf-info): Fixed typo: changed "text" to "conference". Be clearer about the default prefix. (Bug 306). * doc/lyskomd.texi (Parameter Types): Be clearer about the fact that ``Prefix:'' overrides the compile-time default. (Parameters): Ditto. Added a footnote for the first path that reiterates this fact. (DBCK Files): Added a missing colon. Document super-conf better, and simplify the rules slightly. Document permitted-submitters slighlty more. (Bug 310). * doc/Protocol-A.texi (Conferences): Added a reference to ``Recipients of comments'' under the explanation of rd-prot. (Conference Status Types): Document super-conf properly. It has two different uses. (set-permitted-submitters): Document what it means when ``permitted-submitters'' is zero, and that that setting is the default. (set-super-conf): Added a reference to ``Conference Status Types''. (The User Area): Spelling error fixed. (Recipients of comments): Simplified the rules for super-conf. A setting of 0 no longer means anything. The previous meaning wasn't implemented. 2001-12-13 Per Cederqvist Added new aux-item send-comments-to. (Bug 308). * run-support/aux-items.conf: Added send-comments-to [33]. * src/server/testsuite/lyskomd.0/01.exp: Handle send-comments-to. * src/server/testsuite/lyskomd.0/03.exp: Ditto. * src/server/testsuite/lyskomd.0/18.exp: Ditto. * src/server/testsuite/lyskomd.0/23.exp: Test suite implemented. Robustify test suite. * src/server/testsuite/config/unix.exp (extracting_expect): Set $var to the empty string even on failure, to avoid some TCL errors. 2001-12-12 Per Cederqvist Code cleanup. * src/server/testsuite/lyskomd.0/prot-a-parse-cov.exp: Removed trailing blank lines. Work on test case for new aux-item send-comments-to. * src/server/testsuite/lyskomd.0/23.exp: Check the aux-item send-comments-to (33). This is an early commit of work in process. 2001-11-25 Per Cederqvist Documentation fixes. * doc/Protocol-A.texi (Recipients of comments): Errata from Hans Persson and Per Starbäck. 2001-11-22 Per Cederqvist Documentation clarifications. * doc/Protocol-A.texi (Aux-Item Types): Clarify that the address part of redirect is a conference number, not a name. Clarify the text for send-comments-to. 2001-11-21 Per Cederqvist Add documentation for aux-item send-comments-to. * doc/Protocol-A.texi (Article Information): Mention bcc-recpt in a few places where only recpt and cc-recpt was mentioned. (Aux-Item Types): Document send-comments-to. (Bug 308). (Recipients of comments): New subsection. 2001-11-20 Per Cederqvist Document splitkomdb. Fix its usage message. (Bug 21). * doc/lyskomd.texi (Parameters): Document "Backup export directory:". (splitkomdb): New chapter. * src/server/splitkomdb.c (usage): Added the "-f" option to the usage message. 2001-11-18 Per Cederqvist Replace internal-services.h with text.h. Make sure all text in the file is in English. (Bug 150.) * src/server/Makefile.am (lyskomd_SOURCES): Removed internal-services.h. Added text.h. * src/server/text.h: New file, containing the prototype for do_delete_text(), that was moved from internal-services.h. * src/server/text-garb.c: Include text.h instead of internal-services.h. * src/server/text.c: Ditto. * src/server/ramkomd.c: Don't include internal-services.h. It isn't used. * src/server/internal-services.h: File removed. 2001-11-17 Per Cederqvist Added markup for content types. (Bug 230). * doc/Protocol-A.texi (LysKOM Content Types): Added markup for content types. (Reformattable Text (text/x-kom-basic)): Ditto. (Content type specification): Ditto. (Document Edition History): Ditto. * doc/constructs.expected: Updated. Document that the elisp-client has used the wrong content type. * doc/Protocol-A.texi (Reformattable Text (text/x-kom-basic)): Mention that the elisp client used to enter texts as "x-kom/text" instead of "text/x-kom-basic". 2001-11-16 Per Cederqvist More Bugzilla references added. * src/server/testsuite/lyskomd.0/prot-a-parse-cov.exp: Added Bugzilla reference to a FIXME-style comment that wasn't marked. 2001-11-15 Per Cederqvist Code cleanup. (Bug 166). * src/server/session.c (accept_async): Removed redundant code. * src/server/testsuite/lyskomd.0/03.exp: Comments added. 2001-11-13 Per Cederqvist Change the name of the administrator in the English database. Try to load that database from the test suite. * db-crypt/db/lyskomd-data-en: Change "Administrator (for) LysKOM" into "Administrator (of) LysKOM". (Bug 13). * src/server/testsuite/lyskomd.0/22.exp: Test that the English database is loadable. * src/server/testsuite/config/unix.exp (lyskomd_start): New optional argument: db_suffix. Test suite cleanup. * src/server/testsuite/leaks.0/leaks99.exp: Remove redundant tests. The tests in lyskomd.0 automatically check for memory leaks, so there is no need to rerun those the tests here. (Bug 219). * src/server/testsuite/leaks.0/leaks00.exp: Remove obsolete comments. (Bug 218). Fixed bogus examples in Protocol-A.texi. * doc/Protocol-A.texi (query-read-texts): Fixed the example. It was missing both the "position" and "added-at" fields. (Bug 198, reported by Kent.) (get-membership): Ditto. (Bug 223). * doc/constructs.expected: Updated. 2001-11-11 Per Cederqvist Remove some uses of rcs.h that was overlooked 2001-11-04. (Bug 140). * src/libraries/libansi/memchr.c: Don't include rcs.h. Remove rcsid variable. * src/libraries/libansi/memcmp.c: Ditto. * src/libraries/libansi/memcpy.c: Ditto. * src/libraries/libansi/memset.c: Ditto. * src/libraries/libansi/remove.c: Ditto. * src/libraries/libansi/strerror.c: Ditto. * src/libraries/libmisc/numlist.c: Ditto. * src/libraries/libmisc/numlist2.c: Ditto. * src/libraries/libmisc/testnumlist.c: Ditto. Several files didn't include . (Bug 191). * src/libraries/libansi/empty.c: Include if HAVE_CONFIG_H is defined. * src/libraries/libansi/memchr.c: Ditto. * src/libraries/libansi/memcmp.c: Ditto. * src/libraries/libansi/memcpy.c: Ditto. * src/libraries/libansi/memset.c: Ditto. * src/libraries/libansi/remove.c: Ditto. * src/libraries/libansi/setsid.c: Ditto. * src/libraries/libansi/strdup.c: Ditto. * src/libraries/libansi/strerror.c: Ditto. * src/libraries/libcommon/kom-errno.c: Ditto. * src/libraries/libcommon/misc-parser.c: Ditto. * src/libraries/libcommon/parser.c: Ditto. * src/libraries/libmisc/ldifftime.c: Ditto. * src/libraries/libmisc/numlist.c: Ditto. * src/libraries/libmisc/numlist2.c: Ditto. * src/libraries/libmisc/s-collat-tabs.c: Ditto. * src/libraries/libmisc/s-string.c: Ditto. * src/libraries/libmisc/testnumlist.c: Ditto. * src/server/Makefile.am (version-info.c): Ditto. More Bugzilla references added. * src/server/testsuite/lyskomd.0/03.exp: Removed obsolete FIXME comments. * src/server/testsuite/lyskomd.0/06.exp: Ditto. * configure.in: Added references to Bugzilla for all FIXME comments. * src/server/testsuite/l2g.0/09.exp: Ditto. * src/server/testsuite/leaks.0/leaks00.exp: Ditto. * src/server/testsuite/lyskomd.0/aux-items-cov.exp: Ditto. * src/server/testsuite/lyskomd.0/prot-a-parse-cov.exp: Ditto. Don't build libcheck.a unless we are running the test suite. * src/server/Makefile.am (check_LIBRARIES): This target was formerly named noinst_LIBRARIES, but there is no reason to build the libcheck.a library unless we are running the checks. (all-recursive): Don't depend on libcheck.a. 2001-11-10 Per Cederqvist More Bugzilla references added. * src/server/testsuite/Makefile.am: Added references to Bugzilla for all FIXME comments. 2001-11-09 Per Cederqvist More Bugzilla references added. * doc/Makefile.am: Added references to Bugzilla for all FIXME comments. 2001-11-08 Per Cederqvist More Bugzilla references added. * doc/Protocol-A.texi: Added references to Bugzilla for all FIXME comments. 2001-11-06 Per Cederqvist Code cleanup: Remove all traces of logins_allowed. (Bug 151). * src/server/session.c (login_old): Removed #if 0'd code that referenced logins_allowed. (login): Ditto. * src/server/person.c (create_person_generic): Removed #if 0'd code that referenced logins_allowed. * src/server/internal-services.h (logins_allowed): Removed declaration of this unused variable. Code cleanup. * src/server/cache-node.c (EMPTY_CACHE_NODE): Don't initialize the "snapshot" member. (Bug 100). * src/server/cache-node.h (cache_node): Removed the unused "snapshot" member. (Bug 100). 2001-11-04 Per Cederqvist Added bug tracking numbers to the expected failures in the test suite. * src/server/testsuite/lyskomd.0/14.exp: Added bug tracking numbers to the setup_xfail statements. * src/server/testsuite/lyskomd.0/20.exp: Added bug tracking numbers to the setup_xfail statements. Removed the unused pom.c and pom.h files. We don't have explicit permission to distribute them under GPL. * src/libraries/libmisc/Makefile.am (libmisc_a_SOURCES): Removed pom.h. * src/libraries/libmisc/pom.h: Removed. * src/libraries/libmisc/pom.c: Removed. Remove rcs.h and all uses of it. (Bug 140). * src/include/Makefile.am (noinst_HEADERS): Removed rcs.h. * src/include/rcs.h: Removed. * src/libraries/libcommon/kom-errno.c: Ditto. * All files: Don't include rcs.h. Remove rcsid variable. Simplify the code by breaking out loops from do_sub_comment and do_sub_footnote. * src/server/text.c (remove_misc_item): New function. (do_sub_comment): Use it to simplify code. (do_sub_footnote): Ditto. (Bug 186). Simplify the code by unifying do_add_recpt, do_add_cc_recpt and do_add_bcc_recpt. (Bug 190). * src/server/text.c (do_add_recipient): New function, that is like do_add_recpt, but with an additional Info_type argument that specifies what kind of recipient to add. (do_add_recpt): Function removed. (do_add_cc_recpt): Function removed. (do_add_bcc_recpt): Function removed. (create_text_add_miscs): Use do_add_recipient. Simplify code. (add_recipient): Ditto. Unify several fields in the Info_datum union. This makes it possible to handle recpt, cc_recpt and bcc_recpt by the same code in many places, resulting in the removal of approximately 300 lines of code. (Bug 139). * src/include/kom-types.h (Info_datum): Removed cc_recipient and bcc_recipient -- use recipient instead. Removed comment_to, commented_in, footnote_to and footnoted_in, and added text_link as a replacement. * src/server/text.c (find_recipient): Adjusted to Info_datum unification. Simplified code. (is_member_in_recpt): Ditto. (do_sub_recpt): Ditto. (is_sender): Ditto. (filter_secret_info): Ditto. (person_text_read_access): Ditto. (do_delete_text): Ditto. (check_double_subm): Ditto. (check_double_comm): Ditto. (create_text_check_misc): Ditto. (create_text_add_aux): Ditto. (is_comment_to): Adjusted to Info_datum unification. (is_footnote_to): Ditto. (do_add_footnote): Ditto. (do_add_comment): Ditto. (do_add_bcc_recpt): Ditto. (do_add_cc_recpt): Ditto. (do_sub_comment): Ditto. (do_sub_footnote): Ditto. (is_comm_sender): Ditto. (create_text_add_miscs): Ditto. * src/server/text-garb.c (garb_text): Adjusted to Info_datum unification. Simplified code. * src/server/ram-parse.c (fparse_misc_info): Ditto. * src/server/ram-output.c (foutput_misc_info): Ditto. * src/server/prot-a-parse.c (prot_a_parse_misc_info): Ditto. * src/server/prot-a-output.c (prot_a_output_misc_info): Ditto. * src/server/membership.c (add_rec_time): Ditto. * src/libraries/libcommon/misc-parser.c (parse_next_misc): Adjusted to Info_datum unification. * src/server/dbck.c (is_comment_to, is_commented_in) (is_footnote_to, is_footnoted_in): Adjusted to Info_datum unification. (is_recipient): Adjusted to Info_datum unification. Simplified code. 2001-11-03 Per Cederqvist Add references to Bugzilla for all relevant FIXME comments, and remove the others. All FIXME comments now use the same format. * src/server/aux-items.c: Added references to Bugzilla for all FIXME comments. * src/server/conference.c: Ditto. * src/server/conf-file.c: Ditto. * src/server/dbck.c: Ditto. * src/server/disk-end-of-atomic.c: Ditto. * src/server/internal-connections.c: Ditto. * src/server/internal-services.h: Ditto. * src/server/local-to-global.c: Ditto. * src/server/person.c: Ditto. * src/server/prot-a-parse.c: Ditto. * src/server/regex-match.c: Ditto. * src/server/server-config.c: Ditto. * src/server/simple-cache.c: Ditto. * src/server/text-garb.c: Ditto. * src/server/updateLysKOM.c: Ditto. * src/server/admin.c: Removed obsolete FIXME comments. * src/server/cache-node.c: Ditto. * src/server/log.c: Ditto. * src/server/session.c: Removed obsolete FIXME comments. Added references to Bugzilla for all remaining FIXME comments. * src/server/text.c: Ditto. * src/libraries/libmisc/numlist.c: Use FIXME instead of "+++" to note stuff that needs fixing. Don't enter these things into Bugzilla, since numlist.c isn't used. Remove unneeded casts. * src/server/ram-parse.c (fparse_aux_item_link): Removed unneeded cast. * src/server/prot-a.c (prot_a_parse_packet): Removed unneeded cast. Log warning messages for two conditions that should never occur. * src/server/membership.c: Added references to Bugzilla for all FIXME comments. (access_perm_helper): Log a warning if viewer_p == NULL. * src/server/connections.c: Added references to Bugzilla for all FIXME comments. (logout_client): Log a warning message if active_connection != NULL. 2001-10-29 Per Cederqvist * src/libraries/libansi/setsid.c (setsid): Updated a comment. (rcsid): Removed. 2001-10-28 Per Cederqvist Make more symbols private to aux-items.c. * src/server/aux-items.h (aux_item_add_perm): Now static; removed from this file. (find_aux_item_definition): Ditto. (find_aux_item_index): Ditto. (find_aux_item): Ditto. * src/server/aux-items.c (simple_aux_item): Added a cast for the name. (find_aux_item_definition): Added static modifier. (find_aux_item_index): Ditto. (aux_item_add_perm): Ditto. (find_aux_item): Ditto. (aux_item_trigger_mirror_faq): Ditto. (aux_item_trigger_link_item): Ditto. (aux_item_validate_existing_text): Ditto. (aux_item_trigger_mark_text): Ditto. (aux_item_trigger_unmark_text): Ditto. Code cleanup. * src/server/prot-a-parse.c (prot_a_parse_misc_info): Removed a couple of unnecessary casts. Enter "Future Changes" notes into Bugzilla. * doc/Protocol-A.texi (Future changes): Entered all future changes into Bugzilla. Refer to Bugzilla. (Bug 131). * doc/constructs.expected: Updated. Handle @w{} in Protocol-A.texi, and refine the checkargs.py. * doc/checkargs.py (lexer.pushback): New function. Use it for @w. Also use it, intstead of lexer.ignore, for @code, @uref, @footnote, @email, @asis, @samp, @pxref, @var, @emph, @xref, @badspell, @holl and @file. (lexer.__read_arg): Handle nested braces properly. * doc/Protocol-A.texi (Future changes): Fix markup error. 2001-10-27 Per Cederqvist Fixed the documentation of the user area. * doc/Protocol-A.texi (The User Area): The documented format was not the one used by the elisp-client and kom++. Updated the documentation to the current practice. (Bug 97). (Future changes): Added a link to Bugzilla for one of the ideas. The TODO list is now moved to Bugzilla @ Lysator. * README (Contact information): Mention http://bugzilla.lysator.liu.se/. * doc/IDEAS: All items are now moved to Bugzilla. * TODO: All unfixed items are now moved to Bugzilla. * HACKING: Mention bug 77 (removal of man-pages). 2001-10-26 Per Cederqvist Use difftime() to subtract time_t values. * src/server/rfc931.c (get_real_username): Use difftime() instead of '-'. (Bug 103). * src/server/dbck-cache.c (timerdiff): The tv_usec part of the timeval is ignore. Added a comment documenting that that is OK. 2001-10-04 Per Cederqvist * TODO (BUGZILLA-MARKER): Start to move stuff to http://bugzilla.lysator.liu.se/. Everything above the marker is copied into that bug reporting system. 2001-09-30 Per Cederqvist * Release 2.0.5. Release administrativa. * configure.in: Set version 2.0.5. * versions (SERVER-VERSION): 2.0.5. (SERVER-COMPAT-VERSION): 20005. * NEWS: Documented 2.0.5. * doc/Protocol-A.texi (Document Edition History): Document edition 10.5. Doc fix. * doc/lyskomd.texi (Aux-Item Definition File): Define what is meant by "owner" for the owner-delete property. Expand the test suite. * src/server/testsuite/lyskomd.0/21.exp: Test owner-delete handling, currently only on conferences. Release preparations. * README: Updated required version of Dejagnu. Say that it needs TCL and expect, and add URL:s to them. * HACKING: Updated required versions for automake and autoconf. Mention Python and DejaGnu. The validate regexp for mx-date allowed junk before and after the time. * run-support/aux-items.conf (mx-date): Anchor the regexp. Reported by Per Starbäck. * src/server/testsuite/lyskomd.0/20.exp: Added tests for the syntax of the mx-date aux-item. 2001-09-29 Per Cederqvist Write tests for aux-items 32 and 10100-10104, and discover a minor conference number leak. * src/server/testsuite/lyskomd.0/20.exp: Write tests for aux-items 32 and 10100-10104. * src/server/person.c (create_person_generic): This can leak conference numbers. Write a comment about it. * src/server/conference.c (do_create_conf): Ditto. * doc/lyskomd.texi (Adding Aux-Item Types): Talk more about test cases. Write test cases for aux-item 31 (canonical-name), and fix a bug in the validate regexp. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added 20.exp. * run-support/aux-items.conf (canonical-name): Added a missing "?" to the validate regexp: the port number part should be optional. * src/server/testsuite/lyskomd.0/20.exp: New file that is intended to check aux-item 31, 32 and 10100-10104. Tests for aux-item 31 are written now. Cleanup. * src/server/testsuite/lyskomd.0/13.exp: State what this test is about. * src/server/testsuite/lyskomd.0/03.exp: Removed an unneeded "sleep 2" and some disabled code that is no longer needed. Mark where letterbox auxitems should be added. Fix release lint. * src/server/testsuite/lyskomd.0/Makefile.am (MOSTLYCLEANFILES): Added aux-items-18.conf. (EXTRA_DIST): Added regexp-match-cov.exp. * src/server/testsuite/lyskomd.0/18.exp (copy_aux): New function. Use built-in TCL support instead of system "cp ..." to copy files. Remove the target file before copying a file to it, to avoid permission problems. Use copy_aux everywhere that aux-items-18.conf was created. * src/server/testsuite/Makefile.am (EXTRA_DIST): Added l2g.0/12.exp (MOSTLYCLEANFILES): Added usage.all. * src/server/Makefile.am (MOSTLYCLEANFILES): Added version-info.c and prot-a-parse-arg.c. (nodist_lyskomd_SOURCES): New target. (nodist_dbck_SOURCES): New target. (NODIST_PROTA): New variable. Moved prot-a-parse-arg.c from PROTA to this variable. (NODIST_GENOBJS): New variable. Moved version-info.c from DISKOBJS to this variable. (NODIST_DISKOBJS): New variable. (NODIST_DBCK): New variable. Moved version-info.c from DBCK to this variable. * src/libraries/libansi/Makefile.am (MOSTLYCLEANFILES): Added *.da, *.bb, *.gcov and *.bbg. * run-support/Makefile.am (EXTRA_DIST): Added aux-items.conf. (uninstall-local): Remove config, but only if it isn't modified. * doc/Makefile.am (MOSTLYCLEANFILES): Added *.tmp. (EXTRA_DIST): Added checkargs.py and constructs.expected. * db-crypt/db/Makefile.am (uninstall-local): New target. Remove lyskomd-data and lyskomd-texts, but only if they are unmodified. 2001-09-23 Per Cederqvist * HACKING: Run extended tests as part of the release process. Fixed a bug that caused async-new-recipient to not be sent in some cases when passive memberships were involved. * src/server/text.c (is_member_in_recpt): Added patch by Joel Rosdahl so that bcc-recpt are really skipped over instead of producing false negatives -- a later cc-recpt or recpt can now produce a positive answer. * src/server/testsuite/lyskomd.0/gen-19.py: New file. This is mostly a copy of gen-15.py, but changed so that combinations of passive and active memberships are tested. * src/server/testsuite/lyskomd.0/Makefile.am (check_DATA): Added 19.exp. (19.exp): New target. (EXTRA_DIST): Added 16.exp, 17.exp, 18.exp, 19.exp and gen-19.py. Add progress message on slow tests. * src/server/testsuite/lyskomd.0/gen-15.py: Added some documentation. (simple_create_delete): Print progres messages when running extended tests. (simple_create_add_delete): Likewise. Re-enable all tests. * src/server/testsuite/lyskomd.0/01.exp: Enable some matching that David Byers commented out yesterday. The test works for me. The re-enabled lines are marked with a "NOTE:" comment. * src/server/testsuite/lyskomd.0/03.exp: Ditto. Port to DejaGnu 1.4.2/TCL 8.3/expect 5.32.2. * src/server/testsuite/lyskomd.0/14.exp: Use "*-*-*" instead of "*" as argument to setup_xfail, as required by DejaGnu 1.4.2. * src/server/testsuite/config/leaks.exp (startup_leaks): Don't use variable substitution in default arguments. It doesn't work. Port to Python 2.1. * src/server/testsuite/tcpconnect.py: Use string.replace instead of regsub.gsub. Port to autoconf 2.52/automake 1.5. * doc/Makefile.am: Stop complaints from automake by using "##" instead of "#" as comment leader in commands. * configure.in: Adjusted to autoconf 2.52: AC_INIT now takes package name and version as arguments. Use AC_CONFIG_SRCDIR. Use AC_HELP_STRING to format help strings. Use CMOD_CHECK_CC_OPT instead of CMOD_COMPILER_CC_ACCEPTS. Use AC_CONFIG_FILES. * acinclude.m4 (CMOD_COMPILER_CC_ACCEPTS): Removed. (CMOD_CHECK_CC_OPT): New macro. 2001-09-22 Per Cederqvist Code cleanup. * src/server/updateLysKOM.c (checkstatus): Use sizeof(lbuf) instead of 80. 2001-09-22 Per Cederqvist Document the "owner-delete" aux-item configuration parameter. * doc/lyskomd.texi (Aux-Item Definition File): Document owner-delete. Back out the patch from Joel Rosdahl for now. * src/server/text.c: Back out a patch from Joel Rosdahl that was included in the last commit by David Byers. The patch is probably good, but there was no changelog entry, and (more importantly) I want to write test cases that illustrates the problem before applying the fix. Whitespace fixes. * src/server/aux-items.c (check_delete_aux_item_list): Indentation fixes. (aux_inherit_items): Indentation fix. 2001-09-22 David Byers Port the test suite to a modern dejagnu. * src/server/testsuite/config/unix.exp (l2g_start): Use exp_continue instead of continue -expect. (lyskomd_start, lyskomd_fail_start, dbck_run): Ditto. * src/server/testsuite/lyskomd.0/11.exp: Use exp_continue instead of continue -expect. Test suite fixes. * src/server/testsuite/lyskomd.0/01.exp: Expect aux-item 31, 32 and 10100-10104 to exist. * src/server/testsuite/lyskomd.0/03.exp: Ditto. * src/server/testsuite/lyskomd.0/18.exp: Ditto. Added the "owner-delete" aux-item configuration parameter. * src/server/aux-items.c (check_delete_aux_item_list): Rewrote check for delete permissions as multiple if-elseif statements instead of a compound expression, 'cause the compound expression was getting just a little bit difficult to understand. * run-support/aux-items.conf (redirect): Set owner-delete. (x-face): Ditto. (pgp-public-key): Ditto. (e-mail-address): Ditto. (faq-text): Ditto. (allowed-content-type): Ditto. * src/server/text.c (modify_text_info): Added author as owner argument to check_delete_aux_item_list. * src/server/admin.c (modify_system_info): Added zero as owner argument to check_delete_aux_item_list. * src/server/aux-item-def-parse.y (assign): Added owner-delete. * src/server/aux-items.c (empty_aux_item_definition): Added value for owner_delete. (simple_aux_item): Ditto. * src/server/aux-items.h (struct Aux_item_definition_s): Added owner_delete field after may_not_delete. (check_delete_aux_item_list): Added owner parameter. * src/server/aux-items.c (check_delete_aux_item_list): Add owner parameter. Check owner_delete to see if object owner may delete item. * src/server/conference.c (modify_conf_info): Pass conference supervisor to check_delete_aux_item_list. 2001-09-22 Per Cederqvist Document that clients should allow conferences to be looked up by number. * doc/Protocol-A.texi (VERSION): Bugfix: set to 2.0.4, not 1.0.4. (Client-side name expansion): New node. 2001-05-24 Per Cederqvist * Protocol-A.texi 10.4 released. Added new aux-items to aux-items.conf. * run-support/aux-items.conf: Added canonical-name [31], mx-list-name [32] mx-mime-belongs-to [10100], mx-mime-part-in [10101], mx-mime-misc [10102], mx-envelope-sender [10103] and mx-mime-file-name [10104]. Fix "make check". * doc/checkargs.py (lexer.ignore): Ignore @file and @TeX. New aux-items: canonical-name and mx-list-name. Two cross references added. * doc/Protocol-A.texi (Aux-Item Types): Added canonical-name [31] and mx-list-name [32]. (Predefined Aux-Item Types): Added a cross reference to Aux-Item Types. (query-predefined-aux-items): Likewise. (Document Edition History): Document edition 10.4. 2001-05-23 Per Cederqvist Fix the update-www target in doc. * doc/Makefile.am (protocol-a.html): New target. (update-www): Give up on DVI and PDF. texinfo.tex is currently too broken for my macro usage. Fix the generation of HTML and Info for the web page. Texinfo tweaking. * doc/Protocol-A.texi (Preface): Rearrange conditionals so that some duplicated text can be removed. 2001-05-20 Per Cederqvist The documentation for the old-pwd argument to set-passwd was wrong. * doc/Protocol-A.texi (set-passwd): old-pwd must match the password of the currently logged in person, not of the person whose password is being changed. Texinfo tweaking. * doc/Protocol-A.texi (Top): Fix braino ("protocol" -> "request"). (get-session-info-ident): Fix TeX complaints. (map-created-texts): Likewise. Remove trailing @c in macro blocks. They are not needed, and they do some harm. (daemon): Move macro definition to avoid using @badspell before that macro is defined. 2001-05-17 Per Cederqvist More Protocol-A.texi tweaks. * doc/Protocol-A.texi (Top, Concepts, The Aux-Item List) (Fundamentals, LysKOM Data Types, Who Information) (Protocol Requests, Asynchronous Messages, Common Commands): Menu descriptions added. (get-text): @badspell added in example. (Who Information): These types are all obsolete. Almost. (Client-Server Dialog): Mention asynchronous messages. 2001-05-13 Per Cederqvist Spell-check Protocol-A.texi. * doc/Makefile.am (check-doc): Ignore @holl and @badspell. * doc/checkargs.py (lexer): Ignore @badspell, @holl and @daemon. * doc/Protocol-A.texi: Added spell-ignore and spell-end-ignore about several regions where spell checking doesn't make sense. Removed rcsid line. Added ispell magic after @bye. Several spelling errors fixed. (daemon, badspell): New macros. Use them where appropriate. (holl): New macro. Change all examples of Hollerith-coded strings to use this. (re-z-lookup): Fixed broken length of Hollerith string in the example. * doc/Makefile.am (check-doc): Ignore stuff after @bye. 2001-05-09 Per Cederqvist New predefined aux-items: 10100-10104. * doc/Protocol-A.texi (Predefined Aux-Item Types): State that client-specific aux-items can be redefined as predefined. (Client-Specific Aux-Item Types): Likewise. (komimportmail Aux-Item Types): Node removed. Contents moved to "Aux-Item Types". (Aux-Item Types): Added mx-mime-belongs-to [10100], mx-mime-part-in [10101], mx-mime-misc [10102], mx-envelope-sender [10103] and mx-mime-file-name [10104]. 2001-05-08 Per Cederqvist * doc/Protocol-A.texi (Aux-Item Types): Use text/x-kom-basic instead of x-kom/basic in the examples. (Reformattable Text (text/x-kom-basic)): New name for former "Reformattable Text (x-kom/basic)". Mention that the type was previously known as x-kom/basic. Removed a few nodes that contained no information. * doc/Protocol-A.texi (Conference Lists (x-kom/conflist)): Empty node removed. (Only read the most recent N texts): Likewise. (Review the last N by FOO to BAR): Likewise. (Remote control): Likewise. 2001-05-05 Per Cederqvist Update checkargs.py for todays edits of Protocol-A.texi. * doc/checkargs.py (lexer.run): It is not OK to reach EOF. (lexer.ignore): Ignore @display. (lexer.toplevel_bye): Exit when reaching "bye". (lexer.__parse_userdefined_types): Ignore @need commands. Separate sentences with two spaces, not one, as per the Texinfo documentation. * doc/Protocol-A.texi: Sentences in Texinfo should end with double spaces. Set sentence-end and sentence-end-double-space in the local variables section, and update the entire document with lots of scattered whitespace changes. Split and move text in Protocol-A.texi to make the generated Info file more useful. * doc/Protocol-A.texi (LysKOM Data Types): Split into several subnodes. Updated all cross references to point to the relevant subnode. (Protocol Notation): New node. Move text here to avoid too much text before menus in Info and HTML output. Describe the syntax of call headings. (About Asynchronous Messages): New node. Move text here to avoid too much text before menus in Info and HTML output. Remove redundancy in the description of error messages. Fix the wording of the error messages that may be sent during connection establishment. Mention that the client can issue several calls at once, and that replies are sent in order. * doc/Protocol-A.texi (Connecting to the Server): New node, containing the first part of the "Client-Server Dialog" node. Added a footnote about "Protocol A" and "Protocol B". Added some missing markup. Don't talk about what happens when a protocol other than Protocol A is used. The error message for an unsupported protocol is "%%LysKOM unsupported protocol.", not "%%Unsupported protocol". The error message used when no connections are available was lacking the trailing dot. (Client-Server Dialog): Much text moved to "Connecting to the Server". Mention that the client can issue several calls without waiting for the replies, but that it must read replies when they arrive. Mention that the replies are sent back in the proper order, but that clients are wise not to rely on that. Renamed error-no in the error-reply to error-code, to make the document more coherent. Changed the type of error-code to INT32, and removed the types Error-No and error-no. Added the "insane token length" and "insane array size" error messages to protocol-error. (Error Responses): Node removed. The old contents were moved into "Client-Server Dialog" or discarded because it was redundant. (Protocol Error Messages): New name for former "Special Errors". Removed "%%No connections left.", since that message is only sent during connection establishment. (Error Codes): Refer to error-status, not error-code. (Future changes): Talk about why giving the server freedom to reorder the replies may be beneficial, and how it can be done without breaking any clients. 2001-05-04 Per Cederqvist Minor Protocol-A edits. * doc/Protocol-A.texi (Error Codes): Introductory text added. 2001-05-03 Per Cederqvist More minor Protocol-A fixes. * doc/Protocol-A.texi (Future changes): The mark-as-unread call is missing. (Error Responses): New name for former "Error Codes". Moved to inside the "Client-Server Dialog" chapter. (Special Errors): Moved inside the "Client-Server Dialog" chapter. (Error Codes): New name for former "Normal Errors". 2001-05-01 Per Cederqvist Some minor Protocol-A.texi fixes. * doc/Protocol-A.texi (mark-as-read): Typo fixed: "as" -> "at". (create-text): Added missing @misc markup. (Name Expansion): Removed the "Case Conversion" heading, as the collate table is only relevant for "KOM Conventions" name expansion. Update the information with a link to the get-collate-table request. (The Misc-Info List): Mention that bcc-recpt are converted to cc-recpt only when visible. (Client-Server Dialog): Spelling error fixed. Mention that not-implemented works only if the client follows the strict rules regarding whitespace in protocol requests. (set-conf-type): Name the "four-bit conference type". (get-conf-stat-old): This returns a Conference-Old, not a Conference. (Future changes): Complain about super conferences, the securty system, and last-text-read/read-texts. Move some stuff to appendices in Protocol-A.texi, and move some other stuff around. * doc/Protocol-A.texi (Concepts): New name for former "Introduction". (The User Area (x-kom/user-area)): Added a reference to "The User Area". * doc/Protocol-A.texi (Preface): New name for former "Overview". (Notation): Section moved from "Overview" to "Fundamentals". (Client-Server Dialog): Section moved from "Introduction" to "Fundamentals". (Fundamentals): New name for former chapter "Data Types". (LysKOM Data Types): Moved from "Data Types" to a separate chapter. All subsections moved up one level. (Name Expansion): All subsections moved up one level -- the level was wrong. (Aux-Item Types, Predefined Aux-Item Types): Moved the list of predefined aux-items to the new chapter Aux-Item Types. * doc/checkargs.py (lexer): Ignore @appendix. * doc/Protocol-A.texi (Document Edition History): Moved to a separate appendix. (Protocol Version History): Moved to a separate appendix. (Name Expansion): Moved to a separate chapter. (Writing Clients): Now an appendix, not a chapter. (Importing and Exporting E-Mail): Likewise. (Articles, LysKOM Data Types): Don't say that the misc-info list will be removed in the future. Move such speculation to a new appendix. (Future changes): New appendix. (Articles): Clarify the discussion about local and global text numbers. (Persons and Sessions): Make this a @section instead of a @subsection to Conferences. 2001-05-01 Per Cederqvist Make all types in requests and asynchronous messages clickable in HTML. Prepend @i{Example:} to *all* request examples. Added a missing example. Avoid @iftex constructs in the document body. * doc/Makefile.am (check-doc): Ignore @anchor and @lt. * doc/checkargs.py (lexer): Ignore @need, @reqexample and @anchor. (lexer.__parse_userdefined_types): Handle @anchor. (lexer.__parse_type): Requre @lt markup. (lexer.__get_lt_token): New method. (lexer.__get_token): Handle the new tokens '{' and '}'. (lexer.__parse_userdefined_types): Expect @lt{} markup (lexer.__parse_userdefined_struct): Likewise. (lexer.__parse_userdefined_selection): Likewise. (lexer.__parse_userdefined_enumeration_of): Likewise. * doc/Protocol-A.texi (@reqexample): New macro. Use it in front of every example of request usage. Previously, many but not all examples were introduced by a @i{Example:} line. That line is now included in the @reqexample macro, together with a "@need 2000" statement. (IAM, Pell, Kent, presconf): New values, to handle TeX/Info incompatibilities regarding Latin-1 characters without having to clutter the document with @iftex constructs. Removed all related @iftex constructs in the body of the document. @ae{} can be used in both Info and TeX mode; do so. (set-super-conf): Missing example added. (Simple Data Types): Add @anchor targets for all types. (LysKOM Data Types): Likewise. (@lt): New macro. Use it in all requests and asynchronous messages to mark up the types. (LysKOM Data Types): Added @lt markup around all types on the right hand side. 2001-04-30 Per Cederqvist Added macros @asynclink and @asyncdlink. * doc/checkargs.py (lexer): Ignore asynclink. (lexer.toplevel_asyncdlink): New method. * doc/Protocol-A.texi (@asynclink, @asyncdlink): New macros. Use them instead of @link where appropriate. (Asynchronous Messages): Use @reqlink instead of @req. * doc/Makefile.am (check-doc): Handle @asynclink and @asyncdlink. Check documentation of asynchronous messages. * doc/Makefile.am (check-doc): Create requests-numbered.tmp. Create asyncs-numbered.tmp. Omit DEBUG_CALLS-only asynchronous messages from "async.h". * doc/Protocol-A.texi: Create the "am" index for asynchronous messages. Add @amindex and @aarg markup for all asynchronous messages, and remove the trailing semicolon in the argument list. Merge all indices into one. (add-member): Malformed sentence fixed. (async-i-am-off, async-i-am-on-obsolete): Mark as obsolete, and tell why they are no longer used. (async-broadcast): Mark as obsolete. (Type Index, Request Index): Removed. (Index): Added. * doc/checkargs.py (lexer.__init__): Initialize __amindex, __defined_asyncs and __implemented_asyncs. (lexer): Ignore @defcodeindex and @syncodeindex. (lexer.toplevel_node): Check for undocumentet arguments to asynchronous messages. (lexer.toplevel_findex): Check for @amindex entries in @findex nodes. (lexer.toplevel_amindex): New method. (lexer.__parse_async): New method. (lexer.toplevel_aarg): Implemented. (lexer.toplevel_bye): Check for unterminated @amindex nodes and undocumented asynchronous messages. * doc/checkargs.py (lexer.__init__): Read requests-numbered.tmp. (lexer.toplevel_findex): Check that the same request name isn't used twice. (lexer.toplevel_bye): Check that all implemented requests are documented. (lexer.__parse_request): Check that the proper request number is used, and that the request is really implemented. Check type definitions, that all types are used, and some related stuff. Renamed ENUMREATION_OF to ENUMERATION-OF. * doc/Protocol-A.texi (Simple Data Types): Renamed ENUMERATION_OF to ENUMERATION-OF. Nothing else uses "_". The only user updated. (LysKOM Data Types): Missing semicolon added. * doc/checkargs.py (defined_types): New variable. (number_suffixed): New function. (prot_a_type): New class, with several derived classes. (reader.error): Allow the line number to be a string, such as '*builtin*'. (lexer.__init__): Added 'ENUMERATION-OF' to the set of builtin aggregates. Add builtin types to defined_types. (lexer): Ignore @dots{}. (lexer.toplevel_bye): Check that all defined types are used. (lexer.toplevel_tindex): Pass a list of the @tindex entries to __parse_userdefined_types, so that that function can check that they are all defined. (lexer.__parse_userdefined_types): Implemented. Several helper functions introduced. (lexer.__parse_type): Simplified. Do some error checking and bookkeeping. Return a tuple, so that it is easier for the caller to see if an array was used. All callers updated. (lexer.__bad_arg): Accept "reservedX" and "flgX" for numerical values of X. (lexer.__get_token): Handle the new tokens "::=", "|" and "=". Ignore comments (introduced with "!"). 2001-04-29 Per Cederqvist Minor fixes to the protocol specification. * doc/Protocol-A.texi: Use @dots{} instead of "...". (Simple Data Types): Use "::=" instead of ":" in two places. Added missing @example...@end example markup. Fixed the SELECTION example -- the tail is not optional. @reqdlink now works when using TeX. * doc/Protocol-A.texi: Added a proper definition of @reqdlink for TeX, written by David Byers. Use "@tex" instead of "@begin tex". * doc/checkargs.py (lexer): Ignore @tex. 2001-04-28 Per Cederqvist Check case of user-defined types. * doc/checkargs.py (lexer.__init__): Set __builtin_types, __builtin_aggregates, __builtin_typelike, __tindex_seen and __types_used. (lexer.__seen_type): New method. (lexer.toplevel_tindex): Implement. (lexer.__parse_userdefined_types): New method, not yet implemented. (lexer.__bad_type): Check that the casing rules for user-defined types are adhered to. * doc/Protocol-A.texi (set-pers-flags): Fixed typo. Check @linkhere usage. Stricter parens checking. * doc/checkargs.py (reader.check_paren_null): New name for former check_paren_eof. All callers updated. Clear __parenstack, so that errors are reported only once. (lexer.__init__): Initialize __linkhere. (lexer.toplevel_node): Check that no @linkhere or closing parenthesis are pending. (lexer.toplevel_reqdlink, lexer.__assert_no_linkhere) (lexer.toplevel_linkhere): New methods. Renamed modify_server_info to modify_system_info, to match Protocol-A.texi. * src/include/services.h (modify_system_info): New name for former modify_server_info(). * src/server/admin.c: Likewise. * src/server/fncdef.txt: Likewise. Mark up all requests and fix all references in Protocol-A.texi. Check for balanced parenthesis. * doc/checkargs.py (reader.parens, reader.rev_parens): New constants. (reader.__init__): Initialise __parenstack, __errfound and __quoted. (reader.error, reader.errfound): New methods. (reader.ungetc, reader.getc_eofok): Handle quoting and parens nesting. (reader.check_paren_eof): Report unbalanced parens at EOF. (lexer.__init__): Moved __errfound to the reader class. (lexer.run): Check for unbalanced parens at EOF. (lexer.toplevel_reqlink): Ignore. (lexer.toplevel_reqdlink, lexer.toplevel_linkhere): Ignore, for now. We should check nesting et c of these. (lexer.toplevel_unmacro): Ignore. (lexer.error): Moved the implementation to the reader class. This is only a wrapper. * doc/Makefile.am (check-doc): Add @reqlink and @reqdlink to requests-@.tmp. * doc/constructs.expected: Added "@linkhere{}". * doc/Protocol-A.texi: Use @reqlink and @reqdlink where appropriate. Fix lots of malformed @ref, @xref and @pxref usages. Also: (@reqlink, @reqdlink, @linkhere): New markup macros. (Document Edition History): Added missing @async markup. (About Aux-Items): Added missing @field markup. (Simple Data Types): Removed an unbalanced close parenthesis. (LysKOM Data Types): Added missing @field markup. Removed an unbalanced close parenthesis. (lookup-name): Added a missing close parenthesis. (get-info-old): Added a missing close parenthesis. This returns Info-Old, not Info. (create-anonymous-text-old): Added missing @field markup. (login): Added missing close parenthesis. (local-to-global): Don't use fancy mathemtical notations for half-closed intervals. Added missing @type markup. 2001-04-23 Per Cederqvist Don't omit stuff when formatting Protocol-A.texi as HTML. * doc/Protocol-A.texi: Use @ifnottex instead of @ifinfo almost everywhere that @ifinfo was used. (re-z-lookup): Added missing spaces in the example. (lookup-z-name): Likewise. (get-members): Likewise. (Protocol Requests): Removed text about "upright text" in the replies in the examples, since no such text exists. 2001-04-19 Per Cederqvist Fix a couple of Protocol-A.texi errors. * doc/Protocol-A.texi (Protocol Requests): Mention that extra newlines sometimes are used in the examples. (create-person): Language fix. 2001-04-18 Per Cederqvist Fix a few more Protocol-A.texi errors. * doc/Protocol-A.texi (get-membership-old): Use a "want-read-texts : BOOL" argument instead of "mask : BITSTRING(want-read-texts)". The result is the same, but using BOOL makes the prototype easier to read. Document the argument more verbosely. (get-membership): Do likewise. (login): Do likewise for the "invisible" argument. (create-anonymous-text-old): Added @misc{} markup. * doc/constructs.expected: Updated. Fix lots of minor errors in Protocol-A.texi. Document that the invitation membership flag is automatically set in some circumstances. * doc/checkargs.py (lexer.__bad_arg): Added a missing __unget_token to get a better error message. * doc/Protocol-A.texi: Fix all @rarg{} arguments that used the wrong argument name. Edit all request prototypes so that the consistently use semicolon as an argument delimiter, not an argument terminator. Add missing @rarg{} markup. (Protocol Version History): Remove a trailing space. (get-membership-old): Use @field{read-texts} instead of @rarg{read-texts}. (get-created-texts): Added missing '->' token. (create-anonymous-text): Added @misc{} markup. (create-person): Use @priv{create-pers} instead of @rarg{create-pers}. (modify-system-info): Docuent items-to-delete and items-to-add. (add-member): Document type, including the fact that the invitation field is sometimes set automatically. Check that @rarg{} is used correctly. * doc/Makefile.am (check-doc): Depend on info. so that checkargs.py is only run on a file that makeinfo can process. Run checkargs.py on Protocol-A.texi. * doc/checkargs.py: New file. * doc/lyskomd.texi: Break overly long lines. 2001-04-16 Per Cederqvist Fix comments. * src/server/async.h: Don't refer to removed files. * src/include/kom-types.h: Likewise. * HACKING: There are version numbers in Protocol-A.texi as well. Prepare Protocol-A.texi for web publication. Add and check domain-specific markup. * doc/Makefile.am (.texi.notab): Check that no lines are more than 79 characters long. (update-www): New target. This is work in progress and does not yet work. (Protocol-A.pdf): New target. (check): Depend on check-doc. (check-doc): New target. This is work in progress, but it already performs several useful sanity checks on Protocol-A.texi. * doc/.cvsignore: Ignore *.tmp, Protocol-A.pdf, protocol-a.html, and stamp-vti1. * doc/constructs.expected: New file, that enumerates the expected @-constructs in Protocol-A.texi. * doc/Protocol-A.texi (PROTOEDITION, PROTOVER, VERSION): New constants. Use them throughout the document instead of 10.3, 10 and 1.0.4. Bump PROTOEDITION to 10.4. Added an explicit permission to process the texi file with TeX. Ensure that all permission notices are equal. Print all version information on the title page. Moved the contents to the front of the document, and avoid printing them in the html document. Add HTML links to Lysator and LysKOM before the first node. (Top): Enclose this node in @ifnottext instead of @ifinfo. Refer to the web site. (Overview): Include all version numbers and the canonical URL for the protocol specification here as well, but only @iftex. (Document Edition History): New name for former node "Document Revision History". Use the term "edition" throughout the document. Added a not for edition 10.4. (Predefined Aux-Item Types, create-anonymous-text-old) (create-anonymous-text, modify-system-info): Get rid of overfull hbox messages from TeX. (Type Index, Request Index): Use @unnumbered instead of @chapter. (all call nodes): Replaced "@unnumberedsubsec Error codes" with "@subheading Error codes" so that they are not included in the table of contents, and so that the PDF menus work better. (Overview, Document Edition History): TeX lint. (@req, @aux, @async, @type, @priv, @conftype, @misc, @rarg, @aarg) (@errorcode, @field): New Texinfo macros. Use them where appropriate. 2001-04-13 Per Cederqvist Register the undocumented "rkom" user-area block. * doc/Protocol-A.texi (set-client-version): The client names are "registered", not "reserved". (The User Area): Registered the "rkom" block. 2001-04-10 Per Cederqvist Protocol A: Document the hello string. Improve the recommended algorithm for determining what a client has unread. * doc/Protocol-A.texi (Client-Server Dialog): Document the format of the hello string. Fix the example. (What do I have unread): Recommend that clients use get-uconf-stat instead of get-conf-stat. 2000-11-08 Per Cederqvist Typo fixed. * README: Fixed typo ("IP address" -> "hostname"). Reported by Andreas Ehliar. 2000-09-06 Per Cederqvist * Release 2.0.4. Remove Y2k bug. * src/server/prot-a-output.c (prot_a_output_time): Remove stupid Y2k joke.q Added missing files to the distribution. * src/server/testsuite/lyskomd.0/Makefile.am (EXTRA_DIST): Added gen-15.py. Test and document SIGWINCH (re-read aux-item.conf). * src/server/testsuite/lyskomd.0/18.exp: New file, testing SIGWINCH. * src/server/testsuite/lyskomd.0/04.exp: Add $srcdir to the front of the aux-item file name when calling lyskomd_start. * src/server/testsuite/lyskomd.0/aux-items-cov.exp: Likewise. * src/server/testsuite/leaks.0/leaks10.exp: Add $srcdir to the front of the aux-item file name when calling startup_leaks. * src/server/testsuite/leaks.0/leaks99.exp: Likewise. * src/server/testsuite/config/leaks.exp (startup_leaks): Added $srcdir to aux-item file. * src/server/testsuite/config/unix.exp (lyskomd_start): Don't add $srcdir to the name of the aux-item file. (lyskomd_fail_start): Likewise. * doc/lyskomd.texi (Parameters): aux-items.conf is reread when a SIGWINCH is received. (Signals): Likewise. Document the new visibility rules for bcc-recpt. * doc/Protocol-A.texi (The Misc-Info List): Fix the description of the visibility of bcc-recpt. Clarify the documentation for mark-as-read. * doc/Protocol-A.texi (mark-as-read): State that it isn't necessary for clients to call mark-as-read on deleted texts. 2000-09-05 Per Cederqvist Set version numbers. * versions (SERVER-VERSION): 2.0.4. (SERVER-COMPAT-VERSION): 20004. * configure.in: Set version number to 2.0.4. * README: Updated for the 2.0.4 release. * doc/Protocol-A.texi: This is revision 10.3. (Document Revision History): Documented changes for 10.3. Various cleanup. * doc/lyskomd.texi (Overview): Remove mal-placed plug about the cool free software company Cendio Systems. * src/server/testsuite/lyskomd.0/gen-15.py (DEBUG): Set to 0. Don't leak secret information when telling about the current working conference. * src/server/testsuite/lyskomd.0/16.exp (assert_0): No longer excpect these tests to fail. * src/server/session.c (who_is_on): Don't send info about secret conferences. (who_is_on_ident): Likewise. (who_is_on_dynamic): Likewise. (get_session_info): Likewise. (get_session_info_ident): Likewise. (who_is_on_old): Likewise. * src/server/send-async.c (async_i_am_on): Don't send info about secret conferences. * src/server/membership.c (filter_conf_no): New function. * src/server/manipulate.h (filter_conf_no): New function. 2000-09-04 Per Cederqvist Implement the aux-items recommended-conf and allowed-content-type. * src/server/testsuite/lyskomd.0/01.exp: Expect aux-item 29 and 30 to exist. * src/server/testsuite/lyskomd.0/03.exp: Expect aux-item 29 and 30 to exist. Give Kelly Talisman two allowed-content-type aux-items. Renumber. * run-support/aux-items.conf: faq-text may be set on the server. Added recommended-conf and allowed-content-type. * src/server/testsuite/lyskomd.0/17.exp: New test. * doc/Protocol-A.texi (Predefined Aux-Item Types): Added lots of things that aux-items can be set on: cross-reference += letterbox redirect += letterbox x-face += letterbox, server alternate-name += letterbox mx-allow-filter += letterbox mx-reject-forward += letterbox allowed-content-type += letterbox, server Updated the description of the allowed-content-type aux item. Typo fixed. * doc/Protocol-A.texi (Protocol Requests): Typo in menu fixed. Fix the visibility of bcc-recipients, so that the same rules are used everywhere. Tighten the rules so that secret info cannot leak through get-text-stat. * src/server/testsuite/lyskomd.0/gen-15.py (text_stat): New class. Rewrite the rest of this file to use it. Give authors special privileges regarding bcc-recpts. * src/server/testsuite/lyskomd.0/10.exp: Removed an obsolete comment, since this test no longe fails. * src/server/testsuite/config/unix.exp (lyskomd_start): The tests now require more than 2000 texts. Give them 20000. * src/server/text.c (send_async_sub_recipient): Use filter_secret_info() so that the exact same visibility is used by async-sub-recipient and get-text-stat. (filter_secret_info): Don't allow the author of a text to see bcc-recpt which are secret to him. Simplify the code slightly. (send_async_add_recipient): Use filter_secret_info() so that the exact same visibility is used by async-add-recipient and get-text-stat. 2000-09-02 Per Cederqvist Re-indent text.c. Add a few const qualifiers. * src/server/text.c: Code re-indented. (count_recipients): const qualifiers added to some arguments. Code simplified. (count_footn): Likewise. (count_comment): Likewise. (text_read_access): Code clarified. (delete_text): Likewise. (find_recipient): qualifiers added to some arguments. (is_comment_to): Likewise. (is_footnote_to): Likewise. (submit_to): Likewise. (is_member_in_recpt): Likewise. (send_async_sub_recipient): Likewise. (sender): Likewise. (is_sender): Likewise. (is_comm_sender): Likewise. (check_footn): Likewise. (check_comm): Likewise. (locate_mark): Likewise. (skip_recp): Likewise. (recp_sent_by): Likewise. (filter_secret_info): Likewise. (send_async_deleted_text): Likewise. (check_double_subm): Likewise. (check_double_comm): Likewise. (send_async_new_text_old): Likewise. (send_async_new_text): Likewise. (send_async_add_recipient): Likewise. * src/server/membership.c (access_perm_helper): const qualifiers added to some arguments. (access_perm): Likewise. (locate_membership): Likewise. * src/server/dbck.c (locate_membership): const qualifiers added to some arguments. * src/server/conference.c (is_supervisor): const qualifiers added to some arguments. (is_strictly_supervisor): Likewise. * src/server/manipulate.h: (access_perm): const qualifiers added to some arguments. (is_supervisor): Likewise. (is_strictly_supervisor): Likewise. (locate_membership): Likewise. * src/server/aux-items.c: Lots of const qualifiers added. * src/server/aux-items.h (Aux_item_validation_data): const qualifiers added to the item and def members. (aux_inherit_items): const qualifiers added to some arguments. (aux_item_add_perm): Likewise. (prepare_aux_item): Likewise. (find_aux_item_definition): Likewise. (aux_item_find_trigger): Likewise. (aux_item_find_validator): Likewise. (find_aux_item): Likewise. (filter_aux_item_list): Likewise. (delete_aux_item_list): Likewise. (undelete_aux_item_list): Likewise. (check_delete_aux_item_list): Likewise. Test suite cleanup. * src/server/testsuite/lyskomd.0/16.exp (assert_0): New proc. Use it to simplify the code. 2000-08-28 Per Cederqvist Secret conference numbers can apparently leak from the get-session-info and who-is-on family of functions. Test cases added. * src/server/testsuite/lyskomd.0/16.exp: Added test cases for async-i-am-on, who-is-on-old, who-is-on, get-session-info, who-is-on-ident, get-session-info-ident and who-is-on-dynamic. They all leak info about secret conferences. 2000-08-12 Per Cederqvist More work on test cases for async messages 14-17. * src/server/testsuite/lyskomd.0/gen-15.py: Test simple create+add+delete. 2000-08-09 Per Cederqvist Start writing test cases for async messages 14-17. * src/server/testsuite/lyskomd.0/gen-15.py: New file. This is very far from complete. * src/server/testsuite/Makefile.am (SUBDIRS): Added lyskomd.0. (EXTRA_DIST): Moved all files in lyskomd.0 to that makefile. (check-lyskomd): Depend on check-recursive. * configure.in: Remove -Wpointer-arith since it gives a lot of false warnings when using glibc-2.1.3 and gcc-2.95.2. Create src/server/testsuite/lyskomd.0/Makefile. * src/server/testsuite/lyskomd.0/Makefile.am: New file, mostly extracted from ../Makefile.am. (15.exp): New target. (check_DATA): New target. Added 15.exp. 2000-08-05 Per Cederqvist The dummy_aux_item introduced 2000-05-09 was not properly initialized. * src/server/prot-a.c (prot_a_init): Initialize dummy_aux_item.data and aux_item.data. * src/server/internal-connections.c (init_connection): Initialize dummy_aux_item.data. (kill_client): Check dummy_aux_item.data and aux_item.data. 2000-08-04 Per Cederqvist Minor documentation improvement. * doc/lyskomd.texi (Parameters): Clarified the warning about "Never save". Documented the allowed-content-type aux item. * doc/Protocol-A.texi (Predefined Aux-Item Types): Added a draft description of the allowed-content-type aux item. 2000-05-09 David Byers The server could crash when parsing over-long aux-item lists. * src/server/connections.h: Added dummy_aux_item field. * src/server/prot-a-parse.c (prot_a_parse_string): (prot_a_parse_aux_item_list): Use dummy_aux_item in client structure instead of an auto variable. * src/server/connections.c (free_parsed): Clear client->dummy_aux_item. 2000-04-28 Per Cederqvist The data base was saved even when "Never save: true" was used. * src/server/simple-cache.c (cache_sync_all): Return early if param.never_save is set, so that the database won't be saved even at normal server shutdown. * doc/lyskomd.texi (Parameters): Updated the documentation for "Never save". 2000-03-13 Per Cederqvist Large garb-nice values could be truncated. * src/server/text-garb.c (garb_text): Avoid overflow when converting the garb-nice value from days to seconds. (Suspected by Anders Åke Carlsson.) 1999-11-20 Per Cederqvist Fixed a cut-n-paste error in the protocol spec. * doc/Protocol-A.texi (LysKOM Data Types): bcc-recpt is of course a Conf-No, not a Text-No. (Reported by Anders Franzén.) 1999-10-28 David Byers * src/server/text.c (send_async_sub_recipient): Don't send sub-recipient messages for bcc recipients to users who are not members of the bcc recipient. * src/server/testsuite/lyskomd.0/06.exp (shutdown_06): Added test cases to test async messages when adding and removing BCC recipients. 1999-10-27 David Byers * src/server/ramkomd.c (dump_exit_statistics): Free read_config_file (main): Save name of configuration file in read_config_file. Handle WINCH signal (re-read config file.) * src/server/param.h: Added reread_param. Added read_config_file * src/server/server-config.c: Added reread_param. 1999-10-20 Kent Engström Documentation updates w.r.t. e-mail import. * doc/Protocol-A.texi (Predefined Aux-Item Types): Introduced some hints for client authors and clarified the description of some aux-items based on experiences from writing "komimportmail"; changed definition of mx-in-reply-to to specify that is should really be the Message-ID used for threading, regardless of which header line that supplied it. Marked mx-allow-filter and mx-reject-forward obsolete. (komimportmail Aux-Item Types): new node describing the aux-items introduced by this importer. (Importing and Exporting E-Mail): rewrote most of the chapter, using experience from "komimportmail". Removed text about export, as it was rather naive. 1999-10-12 Kent Engström Documentation fix. * doc/lyskomd.texi (Parameters): Moved cross-reference to stop newer makeinfo versions from complaining. 1999-10-09 David Byers * doc/Protocol-A.texi (Client-Specific Aux-Item Types): Added komimportmail to reserved range. * run-support/aux-items.conf: Fixed date validation regexp. 1999-08-13 David Byers * doc/Protocol-A.texi (Predefined Aux-Item Types): Changed "of" to "or" in documentation of content-type. The old wording was incorrect and conveyed the wrong idea. 1999-09-19 Per Cederqvist Prepare for dbck improvement. * src/server/local-to-global.c (add_block_before): New static function. (find_block): Return a pointer to the last block instead of a NULL pointer if a too large local text number is supplied. (l2g_expensive_set): Now fully implemented. * src/server/testsuite/l2g.0/12.exp: New file, that tests l2g_expensive_set. * src/server/testsuite/test-l2g.c (main): Handle l2g_expensive_set. Code cleanup. * src/server/dbck.c (check_misc_any_recipient): New static function. (check_misc_infos): Use it, to avoid repeating the same code inline three times. 1999-09-18 Per Cederqvist Prepare for dbck improvement. * src/server/local-to-global.c (l2g_expensive_set): New function, not yet completely implemented. * src/server/local-to-global.h (l2g_expensive_set): New function. Always install the distributed aux-items.conf. * run-support/Makefile.am (sysconf_DATA): Added aux-items.conf. (EXTRA_DIST): Removed aux-items.conf. (install-data-local): Don't install aux-items.conf here. * README: Warn that aux-items.conf is always installed. 1999-08-18 Per Cederqvist Added aux-item "recommended-conf". * doc/Protocol-A.texi (Predefined Aux-Item Types): The last space and descriptive text in a cross-reference are optional. Added recommended-conf. 1999-07-25 Kent Engström Fixed inconsistent format for aux-item mx-date. * run-support/aux-items.conf: change the validation of aux-item mx-date to the format specified in Protocol-A.texi. * src/server/testsuite/leaks.0/lots-aux-items.conf: Ditto. Experience from writing a mail importer. * doc/Protocol-A.texi: made definition of address aux-items clearer (after a discussion in LysLysKOM), rewrote a lot of the text on mail import. Miscellaneous documentation fixes. * doc/Protocol-A.texi (get-map): this request is indeed obsolete as of version 10 of Protocol A. 1999-07-25 Per Cederqvist * Release 2.0.3. * NEWS: Document version 2.0.3. * configure.in: Set version number to 2.0.3. * versions (SERVER-VERSION): 2.0.3. (SERVER-COMPAT-VERSION): 20003. Looking up the empty name still caused a core dump. * src/server/simple-cache.c (cached_lookup_name): Leaving uninitialized data in the result is almost as bad as following the NULL pointer. The result may contain fewer than no_of_match_info entries -- and now the code attempts to handle it properly. * src/server/testsuite/lyskomd.0/03.exp: Test for name lookup of the empty string when a conference has been deleted. * src/server/testsuite/config/unix.exp (lyskomd_start): Arrange to always test for eof from lyskomd in expect_after, and fail if it is detected. Added missing newlines in restart_kom format strings. * src/server/conference.c (lookup_z_name): Added a missing newline in a restart_kom format string. (do_create_conf): Likewise. 1999-07-24 Per Cederqvist Implemented splitkomdb. This is highly experimental and not yet documented. * src/server/splitkomdb.c: New file. * src/server/Makefile.am (bin_PROGRAMS): Added splitkomdb. (splitkomdb_SOURCES): New variable. * src/server/param.h (struct kom_par): Added backup_dir. * src/server/server-config.c (parameters): Added "Backup export directory". (read_configuration): Handle param.backup_dir. 1999-07-23 Per Cederqvist * Release 2.0.2. * NEWS: Document version 2.0.2. * configure.in: Set version number to 2.0.2. * versions (SERVER-VERSION): 2.0.2. (SERVER-COMPAT-VERSION): 20002. * doc/Protocol-A.texi: This is revision 10.2. (Document Revision History): This is revision 10.2. Looking up the empty name caused a core dump. * src/server/simple-cache.c (cached_lookup_name): Don't follow the NULL pointer. * src/server/conference.c (match_table): Don't declare it here. 1999-07-20 Per Cederqvist * doc/Protocol-A.texi (Predefined Aux-Item Types): Typo fixed -- there is nothing called mx-o. 1999-07-14 Kent Engström Documentation fixes. * doc/Protocol-A.texi (Protocol Requests): set-info sets server information. (set-last-read): last-read is a Local-Text-No. (set-info): Info-Old is returned by get-info-old. (async-logout): Not called async-async-logout. 1999-07-13 Kent Engström Documentation fixes. * doc/Protocol-A.texi: Corrected spelling errors, etc. (Conference Type): reserved1 is now called forbid-secret. (lookup-z-name): use correct call in examples. 1999-07-12 Per Cederqvist * Release 2.0.1. * doc/Protocol-A.texi (Document Revision History): Release date set to 1999-07-12. The performance fix of 1999-07-06 introduced an extra newline in the files. Fix. * src/server/simple-cache.c (copy_file): Don't emit duplicate newlines. Remove false warnings. * src/server/membership.c (access_perm): Fixed the logic error that caused several false warnings to be logged. 1999-07-11 Per Cederqvist Fix the documentation of add-recipient, async-new-recipient and async-sub-recipient. * doc/Protocol-A.texi (Simple Data Types): ENUMERATIONs can be inherited from SELECTIONS. (LysKOM Data Types): Define Info-Type. (add-recipient): The recpt-type argument is an Info-Type, not a complete Misc-Info. (async-new-recipient): The type argument is an Info-Type, not a complete Misc-Info. (async-sub-recipient): Likewise. (Document Revision History): Mention Info-Type. Don't overwrite installations that have lyskomd-backup but no lyskomd-data. * db-crypt/db/Makefile.am (install-data-local): Don't install the database if lyskomd-backup exists. Don't install it if any of the databases exist. Fixed a database error that caused damage to conferences. * src/server/simple-cache.c (save_one_conf): Fixed a serious bug introduced 1997-10-23 when the (as yet unused) FASTSAVE code was written. Changes made to conferences could in some cases be forgotten. Fixed a harmless Y2k bug. * src/server/log.c (kom_logv): Log the year 2000 as "00", not "100". (kom_log): (non-HAVE_VPRINTF version) Likewise. Release preparations. * NEWS: Added an entry for the 2.0.1 release. * versions (SERVER-VERSION): 2.0.1. (SERVER-COMPAT-VERSION): 20001. * configure.in: Set version number to 2.0.1. * README: Recommend running dbck when upgrading from 2.0.0. Regexps are always case sensitive. * doc/Protocol-A.texi: This is revision 10.1 of the specification. (Overview): Protocol versions never have a suffix. (Document Revision History): Wrote entry for 10.1. (Name Expansion): Regexps are case sensitive. (re-lookup-person): Tempus changed. (re-lookup-conf): Tempus changed. (re-z-lookup): Regexps are case sensitive. * src/server/param.h (struct kom_par): Removed the regex_use_collate_table field. * src/server/regex-match.c (lookup_regexp): Never use a translate table. * src/server/server-config.c (parameters): Removed "Regexps use collate table". * doc/lyskomd.texi (Parameters): Removed "Regexps use collate table". * src/server/testsuite/lyskomd.0/03.exp: Don't use "Regexps use collate table". * src/server/testsuite/lyskomd.0/regexp-match-cov.exp: LIkewise. Fixed a minor bug that currently had no effects. * src/server/person.c (create_person_generic): Added a missing call to mark_conference_as_changed. Fixed a buffer overrun. * src/server/aux-items.c (aux_item_trigger_mirror_faq): Fixed a buffer overflow. * src/server/testsuite/lyskomd.0/14.exp: Added a few FAQ aux-item tests. Code cleanup. * src/server/aux-item-def-parse.y (aux_item_def_check_trigger): Added static qualifier. (aux_item_def_check_validate): Likewise. * src/include/kom-types.h (Object_type): Removed the almost unused type PERS_OBJECT_TYPE. * src/server/aux-items.c (find_linked_aux_item_list): Don't test for the non-used PERS_OBJECT_TYPE object type. (mark_linked_object_as_changed): Likewise. 1999-07-08 Per Cederqvist Allow the author of a text to change the recipient type. * src/server/text.c (add_recipient): Allow the text author to change the recipient type. * src/server/testsuite/lyskomd.0/14.exp: New file. * src/server/testsuite/Makefile.am (EXTRA_DIST): Added lyskomd.0/14.exp. 1999-07-07 Kent Engström Documentation fixes. * doc/Protocol-A.texi: corrected some spelling errors; changed cross-references so that new versions of makeinfo will stop complaining; added forbid-secret to the list of conference flags above the table. 1999-07-06 Per Cederqvist Remove a few performance problems. * src/server/membership.c (access_perm_helper): New argument: wanted_access. All callers updated. Avoid calling is_supervisor or is_member if not needed. (get_unread_confs): Minor performance improvement: there is no need to call access_perm if pers_no is the logged-in person. * src/server/simple-cache.c (copy_file): Use a static buffer instead of allocating and releasing a buffer each time this function is called. Remove dead code. * src/server/manipulate.h (IMPL): Unused macro removed. * src/server/dbck-cache.c (IMPL): Unused macro removed. * src/server/ram-parse.c (fparse_conference_2): Remove dead code that depends on the long-obsolete DISKERR symbol. (fparse_conference_0): Likewise. (fparse_person_0): Likewise. (fparse_person_2): Likewise. (fparse_text_stat_2): Likewise. (fparse_text_stat_0): Likewise. 1999-07-05 Per Cederqvist Speed up access_perm, is_supervisor and is_strictly_supervisor by adding a supervisor field to Small_conf, and using it instead of a call to GET_C_STAT. Remove the Conference argument to the above three functions and update all callers. A few stray calls to GET_C_STAT were eliminated in the process. * src/include/kom-types.h (Small_conf): Added a supervisor field. * src/server/cache.h (cached_get_conf_supervisor): New function. * src/server/simple-cache.c (cached_get_conf_supervisor): New function. (mark_conference_as_changed): Copy the supervisor to the entry in small_conf_arr. (init_small_conf): Set supervisor. (setup_small_conf): Set supervisor. * src/server/manipulate.h (access_perm): Removed the victim_c argument. (is_supervisor): Removed the conf_c argument. (is_strictly_supervisor): Removed the conf_c argument. * src/server/membership.c (access_perm_helper): New name for former plain_ol_access_perm. Get rid of call to GET_C_STAT by calling cached_get_conf_type instead. Removed the victim_c argument from all calls to is_supervisor. (plain_ol_fast_access_perm): Removed. (access_perm): Removed the victim_c argument. (copy_public_confs): Removed the victim_c argument from all calls to is_supervisor. Removed the victim_c argument from all calls to access_perm. (sub_member): Likewise. (do_get_members): Likewise. (get_unread_confs): Likewise. (add_member_common): Likewise, and get rid of a call to GET_C_STAT. (do_get_membership): Likewise, and get rid of a call to GET_C_STAT. (set_membership_type): Likewise, and get rid of a call to GET_P_STAT. * src/server/conference.c (do_create_conf): Call mark_conf_as_changed before checking that ACTPERS is allowed to create aux-items in the conference he is creating. (is_supervisor): Removed the conf_c argument. (is_strictly_supervisor): Removed the conf_c argument. Use cached_conf_exists and cached_get_conf_supervisor and eliminate one expensive call to GET_C_STAT. (change_name): Removed the victim_c argument from all calls to access_perm. (delete_conf): Likewise. (lookup_name): Likewise. (lookup_z_name): Likewise. (do_lookup): Likewise. (get_conf_stat_old): Likewise. (get_uconf_stat): Likewise. (get_conf_stat_older): Likewise. (set_presentation): Likewise. (set_etc_motd): Likewise. (set_conf_type): Likewise. (set_garb_nice): Likewise. (set_expire): Likewise. (set_keep_commented): Likewise. (modify_conf_info): Likewise. (set_supervisor): Removed the conf_c argument from all calls to is_strictly_supervisor and is_supervisor. (set_permitted_submitters): Likewise. (set_super_conf): Likewise. * src/server/admin.c (send_message): Removed the victim_c argument from all calls to access_perm. * src/server/person.c (get_person_stat): Removed the victim_c argument from all calls to access_perm. Eliminate one call to GET_C_STAT. (get_person_stat_old): Likewise. (get_created_texts): Removed the victim_c argument from all calls to access_perm. (map_created_texts): Likewise. (do_query_read_texts): Likewise. (set_user_area): Likewise. (set_pers_flags): Likewise. (set_passwd): Removed the victim_c argument from all calls to is_supervisor. * src/server/regex-match.c (lookup_regexp): Removed the victim_c argument from all calls to access_perm. * src/server/send-async.c (async_new_name): Removed the victim_c argument from all calls to access_perm. * src/server/text.c (submit_to): Removed the victim_c argument from all calls to access_perm and is_supervisor. (send_async_sub_recipient): Likewise. (recp_sent_by): Likewise. (filter_secret_info): Likewise. (person_text_read_access): Likewise. (delete_text): Likewise. (send_async_add_recipient): Likewise. (add_recipient): Likewise. (sub_recipient): Likewise. (sub_comment): Likewise. (sub_footnote): Likewise. (get_map): Likewise. (local_to_global): Likewise. * src/server/aux-items.c (aux_item_add_perm): Removed the conf_c argument from all calls to is_strictly_supervisor and is_supervisor. (filter_aux_item_list): Likewise. (check_delete_aux_item_list): Likewise. * src/server/session.c (login_old): Removed the conf_c argument from all calls to is_supervisor. (login): Likewise. (disconnect): Likewise. 1999-07-03 David Byers * src/server/handle-malloc-dump.el (trace-run-programs): Fixed timing problems that caused lyskomd to run before gdb was prepared for it. 1999-07-04 Per Cederqvist Prepare for improving access_perm(). * src/server/membership.c (plain_ol_fast_access_perm): Assert that viewer_conn is never NULL. (access_perm): Log a warning if called with an unexpected wanted_access argument. New convenience check targets. * src/server/Makefile.am (check-lyskomd): New target. (check-leaks): New target. 1999-07-02 David Byers Automatic operation of memory trace analysis: * src/server/ram-smalloc.c: Mention automatic analysis. Update the description on how to do it manually (MEMTRACE=file, ATTACH=yes) * src/server/handle-malloc-dump.el: Added automatic operation in batch mode. Just run -batch and watch the magic happen. 1999-07-02 David Byers Some test cases for name lookup: * src/server/testsuite/Makefile.am (EXTRA_DIST): Added 12 and 13.exp. * src/server/testsuite/lyskomd.0/13.exp: New file. Some name lookup tests. * src/server/testsuite/lyskomd.0/11.exp: Do the right thing when traced allocations are on. 1999-07-01 David Byers * src/server/dbck.c (main): Stole code from test-l2g.c for when traced allocations are on. Eliminate the need to call build_matching_info all the time: * src/server/simple-cache.c (rebuild_matching_info_entry): New function to rebuild a single entry in the matching info table. (find_matching_info_index): New function. (cached_change_name): Use rebuild_matching_info_entry insead of build_matching_info. * src/libraries/libcommon/parser.c (parse): Loop until we see a zero conf-no instead of an empty name. Just skip empty names. * src/server/cache.h (cached_no_of_existing_conferences): Removed extern declaration of build_matching_info. Eliminate conf_table: * src/libraries/libcommon/parser.c: Include kom-types.h so we can include parser.h. * src/server/conference.c: Removed extern declaration of conf_table. Added extern declaration of match_table. (unique_name): Use match_table, not conf_table. * src/server/simple-cache.c: (conf_table): Removed. (build_matching_info): Removed conf_table. (cached_lookup_name): Use match_table instead of conf_table. (free_all_cache): Removed conf_table. * src/libraries/libcommon/parser.h (Matching_info): Added conf_no field. 1999-06-29 David Byers * doc/Protocol-A.texi (sub-comment): Changed sub-comment from obsolete to recommended. 1999-07-01 Per Cederqvist Added the ``wanted_access'' argument to access_perm(), removed fast_access_perm(), and updated all callers. * src/server/manipulate.h (access_perm): New parameter: wanted_access. Never return anything higher than it. All callers updated. (fast_access_perm): Removed. All callers changed to use access_perm instead. * src/server/membership.c: Pass the new argument wanted_access to access_perm(). Use access_perm() instead of fast_access_perm(). (access_perm): Proof-of-concept implementation using plain_ol_access_perm and plain_ol_fast_access_perm. This needs lots of clever speedups. * src/server/admin.c: Pass the new argument wanted_access to access_perm(). Use access_perm() instead of fast_access_perm(). * src/server/conference.c: Likewise. * src/server/person.c: Likewise. * src/server/regex-match.c: Likewise. * src/server/send-async.c: Likewise. * src/server/text.c: Likewise. Turn of async messages during shutdown. * src/server/ramkomd.c (main): Turn of async messages during shutdown. * src/server/testsuite/lyskomd.0/00.exp: Dont expect any async messages during server shutdown. * src/server/testsuite/lyskomd.0/02.exp: Likewise. * src/server/testsuite/lyskomd.0/03.exp: Likewise. * src/server/testsuite/lyskomd.0/08.exp: Likewise. 1999-06-30 Per Cederqvist * README: Talk a little about the config file. Broken typo fix fixed. * NEWS: Changed "the near feature" to "a future release". 1999-06-28 Per Cederqvist Fixed a bug that causes created_texts to contain some deleted texts. * src/server/text.c (do_delete_text): Don't forget to call mark_person_as_changed -- the authors' list of created texts must be updated. * src/server/testsuite/lyskomd.0/12.exp: Detect the above bug. * src/server/testsuite/config/unix.exp (dbck_run): New proc. (lyskomd_death): Call dbck_run to check the database after each shutdown. 1999-06-27 Per Cederqvist * Release 2.0.0. Port to places such as AIX 4.2 where char is an unsigned type. * src/server/dbck.c (main): Use an int to store the return value from getopt_long. * src/server/dbck-cache.c (init_cache): Use an int to store the return value from getc. Port the test suite to OSF 3.0. * src/server/testsuite/config/unix.exp (stty_init): Quote the ^ character. Some shells interpret it as a pipe. * README: Mention that Python is needed by the test suite. Specify more of the behavior of get-unread-confs. * doc/Protocol-A.texi (get-unread-confs): Specify the order of the returned conference numbers. 1999-06-26 Per Cederqvist Port the makefiles and test suite to FreeBSD. * src/server/testsuite/Makefile.am (RM): Set it. * src/server/Makefile.am (RM): Set it. * doc/Makefile.am (RM): Set it. * src/server/testsuite/config/unix.exp (unanchored_expect): Don't leave an unparsed space behind when an unexpected output appears before a prompt. * src/server/testsuite/lyskomd.0/01.exp: Don't be confused about the newline emitted in the collate table. * src/server/testsuite/lyskomd.0/03.exp: Likewise. * src/server/testsuite/config/unix.exp (stty_init): Remove "-ocrnl" which isn't portable to FreeBSD. Port the test suite to HP/UX. * src/server/testsuite/config/unix.exp (stty_init): Add "-isig erase ^- kill ^- werase ^-". Port the test suite to non-gcc compilers. * src/server/testsuite/test-l2g.c (MAXMAPS): Use #define instead of "const int" so that the symbol can portably be used as an array size. (LINSIZE): Likewise. (ARGS): Likewise. 1999-06-26 David Byers * src/include/kom-types.h (Membership_type): Changed all fields from Bool to unsigned int. * src/server/aux-items.c: Removed support for precompiled aux items. It was not currently used, and caused compilation errors under HP/UX. 1999-06-26 Per Cederqvist Fix coding error. * src/server/aux-items.c (aux_item_add_perm): Don't use find_aux_item_definition to set def if def is already set. Remove lint found by HP/UX c89. * src/server/ram-parse.c (fparse_aux_item_link): Missing semicolon added. * src/server/ram-output.c (foutput_aux_item_link): Missing semicolon added. (foutput_mark_list): Declare the function static in all declarations, not only some. * src/server/aux-items.h (aux_item_validators): This is static, so remove it form the header file. (aux_item_triggers): Likewise. * src/server/aux-items.c (mark_linked_object_as_changed): Missing semicolon added. * src/server/session.c (create_oldstyle_username): Remove needless casts. (login_old): Likewise. (login): Likewise. * HACKING: We use bison 1.27. 1.25 had problems with alloca under HP/UX. 1999-06-26 David Byers Send new-membership only for new memberships. * doc/Protocol-A.texi (async-new-membership): Remove documentation that says this message is sent when a membership is reprioritized. * src/server/testsuite/lyskomd.0/06.exp (shutdown_06): Don't expect new-membership when membership is changed. * src/server/membership.c (add_member_common): Only send new-membership for new memberships, not changed memberships. 1999-06-25 Per Cederqvist "make check" failed if the source tree was read-only. * src/server/testsuite/config/unix.exp (lyskomd_start): Use chmod to make sure that the database is writable even if it is copied from a read-only tree. "make -j install" could fail. * run-support/Makefile.am (install-data-local): Depend on installdirs. * db-crypt/db/Makefile.am (install-data-local): Depend on installdirs. Port to SunOS 4.1.1. * src/server/aux-item-def-scan.l: Include . * configure.in: Check for sig_atomic_t. * acconfig.h: Added sig_atomic_t. Release administrativa. * scripts/lyskomd-copyrights: Don't attempt to update copyright notices in TeX temporary files. Documentation fixes. * TODO: No showstoppers left. * NEWS: Several minor modifications. * README: Spelling errors fixed. * doc/Protocol-A.texi (mark-text-old): Spelling error fixed. (get-text-stat-old): Talk about bcc-recpt. (Protocol Requests): Warn that obsolete calls perform compatibility magic. Include the number of the protocol request in the printed heading of the corresponding section. (set-pers-flags): Fix sectioning error. (get-unread-confs): Clarify that passive memberships are never returned. Performance fix. * src/server/internal-connections.c: Turn off defensive checks in this file. They cost too much CPU. Release administrativa. * doc/Protocol-A.texi (Document Revision History): Update the release date for revision 10.0. * NEWS: Sort the news. The test suite failed when compiled outside the source directory. * src/server/testsuite/leaks.0/leaks10.exp: startup_leaks wants a relative path to the aux-items.conf file. * src/server/testsuite/leaks.0/leaks99.exp: Likewise. 1999-06-24 Per Cederqvist Fix messages created by dbck. * src/server/dbck.c (garb_text_file): Don't log the message "Ready."; the caller also logs it. Add trailing newline in format string to kom_log in the following functions: * src/server/regex-match.c (lookup_regexp): * src/server/ramkomd.c (sighandler_usr2): * src/server/prot-a-parse.c (prot_a_parse_num_list): (prot_a_parse_string): (prot_a_parse_aux_item_list): (prot_a_parse_misc_info_list): * src/server/person.c (do_unmark_text): (create_person_generic): * src/server/membership.c (mark_as_read): (set_membership_type): * src/server/dbck.c (main): * src/server/dbck-cache.c (cached_flush_text): * src/server/connections.c (call_function): (toploop): * src/server/conference.c (do_create_conf): * src/server/aux-items.c (find_linked_aux_item_list): (aux_item_validate): 1999-06-24 David Byers * src/server/aux-items.c (aux_item_validate): Do not print the regexp that failed to compile since it is gone by this time. 1999-06-23 Per Cederqvist The default language is now selectable at configure time. * README: Mention --with-language=sv. * configure.in: Handle --with-language=sv. * db-crypt/db/Makefile.am (LANGUAGE_SUFFIX): New variable. (EXTRA_DIST): Added lyskomd-data-en. (install-data-local): Install lyskomd-data-en or lyskomd-data, depending on LANGUAGE_SUFFIX. * db-crypt/db/lyskomd-data-en: New file. Remove the unused file tmp-limits.h. * src/server/Makefile.am (lyskomd_SOURCES): Removed tmp-limits.h. * src/server/tmp-limits.h: Unused file removed. * NEWS: More items added. This should now be fairly complete, but it may need restructuring. 1999-06-23 David Byers * src/server/dbck.c (init_person_scratch): Initialize person scratchpad entries to NULL. 1999-06-21 Per Cederqvist Fix the test suite. * src/server/testsuite/lyskomd.0/11.exp: Updated to match the log messages currently sent by lockdb.c. Don't send too many async-logout messages. * src/server/connections.c (logout_client): Back out the change made 1999-01-16; no longer send async-logout if the session is not logged in. * src/server/testsuite/lyskomd.0/07.exp: Don't expect async-logout when sessions are disconnected. * doc/Protocol-A.texi (async-logout): This message is not necessarily sent when a session disconnects and nobody is logged in. 1999-06-20 Per Cederqvist Release fixes. * HACKING: Added a missing call to ./configure. * NEWS: Updated the release date. Improve log messages regarding database locking. * src/server/lockdb.c (lock_db): Clarify log messages. * src/server/ramkomd.c (initialize): Write an "exiting" message when the lock cannot be obtained. Fix parameters "Jubel" and "Ident-authentication". * src/server/server-config.c (parameters): Removed duplicate "Ident-authentication". * src/server/standalone.c (register_jubel): Don't call abort -- this gets called from dbck if the config file contains a Jubel. 1999-06-19 Per Cederqvist Save 5 items (configurable) per call. * src/server/param.h (struct kom_par): Added saved_items_per_call. * src/server/disk-end-of-atomic.c (end_of_atomic): Handle param.saved_items_per_call. * doc/lyskomd.texi (Parameters): Documented "Saved items per call". * src/server/server-config.c (parameters): Added "Saved items per call". (read_configuration): Check that param.saved_items_per_call is at least 1. 1999-06-14 Per Cederqvist Track name change of 556450-2507. * doc/lyskomd.texi (Overview): Signum Support has a new name: Cendio Systems. 1999-06-13 Per Cederqvist Allow at most 128 aux_items of at most 16384 bytes each to be added at a single time. * src/server/server-config.c (parameters): Added "Max aux_item length". Changed default of "Max aux_items added per call" to 128. * src/server/prot-a-parse.c (prot_a_parse_aux_item): Use param.aux_len instead fo param.text_len as the limit for the aux-item size. * src/server/param.h (struct kom_par): Added aux_len. * doc/lyskomd.texi (Parameters): Document "Max aux_items added per call". Lowered the default from "Max aux_items added per call". 1999-06-13 David Byers * src/server/testsuite/lyskomd.0/03.exp: Fix test cases for change in aux_item_link_items below. * src/server/testsuite/lyskomd.0/aux-items-cov.exp: Fix test cases for change in aux_item_link_items below. * src/server/aux-items.c (aux_item_link_items): Creator of linked aux item is now the creator of the source item. This gives the creator of the source item power over the linked item. 1999-06-11 David Byers * src/server/aux-items.c: Cleared up comment for undelete_aux_item_list. 1999-06-05 David Byers * src/server/text-garb.c: Always include setjmp.h 1999-06-05 Per Cederqvist Test lock files. * src/server/testsuite/lyskomd.0/11.exp: New file. * src/server/testsuite/Makefile.am (EXTRA_DIST): Added lyskomd.0/11.exp. * src/server/Makefile.am (all-recursive check-recursive): Depend on dbck. * src/server/lockdb.c (lock_db): Log a message when a stale lock is removed. * src/server/dbck.c (main): Don't die until a character has been read if -d is used. * src/server/ramkomd.c (initialize): Don't die until a character has been read if -d is used. text-garb.c failed to compile unless --with-debug-calls was used. * src/server/text-garb.c: Always include , since it is needed by connections.h. strdup() is no longer used, so a replacement function is not needed. * configure.in: Commented out AC_REPLACE_FUNCS(strdup). * src/libraries/libansi/Makefile.am (EXTRA_DIST): Added strdup.c. 1999-06-05 David Byers * regexp-match-cov.exp: New test case. * src/server/regex-match.c (lookup_regexp): Don't use strdup to copy the collate table. * src/server/text.c (modify_text_info): Check for read access on text. * src/server/conference.c (modify_conf_info): Check for secret confs. 1999-05-31 David Byers * src/server/text.c (add_comment): Moved access checks to avoid leaking information. (add_footnote): Same here. * src/server/membership.c (set_membership_type): Move permission checks to avoid leaking information. * doc/lyskomd.texi (Adding a New Protocol Request): Added notes on CHK_CONNECTION, CHK_LOGIN and how to avoid leaking secret information. * src/server/text.c (add_recipient): Moved GET_X_STAT and permission checks around to avoid leaking secret information. * src/server/text-garb.c (start_garb): Same here. * src/server/debug.c (get_memory_info): Call CHK_CONNECTION. (backdate_text): Same here. * src/server/aux-items.c (query_predefined_aux_items): Call CHK_CONNECTION. * src/server/admin.c (get_info_old): Call CHK_CONNECTION. (get_version_info): Same here. (set_info): Same here. (set_motd_of_lyskom): Same here. (sync_kom): Same here. * src/server/session.c (get_time): Call CHK_CONNECTION. (who_is_on_old): Same here. * src/server/text.c (local_to_global): Moved CHK_CONNECTION to very start of function. (get_last_text): Call CHK_CONNECTION. * src/server/person.c (set_priv_bits): Call CHK_CONNECTION. * src/server/session.c (get_client_version): Call CHK_CONNECTION. (get_client_name): Same here. (get_session_info): Same here. (get_session_info_ident): Same here. (get_static_session_info): Same here. 1999-06-04 Per Cederqvist Clean up file inclusion. Avoid including files from .h files. Avoid underscores in dubious places. * src/server/admin.c: Don't include . * src/server/conf-file.c: Likewise. * src/server/conference.c: Likewise. * src/server/connections.c: Likewise. * src/server/dbck-cache.c: Likewise. * src/server/internal-connections.c: Likewise. * src/server/membership.c: Likewise. * src/server/memory.c: Likewise. * src/server/person.c: Likewise. * src/server/prot-a-parse.c: Likewise. * src/server/ram-output.c: Likewise. * src/server/ram-parse.c: Likewise. * src/server/ramkomd.c: Likewise. * src/server/regex-match.c: Likewise. * src/server/rfc931.c: Likewise. * src/server/send-async.c: Likewise. * src/server/server-config.c: Likewise. * src/server/session.c: Likewise. * src/server/simple-cache.c: Likewise. * src/server/text-garb.c: Likewise. * src/server/text.c: Likewise. * src/server/testsuite/test-l2g.c: Include "kom-types.h". * src/server/local-to-global.h: Don't include "kom-types.h". * src/server/log.h: Don't include . Don't declare kom_logv. Don't use leading underscores or double underscores in symbols we define. * src/server/log.c (kom_logv): Now static. * src/include/compiler.h: Don't use leading underscores or double underscores in symbols we define. * src/include/kom-errno.h: Likewise. * src/include/kom-types.h: Likewise. * src/include/misc-types.h: Likewise. * src/include/services.h: Likewise. Distribute new test suite files. * src/server/testsuite/Makefile.am (EXTRA_DIST): Added lyskomd.0/09.exp and lyskomd.0/10.exp. Some systems lack strdup. * configure.in: Added AC_REPLACE_FUNCS(strdup). * src/libraries/libansi/strdup.c (strdup): Replacement implementation. 1999-05-31 Per Cederqvist Fixed typo in the test suite. * src/server/testsuite/lyskomd.0/09.exp: Don't mix the timestamps for texts 5 and 6. 1999-05-31 David Byers * src/server/server-config.c: Removed duplicate regexps use collate table. * src/server/manipulate.h (CHK_LOGIN): Check for NULL active_connection. (ENA): Survive a NULL active_connection. (HAVE_PRIV): Take a Person argument. 1999-05-30 David Byers * src/server/text-garb.c (garb_text): Reset deleted_texts after sending the debug message. 1999-05-30 David Byers * src/server/testsuite/lyskomd.0/09.exp (1015): Data sent to client 2 contained secret recipient. Fixed. * src/server/testsuite/lyskomd.0/05.exp: Fixed added_by field in Membership and Member * src/server/testsuite/lyskomd.0/03.exp: (1349,1350, 1351, 2001, 2006): Fixed added_by field in Membership and Member * src/server/testsuite/lyskomd.0/01.exp: (1116): Fixed added_by field in Membership * src/server/regex-match.c (lookup_regexp): Copy the collate table before putting it into the pattern buffer. * src/server/testsuite/lyskomd.0/00.exp (1038): Person 6 added himself to his letterbox. * src/server/membership.c (do_add_member): Take added_by as an argument. (add_member_common): Call do_add_member with explicit added_by. * src/server/person.c (create_person_generic): The person adding the mailbox membership is the same as the creator of the person. Fixed problems related to permission checking * src/server/membership.c (fast_access_perm): Take a connection argument instead of a person and pers_stat combo. (access_perm): Same here. (copy_public_confs): Same here. * src/server/text.c (ok_to_create_next_text): Same here. * src/server/regex-match.c (lookup_regexp): Test for param.regex_use_collate_table was inverted. (lookup_regexp): Added connection argument. * src/server/text.c (filter_secret_info): Take a connection argument instead of viewer and viewer_p (send_async_deleted_text): Call filter_secret_info with connection argument. (get_text_stat_old): Same here. (get_text_stat): Same here. (send_async_new_text_old): Same here. (send_async_new_text): Same here. (person_text_read_access): Check that active_connection is set before attempting to use it. (text_read_access): Take a connection as an argument. * src/server/conference.c (get_conf_stat): Call filter_aux_item_list with active_connection instead of ACTPERS and ACT_P. * src/server/admin.c (get_info): Call filter_aux_item_list with active_connection instead of ACTPERS and ACT_P. * src/server/session.c (leave_conf): New parameter for connection to remove dependency on active_connection. * src/server/internal-connections.c (get_conn_by_number): Defensive check on active_connection. Restart server if active_connection is unset and no session number is specified since callers of this function expect to get something sensible out of it. * src/server/manipulate.h (CHK_CONNECTION): New macro. Call this at the head of every RPC function. * src/server/admin.c (shutdown_kom): Signal internal error if we don't have an active connection. 1999-05-30 Per Cederqvist Improve the test suite. * src/server/testsuite/lyskomd.0/09.exp: Added async messages sent by the garb when it deletes text 2, 4 and 6. This is untested and may break. 1999-05-30 Per Cederqvist Don't send async-sub-recipient messages when texts are deleted. * src/server/text.c (perform_subtraction): New static function, extracted from do_sub_recpt. Only send async-sub-recipient if the new argument want_async is true. (do_sub_recpt): Code simplified by creation of perform_subtraction(). New argument: want_async (see above). (do_delete_text): Tell do_sub_recpt that we don't want any async-sub-recipient messages. (sub_recipient): Tell do_sub_recpt to send async-sub-recipient messages. * src/server/testsuite/lyskomd.0/09.exp: async-sub-recipient messages are no longer erroneously sent. Comment out the code that causes a core dump. * src/server/testsuite/lyskomd.0/send-async-cov.exp: Likewise. * src/server/testsuite/lyskomd.0/06.exp: async-sub-recipient messages are no longer erroneously sent. Added a test case that corresponds to the bug found 1999-05-24. * src/server/testsuite/lyskomd.0/09.exp: This test now causes lyskomd to dump core while garbing texts. Async-sub-recipient was not always sent when it should be, and it contained bogus data. * src/server/testsuite/lyskomd.0/10.exp: Check async-sub-recipient. * src/server/text.c (do_sub_recpt): Send async-sub-recipient immediately before removing the recipient, so that we know where to send it. As a side effect the type is now read from the proper misc-info group. (send_async_deleted_text): Use #if 0 instead of comments to comment out code. * src/server/testsuite/lyskomd.0/send-async-cov.exp: Handle async-sub-recipient messages that are (probably erroneously) sent. * src/server/testsuite/lyskomd.0/06.exp: Handle async-sub-recipient messages that are (probably erroneously) sent. New debug call: start-garb. New debug async: garb-ended. * src/server/testsuite/lyskomd.0/09.exp: New tests. * src/server/text-garb.c (last_checked): Moved to file-level scope, so that start_garb can access it. (last_start): Likewise. (garb_text): Send async-garb-ended when the garb ends, but only if DEBUG_CALLS is defined. (start_garb): New function, only present when DEBUG_CALLS is defined. * src/server/session.c (accept_async): Handle ay_garb_ended if DEBUG_CALLS is defined. * src/server/send-async.c (async_garb_ended): New function, only present when DEBUG_CALLS is defined. * src/server/send-async.h: Likewise. * src/server/prot-a-send-async.c (prot_a_async_garb_ended): New function, only present when DEBUG_CALLS is defined. * src/server/prot-a-send-async.h: Likewise. * src/server/fncdef.txt: New debug call: start_garb. * src/server/async.h (Async): New debug async: ay_garb_ended. * src/include/services.h (start_garb): New debug call. Cut-n-paste error in Protocol-A.texi fixed. * doc/Protocol-A.texi (async-sub-recipient): The explanation talked about "the new recipient". 1999-05-24 Per Cederqvist Removed a newline in the log. * src/server/simple-cache.c (init_cache): Removed an extra newline in the log output. Don't lose data when converting the database. * src/server/ram-output.c (foutput_membership): Call foutput_membership_0 for output format 1. (foutput_membership_list): Call foutput_membership_list_0 for output format 1. * src/server/ram-output.c (foutput_text_list): Don't get stuck in an eternal loop. * src/server/dbck-cache.c (cache_sync_all): Output format 2 is known. * src/server/ram-parse.c (fparse_text_list): Set first_appendable_key when reading a Local_to_global from an old-style empty text-list. * src/server/local-to-global.c (l2g_set_first_appendable_key): New function. * src/server/local-to-global.h: Likewise. 1999-05-24 David Byers * src/server/ram-parse.c (fparse_member_list): Initialize member structure before parsing it. * src/server/memory.c (init_member): New function. 1999-05-24 Per Cederqvist Update the distributed config file. * run-support/config: Removed the "Mux port" line. Update the help message of dbck. * src/server/dbck.c (give_help): File format 2 is supported. Port to Solaris. * src/server/lockdb.c: Include . Fix the anti-timetravel change. * src/server/dbck-cache.c (sync_output_header): Output the supplied state instead of hardcoding it to DIRTY. Added a missing const. Added copyright header to the following files. * src/server/testsuite/config/leaks.exp: * src/server/testsuite/config/prot-a.exp: * src/server/testsuite/l2g.0/00.exp: * src/server/testsuite/l2g.0/01.exp: * src/server/testsuite/l2g.0/02.exp: * src/server/testsuite/l2g.0/03.exp: * src/server/testsuite/l2g.0/04.exp: * src/server/testsuite/l2g.0/05.exp: * src/server/testsuite/l2g.0/06.exp: * src/server/testsuite/l2g.0/07.exp: * src/server/testsuite/l2g.0/08.exp: * src/server/testsuite/l2g.0/09.exp: * src/server/testsuite/l2g.0/10.exp: * src/server/testsuite/l2g.0/11.exp: * src/server/testsuite/leaks.0/leaks00.exp: * src/server/testsuite/leaks.0/leaks01.exp: * src/server/testsuite/leaks.0/leaks02.exp: * src/server/testsuite/leaks.0/leaks03.exp: * src/server/testsuite/leaks.0/leaks04.exp: * src/server/testsuite/leaks.0/leaks05.exp: * src/server/testsuite/leaks.0/leaks06.exp: * src/server/testsuite/leaks.0/leaks07.exp: * src/server/testsuite/leaks.0/leaks08.exp: * src/server/testsuite/leaks.0/leaks09.exp: * src/server/testsuite/leaks.0/leaks10.exp: * src/server/testsuite/leaks.0/leaks99.exp: * src/server/testsuite/lyskomd.0/00.exp: * src/server/testsuite/lyskomd.0/01.exp: * src/server/testsuite/lyskomd.0/02.exp: * src/server/testsuite/lyskomd.0/03.exp: * src/server/testsuite/lyskomd.0/04.exp: * src/server/testsuite/lyskomd.0/05.exp: * src/server/testsuite/lyskomd.0/06.exp: * src/server/testsuite/lyskomd.0/07.exp: * src/server/testsuite/lyskomd.0/08.exp: * src/server/testsuite/lyskomd.0/admin-cov.exp: * src/server/testsuite/lyskomd.0/aux-items-cov.exp: * src/server/testsuite/lyskomd.0/aux-items.conf: * src/server/testsuite/lyskomd.0/aux-items.cov: * src/server/testsuite/lyskomd.0/broken-aux-items.conf: * src/server/testsuite/lyskomd.0/cache-node-cov.exp: * src/server/testsuite/lyskomd.0/conf-file-cov.exp: * src/server/testsuite/lyskomd.0/conference-cov.exp: * src/server/testsuite/lyskomd.0/connections-cov.exp: * src/server/testsuite/lyskomd.0/disk-end-of-atomic-cov.exp: * src/server/testsuite/lyskomd.0/membership-cov.exp: * src/server/testsuite/lyskomd.0/null.exp: * src/server/testsuite/lyskomd.0/person-cov.exp: * src/server/testsuite/lyskomd.0/prot-a-parse-cov.exp: * src/server/testsuite/lyskomd.0/prot-a-send-async-cov.exp: * src/server/testsuite/lyskomd.0/send-async-cov.exp: * src/server/testsuite/lyskomd.0/session-cov.exp: * src/server/testsuite/lyskomd.0/text-cov.exp: * src/server/testsuite/tcpconnect.py: * src/server/testsuite/test-l2g.c: Release administrativa. * NEWS: Set the release date to 1999-05-31. * configure.in: Set version number to 2.0.0. * versions (SERVER-VERSION): 2.0.0. (SERVER-COMPAT-VERSION): 20000. Cleanup. * doc/prot-A-english.txt: File removed. * src/server/To-do: File removed. * src/server/Makefile.am (EXTRA_DIST): Removed To-do. Update copyright notices. * : update the year in the copyright notice. * scripts/update-copyright: Handle yearspans. * scripts/lyskomd-copyrights: Updated the list of files to ignore. Documentation fixes. * doc/Protocol-A.texi (get-collate-table): Document what short collate tables means. * doc/lyskomd.texi (Administration): komrunning now takes the arguments "start" and "stop". * HACKING: Mention the versions of bison and flex. * README: Updated for the release. Work around automake bugs. * src/server/testsuite/Makefile.am (noinst_DATA): Removed the "nodist_" prefix, which was apparently broken. * doc/Makefile.am (dist_noinst_DATA): Removed to work around an automake bug. For now, the check for tabs is not performed automatically. 1999-05-23 Per Cederqvist Documentation fixes. * doc/Protocol-A.texi (Top): Updated for release. (What do I have unread): @code{@xref{}} and @code{@ref{}} don't work, so don't use the construct. --with-traced-allocations broke the test suite. * src/server/testsuite/config/unix.exp (l2g_start): Handle TRACED_ALLOCATIONS. * src/server/testsuite/test-l2g.c (main): Handle TRACED_ALLOCATIONS. * src/server/ram-smalloc.c: Comment updated. Update the protocol revision. * src/server/fncdef.txt: Whitespace fix. * doc/Protocol-A.texi: Removed all up, next and prev pointers once again. (Document Revision History): Specify tomorrow as release date. (Protocol Version History): Update the entry for protocol version 10. The status of 59=create-anonymous-text-old was changed to Obsolete in protocol version 10, not version 9. (Protocol Requests): Mark experimental calls with an "e". (add-member-old): Typo fixed. (unmark-text): This was introduced in protocol version 6, not 4. (set-expire): Change status to Experimental. (set-keep-commented): Change status to Experimental. (set-pers-flags): Fix markup error. 1999-05-22 David Byers Timestamp the saved database and refuse to start if the server travels backwards through time: * doc/lyskomd.texi (Version 2): Documented new header format. * db-crypt/db/lyskomd-data: Added timestamp * src/server/dbck-cache.c (cache_sync_all): Handle output format 2. (sync_output_header): New function. (cache_sync_all): Use sync_output_header to output file header. * src/server/simple-cache.c (pre_sync): Use sync_output_header. (sync_output_header): New function outputs file header and timestamp. (save_one_text): Use it. (init_cache): Check the timestamp on the database before loading. * src/server/connections.c (toploop): Log a warning if time starts moving backwards. Documentation fixes: * doc/Protocol-A.texi (get-membership): Fixed FIXME. * doc/lyskomd.texi: Fixed misplaced @code and @i markup. * doc/Protocol-A.texi: Fixed misplaced @code and @samp markup. 1999-05-23 Per Cederqvist Port to automake 1.4a. * src/server/testsuite/Makefile.am (check_PROGRAMS): Don't bother building test-l2g until "make check". (nodist_noinst_DATA): Dont' distribute site.exp and .gdbinit. 1999-05-23 Per Cederqvist Disallow tabs in lyskomd.texi. * doc/Makefile.am (dist_noinst_DATA): New target, containing Protocol-A.notab and lyskomd.notab. (MOSTLYCLEANFILES): Added Protocol-A.notab and lyskomd.notab. (protocol-a.info): Remove the tab-checking code. (SUFFIXES): Added .texi .notab. (.texi.notab): New rule, that checks that no tabs exist in Texinfo files. Get rid of the file local-to-global.doc. Various fixes to lyskomd.texi. * doc/Makefile.am (EXTRA_DIST): Remove local-to-global.doc. * doc/local-to-global.doc: File removed; contents moved into lyskomd.texi. * doc/lyskomd.texi: Removed all up, next and prev pointers once again. Untabify. Remove trailing whitespace from lines. (Overview): Added a missing "General" to the name of the license. Don't talk about my private future plans. (Installation): Refer to README. (DBCK Bugs): don't say that dbck doesn't lock the database; it does. (Function Templates for prot-a-send-async.c): Improve the markup. (Configuration Options): Mention --with-traced-allocations. (local-to-global): New node. Not yet translated. 1999-05-22 Per Cederqvist Translated and updated the release instructions. * HACKING: New file. This contains an updated translation of SERVER-RELEASE and information about the versions of various tools that was used to create the release. * SERVER-RELEASE: Removed. * Makefile.am (EXTRA_DIST): Added HACKING. Removed SERVER-RELEASE. 1999-05-21 Per Cederqvist "make dist" fixes. * src/server/Makefile.am (lyskomd_SOURCES): Added server-time.h * src/server/testsuite/Makefile.am (EXTRA_DIST): Changed leaks.0/no-aux-items.exp and leaks.0/lots-aux-items.exp to leaks.0/no-aux-items.conf and leaks.0/lots-aux-items.conf. * doc/Makefile.am (EXTRA_DIST): Removed ADMINISTRATION and misc_items. Get rid of the very obsolete SERVER and CLIENT macros. * src/server/testsuite/Makefile.am (INCLUDES): Removed -DSERVER. * src/server/Makefile.am (INCLUDES): Removed -DSERVER. * src/libraries/libcommon/parser.c: Don't use SERVER. * src/libraries/libcommon/Makefile.am (INCLUDES): Removed -DSERVER. * src/include/services.h: Don't use SERVER or CLIENT. Fix some indentation. (KOM_): Macro removed. All users updated. * src/include/kom-types.h: Don't use SERVER or CLIENT. Fix some indentation. * configure.in: Don't define SERVER. * acconfig.h (PROTOTYPES): Removed. (SERVER): Removed. (VERSION): Removed. Remove all gcov files in "make mostlyclean". * src/server/testsuite/Makefile.am (MOSTLYCLEANFILES): Added "*.da", "*.bb", "*.gcov" and "*.bbg". * src/libraries/libmisc/Makefile.am: Likewise. * src/libraries/libcommon/Makefile.am: Likewise. 1999-05-21 David Byers * doc/lyskomd.texi (Adding New Input Types): Document the fact that you have to free data in prot_a_destruct as well. * src/server/prot-a.c (prot_a_destruct): Free num_lists in the client structure. 1999-05-21 Per Cederqvist Don't lock the database when dbck is running in read-only mode. * src/server/dbck.c (iflag): Now static. (rflag): Now static. (gflag): Now static. (sflag): Now static. (force_output): Now static. (unset_change_name_is_error): Now static. (dump_text_numbers): Now static. (main): Only lock the database when dbck might want to change it. Added a missing break statement. Mark the database as modified if any of --pres-pres-conf, --conf-pres-conf, --motd-conf, --motd-of-kom or --kom-news-conf is used. 1999-05-21 David Byers * src/server/testsuite/Makefile.am (EXTRA_DIST): Added null.exp * doc/lyskomd.texi: Merged lyskomdb.texi into this document. * src/server/server-config.c: Unassign the lockfile name. * doc/Makefile.am (info_TEXINFOS): Removed deleted files. (EXTRA_DIST): Removed deleted files from EXTRA_DIST. * src/server/conf-file.c (unassign_string): New function. * src/server/conf-file.h (parameter): Added a free function. * src/server/simple-cache.c (free_all_cache): Free the small_conf_arr. * src/server/ramkomd.c (dump_exit_statistics): Moved remaining frees from main to here. 1999-05-20 David Byers * src/server/testsuite/config/unix.exp: You can now supply MEMTRACE, ATTACH and EFENCE algorithms on the runtest command line. * src/server/testsuite/Makefile.am (EXTRA_DIST): Added new leak tests to EXTRA_DIST. Eliminated memory leaks in aux-item definition parser * src/server/aux-items.c (free_aux_item_definitions): Free each individual aux item definition. Another memory leak down the drain. * src/server/aux-item-def-parse.y: Free the string of an ID parameter when we see one. Another memory leak bites the dust. * src/server/aux-items.c (aux_item_definition_cache_regexp): Plug a really minor (constant size) memory leak. * src/server/aux-item-def-parse.y: Use string_free to free stuff allocated with s_crea_c_str. * src/server/aux-items.c (aux_item_trigger_link_item): Use string_free to free string allocated with s_crea_c_str. (free_aux_item_definitions): Same here. 1999-05-19 David Byers * src/server/prot-a-parse.c (prot_a_parse_aux_item_list): Clear the dummy aux item after parsing it. Memory leak plugged. * src/server/memory.c (clear_aux_item): New function. (free_aux_item_list): Use it. * src/server/prot-a-parse.c (prot_a_parse_num_list): Handle truncation so protocol errors during truncation will not break the server. (prot_a_hunt_nl): Same here. (prot_a_parse_aux_item_list): Same here. * src/server/prot-a.c (prot_a_init): Initialize array_parse_parsed_length * src/server/internal-connections.c (init_connection): Initialize array_parse_parsed_length * src/server/connections.c (free_parsed): Initialize array_parse_parsed_length. * src/server/connections.h (Connection): Added array_parse_parsed_length * src/server/fncdef.txt: Truncate strings in set_client_version to client_data_len. * src/server/ramkomd.c (main): Free aux-item definitions on exit. * src/server/aux-items.c (free_aux_item_definitions): New function to free all data associated with aux-item defs. * src/server/ramkomd.c (main): Free aux-item definition. 1999-05-18 David Byers * src/server/prot-a-parse.c (prot_a_parse_aux_item_flags): Handle variable-length bitfields. * src/server/memory.c (init_aux_item_flags): New function. * src/server/prot-a-parse.c (prot_a_parse_priv_bits): Handle variable-length bitfields. (prot_a_parse_membership_type): Same here. (prot_a_parse_conf_type): Same here. * src/server/memory.c (init_membership_type): New function. * doc/Protocol-A.texi (set-client-version): Added list of known clients. * ChangeLog.1: Inserted doc/LOGG * doc/LOGG: Added to ChangeLog.1 * src/server/conference.c (set_supervisor): Use is_strictly_supervisor instead of is_supervisor. 1999-05-21 Per Cederqvist Lock the database file with an explicit lock file. * src/server/dbck.c (main): Lock and unlock the database. * src/server/ramkomd.c (init_data_base): Log the name of the lock file. (initialize): Lock the database before opening it. (main): Unlock the database. * src/server/server-config.c (parameters): Added "Lock file". (read_configuration): Handle param.lockfile_name. * src/server/param.h (struct kom_par): Added lockfile_name. * src/server/Makefile.am (lyskomd_SOURCES): Added lockdb.h and lockdb.c. (DBCK): Likewise. * src/server/lockdb.c, src/server/lockdb.h: New files. (lock_db): New function. (unlock_db): New function. * doc/lyskomd.texi (Parameters): Document "Lock file:". 1999-05-20 Per Cederqvist Clean up the framework for hunting memory leaks. * src/server/ram-smalloc.c: Document --with-traced-allocations. * src/server/realloc.gdb: File removed. * src/server/malloc.gdb: File removed. * src/server/free.gdb: File removed. * src/server/Makefile.am (EXTRA_DIST): Removed free.gdb, malloc.gdb and realloc.gdb. 1999-05-20 Per Cederqvist dbck failed to handle bcc_recpts. * src/libraries/libcommon/misc-parser.c (parse_next_misc): Handle bcc_recpt. Fix usage of the COMPILE_CHECKS macro. Fix usage of the COMPILE_CHECKS macro. * src/server/text.c (find_recipient): Fix usage of the COMPILE_CHECKS macro. (is_member_in_recpt): Likewise. (do_delete_misc): Likewise. (do_sub_recpt): Likewise. (sender): Likewise. (is_sender): Likewise. (is_comm_sender): Likewise. (skip_recp): Likewise. (recp_sent_by): Likewise. (filter_secret_info): Likewise. (do_delete_text): Likewise. (check_double_subm): Likewise. (check_double_comm): Likewise. (create_text_add_miscs): Likewise. * src/server/text-garb.c (garb_text): Fix usage of the COMPILE_CHECKS macro. * src/server/ram-output.c (foutput_misc_info): Fix usage of the COMPILE_CHECKS macro. * src/server/prot-a-output.c (prot_a_output_misc_info): Fix usage of the COMPILE_CHECKS macro. * src/server/dbck.c (delete_misc): Fix usage of the COMPILE_CHECKS macro. (is_recipient): Likewise. Code cleanup. * src/include/kom-types.h: Removed code within #ifdef PROT_a. It was never used, and is obsoleted by aux-items. 1999-05-19 Per Cederqvist * NEWS: We document in Texinfo, not info. 1999-05-18 Per Cederqvist Avoid ".*" in regexps in the test suite, since they can easily match too much. * src/server/testsuite/lyskomd.0/06.exp: Use "$hollerith" instead of a hard-coded regexp, to avoid parsing past newlines. * src/server/testsuite/lyskomd.0/person-cov.exp: Likewise. * src/server/testsuite/lyskomd.0/send-async-cov.exp: Likewise. * src/server/testsuite/lyskomd.0/04.exp: Use "$any" instead of "." to match any character, to avoid parsing past newlines. * src/server/testsuite/lyskomd.0/membership-cov.exp: Likewise. 1999-05-18 Per Cederqvist Increase coverage. * src/server/testsuite/Makefile.am (EXTRA_DIST): Added lyskomd.0/08.exp. * src/server/testsuite/lyskomd.0/08.exp: New file. 1999-05-18 David Byers * doc/lyskomd.texi: Merged dbck.texi and hacking.texi into lyskomd.texi. * src/server/testsuite/lyskomd.0/03.exp: Updated query-predefined-aux-items result. * src/server/testsuite/lyskomd.0/01.exp: Updated query-predefined-aux-items result. * src/server/aux-items.c (undelete_aux_item_list): Fixed conference/text mixup (delete_aux_item_list): Same here. (undelete_aux_item_list): Save kom_errno and err_stat across call. * src/server/aux-item-def-parse.y: Deal with disabled definitions in a more sensible manner. * src/server/aux-items.c (aux_item_add_perm): Check the disabled field of the aux-item definition. * src/server/aux-items.h: Added disabled field. 1999-05-17 David Byers * src/server/aux-items.c (aux_item_list_add_items): New utility function. (system_add_aux_item_list): Use aux_item_list_add_items. (text_stat_add_aux_item_list): Use aux_item_list_add_items. (conf_stat_add_aux_item_list): Use aux_item_list_add_items. 1999-05-16 Per Cederqvist Use a global variable to store the current time, so that it is never changes during an atomic call, and so that we don't call time() more than once per call. * src/server/server-time.h: New file. * src/server/ramkomd.c (main): Initialize current_time. * src/server/connections.c (milli_timevaldiff): Removed. (dump_statistics): Use current_time instead of calling time(). (toploop): Call time once per select loop instead of calling gettimeofday twice. Simplify the computation of the timeout. * src/server/conference.c (do_create_conf): Use current_time instead of time(). * src/server/text.c (add_text_in_conf): Use current_time instead of calling time(). (do_create_text): Likewise. (add_recipient): Likewise. (add_footnote): Likewise. (add_comment): Likewise. (create_text_add_miscs): Removed the now argument. All callers updated. User current_time instead of now. * src/server/text-garb.c (garb_text): Use current_time instead of calling time(). * src/server/simple-cache.c (sync_part): Use current_time instead of calling time(). (init_cache): Likewise. * src/server/session.c (leave_conf): Use current_time instead of calling time(). (login_old): Likewise. (login): Likewise. (logout): Likewise. (who_is_on_dynamic): Likewise. (get_session_info): Likewise. (get_session_info_ident): Likewise. (get_time): Likewise. (user_active): Likewise. * src/server/send-async.c (async_rejected_connection): Use current_time instead of calling time(). * src/server/person.c (create_person_generic): Use current_time instead of calling time(). * src/server/membership.c (do_add_rec_time): Use current_time instead of calling time(). (do_add_member): Likewise. * src/server/internal-connections.c (init_connection): Use current_time instead of calling time(). (new_client): Likewise. * src/server/aux-items.h: (prepare_aux_item_list): Removed the "now" argument. (prepare_aux_item): Likewise. * src/server/aux-items.c (prepare_aux_item_list): Removed the "now" argument. Use current_time instead. Call callers updated. (prepare_aux_item): Likewise. * src/server/admin.c (modify_server_info): Don't pass the current time to prepare_aux_item_list. Document updateLysKOM and komrunning. Make them accept -v/-V. * doc/lyskomd.texi: Removed all up, next and prev pointers. (Invoking updateLysKOM): New node. (Invoking komrunning): New node. * src/server/updateLysKOM.c (main): Use PACKAGE and VERSION (from config.h) when reporting the version number. * src/server/komrunning.c (usage): Accept -v and -V. (main): Likewise. The test suite now fails without having to wait for a timeout if a wrong result with the proper ref-no is returned. * src/server/testsuite/config/unix.exp (MEMTRACE): Default to /dev/null. (simple_expect): Recognize attempts to match protcol-A replies, and fail without a timeout if the correct reference number is returned with bogus data. Fix "make dist". * src/server/testsuite/Makefile.am (EXTRA_DIST): Added lyskomd.0/07.exp, lyskomd.0/broken-aux-items.conf, lyskomd.0/cache-node-cov.exp, lyskomd.0/conf-file-cov.exp, lyskomd.0/conference-cov.exp, lyskomd.0/connections-cov.exp, lyskomd.0/disk-end-of-atomic-cov.exp, lyskomd.0/internal-connections-cov.exp, lyskomd.0/isc-parse-cov.exp, lyskomd.0/log-cov.exp, lyskomd.0/membership-cov.exp, lyskomd.0/memory-cov.exp, lyskomd.0/person-cov.exp, lyskomd.0/prot-a-parse-cov.exp, lyskomd.0/prot-a-send-async-cov.exp, lyskomd.0/send-async-cov.exp, lyskomd.0/session-cov.exp and lyskomd.0/text-cov.exp. * src/server/Makefile.am (komrunning_SOURCES): Added pidfile.h. (updateLysKOM_SOURCES): Added pidfile.h. (lyskomd_SOURCES): Added trace-alloc.h. Fix the framework for hunting memory leaks. * configure.in: Handle --with-traced-allocations. * acconfig.h (TRACED_ALLOCATIONS): New define. * src/server/trace-alloc.h: New file. * src/server/testsuite/config/unix.exp (lyskomd_start): Handle TRACED_ALLOCATIONS. (lyskomd_fail_start): Likewise. * src/server/ramkomd.c (main): Call trace_alloc_file very early during startup if compiled with TRACED_ALLOCATIONS. * src/server/ram-smalloc.c: Test TRACED_ALLOCATIONS instead of DEBUG_MALLOC. (trace_alloc_file): New function, that sets up malloc_fp. (trace_smalloc): Write to malloc_fp. (trace_free): Likewise. (srealloc): Likewise. * src/server/ram-smalloc.c: Don't test USE_GNU_MALLOC; that symbol was removed 1998-08-09. 1999-05-16 David Byers * src/server/aux-items.c (prepare_aux_item): Don't clear the link field of the aux item. (aux_inherit_items): Clear the link in the copied item before calling add triggers. (aux_item_link_items): New function. (aux_item_trigger_mirror_faq): Use aux_item_link_items. (aux_item_trigger_link_item): Use aux_item_link_items. (aux_item_call_add_triggers): Fix the trigger data after calling each trigger since one of them might move the aux item list in memory. 1999-05-15 David Byers * src/server/aux-items.c (aux_item_trigger_link_item): New function for debugging linking aux items. 1999-05-14 Per Cederqvist Fixes to the test suite. * src/server/testsuite/lyskomd.0/connections-cov.exp: A client dies immediately when it receives %% No connections left, so the test case should not expect it to live longer. Renumber the ref-nos. The nologin file exists in the build directory, not in srcdir. * src/server/testsuite/leaks.0/leaks02.exp: Don't forget the flags argument to create-person. * src/server/testsuite/lyskomd.0/conference-cov.exp: Don't attempt to use debug calls unless debug_calls is true. * src/server/testsuite/lyskomd.0/person-cov.exp: Likewise. * src/server/testsuite/lyskomd.0/person-cov.exp: Look for config/prot-a.exp in srcdir. Don't fail if the clock ticks. * src/server/testsuite/lyskomd.0/conference-cov.exp: Look for config/prot-a.exp in srcdir. * src/server/testsuite/lyskomd.0/connections-cov.exp: Likewise. * src/server/testsuite/lyskomd.0/membership-cov.exp: Likewise. * src/server/testsuite/lyskomd.0/prot-a-parse-cov.exp: Likewise. * src/server/testsuite/lyskomd.0/prot-a-send-async-cov.exp: Likewise. * src/server/testsuite/lyskomd.0/send-async-cov.exp: Likewise. * src/server/testsuite/lyskomd.0/session-cov.exp: Likewise. * src/server/testsuite/lyskomd.0/text-cov.exp: Likewise. * src/server/testsuite/config/unix.exp (timeout): Don't alter the default value. Not every computer is fast computer. (lyskomd_start): The aux-item config file is found relative to $srcdir, not [pwd]. The config/lyskomd-config file is found relative to the current working directory. (lyskomd_fail_start): Likewise. Find the database files relative to top_srcdir. 1999-05-14 David Byers * src/server/text.c (do_create_text): Return long-array if there are too many misc items. (modify_text_info): Set err_stat to max length when returning KOM_LONG_ARRAY. * src/include/kom-types.h (Info_datum): Added unknown_type to union. * src/server/text.c (find_recipient): Add unknown_info to the switch. Stop the server if COMPILE_CHECKS is undefined. (is_member_in_recpt): Same here. (do_delete_misc): Same here. (do_sub_recpt): Same here. (sender): Same here. (is_sender): Same here. (is_comm_sender): Same here. (skip_recp): Same here. (recp_sent_by): Same here. (filter_secret_info): Same here. (do_delete_text): Same here. (check_double_subm): Same here. (check_double_comm): Same here. (create_text_check_misc): Return an illegal-info-typye if we see an unknown info. Set err_stat to the index of the bad item when returning a KOM_ILL_MISC. (create_text_add_miscs): Same here. * src/server/prot-a.c (prot_a_destruct): Free the misc_info_list field of the connection. * src/server/membership.c (add_rec_time): Handle unknown_info and other unknown misc info types by shutting down the server. * src/server/call-switch.awk: Add support for misc_info_list in fncdef.txt. * src/server/text.c (create_text_old): Changed parameter list to use Misc_info_list instead of an integer and a Misc_info pointer. (create_text): Same here. (create_anonymous_text): Same here. (create_anonymous_text_old): Same here. * src/server/fncdef.txt: Changed all "num c_misc_info_p" to misc_info_list. * src/server/prot-a-parse-arg-c.awk: The aux_item type works again. Allow misc_info_list as a type name. * src/server/prot-a-parse.c (prot_a_parse_misc_info_list): New function. * src/server/prot-a.c (prot_a_init): Initialize the misc_info_list field. * src/server/internal-connections.c (kill_client): Use misc_info_list field of Connection. * src/server/connections.c (free_parsed): Clear the misc_info_list field. * src/include/kom-types.h (Misc_info_list): New type. * src/server/internal-connections.c (init_connection): Initialize hunt_parse_pos, array_hunt_depth and array_hunt_num. Initialize misc_info_list. * src/server/prot-a-parse.c (prot_a_hunt_array_end): New function hunts for the end of an array. * src/server/prot-a.c (prot_a_init): Initialize hunt_parse_pos and array_hunt_num. * src/include/kom-types.h (Info_type): Added unknown info type. * src/server/prot-a-parse.c (prot_a_parse_misc_info): Parse all misc-info types that the server knows about. Unknown types generate a protocol error. * src/server/testsuite/lyskomd.0/prot-a-parse-cov.exp (1021): Expect long-array and not protocol-error. * src/server/prot-a-parse.c (prot_a_parse_aux_item_list): Discard the part of the list that is longer than the max rather than send a protocol error. 1999-05-13 David Byers * src/server/testsuite/lyskomd.0/prot-a-parse-cov.exp (protocol_error): Removed expected failure. * src/server/admin.c (modify_server_info): Return KOM_LONG_ARRAY when we see a long array. * src/server/conference.c (modify_conf_info): Return KOM_LONG_ARRAY when we see a long array. * src/server/text.c (modify_text_info): Return KOM_LONG_ARRAY when we see a long array. * src/server/prot-a-parse.c (prot_a_parse_num_list): Truncate a parsed array to one more than the maximum length and skip all other elements. * src/server/aux-items.c (undelete_aux_item_list): Log if the link type is undefined and do not attempt to undelete. (delete_aux_item_list): Likewise. 1999-05-13 Per Cederqvist Distribute the leaks tests, and run them during "make check". * src/server/testsuite/Makefile.am (EXTRA_DIST): Track the rename of lyskomd.0/leaks*.exp -> leaks.0/leaks*.exp. (check): Depend on check-leaks. (check-leaks): New target. Code cleanup/minor bugs fixed. * src/server/testsuite/tcpconnect.py: socket.recv can raise socket.error! Handle it as end-of-file. * src/server/simple-cache.c (cached_conf_exists): Removed the unused variable node. * src/server/aux-items.c (find_linked_aux_item_list): Don't use an uninitialized variable. (delete_aux_item_list): Fail if the default branch is reached. (undelete_aux_item_list): Fail if the default branch is reached. (aux_item_trigger_mirror_faq): Test data->object for NULLness intstead of the uninitialized variable conf_stat. * doc/hacking.texi (Linking Pairs of Aux Items): Texinfo problem fixed. * doc/Protocol-A.texi (set-info): Untabify. (accept-async): Untabify. (query-async): Untabify. 1999-05-12 David Byers Stuff I forgot to add below * Renamed log to kom_log since log is a function in math.h. * src/include/services.h (set_pers_flags): New prototype. (create_person): Added flags parameter. * run-support/config: Set defaults for max texts and max conferences. * run-support/aux-items.conf (faq-text): Removed all triggers. Set add-trigger to link-faq, added validator. (faq-for-conf): New item definition. * doc/lyskomd.texi (Parameters): Added Max conferences, Max texts, Max client data length, Nologin file. Updated some other parameter descriptions. (Aux-Item Definition File): Added system-only. Rewrote validate to allow function identifiers. Added list of validator functions and triggers. (Files): Document /etc/nologin. * doc/hacking.texi: Correct minor typos. Change some @code into @file. (Linking Pairs of Aux Items): New section. * doc/Protocol-A.texi: Correct minor typos (Predefined Aux-Item Types): Rephrase some of the text. Remove statement that faq-text item marks a text. Document faq-for-conf. Specify formate for mx-message-id. (Simple Data Types): Removed documentation for INTEGER. (set-etc-motd): Change too-many-marks to mark-limit (mark-text-old): Change too-many-marks to mark-limit (set-conf-type): Correct documentation for secret-public error. Correct spelling in invalid-membership-type documentation. (add-recipient): Add documentation for access-denied error (add-comment): Define error-status in index-out-of-range. (sub-comment): Change no-comment to not-comment. (send-message): Complete documentation of message-not-sent error. (create-text): Add index-out-of-range as possible error. (create-conf): Complete doc of permission-denied error. (create-person): Added personal-flags parameter. (create-person): Document person-exists error. (set-pers-flags): New call. (Error Codes): Clarify message-not-sent and index-out-of-range. * configure.in: Added flag --with-insure++. Define AVOID_ABORTS when compiling with support for gcov. * src/server/testsuite/tcpconnect.py: Added #hose socket to hose the socket with lots of zeroes. * src/server/testsuite/config/prot-a.exp: New functions kom_set_permitted_submitters, kom_set_super_conf, kom_login_old, kom_mark_text, kom_sub_recipient, kom_set_conf_type, kom_change_conference, kom_set_priv_bits. (kom_create_person): Send the pers_flags field. * src/server/testsuite/config/unix.exp: Print a dot for every test case in verbose mode. (lyskomd_start): New parameters extra_config for additional config file contents and base_config for basic config file contents (defaults will not be used.) Don't print defaults for max conferences or max texts if they are in extra_config. It is possible to start lyskomd with arbitrary arguments. (lyskomd_fail_start): Function to use when lyskomd is supposed to not start properly (like lyskomd_start, but server failue is expected.) (client_start_fail): New function like client_start, but failure is expected. (kill_client): Unset expect_active and expect_always instead of setting to the empty string. (hose_client): New function * src/server/testsuite/lyskomd.0/00.exp: Send pers-flags in calls to create-person. * src/server/testsuite/lyskomd.0/01.exp: Update expected results in query-predefined-aux-items. Send pers-flags in call to create-person. Add test for set-pers-flags. Add test for nonexistent call 107. * src/server/testsuite/lyskomd.0/02.exp: Send pers-flags in call to create-person. * src/server/testsuite/lyskomd.0/03.exp: Expect aux-item 28 in query-predefined-aux-items. Send pers-flags in call to create-person. Expect the faq-for-conf aux-item in test 1327. Expect failure attempting to set nonexistent text as faq (test 1342.) Remove the now failed faq item in subsequent tests. Add test for set-pers-flags. * src/server/testsuite/lyskomd.0/04.exp: Send pers-flags in calls to kom_create_person. * src/server/testsuite/lyskomd.0/05.exp: Send pers-flags in calls to kom_create_person. Be more flexible when expecting time corresponding to time_t zero. Set garb and sync interval to something really high to avoid spurious async messages while running the tests. * src/server/testsuite/lyskomd.0/06.exp: Send pers-flags in calls to kom_create_person. * src/server/testsuite/lyskomd.0/admin-cov.exp: More setup to support new tests. Test that we can't send messages to secret confs. Test that messages are filtered for passive members. * src/server/testsuite/lyskomd.0/aux-items-cov.exp: Send pers-flags in calls to kom_create_person. Attempt to create aux-items with broken validation regexp. Test the system-only attribute. Test a broken aux-item config file. * src/server/testsuite/lyskomd.0/aux-items.cov: Add an item definition with system-only property. * src/server/prot-a-parse.h: Added prototype for prot_a_parse_pers_flags * src/server/prot-a-parse.c (prot_a_parse_pers_flags): New function to parse pers flags. * src/server/prot-a-output.c (prot_a_output_text_mapping): Initialize the fields of iter to avoid warnings from tools that detect access to uninitialize memory. * src/server/local-to-global.c: Use kom_log instead of log. * src/server/kom-memory.c: Added prototypes for init_aux_item and init_aux_item_link. * src/server/aux-items.c (system_check_add_aux_item_list): Call aux_item_add_perm with INFO_OBJECT_TYPE for the object_type parameter. * src/server/admin.c: Use kom_log instead of log everywhere. (send_message): Do not permit sending group messages to secret conferences. Set errno to KOM_MESSAGE_NOT_SENT if there are no appropriate recipients. * src/server/aux-item-def-parse.y: Parse validation functions in addition to validation regexps. Use kom_log instead of log. Parse the system-only property. (aux_item_def_check_validate): New function. * src/server/aux-items.c: Add the aux-item being involved item itself to aux-item trigger data. (aux_item_validate_existing_text): New validation function. (aux_item_trigger_mirror_faq): New add trigger function (aux_item_trigger_unmark_text): Modified to work for aux-items on texts and conferences, not just conferences. Do not unmark an unmarked text. (aux_item_trigger_mark_text): Do not add more marks than permitted. (find_aux_item_index): New function to find the index of an item with a particular number in an aux item list. (commit_aux_item_list): Renamed to commit_aux_item_list_internal. (commit_aux_item_list_internal): Delete linked aux items. (commit_aux_item_list): Wrapper for commit_aux_item_list_internal. (delete_aux_item_list): Manage deletion of linked items. (undelete_aux_item_list): Manage undeletion of linked items. (mark_linked_object_as_changed): New function to mark the object containing a linked aux item as changed. (find_linked_aux_item): New function to find the aux item that is linked to a given aux item. (find_linked_aux_item_list): New function to find the aux item list containing the aux item that is linked to a given aux item. (aux_item_validate): New function for validating aux items. Deals with regexps and validation functions. (aux_item_add_perm): Handle the system-only property of aux item definitions. 1999-05-09 David Byers * src/server/aux-items.c (prepare_aux_item): Clear the linked_item field properly. * src/server/memory.c (init_aux_item_link): New function. (init_aux_item): Use init_aux_item_link (init_aux_item): New function added earlier. * src/server/prot-a-parse.c (prot_a_parse_aux_item): Clear the parsed aux_item to get good defaults for fields that are not read in the parser. * src/server/admin.c (modify_server_info): Pass INFO_OBJECT_TYPE to delete_aux_item_list and undelete_aux_item_list. * src/server/aux-items.h: Changed all declarations of object_type from short to Object_type. * src/server/aux-items.c: Changed all declarations of object_type from short to Object_type. * src/server/ram-parse.c (fparse_aux_item_link): New function. (fparse_aux_item): Parse the link as well. * src/include/kom-types.h (Object_type): New type (moved defs from aux-items.h) (Aux_item_link): New type (Aux_item): Added linked_item field. * src/server/ram-output.c (foutput_aux_item): Output linked_item field. (foutput_aux_item_link): New function to output a link to another aux item. * src/server/aux-items.c: Added handling of item field in aux item trigger calls. * src/server/aux-items.h (Aux_item_trigger_data_s): Added item field. * src/server/aux-items.c (system_check_add_aux_item_list): Set owner_check to TRUE in call to aux_item_add_perm so system-only restriction works on system-info aux-item list. * src/server/testsuite/lyskomd.0/admin-cov.exp: Added tests for sending messages to secret confs and to conf with passive member logged in. * doc/Protocol-A.texi (send-message): Document that message-not-sent is returned when there are no recipients for a group message. * src/server/com-h.awk: Set illegal_fnc to -1 (was cnt) since cnt might be a legal function. 1999-05-02 Per Cederqvist "make check" in the top directory failed in some environments. * src/server/testsuite/Makefile.am (check-lyskomd): Close file descriptors 3-9 to avoid interference between file descriptors inherithed from make, sshd et c with lyskomd.0/07.exp. 1999-05-01 Per Cederqvist Use libisc-1.00. * src/libraries/libisc-new: Replace the old contents with that of isc-1.00. Se src/libraries/libisc-new/ChangeLog for information about any modifications that are made to the library. 1999-04-28 Per Cederqvist Remove support for the mux protocol. Don't use isc_printf. * src/server/testsuite/lyskomd.0/07.exp: Decrease the all file descriptors by one, now that the server no longer listens for a mux. Test that protocol B is unsupported. * src/server/testsuite/config/unix.exp (muxport): Removed. (lyskomd_start): Don't set "Mux port" in the config file. * src/server/server-config.c (parameters): Removed parameter "Mux port". * doc/lyskomd.texi (Parameters): Removed "Mux port". * src/server/ramkomd.c (listen_mux): Removed. (server_init): Remved the "mux_port" argument. Don't listen for muxes. (initialize): Don't pass the "mux_port" argument to server_init. * src/server/prot-a.c (prot_a_reply): Use isc_putc, isc_putul, isc_flush and prot_a_output_ul instead of mux_printf, mux_flush and mux_putc. (prot_a_parse_packet): Likewise. * src/server/prot-a-send-async.c (async_header): Use isc_putc, isc_putul, prot_a_output_ul and isc_flush instead of mux_printf, mux_putc and mux_flush. (async_trailer): Likewise. (prot_a_async_new_text_old): Likewise. (prot_a_async_new_text): Likewise. (prot_a_async_logout): Likewise. (prot_a_async_new_name): Likewise. (prot_a_async_forced_leave_conf): Likewise. (prot_a_async_login): Likewise. (prot_a_async_send_message): Likewise. (prot_a_async_deleted_text): Likewise. (prot_a_async_new_recipient): Likewise. (prot_a_async_sub_recipient): Likewise. (prot_a_async_new_membership): Likewise. * src/server/prot-a-output.h (prot_a_output_ul): New function. * src/server/prot-a-parse.c (prot_a_get_token): Use isc_puts and isc_flush instead of mux_printf and mux_flush. (prot_a_parse_num_list): Likewise. (prot_a_parse_string): Likewise. * src/server/prot-a-output.c (prot_a_output_ul): New function. (prot_a_output_person): Use prot_a_output_ul, isc_puts, isc_putc and isc_write instead of mux_printf, mux_putc and mux_write. (prot_a_output_membership_type): Likewise. (prot_a_output_membership): Likewise. (prot_a_output_membership_old): Likewise. (prot_a_output_membership_list_old): Likewise. (prot_a_output_membership_list): Likewise. (prot_a_output_conf_list): Likewise. (prot_a_output_conf_no_list): Likewise. (prot_a_output_conference): Likewise. (prot_a_output_conference_old): Likewise. (prot_a_output_uconference): Likewise. (prot_a_output_mark_list): Likewise. (prot_a_output_aux_item_flags): Likewise. (prot_a_output_aux_item): Likewise. (prot_a_output_text_stat_old): Likewise. (prot_a_output_aux_item_list): Likewise. (prot_a_output_who_info_ident): Likewise. (prot_a_output_who_info): Likewise. (prot_a_output_who_info_list): Likewise. (prot_a_output_who_info_ident_list): Likewise. (prot_a_output_who_info_list_old): Likewise. (prot_a_output_session_info): Likewise. (prot_a_output_session_info_ident): Likewise. (prot_a_output_info_old): Likewise. (prot_a_output_string): Likewise. (prot_a_output_priv_bits): Likewise. (prot_a_output_personal_flags): Likewise. (prot_a_output_conf_type): Likewise. (prot_a_output_extended_conf_type): Likewise. (prot_a_output_member_list): Likewise. (prot_a_output_member_list_old): Likewise. (prot_a_output_member): Likewise. (prot_a_output_member_old): Likewise. (prot_a_output_mark): Likewise. (prot_a_output_misc_info): Likewise. (prot_a_output_time): Likewise. (prot_a_output_session_no): Likewise. (prot_a_output_text_no): Likewise. (prot_a_output_conf_z_info): Likewise. (prot_a_output_conf_z_info_list): Likewise. (prot_a_output_version_info): Likewise. (prot_a_output_num_list): Likewise. (prot_a_output_dynamic_session_info): Likewise. (prot_a_output_dynamic_session_info_list): Likewise. (prot_a_output_l2g_iterator_as_text_list): Likewise. (prot_a_output_text_mapping): Likewise. (prot_a_output_memory_info): Likewise. * src/server/param.h (struct kom_par): Removed ip_mux_port, num_ip_mux_port and num_ip_client_port. * src/server/isc-interface.h (ISC_UDGTYPE): Use "struct connection" instead of "struct mux". (ISC_PRINTF_SUPPORT): Don't define it. * src/server/internal-connections.c (init_connection): Use isc_session instead of mux. (kill_client): Likewise. * src/server/connections.h (Connection): Replaced mux with isc_session. * src/server/connections.c (logout_client): Use ISC instead of the removed mux layer. (parse_packet): Likewise. (parse_unparsed): Likewise. (login_request): Likewise. Don't handle muxes. (logout_request): Likewise. (message_request): Likewise. (mux_handle_packet): Removed. (mux_logout): Removed. (mux_parse_unparsed): Removed. (mux_parse_message): Removed. (milli_timevaldiff): New name for former timevaldiff. Return the difference in milliseconds instead of microseconds. (toploop): Use milli_timevaldiff instead of timevaldiff. This is a thousand times better at avoiding overflow. Use isc_puts instead of isc_printf. * src/server/mux.h: File removed. * src/server/mux.c: File removed. * src/server/mux-parse.h: File removed. * src/server/mux-parse.c: File removed. * src/server/Makefile.am (lyskomd_SOURCES): Removed mux-parse.h and mux.h. (MUX): Removed. Removed mux.c and mux-parse.c. (GENOBJS): Removed $(MUX). * doc/mux.proto: File removed. * doc/Makefile.am (EXTRA_DIST): Remove mux.proto. * configure.in: Remove enable_isc_printf -- we no longer need isc_printf. Fix a warning message in the testsuite. * src/server/testsuite/lyskomd.0/admin-cov.exp: Fixed the "unsupported" message: The configure option is named --with-debug-calls, not --enable-debug-calls. 1999-04-25 Per Cederqvist Increase the block size of the l2g structure from 10 to 250. * src/server/local-to-global.h (l2g_set_block_size): New function. * src/server/local-to-global.c (L2G_BLOCKSIZE): Now a static int instead of a define. (l2g_set_block_size): New function, that can be called once to set the block size (l2g_init): Set the block size to 250 unless it has already been set. * src/server/testsuite/test-l2g.c (main): Set the block size to 10. 1999-04-23 David Byers * src/server/standalone.c (kom_info): Initialize the aux_item_list too. * src/server/ramkomd.c (initialize): Use kom_log instead of log. * src/server/local-to-global.c (l2g_read): Use kom_log instead of log. * src/server/text.c (text_read_access): Call person_text_read_access to do the work. (person_text_read_access): New function generalizes text_read_access. * src/server/manipulate.h: Prototype for person_text_read_access. 1999-04-21 David Byers * src/server/aux-items.c (aux_item_find_validator): New function. 1999-04-20 Per Cederqvist Two file descriptors were leaked during startup. * src/server/aux-item-def-parse.y (parse_aux_item_definitions): Close the config file once it is read. * src/server/conf-file.c (read_config): Close the config file once it is read. 1999-04-19 Per Cederqvist New parameter: "Client host". * doc/lyskomd.texi (Parameters): Documented "Client host". * src/server/server-config.c (parameters): New parameter: "Client host". * src/server/ramkomd.c (server_init): New argument: host. Bind the specified IP number. (initialize): Pass param.ip_client_host to server_init. * src/server/param.h (struct kom_par): Added ip_client_host. 1999-04-19 Per Cederqvist Test the "% No connections left." message. * src/server/testsuite/lyskomd.0/07.exp: Test what happens when too many clients try to connect at the same time. 1999-04-18 Per Cederqvist More documentation. * doc/lyskomd.texi (Parameters): Documented "lyskomd path", "savecore path", "Normal shutdown time", "Mail after downtime" and "Mail until downtime". * doc/Protocol-A.texi (Protocol Version History): Call 102=set-membership-type was omitted, and later calls were misnumbered. (map-created-texts): Documented. 1999-04-18 Per Cederqvist Removed the last hardcoded configuration from updateLysKOM. * src/server/updateLysKOM.c (savecore): Use param.core_dir and param.savecore_path instead of hardcoding the values. * src/server/server-config.c (parameters): New parameter: "savecore path". (read_configuration): Handle param.savecore_path. * src/server/param.h (struct kom_par): New parameter: savecore_path. 1999-04-17 Per Cederqvist updateLysKOM now reads the configuration file. * src/server/updateLysKOM.c (usage): New function. (checkstatus): Use parameters "Normal shutdown time", "Mail after downtime" and "Mail until downtime" instead of using hard-coded values. Use "mail" instead of "Mail" to send the mail. (main): Read the configuration file. Use parameters "Pid file", "Status file" and "lyskomd path" instead of hard-coded values. * src/server/server-config.c (param): Moved here from various files. (parameters): Added "Normal shutdown time", "Mail after downtime", "Mail until downtime" and "lyskomd path". (read_configuration): Handle param.lyskomd_path. * src/server/ramkomd.c: (param): Moved to server-config.c. * src/server/dbck.c (param): Moved to server-config.c. * src/server/Makefile.am (READ_CONFIG): New variable. (komrunning_SOURCES): Use READ_CONFIG to simplify code. (updateLysKOM_SOURCES): Added READ_CONFIG. * src/server/param.h (struct kom_par): New parameters: lyskomd_path, normal_shutdown_time, downtime_mail_start and downtime_mail_end. * src/server/server-config.c (parameters): Moved a few entries around, so that they fit under the various headings. Fixes to komrunning.c. * src/server/komrunning.c (param): Moved to server-config.c. (create_status): Write the name of the user as the first line of the status file. With luck, that is a valid email address. Handle many simultaneous clients. * src/server/connections.c (login_request): Don't handle the "% No connections left" situation. (toploop): Handle ISC_EVENT_LOGIN_UNRELOCATED by returning a "% No connections left" message and closing the session, the way login_request used to do. * src/server/ramkomd.c (initialize): Warn if getrlimit and sysconf don't agree on the number of possible open files. 1999-04-17 Per Cederqvist Work towards handling more than 250 simultaneous clients. * src/server/ramkomd.c (server_init): Use isc configuration 1006 and isc session configuration 1002. Fill in fd_relocate with PROTECTED_FDS. 1999-04-17 Per Cederqvist Re-implement komrunning in C. * src/server/standalone.c (register_jubel): Dummy implementation. * src/server/dbck.c (register_jubel): Moved to standalone.c. * src/server/dbck-cache.c (kom_info): Moved to standalone.c. * src/server/komrunning.c: New file; a reimplementation of komrunning.sh in C. * src/server/Makefile.am (bin_PROGRAMS): Added komrunning. (komrunning_SOURCES): New variable, which among other files includes komrunning.c. (updateLysKOM_SOURCES): Added pidfile.c. (dbck_SOURCES): Added standalone.c. * run-support/komrunning.sh: Removed. * run-support/Makefile.am (komrunning): Target removed. (bin_SCRIPTS): Removed komrunning. (EXTRA_DIST): Removed komrunning.sh. (MOSTLYCLEANFILES): Removed komrunning. Introduce the "Status file" parameter. * src/server/server-config.c (parameters): Added "Status file". (read_configuration): Handle param.status_file. * src/server/param.h (struct kom_par): Added status_file. * doc/lyskomd.texi (Parameters): Documented "Status file". Move pid file reading to pidfile.c. * src/server/updateLysKOM.c (main): Use pidfile to simplify code. * src/server/pidfile.h (read_pid_file): New function. * src/server/pidfile.c (read_pid_file): New function. 1999-04-15 Per Cederqvist Document 103=local-to-global. * doc/Protocol-A.texi (accept-async): Added the error code long-array. (add-member): Added a comment. (local-to-global): Documented. (The User Area): Register WWW-kom. Test suite improvement. * src/server/testsuite/lyskomd.0/03.exp: Test calls 103 and 104. 1999-04-06 Per Cederqvist Yesterdays changes were incomplete. * src/server/ramkomd.c: Include local-to-global.h. 1999-04-05 Per Cederqvist Explain the Text-Mapping data type. * doc/Protocol-A.texi (LysKOM Data Types): Explain Text-Mapping. 1999-04-05 Per Cederqvist Change the external file format of a Local_to_global. * src/server/testsuite/l2g.0/09.exp: Adjusted to new external format of Local_to_global. * db-crypt/db/lyskomd-data: Adapted to new format of Local_to_global objects. * src/server/local-to-global.c (l2g_read): New file format. (put_ulong): New static function. (l2g_write): New file format. * src/server/testsuite/l2g.0/11.exp: Added lots of test cases for l2g_write. Added statistics to Local_to_global. * src/server/ramkomd.c (dump_exit_statistics): Call dump_l2g_stats. * src/server/local-to-global.h: Comments added and improved. (dump_l2g_stats): New function. * src/server/local-to-global.c (nr_constructs): New static variable, used to gather statistics. Changed all functions to set it where appropriate. (nr_l2gs): Likewise. (nr_l2gs_peak): Likewise. (nr_destructs): Likewise. (nr_clears): Likewise. (nr_copies): Likewise. (nr_joins): Likewise. (nr_joined_blocks): Likewise. (nr_blocks): Likewise. (nr_blocks_peak): Likewise. (nr_blocks_sparse): Likewise. (nr_blocks_sparse_peak): Likewise. (sparse_skip_cost): Likewise. (nr_sparse_compactions): Likewise. (nr_sparsifications): Likewise. (l2g_destruct): Actually fill the destructed object with garbage data, unless NDEBUG is defined. (dump_l2g_stats): New function. Make a lot of functions in ram-output.c static. Increase const awareness. * src/server/ram-output.c (foutput_person_0): Added const qualifier to the person argument. (foutput_person_2): Likewise. (foutput_person): Likewise. (foutput_conference_2): Added const qualifier to the conf_c argument. (foutput_aux_flags): Now static. (foutput_aux_item): Now static. (foutput_aux_item_list): Now static. Added const qualifier to the aux argument. (foutput_membership_type): Now static. (foutput_string): Now static. (foutput_priv_bits): Now static. (foutput_personal_flags): Now static. (foutput_text_list): Now static. (foutput_mark_list): Added const qualifier to the mark_list argument. (foutput_mark): Now static. (foutput_membership_list): Now static. (foutput_time): Now static. (foutput_member_list): Now static. (foutput_member): Now static. (foutput_conf_type): Now static. (foutput_misc_info): Now static. (foutput_ulong): Now static. * src/server/ram-output.h: Track changes in ram-output.c. * src/include/kom-types.h (Text_mapping): The l2g pointer is const. Some minor improvements to memory handling. * src/server/memory.c (free_conference): Call l2g_destruct. (free_person): Likewise. * src/server/conference.c (do_delete_conf): Don't call l2g_clear, since cache_delete_conf will do so. Remove useless compiler warnings. * configure.in: Don't use -Wtraditional and -Wnested-externs. Test suite improvement. * src/server/testsuite/config/unix.exp (lyskomd_death): Collect etc/memory-usage in usage.all. Test suite fix. * src/server/testsuite/config/unix.exp (lyskomd_start): The detection of a server compiled with --with-debug-calls was broken. Test Local_to_global even more. * src/server/testsuite/l2g.0/11.exp: Increase coverage even further. Test l2g_clear. * src/server/local-to-global.h: Comments improved. * src/server/local-to-global.c: Comments improved. 1999-04-05 Per Cederqvist Added range-begin and range-end to Text-Mapping. * doc/Protocol-A.texi (LysKOM Data Types): Added range-begin and range-end to Text-Mapping. * src/server/prot-a-output.c (prot_a_output_text_mapping): Emit range-begin and range-end. * src/server/person.c (map_created_texts): Set result->first to the first text number that the user requested. Don't move it forward if the text has been deleted. * src/server/text.c (local_to_global): Likewise. * src/server/testsuite/lyskomd.0/00.exp: Expect range-begin and range-end in Text-Mappings. 1999-04-04 Per Cederqvist Merge everything from prot-A.txt into Protocol-A.texi and remove prot-A.txt. * doc/prot-A.txt: Removed. Everything in it should now be present in Protocol-A.texi. * doc/Makefile.am (EXTRA_DIST): Removed prot-A.txt. * doc/Protocol-A.texi: Removed all up, next and prev pointers. Makeinfo can figure them out automatically. Fixed proper nesting of nodes, and use @Top, so that this work. Merge everything in prot-A.txt into this document: (Document Revision History): This is going to be revision 10.0 which documents protocol version 10. 9.0 was distributed with lyskomd 1.9.0. 8.0 was distributed with lyskomd 1.8.0. (Protocol Version History): New name for former "Protocol Revision History". Updated the information about version 9. (Protocol Design Principles): Node removed. The "Client-Server Dialog" node contains the same information. (Client-Server Dialog): Specify the LysKOM port in the example. (Simple Data Types): Moved the text about data element separator and call terminator to "Client-Server Dialog". (user-active): Talk more about when clients should send this. (who-is-on-dynamic): Improved the explanation. (get-static-session-info): State that the returned information is immutable. Distribute sigflags.h. * src/server/Makefile.am (lyskomd_SOURCES): Added sigflags.h. 1999-04-03 Per Cederqvist Renam do_sync_db to do_statistics. Use sig_atomic_t instead of Bool for variables set from signal handlers. * src/server/sigflags.h: New file, containing sig_atomic_t flags. * src/server/ramkomd.c: Include "sigflags.h". (sighandler_hup): Use 1 instead of TRUE as value of go_and_die. (sighandler_usr1): Use 1 instead of TRUE as value of do_statistics. Use do_statistics instead of do_sync_db. * src/server/connections.h (go_and_die): Declaration moved to sigflags.h. (do_sync_db): Renamed to do_statistics and moved to sigflags.h. * src/server/connections.c (go_and_die): Now sig_atomic_t instead of Bool. (do_statistics): New name for former do_sync_db. New type: sig_atomic_t instead of Bool. All users of do_sync_db updated. (toploop): Don't call cache_sync when do_statistics is set. * src/server/admin.c (shutdown_kom): Set go_and_die to 1, not TRUE. Cosmetic code cleanup. * src/server/prot-a-parse-arg-c.awk: Insert a blank line between the system includes and the local includes. Remove the empty function cache_sync. Rename cache_sync in dbck to cache_sync_all. * src/server/simple-cache.c (cache_sync): Removed. * src/server/logII.c (log): Call cache_sync_all instead of cache_sync. * src/server/dbck.c (garb_text_file): Call cache_sync_all instead of cache_sync. (main): Likewise. * src/server/dbck-cache.c (cache_sync_all): New name for former cache_sync. * src/server/cache.h (cache_sync): Function removed. Distribution cleanup. * src/server/Makefile.am (EXTRA_DIST): Don't distribute logII.c. * configure.in: Create src/libraries/regex/doc/Makefile and src/libraries/regex/test/Makefile. Documentation fixes. * doc/lyskomdb.texi (Version 0): next-free-num and next-text-num are one greater than the number of existing records. (Version 1): The same error probably exists here. Added comment about it. * doc/lyskomd.texi (Server Configuration File): Markup fixes. (Parameter Types): Markup fixes. (Parameters): Markup fixes. (Aux-Item Definition File): Markup fixes. (Administration): Update the discussion about updateLysKOM, dbck and komrunning. Markup fixes. Make all man pages obsolete. Generate the version number in lyskomd.texi automatically. Make sure that lyskomd.texi and dbck.texi includes everyting that was documented in the man pages. * mkmi: Remove scripts/mdate-sh, which should be generated by automake. * doc/man/dbck.8: All documentation removed. Refer to dbck.info. * doc/man/lyskom.5: Documentation removed. Refer to lyskomdb.info. * doc/man/updateLysKOM.8: All documentation removed. Refer to lyskomd.info. * doc/dbck.texi (Invoking dbck): Mention that dbck with no argument will examine the database without modifying it. (General Options): Document -h (aka --help). (Format Conversion Options): Minor layout fix. (Notes): Typos fixed. (Files): Markup fixes. * doc/Makefile.am: Break long lines. * doc/man/lyskomd.8: All documentation removed. Refer to lyskomd.info. * doc/lyskomd.texi: Include version.texi and use @value{VERSION} instead of hard-coding the value. (Overview): Add Peter Eriksson to the list of signficant contributors. ISC was a piece of very important "enabling technology". (Parameter Types): Mention that all files are absolute if the begin with '/'. (Parameters): Use @var{} instead of @i{}. Markup fixes and other minor typo fixes. The "Log statistics" path is used when the server receives a SIGUSR1 signal -- not a SIGHUP! (Aux-Item Definition File): The file name was wrong. Don't use @i{}. Document the "server" keyword. Mention that permanent aux-items will be deleted when the object they belong to are deleted. (Signals): Removed a note about SIGUSR2 not working on Suns. It should work fine there as well. (Files): Don't use @i{}. (Bugs): There is no detectable memory leak worth noting. 1999-04-03 Per Cederqvist The test cases shouldn't fail just because --with-debug-calls wasn't enabled. * src/server/ramkomd.c (main): Emit a warning message when --with-debug-calls is enabled. * src/server/testsuite/config/unix.exp (lyskomd_start): Look for the warning message about --with-debug-calls, and set debug_calls to a true value if it is found. * src/server/testsuite/lyskomd.0/admin-cov.exp: Don't attempt to use debug calls unless debug_calls is true. 1999-04-02 Per Cederqvist Fix "make clean". * src/server/testsuite/Makefile.am (mostlyclean-local): Remove db and etc. Use automake defaults for the Lex and Yacc files, so that the distribution works. * src/server/Makefile.am (YFLAGS): Set it to "-d" so that we get the .h header file. (EXTRA_DIST): Removed aux-item-def.l and aux-item-def.y. (MAINTAINERCLEANFILES): Removed aux-item-def.tab.h. (lyskomd_SOURCES): Added aux-item-def-parse.y, aux-item-def-parse.h and aux-item-def-scan.l. (DISKOBJS): Removed aux-item-def.tab.c and aux-item-def.lex.c. (aux-item-def.tab.c): Target removed. Rely on automake. (aux-item-def.lex.c): Target removed. Rely on automake. * src/server/aux-item-def-parse.y: Rename hack added. Don't redefine yyin and yylineno, since the Lex file no longer uses "%option prefix". Remove blank lines at end of file. * src/server/aux-item-def-scan.l: Rename hack added. Include aux-item-def-parse.h instead of aux-item-def.tab.h. Don't redefine yylval and yyerror, and don't use "%option prefix" -- this change makes it impossible to have multiple Lex scanners, but on the other hand, it makes it possible to use automake. * src/server/aux-item-def.l: Renamed aux-item-def-scan.l. * src/server/aux-item-def.y: Renamed aux-item-def-parse.y. Added some missing files to the distribution. * doc/Makefile.am (EXTRA_DIST): Added IDEAS. * src/include/Makefile.am (noinst_HEADERS): Added kom-config.h. * src/server/Makefile.am (EXTRA_DIST): Added prot-a-is-legal-fnc.awk. * src/server/testsuite/Makefile.am (EXTRA_DIST): Added renumber.el, l2g.0/*.exp, lyskomd.0/*.exp, lyskomd.0/summarize.sh, lyskomd.0/aux-items.conf, lyskomd.0/aux-items.cov and lyskomd.0/aux-items.leaks. 1999-04-02 Per Cederqvist Make it possible to run "make check" even when not building in srcdir. * src/server/testsuite/config/unix.exp: (lyskomd_start): Run the test suite in the build directory. Look for files relative to $srcdir or top_srcdir so that they are found properly. (aux_item_default_conf_file): Use $top_srcdir to get a full path. * src/server/testsuite/config/leaks.exp: Look for exp files in $srcdir. * src/server/testsuite/lyskomd.0/04.exp: Likewise. * src/server/testsuite/lyskomd.0/05.exp: Likewise. * src/server/testsuite/lyskomd.0/06.exp: Likewise. * src/server/testsuite/lyskomd.0/admin-cov.exp: Likewise. * src/server/testsuite/lyskomd.0/aux-items-cov.exp: Likewise. * src/server/testsuite/lyskomd.0/leaks00.exp: Likewise. * src/server/testsuite/lyskomd.0/leaks01.exp: Likewise. * src/server/testsuite/lyskomd.0/leaks02.exp: Likewise. * src/server/testsuite/lyskomd.0/leaks03.exp: Likewise. * src/server/testsuite/lyskomd.0/leaks04.exp: Likewise. * src/server/testsuite/lyskomd.0/leaks05.exp: Likewise. * src/server/testsuite/lyskomd.0/leaks06.exp: Likewise. * src/server/testsuite/lyskomd.0/leaks07.exp: Likewise. * src/server/testsuite/lyskomd.0/leaks08.exp: Likewise. * src/server/testsuite/lyskomd.0/leaks99.exp: Likewise. Fix broken tests. * src/server/testsuite/lyskomd.0/01.exp: The test could fail due to bad timing. Fixed. Makefile fixes. * src/server/testsuite/config/Makefile.am (EXTRA_DIST): Added leaks.exp. (MOSTLYCLEANFILES): Added lyskomd-config. 1999-03-31 Per Cederqvist Fix bugs in "make dist". * doc/Makefile.am (EXTRA_DIST): Removed Makefile.src. Dead code removal. * src/server/local-to-global.c (find_block_index_key): Blocks can never be completely empty. Code simplified accordingly. (l2g_append): Likewise. (l2gi_next): Likewise. * src/server/ram-parse.c (fparse_info_2): Unreachable code removed. Increase coverage of local-to-global.c. * src/server/testsuite/l2g.0/11.exp: New file. 1999-03-28 Per Cederqvist * TODO: Updated according to priorization made by me and David Byers. 1999-03-28 David Byers * src/server/simple-cache.c (cached_conf_exists): Test existance in small_conf_arr. Don't go to disk. (cached_delete_conf): Free the associated small_conf_stat and set small_conf_arr[x] to NULL. * run-support/aux-items.conf: Restrict creation of mx-author to creation time. 1999-02-06 Per Cederqvist * configure.in: Fixed a syntax error introduced yesterday. 1999-02-05 Per Cederqvist Don't produce meaningless warnings. * configure.in: Remove -Wshadow and -Wcast-qual since they give too many false warnings and are of limited use. Get rid of some warnings. * src/include/kom-types.h (Version_info_internal): const qualifiers added. * src/server/Makefile.am (version-info.c): Added const qualifier to kom_version_info. * src/server/version-info.h (kom_version_info): Added const qualifier. Don't use the wrong member of a union. * src/server/prot-a.c (prot_a_reply): Emit res->membership_list_old, not res->membership_list, when the return type is rt_membership_list_old. Remove the L2g_iterator_as_text_list typedef. * src/server/text.c (get_map): Use L2g_iterator instead of L2g_iterator_as_text_list. * src/server/prot-a-output.h, src/server/prot-a-output.c (prot_a_output_l2g_iterator_as_text_list): Use L2g_iterator instead of L2g_iterator_as_text_list. * src/server/person.c (get_created_texts): Use L2g_iterator instead of L2g_iterator_as_text_list. * src/server/connections.h (Result_holder): The l2g_iterator_as_text_list member is now of type L2g_iterator instead of the typedef L2g_iterator_as_text_list. * src/include/services.h (get_created_texts): Use L2g_iterator instead of L2g_iterator_as_text_list. (get_map): Likewise. * src/include/kom-types.h (L2g_iterator_as_text_list): Typedef removed. 1999-02-02 David Byers * src/server/aux-items.h (Aux_item_validation_data): New type. (Aux_item_validation_function): New type. (Aux_item_validator): New type. 1999-01-28 David Byers * src/server/prot-a-parse.c (prot_a_parse_aux_item_list): Check array size for -1. Check allocation of result. * src/server/person.c (mark_text): Return no-such-text if the user is not allowed to read the text (just like get-text-stat) (set_user_area): Return UNDEF_PERS, not UNDEF_CONF. * src/include/kom-errno.h (enum kom_errno): Define KOM_PERS_EXISTS. * src/server/person.c (create_person_generic): Return KOM_PERS_EXISTS instead of KOM_CONF_EXISTS 1999-01-27 David Byers * src/server/conference.c (do_create_conf): Don't just DIE if we fail to create a conference. Log a message and return an error. * src/server/person.c (create_person_generic): Don't just DIE if we fail to create a conference. Log a message and return an error. * src/server/ram-output.c (foutput_conference_2): Output a space before the l2g mapping. (foutput_person_2): Same thing here. 1999-01-26 David Byers * src/server/person.c (create_person_old): Add parameter in call to create_person. (create_person): Added flags parameter. (create_person_generic): Set the personal flags from the parameter. (set_pers_flags): New function to set the personal flags of a person. * src/server/fncdef.txt: Added set_pers_flags and added pers_flags argument to create_person. 1999-01-25 David Byers * doc/hacking.texi (Parsing Bit Fields): New section. * src/server/prot-a-parse.c (prot_a_parse_priv_bits): New function. New model for parsing bit fields that's really tolerant about the token length. Anything from one bit and up is cool. * src/server/prot-a-parse.h: Added prot_a_parse_priv_bits. * src/server/connections.h: Added pers_flags to Connection. * src/server/internal-connections.c (init_connection): Initializer pers_flags field. * src/server/prot-a-parse-arg-c.awk: Added pers_flags. * src/server/call-switch.awk: Added pers_flags. * src/server/person.c (set_user_area): Return KOM_UNDEF_CONF if the person is secret. * src/server/conference.c (get_conf_stat_old): Check access with <= none and not == none. (get_conf_stat_older): Same here. * src/server/person.c (get_person_stat): Check access with <= none and not == none (get_person_stat_old): Same here. (get_created_texts): Same here. (map_created_texts): Same here. 1999-01-24 David Byers * src/server/connections.c (login_request): Use param.nologin_file instead of hard-coded path. * doc/lyskomd.texi (Parameters): Documented Nologin file * src/server/server-config.c: Added "Nologin file" * src/server/param.h: Added nologin_file. * src/server/conference.c (legal_name): Return bad-name on attempt to use null string. * src/server/log.c (restart_kom): Do normal exit if AVOID_ABORTS is defined. * acconfig.h: Added AVOID_ABORTS * configure.in: Define AVOID_ABORTS when the user says --with-gcov * src/server/conf-file.c (configure_line): Complain about too many assignments at one too many assignments, not two too many. * src/server/simple-cache.c (sync_part): Don't save if param.never_save is set. * src/server/server-config.c: Compile in never_save always. 1999-01-23 David Byers * src/server/session.c (set_client_version): Use client_data_len as max length for client version and client name. * doc/lyskomd.texi (Parameters): Documented max client data length. * src/server/param.h: Added client_data_len. * src/server/server-config.c: Added max client data length. * src/server/text.c (submit_to): Set err-stat to the last conf in the chain, not zero, if we hit the top of the super-conf chain without finding something we can write to. (sub_recipient): Check for access to the supposed recipient before checking if it is a recipient. This plugs two leaks of secret information. (add_footnote): Set err-stat to footnote when failing because of not being author to footnote. (check_comm): Don't set err-stat. The caller will. 1999-01-22 David Byers * src/server/text.c (create_text_check_misc): Return no-such-text if no read access to footnoted text. Check read access before checking anything else to avoid leaking secret information. * src/server/membership.c (fast_access_perm): fast_access_perm always returned read_protected for rd_prot conferences, even if the viewer was the supervisor. Fixed. * src/server/text.c (text_read_access): If an open conf is a bcc recpt, anyone can see the text. * doc/Protocol-A.texi (add-recipient): Added error code access-denied. * src/server/text.c (create_text_check_misc): Don't set kom_errno if it was set in submit_to. (submit_to): Set kom_errno here instead of in the caller. (add_recipient): Return KOM_ACCESS if we are not allowed to write to the target conference. * doc/Protocol-A.texi (Error Codes): Fxied speling error 1999-01-21 David Byers * src/server/text.c (recp_sent_by): Fixed error message. (do_create_text): Fixed speling erorr * doc/lyskomd.texi (Parameters): Added documentation for max conferences and max texts. 1999-01-19 David Byers * src/server/text.c (do_create_text): Pass time to create_text_add_miscs to ensure correct timestamp. (create_text_add_miscs): Set last_written to correct timestamp. * src/server/conf-file.c (assign_ulong): New function. * run-support/config: Added max_confs and max_texts to default config file. Remove compiled-in size limits. * src/server/dbck-cache.c (init_cache): Dynamically allocate pers_arr, conf_arr, text_arr and name_list. * src/server/dbck.c: Dynamically alloc person_scratchpad in init_person_scratchpad. * src/server/simple-cache.c (init_cache): Allocate the small_conf_arr. (cached_create_conf): Use param.max_conf, not MAX_CONF (cached_create_text): Use param.max_text, not MAX_TEXT (init_cache): Use param.max_conf and param.max_text, not MAX_CONF and MAX_TEXT * src/server/aux-items.c: Moved initialization of sent_at to prepare_aux_item_list from other functions. * src/server/log.h: Changed names from log to kom_log to avoid shadowing log in math.h. 1999-01-18 David Byers * src/server/testsuite/config/unix.exp (suspend_client): New function. Suspends reading from lyskomd. (resume_client): New function. Resumes reading. * src/server/testsuite/.cvsignore: Added .da, .bb, .bbg and .da files. * src/libraries/libansi/.cvsignore: Added .da, .bb, .bbg and .da files. * src/libraries/libmisc/.cvsignore: Added .da, .bb, .bbg and .da files. 1999-01-17 David Byers * src/server/conference.c: Don't allow change to forbid_secret if there are secret members. * src/server/testsuite/tcpconnect.py (fdset): Added command #suspend socket to stop the relay from reading from the socket, to simulate a communications failure of sorts. Added #resume socket to reopen communications. 1999-01-16 David Byers * src/server/debug.c: New file. (get_memory_info): Moved here from admin.c. * src/server/Makefile.am (ATOMS): Added debug.c * src/server/person.c (create_person_generic): Don't autologin unless do_auto_login is true (create_person_old): Set do_auto_login to true in call to create_person_generic. (create_person): Set do_auto_login to false in call to create_person_generic. * src/server/connections.c (logout_client): Send async logout if the session is not logged in. 1999-01-15 David Byers * src/server/send-async.c (async_new_name): Send new-name only to clients with the appropriate privileges. * src/server/membership.c (fast_access_perm): Only check priv bits if the viewer is ACTPERS or ACT_P (access_perm): Ditto. * src/server/manipulate.h (ENA_C): New macro. * configure.in: New argument --with-optimization * src/server/conference.c (legal_name): Set err_stat when returning KOM_LONG_STR. * src/server/text.c (do_create_text): Set err_stat when returning KOM_LONG_STR. * src/server/aux-item-def.y: Never add disabled items to the definition list. * src/server/admin.c (send_message): Set err_stat to param.broadcast_len. 1999-01-14 David Byers * src/server/connections.h: Added Memory_info to Res_type and Result_holder to be compiled if DEBUG_CALLS is defined. * src/server/admin.c (debug_info): New function to get memory usage stats. * src/server/prot-a.c (prot_a_reply): Output memory_info * configure.in: Check for mallinfo if we do debug calls. Substitute EFENCE=1 if we use efence. * src/server/session.c (who_is_on): Changed for loops to while loops to deal with new semantics of session 0 and to make the code clearer. (who_is_on_ident): Ditto. (who_is_on_dynamic): Ditto. (who_is_on_old): Ditto. * src/server/internal-connections.c (get_conn_by_number): Always interpred session 0 as the current session. (traverse_connections): Explicit check for session_no == 0 since change in get_conn_by_number. * src/server/session.c (disconnect): disconnect(0) disconnects the current session Did some work on mail import and export (that jsk should have taken care of. Grrrr....) * doc/Protocol-A.texi (Predefined Aux-Item Types): Rewrote documentation for mail import and export aux-items. Wrote a chapter on mail import and export. * run-support/aux-items.conf: Added aux-items for mail import and export. * doc/Protocol-A.texi: Removed all @codes surrounding cross-references since texinfo chokes on them. * doc/hacking.texi (Notes for fncdef.txt): Added notes on fncdef.txt. 1999-01-13 David Byers Handle #ifdef/#endif and empty lines in fncdef.txt * src/server/fncdef.txt: Added debug_info. This call does NOTHING at the moment. It is just a proof of concept. It will do stuff later. * src/server/prot-a-parse-arg-h.awk: Handle #ifdef and #endif and empty lines. * src/server/fnc-def-init.awk: Ditto. * src/server/prot-a-is-legal-fnc.awk: Ditto. * src/server/call-switch.awk: Ditto. * src/server/prot-a-parse-arg-c.awk: Ditto. * src/server/com-h.awk: Ditto. * acconfig.h: Added DEBUG_CALLS * configure.in: Added option --with-efence to link with efence. Added option --with-debug-calls to define DEBUG_CALLS when compiling. Arranged things so we have to put a call number into the fncdef.txt file. This makes call numbers more explicit. It is also possible to have non-contiguous call numbers. * src/server/prot-a.c (prot_a_parse_packet): Use function_index field of connection to access parsers etc. * src/server/connections.c: Added num_fnc_defs * src/server/prot-a-parse-arg-h.awk: Updated for new format. * src/server/connections.c (dump_statistics): Changed the format of the statistics file to output function number before the call number. * src/server/connections.h: New field function_index Added function field to Fnc_descriptor. * src/server/call-switch.awk: Updated for new format in fncdef.txt * src/server/com-h.awk: Updated for new format in fncdef.txt * src/server/prot-a-parse-arg-c.awk: Updated for new format in fncdef.txt. * src/server/prot-a.c (prot_a_is_legal_fnc): Removed hard-coded switch and replaced it with include of prot-a-is-legal-fnc.incl * src/server/prot-a-is-legal-fnc.awk: New function. * src/server/Makefile.am: Add rules for prot-a-is-legal-fnc.incl 1999-01-12 David Byers * src/server/testsuite/lyskomd.0/03.exp: Updated membership tests. * src/server/testsuite/lyskomd.0/05.exp: Updated membership tests. * src/server/membership.c (do_get_membership): Set the position field in the returned structure. (locate_membership_and_position): Removed. (locate_membership): Set the position field in the membership. * src/server/memory.c (init_membership): Init position field. * src/include/kom-types.h: Removed Extended_Membership. Added position field to Membership. * src/server/connections.h: Removed Extended_Membership. * src/server/prot-a.c (prot_a_reply): Removed rt_extended_membership. * src/server/prot-a-output.c (prot_a_output_membership): Output membership position. 1999-01-08 David Byers * db-crypt/db/lyskomd-data: Updated database with keep_commented field. 1999-01-07 David Byers * src/server/person.c (create_person_generic): Initialize keep_commented. * src/server/memory.c (copy_conference): Copy keep_commented. (init_conference): Initialize keep_commented. * src/server/dbck.c (delete_misc): Moved initialization of ready to avoid spurious compiler warning. * src/server/text.c (do_delete_misc): Moved initialization of ready to avoid spurious compiler warning. * src/server/simple-cache.c: Changed sync_next to unsigned to get rid of compiler warnings. (save_one_conf): Output sync_next as unsigned. (save_one_text): Ditto. (init_cache): Move initialization of done, read_text_no and read_conf_no to avoid spurious compiler warning. (init_cache): Initialize c for same reason. * src/server/cache-node.c: Added initializer for s.snapshot in EMPTY_CACHE_NODE. * src/server/cache-node.h: Removed saved_sirty [sic] flag from cache_node. It wasn't used anywhere. * src/include/rcs.h (USE): Use __typeof__ to avoid compiler warnings. This macro only does something when __GCC__ is two or more, in which case __typeof__ exists, so it should be safe. * src/server/server-config.c: Added default_keep_commented to parameters. * src/server/param.h: Added default_keep_commented to kom_par. * src/server/conference.c (do_create_conf): Initialize keep_commented * doc/lyskomd.texi (Parameters): Documented Default keep commented nice. * src/include/services.h: Declare set_keep_commented. * src/server/conference.c (set_keep_commented): New function. * src/server/fncdef.txt: Added set_keep_commented. * src/server/prot-a-output.c (prot_a_output_conference): Output keep_commented after nice. * src/server/ram-parse.c (fparse_conference_2): Parse keep_commented. * src/include/kom-types.h: New field keep_commented. * src/server/ram-output.c (foutput_conference_2): Output keep_commented. 1999-01-01 Per Cederqvist Use NO_TIME instead of 0. * src/server/memory.c (init_membership): Use NO_TIME instead of 0. 1998-12-31 Per Cederqvist Avoid pty buffer size overflow in the test suite. * src/server/testsuite/lyskomd.0/03.exp: Split long lines so that at most approximately 250 bytes are sent via a pty. Many operating systems have a limit of approximately 256 bytes per line. Fix test suite typo. * src/server/testsuite/config/leaks.exp (check_usage): Fixed a typo: it is an error if the number of strings is use change, not if they stay the same. Ignore some generated files. * src/server/testsuite/.cvsignore: Ignore lyskomd.*.base, lyskomd.*.usage and usage-base.tmp. * .cvsignore: Ignore config.h, config.h.in, stamp-h and stamp-h.in. 1998-12-30 David Byers * src/server/aux-items.h: Removed ADD_AUX_ITEM macro. * src/server/aux-items.c (aux_inherit_items): Fixed memory leak. * src/server/ramkomd.c (free_kom_info): New function. (main): Call it so that memory usage reported at end of session is not dependent on the length of the aux-item list attached to kom_info since that messes up testing for memory leaks. * doc/lyskomd.texi: Added this file. Finished writing it too. 1998-12-29 David Byers * src/server/testsuite/config/unix.exp (lyskomd_start): Added optional third argument for stuff to put at the end of the config file. * src/server/prot-a-send-async.c (prot_a_async_new_membership): Send the correct header. * src/server/membership.c (add_member_common): Added calls to send_async_new_membership. (send_async_new_membership): Send message to the right recipients. 1998-12-28 David Byers * src/server/membership.c (add_member_old): Don't set invitation bit here. It is dealt with in add_member_common. (do_change_priority): Don't change priority to zero if we are being called from old functions. Just fake the passive bit. (locate_membership_and_position): Return the correct position of the membership. 1998-12-27 David Byers * doc/Protocol-A.texi (Error Codes): Added invalid-membership-type. 1998-12-26 David Byers * doc/man/lyskomd.8 (value): Documented regexps use collate table. * src/server/param.h: Added regex_use_collate_table. * src/server/server-config.c: Added regexps use collate table. * src/server/regex-match.c (lookup_regexp): Set translation table for regex according to regex_use_collate_table option. * src/server/manipulate.h: New function declaration. * src/server/membership.c (locate_membership_and_position): New function. (locate_membership): Use it. * src/server/person.c (do_query_read_texts): New function. (query_read_texts_old): Use it. (query_read_texts): Use it. * src/server/prot-a-output.h(prot_a_output_extended_membership): New function declaration. * src/server/prot-a-output.c (prot_a_output_extended_membership): New function. * src/server/prot-a.c (prot_a_reply): Added rt_extended_membership. * src/include/kom-types.h: New type Extended_Membership. * src/server/connections.h: Added extended_membership to Result_holder. Added rt_extended_membership to Res_type * src/include/services.h: Declare query_read_texts to take an Extended_Membership * doc/Protocol-A.texi (query-read-texts): Documented that this function returns the position as well as the membership. 1998-12-25 David Byers * README: Updated clients information. * src/server/membership.c (set_membership_type): Removed F-word from comment. Inserted F-abbreviation instead :-) * src/server/conference.c (get_uconf_stat): Removed FIXME after fixing fast_access_perm. * src/server/membership.c (fast_access_perm): Set kom_errno if we can't find the conference conf_no. * src/server/membership.c (do_get_members): Don't filter secret memberships if we have privilege bits set. * doc/Protocol-A.texi (Error Codes): Fixed error in documentation of secret-public 1998-12-24 David Byers * src/server/aux-items.c (system_add_aux_item_list): Call add triggers (check_delete_aux_item_list): Return KOM_AUX_PERM if an item to delete is mission. This is in accordance with the documentation. * src/server/aux-items.h (INFO_OBJECT_TYPE): New constant. 1998-12-23 David Byers * src/server/testsuite/lyskomd.0/03.exp: Updated test 1010 for item 27. Updated test 1017 for asyncs 16, 17 and 18 Updated test 1020 for asyncs 16, 17 and 18 Updated test 1022 for asyncs 16, 17 and 18 Updated test 1024 for asyncs 16, 17 and 18 In test 1032 updated async messages to show the bcc recpt. This is because of the change to make bcc recpts visible to the creator and to all when target is an open conference. Added sleep 2 before test 1310. Otherwise test 1311 may fail since one of the clients has not been idle for long enough (lyskomd is OK.) Updated test 1333 to not show deleted items Similar in 1334, 1335 and 1339. * src/server/testsuite/lyskomd.0/01.exp: Updated query-predefined-aux-items test for item 27 1998-12-22 David Byers * src/server/conf-file.c (MAXLINE): Increased line length limit to 1000 characters 1998-12-22 Per Cederqvist One more test. * src/server/testsuite/lyskomd.0/03.exp: Test call 99. 1998-12-20 Per Cederqvist More tests. * src/server/testsuite/lyskomd.0/03.exp: Test call 95-98. Speed up regexp matching a little. * src/server/regex-match.c (lookup_regexp): Attempt to allocate a fastmap. The invitation bit should not be set when a user himself joins a conference. * src/server/membership.c (add_member_old): Never set the invitation bit when a user adds himself to a conference. Avoid too long lines in the documentation. * doc/Protocol-A.texi (modify-system-info): Remove whitespace to avoid too long lines in the generated info file. 1998-12-17 David Byers * src/server/testsuite/config/Makefile.am (lyskomd-config): Use aux-items.conf in this directory instead of in run-support. * src/server/text.c (modify_text_info): Call commit_aux_item_list. * src/server/conference.c (modify_conf_info): Call commit_auc_item_list. * src/server/admin.c (modify_server_info): Call commit_aux_item_list. * src/server/aux-items.c (commit_aux_item_list): New function to really delete aux_items. 1998-11-14 Per Cederqvist Fixed another uninitialized memory problem: the allow_anon, reserved1, reserved2 and reserved3 bits of the Conf_type was not always properly initialized. * src/server/person.c (create_person_generic): Initialize allow_anon, reserved1, reserved2, and reserved3. * src/server/memory.c (init_conf_type): Initialize allow_anon, reserved1, reserved2, and reserved3. * src/server/prot-a-parse.c (prot_a_parse_conf_type): Let allow_anon default to 1, not 0. We really should have a way to let it default to unset, so that a set-conf-type that only specifies four bits doesn't alter the remaining bits. * src/server/testsuite/lyskomd.0/03.exp: Set allow_anon, and expect it to be set. Test call 92-94. 1998-11-09 Per Cederqvist Fixed an uninitialized memory problem. * src/server/memory.c (init_conference): Initialize highest_aux and expire to 0. * src/server/conference.c (do_create_conf): Initialize expire to 0. Avoid symbols with global linkage. * src/server/aux-items.c (aux_item_triggers): Now static. One more test case. * src/server/testsuite/lyskomd.0/03.exp: Test call 91. 1998-11-09 Per Cederqvist More test cases. * src/server/testsuite/lyskomd.0/03.exp: Test calls 86-90. Minor fixes to the documentation. * doc/Protocol-A.texi (create-text): This call can never generate the error ``anonymous-rejected''. (create-anonymous-text): Avoid too long lines. 1998-10-22 Per Cederqvist More test cases. * src/server/testsuite/config/unix.exp (extracting_expect): New proc. * src/server/testsuite/lyskomd.0/03.exp: Test call 46-85. * src/server/testsuite/renumber.el (renumber-lyskom-send-simple-expect): Handle extracting_expect. Only allow one call to set-client-version. * src/include/kom-errno.h (KOM_CLIENT_IS_CRAZY): Old favourite resurrected. * src/server/session.c (set_client_version): Fail if the client version already was set. Allow set-info with motd_of_lyskom set to 0. * src/server/admin.c (set_info): Allow motd_of_lyskom to be 0. Fixed the error-status of find-previous-text-no. * src/server/text.c (greater): Added const qualifier. (find_previous_text_no): Fixed the returned error status. * src/server/testsuite/lyskomd.0/01.exp: Adjusted to the error status that is now returned by the bug-fixed find_previous_text_no. Documentation fixes and updates. * doc/Protocol-A.texi (send-message): Document that recipient 0 means that the message is sent to all sessions. (get-last-text): Say that this relies on all texts being written in chronological order. (set-client-version): This call can only be used once per session. It will return client-is-crazy if used twice. (get-client-version): This was called "get-client-name". (mark-text): Bogus example fixed. (unmark-text): Bogus example fixed. (lookup-z-name): The want-pers and want-confs arguments were swapped in the function header. (set-info): Document that lyskomd 1.9.0 erroneously returned text-zero if MOTD was 0. 1998-10-17 Per Cederqvist More tests. * src/server/testsuite/lyskomd.0/03.exp: Test call 30-45. Fixed a memory corruption problem. * src/server/memory.c (copy_conference): Fixed a memory corruption problem that was introduced when Local_to_global was introduced. (copy_person): Likewise. (copy_text_stat): Added a const qualifier. Rewritten to decrease the probability that the same kind of bug is introduced here, that is, assign each field separately instead of assigning the entire struct at once. (copy_aux_item_list): Now static. Rewritten as above. (coy_aux_item): Added const qualifier. Rewritten as above. * src/server/kom-memory.h (copy-person): Added const qualifier. (copy_text_stat): Likewise. (copy_aux_item): Likewise. (copy_aux_item_list): Removed (now static). Minor fixes to the documentation. * doc/Protocol-A.texi (Predefined Aux-Item Types): Fixed a Texinfo syntax error. (sync-kom): Fixed bugs in the example. 1998-10-16 Per Cederqvist More tests. * src/server/testsuite/lyskomd.0/03.exp: Test call 27-29, 40. 1998-10-14 Per Cederqvist More test cases. * src/server/testsuite/lyskomd.0/03.exp: Test calls 8-27, 50, 78. * src/server/testsuite/lyskomd.0/summarize.sh: New file. Fixed bug in mark_as_read. * src/server/membership.c (adjust_read): Fixed a fence-post error that was introduced when Local_to_global was introduced. Clarify the documentation. Change the specification of async-leave-conf. * doc/Protocol-A.texi (delete-conf): State the mailboxes can be removed. (get-conf-stat-older): Document the mask argument. (mark-text-old): Document that mark-type 0 is used to remove the mark. (async-leave-conf): This message is always sent to a person when that person ceases to be a member of a conference, whatever the reason is. The protocol specification used to say that it was only sent when a person was forced to leave a conference. The current wording makes more sense, and it was also the implemented behavior, so update the specification rather than the program. 1998-10-12 David Byers * src/libraries/libcommon/Makefile.am (INCLUDES): Added -DSERVER as in src/server 1998-10-11 Jonas S Karlsson Aux-info defined for import/export of emails. These are preliminary. but will be improved. * doc/Protocol-A.texi: email aux-infos x-XXX 1998-10-11 Per Cederqvist Keep an extra copy of the database, just in case. Do some sanity checking when copying file contents. * src/server/simple-cache.c (pre_sync): Store the previous backup file. (copy_file): Abort if we cannot seek or read the file we copy from. Abort if the value we read didn't end in a newline, start with "T ", "C " or "P ", if the identity number in the data isn't what we expected, or if it isn't followed by a space. This change attempts to detect file damage as early as possible. * src/server/server-config.c (parameters): Added "Backup file 2". (read_configuration): Handle backupfile_name_2. * src/server/ramkomd.c (init_data_base): Print backupfile_name_2. * src/server/param.h (struct kom_par): Added backupfile_name_2. * src/server/dbck-cache.c (cache_sync): Store the previous backup file. * doc/man/lyskomd.8: Added "Backup file 2". Allow compaction of the text file even if there are errors in the data base. * src/server/dbck.c (main): Allow -g even if errors occured, but only if the user confirms. 1998-10-11 Per Cederqvist More test cases. * src/server/testsuite/lyskomd.0/03.exp: Test call 4-7. 1998-10-09 Per Cederqvist Commit some Emacs support code for test script writers. * src/server/testsuite/renumber.el: New file. (renumber-lyskom-send-simple-expect): New function. 1998-10-08 Per Cederqvist More test cases. * src/server/testsuite/lyskomd.0/03.exp: Test call 0, 1, 2 and 3. * doc/Protocol-A.texi (login-old): The error-status indicates the person number when invalid-password is returned. 1998-10-08 David Byers * src/server/prot-a-output.c (prot_a_output_membership): Output break_type. * src/server/ram-output.c (foutput_membership_2): Output break_type. * src/server/ram-parse.c (fparse_membership_2): Parse break_type. 1998-10-07 David Byers * src/server/text.c (recp_sent_by): New function. (filter_secret_info): Let the sender of a bcc see a bcc and let bccs to open conferences be visible to all. 1998-10-06 David Byers * src/server/send-async.c (async_new_membership): New function. (async_sub_recipient): Ditto. (async_new_recipient): Ditto. * src/server/prot-a-send-async.c (prot_a_async_new_membership): New function. (prot_a_async_sub_recipient): Ditto. (prot_a_async_new_recipient): Ditto. * src/server/text.c (send_async_add_recipient): New function. (add_recipient): Send async-new-recipient (send_async_sub_recipient): New function. (do_sub_recpt): Send async-sub-recipient. * src/server/membership.c (send_async_new_membership): New function. (add_member_common): Send async-new-membership 1998-10-06 Per Cederqvist Document bcc-recpt. A created person is a member of his mailbox. * doc/Protocol-A.texi (The Misc-Info List): Document blank carbon copies. (create-person-old): Document that the new person will be a member of his letterbox. (create-person): Likewise. Clarify the documentation about accept_async and make the implementation conform to the documentation. * src/server/session.c (accept_async): Don't accept 1, 2, 3, 4 or 10 (which are in the interval [0..ay_dummy_last) but not used). Complain about the first rejected async number, not the last. * doc/Protocol-A.texi (query-async): Added a reference to the currently preselected asynchronous messages, since the example is valid for lyskomd 1.9 but not lyskomd 2.0. (Asynchronous Messages): Encourage clients to use accept-async instead of trusting the defaults. State that the obsolete calls may be non-existing. More test cases. * src/server/testsuite/lyskomd.0/03.exp: New file. * src/server/testsuite/lyskomd.0/01.exp: Use read_versions instead of duplicating code. * src/server/testsuite/config/unix.exp (read_versions): New function, extracted from ../lyskomd.0/01.exp. Makefile improvements. * src/server/testsuite/Makefile.am (MOSTLYCLEANFILES): Added *.sum and *.log. (check-l2g): New name for former target l2g_check. (check-lyskomd): New name for former target lyskomd_check. Remove some unused code. * src/libraries/libcommon/kom-errno.c (kom_perror): Was unused. Removed. * src/include/config.h (kom_errout): Was unused. Removed. 1998-10-04 David Byers * configure.in: Output to include/config.h * src/server/aux-items.c (delete_aux_item_list): Call undelete triggers. * src/server/dbck.c: Moved BUGDECL to top level. * src/server/internal-connections.c (init_connection): Cast in comparisons to get rid of compiler warnings. * src/server/text-garb.c: Moved BUGDECL to top level. * src/server/person.c: Moved BUGDECL to top level. * src/server/conference.c: Moved BUGDECL to top level. * src/server/membership.c (do_change_priority): Only fake the passive flag when fake_passive is true. * src/server/connections.c (dump_statistics): Remove compiler warnings by casting in comparisons. * src/include/kom-types.h: Declared fields of Version_info_internal const to get rid of compiler warnings (plus, it makes sense.) * src/server/simple-cache.c (cached_get_text): Remove compiler warnings by casting in comparisons. * src/include/server/smalloc.h (SMALLOC_MAGIC_FREE): Declare constants as unsigned to avoid compiler warnings. * src/server/ram-parse.c (fparse_string): Remove compiler warnings by casting in comparisons. * src/server/local-to-global.c (find_block): Removed const declarations to get rid of compiler warnings (it was cast away anyway.) * src/libraries/libcommon/kom-errno.c: Include kom-config * src/server/admin.c: Conditionally include config.h * src/server/dbck.c (check_membership): Check duplicated info between member and membership records. Redeclared mship param as non-const. 1998-10-04 Per Cederqvist * TODO: New file. 1998-08-31 Per Cederqvist Added more tests and documentation. * doc/Protocol-A.texi (get-text): Uses the text-zero error code. (get-text-stat-old): Likewise. (get-text-stat): Likewise. * src/server/testsuite/lyskomd.0/02.exp: Added tests for get-text-stat and get-text-stat-old. Check that a text wiht one public and one secret recipient is properly filtered. 1998-08-30 Per Cederqvist query-predefined-aux-items was broken. * src/server/aux-items.c (query_predefined_aux_items): Added a missing statement so that the next link really is followed. Added more tests and documentation. * src/server/testsuite/lyskomd.0/01.exp: Added tests for requests 89-104. * doc/Protocol-A.texi (get-conf-stat): Removed a note that said that only the old bits of the Any-Conf-Type are returned by this call. (Protocol Requests): 47 is obsoleted by 104. (get-created-texts): 47 is obsoleted by 104. (set-membership-type): Document the login-first error code. (local-to-global): Likewise. (map-created-texts): New node. More documentation is needed here. 1998-08-29 Per Cederqvist Introduce Aux-Item-Input in the protocol spec. (It is a subset of Aux-Item.) Don't include aux_no in it. * src/server/testsuite/lyskomd.0/00.exp: Don't send the aux_no field in Aux-Item-Input data. * src/server/prot-a-parse.c (prot_a_parse_aux_item): Don't expect the aux_no field. Leave that field as garbage. * doc/Protocol-A.texi (LysKOM Data Types): Added Aux-Item-Input. Removed the '<10>' indicator in the Text-Stat declaration. (create-text): Use type Aux-Item-Input for input parameters. (create-anonymous-text): Likewise. (create-conf): Likewise. (create-person): Likewise. (modify-text-info): Likewise. (modify-conf-info): Likewise. (modify-system-info): Likewise. Clean up Protocol-A.texi. * doc/Makefile.am (protocol-a.info): Don't allow tabs in the document. * doc/Protocol-A.texi: Write all types as "Foo-Bar", never "Foo-bar". Don't use tabs. (Notation): Be explicit about how types are written. Misc documentation fixes. * doc/Protocol-A.texi (who-is-on-ident): Corrected the return type to ARRAY Who-Info-Ident. (modify-system-info): Changed the type of the times-to-delete argument from the undefined type Number-List to ARRAY Aux-No. (set-info): This accepts an Info-Old, not an Info. 1998-08-29 Per Cederqvist Fixed a memory problem in get_collate_table. * src/server/admin.c (get_collate_table): The result contains garbage on entry, so don't call s_clear() on it. Added more tests and documentation. * src/server/testsuite/lyskomd.0/01.exp: Read $top_srcdir/versions instead of ../version.incl, so the script gets all the versions. Added tests for requests 63-88. * src/server/testsuite/Makefile.am (site.exp): Depends on Makefile. Set top_srcdir, but not srcdir. (srcdir can still be used in the test scripts, since runtest sets it when the --srcdir option is used.) * doc/Protocol-A.texi (LysKOM Data Types): The invisible bit is always set for sessions where no-one is logged on. (who-is-on-dynamic): Likewise. (set-info): The version number was missing from the example. (create-conf): Indentation fixes. 1998-08-28 David Kågedal * doc/Protocol-A.texi: Cleaned up the call definitions. Removed all type synonyms for ARRAY types. Conference had an extra 'type' field. 1998-08-28 Per Cederqvist Added more tests and documentation. * src/server/testsuite/lyskomd.0/01.exp: Added tests for requests 51-62. * doc/Protocol-A.texi (LysKOM Data Types): The order of the elements in Who-Innfo-Old was wrong. The same bug existed at least as far back as in the prot-A.txt file that was distributed with the 1.7.0 server. I find it better to change the documentation than the code. (create-person-old): Document the auto-login feature. (who-is-on): Clarify which sessions that are returned. (get-unread-confs): Clarify that this request may return extra conferences. This request may not be made before you log in. 1998-08-27 Per Cederqvist Added more tests and documentation. * src/server/testsuite/lyskomd.0/01.exp: Added tests for requests 42-50. * doc/Protocol-A.texi (LysKOM Data Types): Removed Member-Old and Member-List-Old. (shutdown-kom): exit-val is an argument to the request, not the result from the request. (get-members-old): Simplified the return value to "ARRAY Pers-No" instead of "Member-List-Old". Explicitly state that the returned list is truncated if there are too few members of the conference. 1998-08-25 Per Cederqvist The request 36=get-info was broken. * src/server/fncdef.txt (get_info_old): Returns an info_old, not an info. Added more tests and documentation. * src/server/testsuite/lyskomd.0/01.exp: Added tests for requests 32-41. * doc/Protocol-A.texi (LysKOM Data Types): Document the aux-item-list part of the Info structure. (who-is-on-old): Document that the returned list contains only sessions that are logged in visibly. 1998-08-25 Per Cederqvist Documentation fixes: async-login was wrong. * doc/Protocol-A.texi (LysKOM Data Types): Added Any-Conf-Type to the type index. (get-text): Never fails with login-first. The no-such-text error is used when the user isn't logged in. (get-text-stat-old): Likewise. (get-text-stat): Likewise. (async-login): This async message includes a session number. More test cases added. * src/server/testsuite/config/unix.exp (any_num): New constant. (lyskomd_start): Increase the timeout around the start of lyskomd, since it can take quite a while on slow computers. * src/server/testsuite/lyskomd.0/01.exp: Added tests of more requests. * src/server/testsuite/lyskomd.0/02.exp: New file. * src/server/testsuite/Makefile.am (lyskomd_check): Added a missing quote character. 1998-08-23 Per Cederqvist Fixed the documentation of 12=lookup-name. * doc/Protocol-A.texi (LysKOM Data Types): Documented Conf-List-Archaic. (lookup-name): This request returns a Conf-List-Archaic, not a Conf-No-List. Added an example. 1998-08-22 Per Cederqvist Document more of the used error codes. * doc/Protocol-A.texi (get-person-stat-old): Added error code `login-first'. (login): Added error code `conference-zero'. (Error Codes): Renamed `illegal-password' to `invalid-password', which is the name the rest of the document uses. More test cases. * src/server/testsuite/lyskomd.0/01.exp: New test suite. * src/server/testsuite/config/unix.exp (lyskomd_start): Create a fresh database before starting lyskomd. * src/server/testsuite/Makefile.am (lyskomd_check): Don't create the database before running the lyskomd tests. Fixed bugs from the Local_to_global introduction. * src/server/membership.c (adjust_read): Fixed a fencepost error that was introduced 1998-07-26. * src/server/ram-output.c (foutput_text_list): Handle empty text lists properly. * src/server/prot-a-output.c (prot_a_output_person): Handle empty Local_to_global structures properly. (prot_a_output_conference): Likewise. (prot_a_output_conference_old): Likewise. * src/server/ram-output.c (foutput_text_list): Handle empty text lists that once was non-empty properly. Added indices to the protocol specification. * doc/Protocol-A.texi: Added a Request Index and a Type Index. Eliminated a race condition in the test case. * src/server/testsuite/config/unix.exp (lyskomd_death): Synchronize with the lyskomd process so that it dies at a proper time. * src/server/ramkomd.c (main): Don't terminate until a confirmation is read on stdin when running under DejaGnu. Implemented map_created_texts. * src/include/services.h (map_created_texts): New function. * src/server/person.c (map_created_texts): New function. * src/server/fncdef.txt: Added map_created_texts. * src/server/prot-a.c (prot_a_is_legal_fnc): Added call_fnc_map_created_texts. * src/server/testsuite/lyskomd.0/00.exp: Added test cases for map_created_texts. 1998-08-16 Per Cederqvist Documented all undocumented Aux-Items. * doc/Protocol-A.texi (Predefined Aux-Item Types): Documented aux-items 13, 14 and 15. 1998-08-14 Per Cederqvist The cache tried to free person, text and conference 0 during server shutdown. * src/server/simple-cache.c (free_all_cache): Don't attempt to access Pers_no, Conf_no or Text_no 0. (get_conf_node): Fail if the argument is less than 1. (get_pers_node): Likewise. (get_text_node): Likewise. (traverse_person): Unused function; don't compile it. * run-support/aux-items.conf (creating-software): New aux-info. 1998-08-10 Per Cederqvist Ported the test suite to DejaGnu 1.2. * src/server/testsuite/config/unix.exp (lyskomd_start): Added missing global declarations. (l2g_start): Likewise. 1998-08-10 Per Cederqvist Typo in a Makefile.am fixed. * src/server/testsuite/config/Makefile.am (lyskomd-config): Added a missing quote. 1998-08-09 Per Cederqvist Fixed bugs in get_created_texts. * src/server/person.c (get_created_texts): Fixed a fencepost error and two other errors, all introduced 1998-07-26. Test suite improvements. * src/server/testsuite/lyskomd.0/00.exp: Added more tests. Added tests for get-created-texts. * src/server/testsuite/l2g.0/10.exp: New file. * src/server/testsuite/config/unix.exp (l2g_stop): Send a quit command to test-l2g, so that we can be sure that the test case doesn't miss some unexpected final output from the test program. (unanchored_expect): Fixed an error message. * src/server/testsuite/test-l2g.c (main): Added 'q' (quit) command. Fixed more bugs in get_map. * src/server/text.c (get_map): Set result.first_local_no correctly if the map in the conference is completely empty. * src/server/prot-a-output.c (prot_a_output_l2g_iterator_as_text_list): Don't forget to emit trailing zeroes in the text-list. Document some previously undocumented behavior of get-map and get-created-texts. * doc/Protocol-A.texi (get-map): Document what happens when attempting to retrieve texts before the start of the map. (get-created-texts): Likewise. The L2g_iterator sometimes iterated past the end of a bounded search. * src/server/local-to-global.c (l2gi_searchsome): Set search_ended correctly when the end is set so that the iterator will loop over nothing, even though later texts exists. Let automake generate the INSTALL file. * README: Include the contents of the INSTALL file. This file needs a major overhaul. * mkmi: Remove INSTALL and expect automake to recreate it. Removed GNU malloc. The integration was poor, to say the least, and it was not generally an improvement to use GNU malloc. * src/server/testsuite/Makefile.am: Removed references to gnumalloc. * src/server/Makefile.am: Removed reference to gnumalloc. * src/libraries/Makefile.am (SUBDIRS): Removed @GNUMALLOC@. * INSTALL: Don't mention GNU malloc. * configure.in: --with-gnu-malloc: flag removed. Don't substitute GNUMALLOC. Don't define USE_GNU_MALLOC or USING_GNU_MALLOC. Don't use the following that was only used because of GNU malloc: SUNOS_LOCALTIME_BUG, getpagesize, memmove, AC_USG. Don't attempt to create src/libraries/gnumalloc/Makefile. * src/libraries/gnumalloc: All files in this directory removed. Added sanity check to local_to_global. * src/server/text.c (local_to_global): Check that the no_of_texts argument isn't larger than 255. 1998-08-08 Per Cederqvist Fixed a protocol error with async_deleted_text. * src/server/prot-a-send-async.c (prot_a_async_deleted_text): Fixed the size in the header. This emits 18 elements, not 16. Minor documentation fixes. * doc/aux-info.doc: Document dont-garb. * doc/Protocol-A.texi: Spell checking performed. Some other minor typos fixed. State that the aux-item read-confirm should only be added after the user has acknowledged that he has read the text. (accept-async): Moved some text that belonged here from the query-async node. The error-status indicates the first offending number, not the index of the first offending number, when unknown-async is returnd. Fixed bugs in get_map and local_to_global. * src/server/text.c (get_map): Fixed a couple of fence errors. (local_to_global): Using first_local_no==0 is an error. Fixed a fence error. * src/server/prot-a-output.c (prot_a_output_text_mapping): Emit "0" or "1", not "48" or "49", as the later-texts-exists flag. Fixed a bug that could cause much too much data to be written. Fixed bugs and made improvements to the test cases for get_map and local_to_global. * src/server/testsuite/lyskomd.0/00.exp: Many bugs fixed. Several tests added. * src/server/testsuite/config/unix.exp (attach): New constant. (line_leader): New variable. (meta_line_leader): New variable. (l2g_start): Set l2g_id, expect_active and expect_always. (fix_expect_after): New proc. (simple_expect): New argument: meta. Handle line leaders. Removed tests for unexpected lines, which should now be handled via expect_active. (unanchored_expect): Added missing quotes. (lyskomd_start): Handle attach. Set expect_active and expect_always to something sane. (client_start): Use tcpconnect.py and line leaders to make it easier to debug the test cases. Set expect_active and expect_always to something sane. (talk_to): Handle l2g. Handle line leaders. Call fix_expect_after. (client_death): New proc. * src/server/testsuite/tcpconnect.py: New file. * src/server/testsuite/Makefile.am (../lyskomd): New target. (lyskomd_check): Depend on ../lyskomd. (site.exp): Added srcdir. (EXTRA_DIST): Added tcpconnect.py. * src/server/Makefile.am (all-recursive check-recursive): Depend on lyskomd. Read the file name of the "Aux-item definition file" from the config file, not from the command line. * src/server/testsuite/config/Makefile.am (lyskomd-config): Added "Aux-item definition file". * src/server/server-config.c (parameters): Added "Aux-item definition file". (AUX_DEF_FILE): Removed. (read_configuration): Handle aux_def_file just like all the other file names. * src/server/ramkomd.c (initialize): Removed the aux_def_file argument. All callers updated. Get the file of the aux_def_file from the config file. (main): Removed the -c and -a options. This reverts the change from Sat Sep 13 15:07:32 1997. It is more consistent to get the file name of the aux-def file from the config file. The -c option was buggy anyhow. * src/server/param.h (struct kom_par): Added aux_def_file. * doc/man/lyskomd.8: Removed the -c and -c flags. Added "Aux-item definition file". * src/include/config.h (AUX_DEF_FILE): Constant removed. Default to sending async_new_text_old and ay_leave_conf, but not async_new_text, just as the documentation says. * src/server/send-async.c (async_new_text_old): Use prot_a_async_new_text_old, not prot_a_async_new_text. * src/server/async.h (ASYNC_DEFAULT_MESSAGES): Added ay_new_text_old instead of ay_new_text. Added ay_leave_conf. Get rid of some compiler warnings. * src/server/rfc931.c (get_real_username): Mark unused arguments. * src/server/dbck-cache.c (cached_lock_person): Marked unused arguments. (cached_unlock_person): Likewise. (cached_lock_conf): Likewise. (cached_unlock_conf): Likewise. 1998-08-07 Per Cederqvist Merged old uncommitted changes to prot-A.txt. * doc/prot-A.txt: Error code 38=no-connect is no longer used. Documented 85=get-collate-table. Typo fixes. Facilitate testing of Local_to_global with Electric Fence. * src/server/testsuite/config/unix.exp (efence): New constant. (efence_blurb): New proc. (l2g_start): Handle an efence-instrumented test program if the global variable efence is true. Improved the documentation on the config file. * doc/man/lyskomd.8: Documented the values that you can pass to bool config parameters. 1998-08-06 Per Cederqvist Added the beginnings of a test suite for the complete lyskomd binary. * README: Talk a little about the test suite. * src/server/testsuite/Makefile.am (l2g_check): Added --srcdir to the runtest command line. (lyskomd_check): New target. * src/server/testsuite/Makefile.am (check): Added lyskomd_check. * src/server/testsuite/lyskomd.0/00.exp: New file. * src/server/testsuite/config/unix.exp: (hollerith): New constant. (maxint): New constant. (clientport): New constant. (muxport): New constant. (unanchored_expect): Continue with the expect if an unexpected line is detected. (lyskomd_start): New proc. (lyskomd_death): New proc. (client_start): New proc. (talk_to): New proc. (holl): New proc. * src/server/testsuite/config/Makefile.am (noinst_DATA): Added lyskomd-config. (lyskomd-config): New target. Regenerate protocol-a.info automatically. * doc/Makefile.am (protocol-a.info): Added an explicit rule because Automake 1.3 fails to add it automatically. 1998-08-05 Per Cederqvist Fixed the documentation for the local-to-global call. * doc/Protocol-A.texi (LysKOM Data Types): Changed the name of the type Local-To-Global_Result to Text-Mapping. All uses updated. Implemented the local-to-global call. * src/server/fncdef.txt: Added local_to_global. * src/include/services.h (local_to_global): New function. * src/include/kom-types.h (Text_mapping): New type. * src/server/text.c (get_map): Fixed the type of the no_of_texts argument. (local_to_global): New function. * src/server/prot-a.c (prot_a_reply): Handle rt_text_mapping. (prot_a_is_legal_fnc): Handle call_fnc_local_to_global. * src/server/prot-a-output.c (prot_a_output_text_mapping): New function. * src/server/prot-a-output.h: Likewise. * src/server/connections.h (Res_type): Added rt_text_mapping. (Result_holder): Added text_mapping. 1998-08-03 Per Cederqvist Document the local-to-global call. * doc/Protocol-A.texi (Articles): Refer to local-to-global instead of get-map. (LysKOM Data Types): Added subsection titled "Mapping Local to Global Text Numbers". (Protocol Requests): Mark get-map as obsolete, and refer to 103. Added 103=local-to-global. (get-map): This is superseded by local-to-global. (accept-async): Fixed typo. (local-to-global): New node. 1998-08-02 Per Cederqvist Generate and install protocol-a.info. * doc/Makefile.am (info_TEXINFOS): New target. Moved Protocol-A.texi here. (EXTRA_DIST): Moved Protocol-A.texi to info_TEXINFOS. * mkmi: Remove scripts/texinfo.tex and expect automake to regenerate it. Minor syntactic documentation fixes. * doc/Protocol-A.texi: Added @dircategory and @direntry commands. (Protocol Requests): Added set-membership-type to the menu. (set-membership-type): Minor typo fixed. (Top): State that this is a draft, and that the version numbers are wrong. 1998-07-27 Per Cederqvist Fixed a pointer bug in Local_to_global. * src/server/local-to-global.c (join_range): Fixed a bug where a pointer that pointed to the old position of a reallocated block was used. 1998-07-26 Per Cederqvist dbck can now read database format 2. * src/server/dbck-cache.c (init_cache): Handle database format 2. Fix the bootstrap database. * db-crypt/db/lyskomd-data: CONF-RECORD uses the Local_to_global structure. Remove all traces of the Text_list type. * src/include/kom-types.h (Text_list): Removed. * src/server/connections.h (Res_type): Removed rt_text_list. (Result_holder): Removed text_list. * src/server/prot-a-output.h (prot_a_output_text_list): Removed. * src/server/prot-a-output.c (prot_a_output_text_list): Removed. * src/server/prot-a.c (prot_a_reply): Don't attempt to handle rt_text_list. Code cleanup. * src/server/aux-item-def.y: Fixed indentation of include statements. * src/server/aux-item-def.lex.c: No longer kept under version control. Improve documentation. * doc/server.extend: Updated. Start using the Local_to_global structure. * doc/lyskomd-database-format (DATABASE VERSION 2): CONF-RECORD and PERS-RECORD uses the Local_to_global structure. * configure.in: Added AC_C_INLINE. * src/server/text.c (add_text_in_conf): Adjusted to the fact that the texts member of Conference is now a l2g. (do_sub_recpt): Likewise. (set_loc_no): Removed. (adjust_text_list): Removed. (do_delete_text): Adjusted to the fact that the created_texts member of Person is now a l2g. (do_create_text): Likewise. (get_map): The result argument now points to a l2g_iterator_as_text_list instead of a Text_list. Adjusted to the fact that the texts member of Conference is now a l2g. * src/server/simple-cache.c (mark_conference_as_changed): Adjusted to the fact that the texts member of Conference is now a l2g. (setup_small_conf): Likewise. * src/server/ram-parse.h (fparse_text_list): Removed. * src/server/ram-parse.c (fparse_conference_2): Use l2g_read instead of fparse_text_list. (fparse_person_2): Likewise. (fparse_text_list): The result argument now points to a Local_to_global instead of a Text_list. * src/server/ram-output.h (foutput_text_list): The text_list argument is now a pointer to Local_to_global instead of a Text_list. * src/server/ram-output.c (foutput_person_0): Adjusted to new API of foutput_text_list. (foutput_person_2): Use l2g_write instead of foutput_text_list. (foutput_conference_2): Likewise. (foutput_conference_1): Adjusted to new API of foutput_text_list. (foutput_conference_0): Likewise. (foutput_text_list): The text_list argument is now a pointer to Local_to_global instead of a Text_list. The generated output is still the same. (foutput_ulong): Eliminated a future buffer overrun. Cleaned up the code. * src/server/prot-a.c (prot_a_reply): Handle rt_l2g_iterator_as_text_list. * src/server/prot-a-output.h (prot_a_output_l2g_iterator_as_text_list): New function. * src/server/prot-a-output.c (prot_a_output_person): Adjusted to the fact that the created_texts member of Person is now a l2g. (prot_a_output_conference): Adjusted to the fact that the texts member of Conference is now a l2g. (prot_a_output_conference_old): Likewise. (prot_a_output_l2g_iterator_as_text_list): New function which emulates a Text_list. * src/server/person.c (do_delete_pers): Adjusted to the fact that the created_texts member of Person is now a l2g. (get_created_texts): The return value is now an l2g_iterator_as_text_list, not a Text_list. Adjusted to the fact that the created_texts member of Person is now a l2g. * src/server/memory.c (clear_text_list): Removed. (copy_text_list): Removed. (clear_conference): Adjusted to the fact that the texts member of Conference is now a l2g. (init_conference): Likewise. (copy_conference): Likewise. Added const qualifier to the argument. (clear_person): Adjusted to the fact that the created_texts member of Person is now a l2g. (copy_person): Likewise. (init_person): Likewise. (init_text_list): Removed. (copy_aux_item_list): Added const qualifier to the src argument. * src/server/membership.c (add_rec_time): Adjusted to the fact that the texts member of Conference is now a l2g. (adjust_read): Likewise. (mark_as_read): Likewise. (check_membership): Likewise. (set_unread): Likewise. (set_last_read): Likewise. * src/server/kom-memory.h (copy_conference): The argument is const. (copy_aux_item_list): Likewise. (init_text_list): Removed. * src/server/fncdef.txt (get_map): Changed return type from text_list to l2g_iterator_as_text_list. (get_created_texts): Likewise. * src/server/dbck.c (struct delete_list): New struct. (delete_list_append): New static function. (execute_deletions): New static function. (check_misc_infos): Adjusted to the fact that the texts member of Conference is now a l2g. (adjust_text_list): Deleted. (check_created_texts): The "created" argument now points to a Local_to_global. Removed the check for "bad created_texts array" since it can no longer be bad in that way. (check_membership): Adjusted to the fact that the texts member of Conference is now a l2g. (check_texts_in_conf): The "tlist" argument now points to a Local_to_global. Removed the check for "bad created_texts array" since it can no longer be bad in that way. * src/server/dbck-cache.c (cached_get_highest_local_no): Adjusted to the fact that the texts member is now a l2g. (cache_sync): Fixed type in some printf format strings. * src/server/connections.h (Res_type): Added rt_l2g_iterator_as_text_list. (Result_holder): Added l2g_iterator_as_text_list. * src/server/conference.c: (do_delete_conf): Adjusted to the fact that the texts member is now a l2g. * src/server/Makefile.am (DBCK): Added local-to-global.c. (all-recursive, check-recursive): Require libcheck.a to be built. * src/include/services.h (get_created_texts): Changed type of the result to L2g_iterator_as_text_list. (get_map): Likewise. * src/include/kom-types.h (struct l2g_block_info): New forward declaration. (Local_to_global): New type. (L2g_iterator): New type. (L2g_iterator_as_text_list): New type. (Conference): The texts member is now a Local_to_global, not a Text_list. (Person): The created_texts member is now a Local_to_global, not a Text_list. Fixes and improvements to the Local_to_global structure. * src/server/local-to-global.h (L2G_BLOCKSIZE): Moved to local-to-global.c. (L2g_block_info): Likewise. (Local_to_global): Likewise. (l2g_copy): Switched placement of src and dest to match other copy functions in the lyskomd code. Added const qualifier. (l2g_lookup): Added const qualifier to the l2g argument. (l2g_next_key): Likewise. (l2g_compact): Removed. (l2g_first_appendable_key): New function. (l2g_delete_global_in_sorted): New function. (l2g_dump): Switch placement of l2g and file arguments to match other similar functions in the lyskomd code. Added const qualifier. (l2g_write): Likewise. (l2g_read): Likewise. (l2g_searchall): Added const qualifier. (L2g_iterator): Moved to kom-types.h. (l2gi_searchsome): Added const qualifier. (l2gi_begin): New function. (l2gi_end): New function. * src/server/local-to-global.c: Include assert.h. Only include stdlib.h if HAVE_STDLIB_H. Include stdio.h if we didn't get NULL from stdlib.h. Inlucd lyskomd.h and server/smalloc.h. (L2G_BLOCKSIZE): Moved here from local-to-global.h. (struct l2g_block_info): Likewise. (is_dense): New static function. (is_empty): New static function. (key_value): New static function. (sparse_skip_deleted): New static function. (sparse_locate_value): New static function. (sparse_compact): New static function. (add_block): Use srealloc instead of realloc. Don't initialize start -- the caller is responsible for doing so. (delete_block): Use sfree instead of free, and srealloc instead of realloc. (make_sparse): Don't change the value of start, since there is no need to, and make_sparse may now be called on an empty block, which would cause start to be set to a garbage value. (find_block): Added a const qualifier to the return value and l2g argument. Use key_value to simplify code. (find_block_index_key): Added a const qualifier to the l2g argument. Use helper functions to simplify the code. Use sparse_skip_deleted so that the function never returns a deleted key. Never return deleted keys in dense blocks either. (join_range): New static function. (join_blocks): New static function. (l2g_init): Set first_unused to 1. (l2g_clear): Use sfree instead of free. Set first_unused to 1. (l2g_copy): Added const qualifier to the src argument. Simplified code by using helper functions and relying on the fact that calling l2g_append with a Text_no=0 is a no-op. Set first_unused of the copy. (l2g_append): Send a log message and do nothing if an attempt to set a local number lower than first_unused is detected. Set first_unused. Fixed the logic about when to add a new block, when to compact the last block, and when to make it sparse. Simplify code by using the helper functions. (l2g_delete): Don't increase the zeroes counter if a zero is deleted. Delete the entire block if it became empty. Attempt to join this block to its neighbors. Compact the block if it was sparse and contained too many deleted entries. (l2g_lookup): Added const qualifier to the l2g argument. Don't return uninitialized data. Use helper functions to simplify code and make it slightly faster. (l2g_next_key): Added const qualifier to the l2g argument. (l2g_first_appendable_key): New function. (l2g_delete_global_in_sorted): New function. (l2g_compact): Removed. (l2g_dump): Switch placement of l2g and file arguments to match other similar functions in the lyskomd code. Added const qualifier. Dump first_unused. Use helper functions to simplify code. (l2g_read): Switch placement of l2g and file arguments to match other similar functions in the lyskomd code. Read first_unused. Return a success indicator. Detect unexpected EOF conditions. (l2g_write): Switch placement of l2g and file arguments to match other similar functions in the lyskomd code. Write first_unused. Use helper functions to simplify code. (l2gi_searchall): Added const qualifier to the l2g argument. Simplify code by calling l2gi_searchsome instead of duplicating the code. (l2gi_searchsome): Added const qualifier to the l2g argument. Complain if the begin argument is less than 1. Don't forget to initialize search_ended. Set beginval. Giving end==0 means that the iterator should continue to the end of the set. Use helper functions to simplify the code. (l2gi_next): Use helper functions to simplify code. The iterator is unlimited if endval==0. (l2gi_begin): New function. (l2gi_end): New function. Improve the test suite with new tests of the Local_to_global structure. * src/server/testsuite/l2g.0/00.exp: The "C" command now takes the arguments the other way around. Adjust the test case. Comments added. Expect the "u" command to print first_unused. * src/server/testsuite/l2g.0/02.exp: New file. * src/server/testsuite/l2g.0/03.exp: New file. * src/server/testsuite/l2g.0/04.exp: New file. * src/server/testsuite/l2g.0/05.exp: New file. * src/server/testsuite/l2g.0/06.exp: New file. * src/server/testsuite/l2g.0/07.exp: New file. * src/server/testsuite/l2g.0/08.exp: New file. * src/server/testsuite/l2g.0/09.exp: New file. * src/server/testsuite/config/unix.exp (l2g_stop): Added a wait statement to avoid creating zombies. (simple_expect): Added a missing space in a prompt regexp. * src/server/testsuite/test-l2g.c (main): Removed the 'c' command since l2g_compact no longer exists. Added the 'i' command that tests iterators. Adjusted to the new API of l2g_dump, l2g_read and l2g_write. Require an extra trailing newline after the representation l2g_read expects when the 'r' command is used, and produce a corresponding newline with the 'w' command. Renamed the 'p' command to 'w'. 1998-07-19 Per Cederqvist Protocol buglets fixed. * doc/Protocol-A.texi (Membership-Type, Session-Flags): Fixed syntax error in the definition. 1998-07-12 Per Cederqvist Build the program in the test suite. * src/server/ramkomd.c (restart_kom): Moved to log.c. * src/server/log.c (restart_kom): Moved here from ramkomd.c. * src/server/Makefile.am (noinst_LIBRARIES): Added libcheck.a. (libcheck_a_SOURCES): New library, used by the test suite. * src/server/testsuite/Makefile.am (noinst_PROGRAMS): Added test-l2g. (EXTRA_DIST): Removed test-l2g.c. (test_l2g_SOURCES): Added test-l2g.c. (test_l2g_LDADD): Added ../libcheck.a. (../libcheck.a): New target. Removed all old makefile template files. * Makefile.src: Removed. * doc/Makefile.src: Removed. * doc/man/Makefile.src: Removed. * run-support/Makefile.src: Removed. * scripts/Makefile.src: Removed. * src/Makefile.src: Removed. * src/include/Makefile.src: Removed. * src/include/server/Makefile.src: Removed. * src/libraries/Makefile.src: Removed. * src/libraries/gnumalloc/Makefile.src: Removed. * src/libraries/libansi/Makefile.src: Removed. * src/libraries/libcommon/Makefile.src: Removed. * src/libraries/libisc-new/Makefile.src: Removed. * src/libraries/libisc-new/src/Makefile.src: Removed. * src/libraries/libmisc/Makefile.src: Removed. * src/libraries/regex/Makefile.src: Removed. * src/libraries/regex/doc/Makefile.src: Removed. * src/libraries/regex/test/Makefile.src: Removed. * src/server/Makefile.src: Removed. * src/server/testsuite/Makefile.src: Removed. Fixed "make dist". * SERVER-RELEASE: Slightly updated. * src/server/testsuite/config/Makefile.am: New file. * src/server/testsuite/Makefile.am (SUBDIRS): Added config. (EXTRA_DIST): Added .cvsignore and test-l2g.c. (MOSTLYCLEANFILES): Added .gdbinit and site.exp. * src/server/Makefile.am (EXTRA_DIST): Added .cvsignore, ChangeLog.1, Magics, To-do, aux-item-def.l, aux-item-def.y, call-switch.awk, com-h.awk, fnc-def-init.awk, prot-a-parse-arg-c.awk, prot-a-parse-arg-h.awk, fncdef.txt, free.gdb, handle-malloc-dump.el, malloc.gdb, realloc.gdb, trace-mem.gdb and logII.c. (MOSTLYCLEANFILES): Added .gdbinit, call-switch.incl, com.h, fnc-def-init.incl, fncdef-no-str-limit.txt, prot-a-parse-arg.h and version.incl. (MAINTAINERCLEANFILES): Added aux-item-def.tab.h. (lyskomd_SOURCES): Added admin.h, async.h, aux-items.h, cache-node.h, cache.h, conf-file.h, connections.h, end-of-atomic.h, exp.h, internal-connections.h, internal-services.h, isc-interface.h, isc-malloc.h, isc-parse.h, kom-memory.h, local-to-global.h, log.h, lyskomd.h, manipulate.h, minmax.h, mux-parse.h, mux.h, param.h, prot-a-output.h, prot-a-parse.h, prot-a-send-async.h, prot-a.h, ram-output.h, ram-parse.h, rfc931.h, send-async.h, server-config.h, string-malloc.h, text-garb.h, tmp-limits.h and version-info.h. (dbck_SOURCES): Added dbck-cache.h and getopt.h. * src/libraries/libmisc/Makefile.am (EXTRA_DIST): Added ChangeLog.1. * src/libraries/libcommon/Makefile.am (EXTRA_DIST): Added ChangeLog.1. * src/include/Makefile.am (EXTRA_DIST): Added ChangeLog.1. * run-support/Makefile.am (EXTRA_DIST): Added .cvsignore, komrunning.sh and savecore.sh. * doc/man/Makefile.am (EXTRA_DIST): Added $(man_MANS). * doc/prot-A-english.txt: Added a reference to Protocol-A.texi. * doc/Makefile.am (EXTRA_DIST): Added Buggar.fixade, Bugrapporter, LOGG, Protocol-A.texi, aux-info.doc, clients.assigned, cmsltt12.mf, dbck.latexinfo, disc-cache.spec, local-to-global.doc, lyskomd-database-format, mux.proto, prot-A-english.txt and security-levels.txt. * db-crypt/db/Makefile.am (EXTRA_DIST): Added .cvsignore. * db-crypt/Makefile.am (EXTRA_DIST): Added .cvsignore. * configure.in: Generate src/server/testsuite/config/Makefile. * Makefile.am (EXTRA_DIST): Added ChangeLog.1, README.FSF, SERVER-RELEASE, mkmi and versions. Removed obsolete and unused files. * src/server/disk-end-of-atomic.c: Don't include disk-cache.h. * src/server/sync.c: Removed. * src/server/disk-cache.h: Removed. * src/server/cache.c: Removed. * src/server/cache-database.h: Removed. * src/server/cache-database.c: Removed. * scripts/mkmi.m4: Removed. * scripts/makedist.sh: Removed. * doc/libraries: Removed * doc/fileformat: Removed. * doc/elisp-client.user-manual: Removed. * doc/elisp-client.internals: Removed. * doc/Introduktion: Removed. Don't version-control generated files. * src/server/aux-item-def.tab.h: No longer kept under version control. Removed the last traces of zmalloc. * src/libraries/libmisc/Makefile.am (libmisc_a_SOURCES): Removed zmalloc.h. 1998-07-11 Per Cederqvist Install the sample database (unless it was already installed). * configure.in: Generate db-crypt/db/Makefile. * db-crypt/Makefile.am (SUBDIRS): Added db. * db-crypt/db/Makefile.am: New file. Fix compilation outside the source directory. * src/server/Makefile.am (aux-item-def.tab.c): Look for aux-item-def.y in srcdir. 1998-07-10 Per Cederqvist Fix "make install". * run-support/Makefile.am (sysconf_DATA): Added, but empty. (EXTRA_DIST): Added config and aux-items.conf. (komrunning): The current standard names the variable sysconfdir, not etcdir. (savecore): Likewise. (install-data-local): Likewise. Fix the configure script so that --enable-isc-printf is no longer needed. * configure.in: Force enable_isc_printf so that libisc contains the proper things. Some versions of libnsl and/or libsocket are reportedly bogus, so don't link against them unless it is really necessary. * configure.in: Improved checking for -lsocket and -lnsl. 1998-07-09 Per Cederqvist Don't forget src/server/testsuite. * configure.in: Don't forget src/server/testsuite. (USING_GNU_MALLOC): An automake conditional. * src/server/testsuite/test-l2g.c (main): Make it a proper prototype. Avoid problems with signed chars. Fixed typo: use l2g_write, not l2g_print. * src/server/testsuite/Makefile.am: New file. * src/server/Makefile.am (SUBDIRS): New variable; added testsuite. Don't try to compile zmalloc which was removed yesterday. * src/libraries/libmisc/Makefile.am (libmisc_a_SOURCES): Removed zmalloc.c. Build komrunning and savecore. * run-support/Makefile.am: New file. Switch to using automake. * mkmi: Run aclocal, automake and autoconf instead of creating Makefile.in via a m4 script. * configure.in: Move up AC_CONFIG_AUX_DIR so that both automake and autoconf detects it early enough. Remove explicit AC_SUBST of several variables that automake handles automatically, or that was used for functionality that automake provides in different ways: CFLAGS, CPPFLAGS, LDFLAGS, DEPENDFLAGS, INCLUDE_CURRENT, EXTRAARFLAGS, SRCTOPDIR, BUILDTOPDIR. Added call to AM_C_PROTOTYPES. Rely on automakes ability to fix dependencies automatically and handle ARFLAGS properly. Use CMOD_COMPILER_CC_ACCEPTS to check for a lot of warning flags to use. Use CMOD_C_ATTRIBUTE_UNUSED. Use AM_PROG_LEX instead of AC_PROG_LEX. Removed check for sys/select.h, which only isc uses. Added check for values.h. Run configure in src/libraries/libisc-new instead of creating makefiles in that directory. Generate db-crypt/Makefile and run-support/Makefile. Don't version-control files that are generated by aclocal, automake, autoconf or bison. * Makefile.in: No longer kept under version control. * aclocal.m4: Likewise. * configure: Likewise. * doc/Makefile.in: Likewise. * doc/man/Makefile.in: Likewise. * run-support/Makefile.in: Likewise. * scripts/Makefile.in: Likewise. * scripts/install-sh: Likewise. * scripts/mkinstalldirs: Likewise. * src/Makefile.in: Likewise. * src/include/Makefile.in: Likewise. * src/include/server/Makefile.in: Likewise. * src/libraries/Makefile.in: Likewise. * src/libraries/libansi/Makefile.in: Likewise. * src/libraries/libcommon/Makefile.in: Likewise. * src/libraries/libmisc/Makefile.in: Likewise. * src/server/Makefile.in: Likewise. * src/server/aux-item-def.tab.c: Likewise. 1998-07-08 Per Cederqvist Use libisc-0.99. * src/server/isc-interface.h: Include "isc.h" instead of "isc-new.h". (ISC_PRINTF_SUPPORT): Define it. * src/libraries/libisc-new: Replace the old contents with that of isc-0.99. Se src/libraries/libisc-new/ChangeLog for information about any modifications that are made to the library. Added files that automake requires. * AUTHORS: New file. * README-serverrelease: Renamed to README. * README: New name for former README-serverrelease. * acinclude.m4: New file. Contents taken from the old aclocal.m4, but changed to match the contents of libisc. Added new makefile templates for automake. * Makefile.am: New file. * db-crypt/Makefile.am: New file. * doc/Makefile.am: New file. * doc/man/Makefile.am: New file. * scripts/Makefile.am: New file. * src/Makefile.am: New file. * src/include/Makefile.am: New file. * src/include/server/Makefile.am: New file. * src/libraries/Makefile.am: New file. * src/libraries/libansi/Makefile.am: New file. * src/libraries/libcommon/Makefile.am: New file. * src/libraries/libmisc/Makefile.am: New file. * src/server/Makefile.am: New file. Code cleanup for increased portability. * src/libraries/libmisc/pom.c: Use HAVE_VALUES_H instead of __svr4__ and __sparc__ to protect inclusion of . (rcsid): Added a missing const. Improved some variable types and fixed problems with signed chars. * src/server/simple-cache.c (rcsid): Added a missing const. (next_free_num): Changed type from int to Conf_no. (next_text_num): Changed type from int to Text_no. (read_person): Flag unused parameters. (read_conference): Likewise. (read_text_stat): Likewise. (cached_get_text_stat): Adjusted printf format according to the next_text_num change. (init_cache): Likewise. (free_match_table): Renamed a parameter name to avoid warnings from gcc. (build_matching_info): Renamed a local variable name to avoid warnings from gcc. (pre_sync): Use tno_iter and cno_iter instead of i to get all types correct. (post_sync): Likewise. (copy_file): Flag unused parameters. * src/server/ram-parse.c (rcsid): Added a missing const. (fparse_info_0): Now static. (fparse_info_2): Likewise. (fparse_conference_2): Likewise. (fparse_conference_0): Likewise. (fparse_person_0): Likewise. (fparse_person_2): Likewise. (fparse_text_stat_2): Likewise. (fparse_text_stat_0): Likewise. (fparse_conf_list): Changed type of local variable "i" from int to unsigned long. (fparse_text_list): Likewise. * src/server/ram-output.c (foutput_text_list): Changed type of local variable "i" from int to unsigned long. (foutput_time): Renamed a parameter name to avoid warnings from gcc. (rcsid): Added a missing const. * src/server/prot-a-output.c (prot_a_output_conf_list): Changed type of local variable "i" from int to unsigned long. (prot_a_output_text_list): Likewise. (prot_a_output_time): Renamed local variable names to avoid warnings from gcc. (rcsid): Added a missing const. * src/server/local-to-global.c (Local_text_no_iter): New experimental typedef. (l2g_append): Renamed i to ix and changed type to Local_text_no_iter. * src/server/dbck-cache.c: Include dbck-cache.h. (rcsid): Added a missing const. (next_text_num): Changed type from int to Text_no. (TEXT_RANGE): Adjusted printf format for next_text_num change. (VOID_TEXT_RANGE): Likewise. (cache_sync): Changed type of local variable i from int to unsigned long. Removed extern declaration of oformat. Adjusted printf formats for next_text_num change. (init_cache): Removed extern declaration of oformat. Adjusted printf formats for next_text_num change. * src/server/conference.c (do_create_conf): Now static. (do_lookup): Changed type of local variables i and retsize to avoid warnings. Handle overflow a little better and log warning messages if overflow ever occurs. (rcsid): Added a missing const. * src/libraries/libmisc/s-string.c (s_strcmp): Changed type of loop variable from "unsigned int" to "String_size". (s_usr_strcmp): Likewise. (char2digit): Added const qualifier to translate_table. Use an int as argument to isalpha and tolower to avoid problems with signed chars. (rcsid): Added a missing const. * src/server/conf-file.c (assign_text_no): Don't use isdigit unless isascii is true. Use an int as argument to isalpha and isdigit to avoid problems with signed chars. (assign_conf_no): Likewise. (assign_int): Likewise. (rcsid): Added a missing const. Many minor tweaks to remove annoying but harmless warnings from gcc. * src/server/updateLysKOM.c (checkstatus): Now static. * src/server/text.c: Include internal-services.h. (rcsid): Added a missing const. (set_loc_no): Renamed a parameter name to avoid warnings from gcc. (find_recipient): Now static. Removed declaration of errno. * src/server/session.c (get_time): Renamed a parameter name to avoid warnings from gcc. (rcsid): Added a missing const. * src/server/server-config.c (log_param): Flag unused argument. (param_name): Now static. (rcsid): Added a missing const. * src/server/rfc931.c: Include rfc931.h. (get_real_username): Added a const qualifier to the return value. * src/server/rfc931.h (get_real_username): Added a const qualifier to the return value. * src/server/ramkomd.c (rcsid): Added a missing const. (init_data_base): Removed unused argument dir_base. All callers updated. (sighandler_hup): Flag unused argument. (sighandler_quit): Likewise. (sighandler_usr1): Likewise. (sighandler_usr2): Likewise. (go_daemon): Make it a function prototype. (initialize): New static. * src/server/mux.c: (rcsid): Added a missing const. (UCB_printf): Specify the return type in the extern declaration. * src/server/membership.c (do_add_member): Renamed local variable names to avoid warnings from gcc. (do_sub_member): Likewise. (locate_member): Likewise. (check_membership): Likewise. (set_membership_type): Likewise. (rcsid): Added a missing const. * src/server/log.c (rcsid): Added a missing const. (logv): Renamed local variable names to avoid warnings from gcc. (log): Likewise. * src/server/internal-services.h (do_create_conf): Declaration removed. This function is static. * src/server/dbck.c (register_jubel): Flag unused arguments. (locate_member): Renamed local variable names to avoid warnings from gcc. (check_misc_infos): Likewise. (check_created_texts): Likewise. (check_membership): Likewise. (check_texts_in_conf): Likewise. (confirm): Added const qualifier to argument question. (check_member): Likewise. (init_data_base): Removed the unused dbase_dir argument. All callers updated. * src/server/dbck-cache.h (oformat): Declaration added. * src/server/connections.c (login_request): Added a missing const to the realuser local variable. (rcsid): Added a missing const. * src/server/conf-file.h (struct parameter): Added const qualifier to the name and default_val tags. * src/server/aux-items.c: Include services.h. (aux_item_definition_cache_regexp): Now static. (initialize_aux_items): Removed declaration of parse_aux_item_definitions. (aux_item_call_add_triggers): Now static. (aux_item_call_delete_triggers): Now static. (aux_item_call_undelete_triggers): Now static. * src/server/aux-items.h (Aux_item_definition_s): Added const qualifier to the name tag. (Aux_item_trigger_mapping): Likewise. (parse_aux_item_definitions): Declaration added. * src/server/aux-item-def.y: (aux_item_def_typename): Added const qualifier to the return value. (aux_item_def_check_assign): Added const qualifier to the id argument. (aux_item_def_check_trigger): Added const qualifier to the check_name argument. * src/server/admin.c (shutdown_kom): Flag unused arguments. (rcsid): Added a missing const. * src/include/services.h: Renamed a few parameter names to avoid warnings from gcc. * src/server/prot-a-output.h: Likewise. * src/server/ram-output.h: Likewise. * src/libraries/libcommon/parser.h: Likewise. * src/server/manipulate.h: Likewise. * src/libraries/libcommon/kom-errno.c (rcsid): Added a missing const. * src/libraries/libcommon/misc-parser.c: Likewise. * src/libraries/libcommon/parser.c: Likewise. * src/libraries/libmisc/s-collat-tabs.c: Likewise. * src/server/cache-node.c: Likewise. * src/server/disk-end-of-atomic.c: Likewise. * src/server/internal-connections.c: Likewise. * src/server/isc-malloc.c: Likewise. * src/server/isc-parse.c: Likewise. * src/server/memory.c: Likewise. * src/server/mux-parse.c: Likewise. * src/server/person.c: Likewise. * src/server/prot-a-parse.c: Likewise. * src/server/prot-a-send-async.c: Likewise. * src/server/prot-a.c: Likewise. * src/server/ram-smalloc.c: Likewise. * src/server/regex-match.c: Likewise. * src/server/send-async.c: Likewise. * src/server/string-malloc.c: Likewise. * src/server/text-garb.c: Likewise. * src/libraries/libansi/empty.c: Likewise. Remove some old unused files. * src/libraries/libmisc/zmalloc.c: Unused file removed. * src/libraries/libmisc/zmalloc.h: Unused file removed. * src/server/kom-types.c: Empty file removed. * scripts/Summarize-Headers: File removed. * scripts/List-Files: File removed. * src/libraries/libclient/.cvsignore: File removed. * src/libraries/libclient/Makefile.in: File removed. * src/libraries/libclient/async.c: File removed. * src/libraries/libclient/async.h: File removed. * src/libraries/libclient/client-Makefile.in: File removed. * src/libraries/libclient/client-malloc.h: File removed. * src/libraries/libclient/client.c: File removed. * src/libraries/libclient/client.h: File removed. * src/libraries/libclient/input.c: File removed. * src/libraries/libclient/input.h: File removed. * src/libraries/libclient/kom-types.c: File removed. * src/libraries/libclient/output.c: File removed. * src/libraries/libclient/output.h: File removed. * src/libraries/libclient/parse.c: File removed. * src/libraries/libclient/parse.h: File removed. * src/libraries/libclient/send.c: File removed. * src/libraries/libclient/send.h: File removed. * src/libraries/libclient/services.c: File removed. * src/libraries/libclient/services.h: File removed. 1998-07-07 Per Cederqvist Fixed spelling of the config file parameter "Max broadcast length". * src/server/server-config.c (parameters): Fixed mis-spelling of "Max broadcast length". * doc/man/lyskomd.8: Likewise. * doc/Protocol-A.texi: Minor errata. * doc/security-levels.txt: Converted from swascii to latin1. 1998-06-14 David Byers * src/server/membership.c (copy_public_confs): The supervisor of a conference can now see secret parts of member's memberships. (get_members): Ditto. (set_membership_type): Don't allow secret memberships if the conference forbids it. (add_member): Ditto. (add_member): Pretend that addition worked if the person is already a secret member. (do_get_membership): Renamed from get_membership_old. (get_membership_old): New function. (get_membership): Call do_get_membership (do_get_members): Renamed from get_members. (copy_public_confs): New argument want_passive. * src/server/prot-a-output.c (prot_a_output_extended_conf_type): Added output of forbid_secret. * src/server/prot-a-parse.c (prot_a_parse_conf_type): Added parse of forbid_secret. * src/server/ram-parse.c (fparse_conf_type): Added parse of forbid_secret. * src/server/ram-output.c (foutput_conf_type_1): Added output of forbid_secret. * src/include/kom-types.h: Added forbid_secret conf_type. 1998-06-10 David Byers * src/server/membership.c (sub_member): Return KOM_NOT_MEMBER for secret memberships. 1998-06-08 David Byers * src/server/membership.c (set_membership_type): New function. * src/server/prot-a-output.c (prot_a_output_membership): Output added_at. (prot_a_output_member): Output added_at * src/server/membership.c (do_add_member): Set added_at. (get_members): Filter out added_at. * src/server/memory.c (init_membership): Init added_at. * src/server/ram-output.c (foutput_member_2): Added output of added_at. * src/server/ram-parse.c (fparse_member_2): Added parsing of added_at. * src/include/kom-types.h: Added added_at to Membership och Member. * src/server/ram-parse.c (fparse_membership_2): Added parsning of added_at. * src/server/ram-output.c (foutput_membership_2): Added output of added_at. Fri Jan 16 22:51:52 1998 David Byers * src/include/kom-types.h (Aux_item_flags): Added dont_garb. * src/server/text-garb.c (garb_text): Check dont_garb aux-item flag. Mon Sep 22 19:06:05 1997 David Byers * src/server/cache-node.h: New flags: snapshot and synced. Sun Sep 21 21:16:28 1997 David Byers * src/server/memory.c (copy_text_stat): Call copy_aux_item_list. (copy_aux_item_list): New function. (copy_aux_item): New function. (copy_conference): Call copy_aux_item_list. (clear_conference): Free the aux_item_list (init_conference): Init the aux_item_list. (clear_text_stat): Free the aux_item_list. (init_text_stat): Init the aux_item_list. (init_aux_item_list): New function. Sat Sep 13 15:07:32 1997 David Byers * run-support/aux-items.conf: New file. This is the aux-item definition file. * src/server/aux-items.h: New file. Include this when using aux-items. * src/server/aux-items.c: New file. Implements most of the functionality associated with aux-items. * src/server/aux-item-def.l: New file. Implements the scanner for the aux-item definition file parser. * src/server/aux-item-def.y: New file. Implements the aux-item definition file parser. * src/server/text.c: Added support for aux-items. Set err_stat whenever kom_errno is set. (create_text_old): Renamed from create_text. Use do_create_text. (create_text): New RPC function. (create_anonymous_text): New RPC function. (create_anonymous_text_old): Renamed from create_anonymous_text. Use do_create_text. (do_create_text): New function similar to old create_text, but with aux-item support. (count_recipients): Handle bcc-recpt. (find_recipient): Handle bcc-recpt. (do_add_bcc_recpt): New function to add bcc-recipient. (do_delete_misc): Handle bcc_recpt. (do_sub_recpt): Handle bcc_recpt. (sender): Handle bcc_recpt. (is_sender): Handle bcc_recpt. (is_comm_sender): Handle bcc_recpt. (skip_recp): Handle bcc_recpt. (is_member_in_recpt): Handle bcc_recpt. (filter_secret_info): Handle bcc_recpt. (text_read_access): Handle bcc_recpt. (do_delete_text): Handle bcc_recpt. (check_double_subm): Handle bcc_recpt. (check_double_comm): Handle bcc_recpt. (create_text_check_misc): Handle bcc_recpt. (create_text_add_miscs): Handle bcc_recpt. (add_recipient): Handle bcc_recpt. (filter_secret_info): Filter aux-items as well as misc-info. (create_text_add_aux): New function. (send_async_new_text_old): Renamed from send_async_new_text. (send_async_new_text): New function. (get_text_stat_old): Renamed from get_text_stat. (get_text_stat): New RPC function. (modify_text_info): New RPC function. (do_delete_text): Send async deleted text. * src/server/text-garb.c (garb_text): Handle bcc-recpt. * src/server/simple-cache.c: Set err_stat whenever kom_errno is set. (cached_lookup_name): Set kom_errno to KOM_INTERNAL_ERROR is parse() fails. (pre_sync): Write version 2 data file. (cached_delete_conf): Delete conference name from small_conf_arr. (pre_sync): Use foutput_info instead of writing it here. (init_cache): Return KOM_INTERNAL_ERROR on problems with the files. Prettier handling of datafile versions (switch instead of testing for one single version.) Call set_input_format to set the input format. Use fparse_info to read info instead of parsing it here. If we encounter an unknown key, print its offset. * src/server/session.c: Set err_stat whenever kom_errno is set. (accept_async): Return KOM_UNKNOWN_ASYNC if an unknown async message is requested. (login_old): Test wheel bit (test removed from is_supervisor.) (login): Test wheel bit (test removed from is_supervisor.) (disconnect): Test wheel bit (test removed from is_supervisor.) * src/server/server-config.c (parameters): Add max_add_aux and max_delete_aux. (toplevel): Set AUX_DEF_FILE constant. * src/server/send-async.h: Declare new functions in send-async.c * src/server/send-async.c (async_new_text_old): Renamed from async_new_text. (async_new_text): New function to send new new-text async. (async_send_group_message): Return KOM_MESSAGE_NOT_SENT on failure because of no accepting recipient. Return KOM_FEATURE_DISABLED if messages are disabled. Return INTERNAL_ERROR on an internal error. (async_deleted_text): New function to send new deleted-text async. * src/server/regex-match.c (lookup_regexp): Set err_stat when kom_errno is set. * src/server/ramkomd.c: (initialize): Initialize aux-item definitions. (main): Handle -a and -c options, and user-selectable aux-item definition file. * src/server/ram-parse.h: Declare new function in ram-parse.c * src/server/ram-parse.c: Better support for reading different input formats by using solution similar to that in ram-output.c. New variable input_format controls input format. (set_input_format): New function selects input format. (fparse_info_0): New function. (fparse_info_2): New function. (fparse_info): New function. (fparse_conference_2): New function. (fparse_conference_0): New function. (fparse_conference): New function. (fparse_person_0): New function. (fparse_person_2): New function. (fparse_person): New function. (fparse_text_stat_2): New function. (fparse_text_stat_0): New function. (fparse_text_stat): New function. (fparse_aux_item_flags): New function to read aux-item flags. (fparse_aux_item): New function to read an aux-item. (fparse_aux_item_list): New function to read an aux-item-list. (fparse_misc_info): Parse bcc-recpt. * src/server/ram-output.h: Declare new functions in ram-output.c * src/server/ram-output.c: Better support for writing different output formats by using foutput_something_ and a switch in foutput_something. New variable output_format selects output format. (set_output_format): New function to select output format. (foutput_info_0): New function. (foutput_info_2): New function. (foutput_info): New function. (foutput_person_0): New function. (foutput_person_2): New function. (foutput_person): New function. (foutput_conference_2): New function. (foutput_conference): New function. (foutput_text_stat_0): New function. (foutput_text_stat_2): New function. (foutput_text_stat): New function. (foutput_aux_flags): New function to output aux-item flags. (foutput_aux_item): New function to output aux-items. (foutput_aux_item_list): New function to output aux-item-lists. (foutput_misc_info): Output bcc-recpt. * src/server/prot-a.c (prot_a_reply): Added support for new and renamed return types: rt_conference, rt_conference_old, rt_text_stat, rt_text_stat_old, rt_info, rt_info_old. (prot_a_init): Initialize aux_item_list of Connection. (prot_a_destruct): Clear the aux_item_list in Connection. (prot_a_is_legal_fnc): Add support for new and changed RPC calls (see entry for fncdef.txt.) * src/server/prot-a-send-async.h: Declare new functions in prot-a-send-async.c * src/server/prot-a-send-async.c (prot_a_async_new_text_old): Renamed from prot_a_async_new_text. (prot_a_async_new_text): New async message function. (prot_a_async_deleted_text): New async message function. * src/server/prot-a-parse.h: Declare new functions in prot-a-parse.c * src/server/prot-a-parse.c (prot_a_parse_aux_item_flags): New function. (prot_a_parse_aux_item): New function. (prot_a_parse_aux_item_list): New function. (prot_a_parse_misc_info): Parse bcc_recpt info type. * src/server/prot-a-output.h: Declare new functions in prot-a-output.c * src/server/prot-a-output.c (prot_a_output_conference): New output function. (prot_a_output_conference_old): Renamed from old prot_a_output_conference. (prot_a_output_aux_item_flags): New function. (prot_a_output_aux_item): New function. (prot_a_output_text_stat_old): Renamed from prot_a_output_text_stat. (prot_a_output_aux_item_list): New function. (prot_a_output_text_stat): New function. (prot_a_output_info): New function. (prot_a_output_info_old): Renamed from prot_a_output_info. (prot_a_output_misc_info): Output bcc_recpt misc type. * src/server/person.c: Added support for aux-items. Set err_stat whenever kom_errno is set. (create_person_generic): Moved all generic create_person code to this function. (create_person_old): Renamed from create_person, use create_person_generic. (create_person): New RPC function. (set_passwd): Test wheel bit when doing is_supervisor (test removed from is_supervisor.) * src/server/param.h: Added max_delete_aux, max_add_aux to struct kom_par. * src/server/memory.c (free_aux_item_list): New function to free all data in an Aux_item_list. * src/server/membership.c: Set err_stat whenever kom_errno is set. (access_perm): Test wheel bit (test removed from is_supervisor.) (add_member): Test wheel bit (test removed from is_supervisor.) * src/server/manipulate.h: Set err_stat whenever kom_errno is set. Declare is_strictly_supervisor. * src/server/kom-memory.h: Declare free_aux_item_list. * src/server/internal-connections.c (init_connection): Clear aux_item and aux_item_list fields of Connection. Clear aux_item_list field of Info. * src/server/fncdef.txt: Added comments to separate protocol versions. New calls: get_collate_table, create_text, create_anonymous_text, create_conf, create_person, get_text_stat, get_conf_stat, modify_text_info, modify_conf_info, get_info, modify_server_info, query_predefined_aux_items, set_expire. Renamed calls: get_text_stat to get_text_stat_old, get_conf_stat_old to get_conf_stat_older, get_conf_stat to get_conf_stat_old, get_info to get_info_old, create_conf to create_conf_old, create_pers to create_pers_old, create_text to create_text_old, create_anonymous_text to create_anonymous_text_old. * src/server/dbck.c (check_misc_infos): Handle m_bcc_recpt. (is_recipient): Handle bcc_recpt. (main): Use set_output_format to select the output format. * src/server/dbck-cache.c: Set err_stat whenever kom_errno is set. (cache_sync): Use foutput_info instead of outputting the info here. (cache_sync): Call foutput_conference, not foutput_conference_old. ram-output now takes care of selecting the correct version to write. (init_cache): Use fparse_info instead of reading the info here. * src/server/connections.h: (Connection): Add aux_item_list and aux_item. (Res_type): Renamed return types: rt_conference to rt_conference_old. rt_text_stat to rt_text_stat_old, rt_info to rt_info_old. Addet rt_conference, rt_text_stat and rt_info. (Result_holder): Added conference_old, text_stat_old and info_old. * src/server/connections.c: Include kom-memory.h. Set err_stat whenever kom_errno is set. (free_parsed): Free data in aux_item and aux_item_list. * src/server/conference.c: Added support for aux-items. Set err_stat whenever kom_errno is set. (is_strictly_supervisor): New function. (is_supervisor): Use is_strictly_supervisor. Don't test the wheel bit of ACTPERS. (create_conf_generic): Moved generic create_conf code here. (create_conf_old): Renamed from create_conf. Use create_conf_generic. (create_conf): New RPC function. (get_conf_stat): New RPC function. (get_conf_stat_old): Renamed from get_conf_stat (modify_conf_info): New RPC function. (set_expire): New RPC function. * src/server/call-switch.awk: Parse aux_item_list. * src/server/async.h: Added ay_new_text, ay_deleted_text. Renamed old ay_new_text to ay_new_text_old. * src/server/admin.c (modify_server_info): New RPC function. (toplevel): Update initializer for kom_info. (all): Set err_stat whenever kom_errno is set. (get_info): New function. Old get_info is not get_info_old. (get_collate_table): New RPC function. * src/server/Makefile.src: Added the new files to source lists. Rules to build aux-item-parser and scanner added. * src/libraries/libcommon/misc-parser.h: Added m_bcc_recpt to Misc_struct_type. Added bcc_recipient to Misc_info_group struct. * src/include/services.h: Declared all new RPC functions and renamed the now obsolete ones. New functions are: create_person, create_conf, create_text, get_conf_stat, get_text_stat, create_anonymous_text, modify_conf_info, modify_text_info, get_info, modify_server_info, get_collate_table, set_expire, query_predefined_aux_items * src/include/kom-errno.h (KOM_err): Added KOM_ILL_AUX, KOM_AUX_PERM, KOM_UNKNOWN_ASYNC, KOM_INTERNAL_ERROR, KOM_FEATURE_DISABLED, KOM_MESSAGE_NOT_SENT. * src/include/config.h: Added AUX_DEF_FILE. * run-support/Makefile.src: Install aux-items.conf. * doc/man/lyskomd.8: Documented aux-item related settings. * doc/lyskomd-database-format: Documented data file version 2. * doc/Protocol-A.texi: Completed all calls, asynch messages, data structures, error codes. Documented protocol version 10. * db-crypt/db/lyskomd-data: Updated to data file version 2. * configure.in: Check for bison and flex (can't use the regular YACC and LEX tests since we need bison and flex specifically.) * INSTALL: Mention that bison and flex may be needed for installation. Wed Jul 23 22:40:08 1997 Per Cederqvist * src/server/conference.c (get_uconf_stat): Added a comment about a bug that needs to be fixed. Sun Jul 20 16:04:23 1997 Per Cederqvist The regexp code could use the wrong collate table. * src/server/regex-match.c (lookup_regexp): Use DEFAULT_COLLAT_TAB, not swedish_collate_tab. (Reported by David Byers). Fri Jun 6 23:16:28 1997 Per Cederqvist Port to AIX. * src/server/local-to-global.c: Include stdlib.h instead of the non-standard malloc.h. * configure.in: Create src/server/Makefile before src/server/testsuite/Makefile. Sun Dec 29 15:55:44 1996 Per Cederqvist * doc/prot-A.txt: 59=create-anonymous-text, 78=get-uconf-stat, 58=get-last-text and 77=set-last-read are recommended, not experimental. Fixed bug in declaration of Dynamic-Session-Info-List. * src/server/Makefile.in (GENOBJS): Added local-to-global.o. Thu Sep 12 19:14:39 1996 Inge Wallin * local-to-global.h: Added code for an iterator. * local-to-global.c: Added code for an iterator. * kom-types.h: Include some files which are used here. Sun Sep 1 21:32:22 1996 Inge Wallin * (l2g_delete): Delete the block if empty. * local-to-global.c (delete_block): New function * local-to-global.c (l2g_destruct): Don't free blocks. * (l2g_clear): Only free if non-NULL. * (l2g_copy): more efficient code. * local-to-global.h, local-to-global.c (l2g_print): Renamed to l2g_write. * (l2g_read, l2g_write): Now implemented. * log.h: Include stdarg.h if possible. Sun Aug 25 14:47:16 1996 Per Cederqvist * src/server/Makefile.src (GENOBJS): Added local-to-global.o. * src/server/local-to-global.c: New file, written by Inge Wallin. Disconnect spamming clients: * src/server/prot-a-parse.c (prot_a_get_token): Disconnect the client if it attempts to send a token (other than a string) that is longer than 1000 characters. Delete obsolete code: * src/libraries/libcommon/kom-errno.c (kom_perror): Removed KOM_NO_CONNECT. * src/include/kom-errno.h (Kom_err): Removed the unused value KOM_NO_CONNECT. Purify support: * scripts/mkmi.m4 (PURIFY): New make variable. * configure.in: New argument --with-purify enables debugging with Purify. * src/server/Makefile.src (lyskomd): Added $(PURIFY) in front of the link line. (updateLysKOM): Likewise. (dbck): Likewise. * src/server/local-to-global.c: Include , and "s-string.h". (l2g_next_key): Don't dereference memory past the last block! Test suite integration: * configure.in: Generate src/server/testsuite/Makefile. Touch src/server/testsuite/dependencies. * src/server/testsuite/Makefile.src: New file. * mkmi: Added src/server/testsuite/Makefile. * src/server/testsuite/l2g.0/00.exp: New file. * src/server/testsuite/l2g.0/01.exp: New file, containing real data from the map of conference 603 (LysKOM; Elispklientens buggrapporter) in LysLysKOM. * src/server/testsuite/config/unix.exp: New file. * src/server/testsuite/test-l2g.c: New file. * For older changes, see ChangeLog.1, src/include/ChangeLog.1, src/server/ChangeLog.1, src/libraries/libcommon/ChangeLog.1, and src/libraries/libmisc/ChangeLog.1. Starting today, all changes in those directories should be documented in this file. Note that local changes to foreign libraries that are included in this distribution should still be documented in a ChangeLog in their directory, so that somebody who looks at them can see what we have modified. As of this writing, the following ChangeLog files fall into this category: src/libraries/gnumalloc/ChangeLog, src/libraries/libisc-new/src/ChangeLog, src/libraries/regex/ChangeLog and src/libraries/regex/test/ChangeLog. lyskom-server-2.1.2/INSTALL0000644000015100000310000002203007716517054011042 Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is free documentation; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. Basic Installation ================== These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. (Caching is disabled by default to prevent problems with accidental use of stale cache files.) If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You only need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not support the `VPATH' variable, you have to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PATH'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH', the package will use PATH as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=PATH' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the `--target=TYPE' option to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc will cause the specified gcc to be used as the C compiler (unless it is overridden in the site shell script). `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of the options to `configure', and exit. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. lyskom-server-2.1.2/Makefile.am0000664000015100472110000000312407721716112012055 # $Id: Makefile.am,v 1.11 2003/08/23 16:38:23 ceder Exp $ # Copyright (C) 1998-1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # include $(top_srcdir)/scripts/common.make SUBDIRS = scripts doc src run-support db-crypt EXTRA_DIST = .cvsignore ChangeLog.1 README.FSF HACKING mkmi \ versions DISTCLEANFILES = config.cache # Since the LysKOM project keep the documentation in the .h file, it # is often more useful to view the declaration than the definition. AM_ETAGSFLAGS = --declarations # The targets below are for the benefit of the Xenofarm automated # builds. They provide information for the build summary. See # http://www.lysator.liu.se/lyskom/lyskom-server/xenofarm.html ident-cc: @echo Compiler: $(CC) @-type $(CC) @-$(CC) --version lyskom-server-2.1.2/Makefile.in0000664000015100472110000004631207723707416012105 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # $Id: Makefile.am,v 1.11 2003/08/23 16:38:23 ceder Exp $ # Copyright (C) 1998-1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = . am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEBUG_CALLS = @DEBUG_CALLS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EFENCE = @EFENCE@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FLEX = @FLEX@ HAVE_PYTHON_FALSE = @HAVE_PYTHON_FALSE@ HAVE_PYTHON_TRUE = @HAVE_PYTHON_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSURE = @INSURE@ LANGUAGE_SUFFIX = @LANGUAGE_SUFFIX@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ SED = @SED@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRACED_ALLOCATIONS = @TRACED_ALLOCATIONS@ U = @U@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ YACC = @YACC@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ RM = rm -f dbdir = $(localstatedir)/lyskomd/db exportdir = $(localstatedir)/lyskomd/exportdb SUBDIRS = scripts doc src run-support db-crypt EXTRA_DIST = .cvsignore ChangeLog.1 README.FSF HACKING mkmi \ versions DISTCLEANFILES = config.cache # Since the LysKOM project keep the documentation in the .h file, it # is often more useful to view the declaration than the definition. AM_ETAGSFLAGS = --declarations subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = DIST_SOURCES = RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \ ps-recursive install-info-recursive uninstall-info-recursive \ all-recursive install-data-recursive install-exec-recursive \ installdirs-recursive install-recursive uninstall-recursive \ check-recursive installcheck-recursive DIST_COMMON = README $(top_srcdir)/scripts/common.make AUTHORS COPYING \ ChangeLog INSTALL Makefile.am Makefile.in NEWS TODO \ acinclude.m4 aclocal.m4 config.h.in configure configure.in DIST_SUBDIRS = $(SUBDIRS) all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/scripts/common.make $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe) $(top_builddir)/config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) cd $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): configure.in acinclude.m4 cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) config.h: stamp-h1 @if test ! -f $@; then \ rm -f stamp-h1; \ $(MAKE) stamp-h1; \ else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOHEADER) touch $(srcdir)/config.h.in distclean-hdr: -rm -f config.h stamp-h1 uninstall-info-am: # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ETAGS = etags ETAGSFLAGS = CTAGS = ctags CTAGSFLAGS = tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if (etags --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ else \ include_option=--include; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -f $$subdir/TAGS && \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$tags$$unique" \ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = . distdir = $(PACKAGE)-$(VERSION) am__remove_distdir = \ { test ! -d $(distdir) \ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr $(distdir); }; } GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print distdir: $(DISTFILES) $(am__remove_distdir) mkdir $(distdir) $(mkinstalldirs) $(distdir)/./scripts @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d $(distdir)/$$subdir \ || mkdir $(distdir)/$$subdir \ || exit 1; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" \ distdir=../$(distdir)/$$subdir \ distdir) \ || exit 1; \ fi; \ done -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r $(distdir) dist-gzip: distdir $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist dist-all: distdir $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist $(am__remove_distdir) GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf - chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && cd $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && $(mkinstalldirs) "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist-gzip \ && rm -f $(distdir).tar.gz \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck $(am__remove_distdir) @echo "$(distdir).tar.gz is ready for distribution" | \ sed 'h;s/./=/g;p;x;p;x' distuninstallcheck: @cd $(distuninstallcheck_dir) \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile config.h installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) distclean-am: clean-am distclean-generic distclean-hdr distclean-tags dvi: dvi-recursive dvi-am: info: info-recursive info-am: install-data-am: install-exec-am: install-info: install-info-recursive install-man: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-info-am uninstall-info: uninstall-info-recursive .PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \ clean-generic clean-recursive ctags ctags-recursive dist \ dist-all dist-gzip distcheck distclean distclean-generic \ distclean-hdr distclean-recursive distclean-tags distcleancheck \ distdir distuninstallcheck dvi dvi-am dvi-recursive info \ info-am info-recursive install install-am install-data \ install-data-am install-data-recursive install-exec \ install-exec-am install-exec-recursive install-info \ install-info-am install-info-recursive install-man \ install-recursive install-strip installcheck installcheck-am \ installdirs installdirs-am installdirs-recursive \ maintainer-clean maintainer-clean-generic \ maintainer-clean-recursive mostlyclean mostlyclean-generic \ mostlyclean-recursive pdf pdf-am pdf-recursive ps ps-am \ ps-recursive tags tags-recursive uninstall uninstall-am \ uninstall-info-am uninstall-info-recursive uninstall-recursive # The targets below are for the benefit of the Xenofarm automated # builds. They provide information for the build summary. See # http://www.lysator.liu.se/lyskom/lyskom-server/xenofarm.html ident-cc: @echo Compiler: $(CC) @-type $(CC) @-$(CC) --version # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/NEWS0000664000015100472110000011156107723633366010540 Changes in lyskomd 2.1.2 (Release date 2003-08-30) -------------------------------------------------- * The server crashed if a person has read more than 65535 texts after the first unread text. * The internal data structure for handling read texts could be damaged, resulting in overlapping ranges in the read-ranges part of a Membership. This version fixes the bug, and automatically fixes the damage in the database. You don't need to run dbck. * The mx-refuse-import aux-item has a new supported value: "html". * A few machine-readable versions of the protocol specification has been extracted. See Protocol-A.texi for details. * The garb process is now documented in Protocol-A.texi. * The garb was running too slowly in version 2.1.0 and 2.1.1. Changes in lyskomd 2.1.1 (Release date 2003-08-26) -------------------------------------------------- * The server could crash when a client disconnects. The problem was introduced in version 2.1.0. All 2.1.0 installations should upgrade to 2.1.1 as soon as possible. * A few auxiliary files was missing from the distribution, most notably src/libraries/adns/changelog. * The file "aux.h" has been renamed to "aux-no.h". Note: this does not mean that Cygwin is a recommended environment. * The exportdb directory, used by splitkomdb, is now created during "make install". * The installation instructions forgot a step, so when upgrading the server would never start if the instructions were followed literally. Changes in lyskomd 2.1.0 (Release date 2003-08-24) -------------------------------------------------- * Protocol changes: (changes that could affect clients) ** add-comment and add-footnote can both return the error codes already-comment and already-footnote. This ensures that a text cannot be both footnote and comment to the same text at the same time. ** The text garb has been modified, so that a fresh comment or footnote to a text prevents the text from being removed. The amount of extra time the text lives depends on the keep-commented field if the conference status, and defaults to 77 days. The set-keep-commented request that was previously labeled "Experimental" is now labeled "Recommended", as it actually does something useful now. ** You can tell the server that you don't want to receive group messages for a group, via the new passive-message-invert bit of the Membership-Type. ** The following requests can no longer be used until you have logged in: 58=get-last-text 60=find-next-text-no 61=find-previous-text-no ** You can now modify the type of a recipient (with the add-recipient request) if you are the supervisor of either the author, recipient or sender. The check used to be more restrictive. ** The following asynchronous messages are now sent to recipients of texts linked to the relevant text: async-deleted-text, async-new-text, async-new-text-old, async-add-recipient and async-sub-recipient. ** New aux-item: 35=mx-refuse-import. ** The supplied aux-items.conf file now validates many aux-items more strictly. ** If the client sends a number apart from 0 or 1 where a BOOL argument is expected, the server now responds with the new error code bad-bool. * Protocol extensions: (should not affect old clients) ** The information about which texts you have read is now transmitted in a much more efficient form: as a list of ranges. Previously, it was transmitted as a number that you have ready everything before, and a list of additional text that you have read. It is now possible to mark a text as not read, and to efficiently tell the server exactly which texts should be marked as read. Affected requests: 107=query-read-texts 108=get-membership 109=mark-as-unread 110=set-read-ranges The old requests 98=query-read-texts-10 and 99=get-membership-10 will continue to work, but clients are encouraged to switch to the new requests instead. ** The server now keeps real-time statistics about a lot of things, such as the number of pending DNS requests, the number of connected clients, the number of processed requests, the size of various buffers, et c. You can also get the ascent and descent rates for all measured variables. 111=get-stats-description 112=get-stats ** The server can tell when it last started, how many texts existed then, and some other information that was current when it started. 113=get-boottime-info ** Three new requests makes it possible to loop through all existing conferences without having to guess what the largest conference number is, and without having to try each number in turn. 114=first-unused-conf-no 116=find-next-conf-no 117=find-previous-conf-no ** The highest text number can now be retrieved. 115=first-unused-text-no ** The times can now be expressed in UTC instead of in the local time zone of the server. This makes it possible to write a client that displays time in the local time zone of the client, and makes it easier to correctly format dates as "today" or "yesterday" even when the client and server are in different time zones. 120=set-connection-time-format ** In case you want to traverse texts in a conference (or written by an author) in the direction from newer to older texts, you can now do so efficiently with these new requests: 121=local-to-global-reverse 122=map-created-texts-reverse (The field later-texts-exists in Text-Mapping has been renamed to more-texts-exists, so that it makes sens when these new requests are used.) ** The server is now much more fair in giving each client approximately the same amount of resources while under heavy load. Clients can use these new requests to tell the server that they want more or less than their fair share, by adjusting their weight. (Compare with the "nice" command of Unix.) 118=get-scheduling 119=set-scheduling These commands can also set the priority. As long as a client of priority N has a request for the server, clients with a priority larger than N will be blocked. However, the current implementation only supports a single priority. The scheduling requests are considered experimental. ** A few new asynchronous messages have been added: 19=async-new-user-area 20=async-new-presentation 21=async-new-motd 22=async-text-aux-changed * Client-visible bugs fixed: ** The session_start field of a Connection was used both to record the connect time and the login/logout time. As a result, the connection-time of a Static-Session-Info was not actually static. Fixed by keeping track of the connect time and the login/logout time separately. ** It is now impossible to add the same text as FAQ for the same conference more than once. ** The code that determined who is allowed to remove or add an aux-item from a conference or person was wrong. ** Idle clients are now disconnected after a (long) timeout. The timeout is different during the differen phases of a connection. The following parameters (with the default value) affects this: Parameter Default Meaning ========= ======= ======= Stale timeout 60 minutes Output buffer full and client not reading Connect timeout 30 seconds Idle timeout before sending initial handshake. Login timeout 30 minutes Idle timeout while not logged in. Active timeout 11.5 days Idle timeout while logged in. The idle timer is reset whenever anything is written to the client. ** If a client sends a 27=mark-as-read request with a too long array, it will now receive the error code long-array instead of a notification of a protocol error. ** If the output buffer to a client becomes too large the server will stop reading from that client until some of the output is drained. The following new parameters affects when the output buffer is considered to be too large: Max client transmit queue messages Max client transmit queue bytes ** In some cases, memcpy() was used to move memory within a buffer, from a higher to a lower address. The source and destination could overlap. This might have caused the server to send garbage to clients in rare occasions, since it is implementation-defined what happens if memcpy() is used with overlapping source and destination. * Other client-visible changes: ** The server is now more careful never to reuse text, person and conference numbers, even after a crash. ** 27=mark-as-read no longer leaks information about secret conferences. ** IPv6 support has been contributed by Thorild Selén. (Changes made in the last few months may however have broken the code, so it should be considered experimental.) * Protocol specification bugs fixed: ** The descripton of the error code index-out-of-range was wrong for some requests. See the "Document Edition History" for details. ** async-leave-conf is not sent when a person is deleted. * Installation changes: ** A serious bug in the SIGWINCH handling has been found but not fixed. Please see lyskomd.texi before you send a SIGWINCH signal to the server! ** The file system layout has changed. The following files and directories have been moved. As a result, it should now be safe to install lyskomd with prefix set to /usr/local or even /usr. The default prefix is still /usr/lyskom, however. See README for upgrade instructions. You should be able to change the file names via standard "./configure" arguments, such as --localstatedir. See INSTALL. Parameter Old default value New default value ========= ================= ================= lyskomd path: bin/lyskomd sbin/lyskomd savecore path: bin/savecore sbin/savecore-lyskom Data file: db/lyskomd-data var/lyskomd/db/lyskomd-data Backup file: db/lyskomd-backup var/lyskomd/db/lyskomd-backup Backup file 2: db/lyskomd-backup-prev var/lyskomd/db/lyskomd-backup-prev Lock file: db/lyskomd-lock var/lyskomd/db/lyskomd-lock Text file: db/lyskomd-texts var/lyskomd/db/lyskomd-texts Number file: db/number.txt var/lyskomd/db/number.txt Number temp file: db/number.tmp var/lyskomd/db/number.tmp Text backup file: db/lyskomd-texts-backup var/lyskomd/db/lyskomd-texts-backup Status file: etc/status var/lyskomd/db/status Log file: etc/server-log var/lyskomd.log Log statistics: etc/lyskomd-log var/lyskomd.stats Memory usage file: etc/memory-usage var/lyskomd.memory Core directory: cores var/lyskomd.cores Pid file: etc/pid var/run/lyskomd.pid Connection status file: etc/connections.txt var/lyskomd.clients Connection status temp file: etc/connections.tmp var/lyskomd.clnt.tmp Backup export directory: exportdb var/lyskomd/exportdb All other binaries have also been moved from "bin" to "sbin". ** lyskomd is now officially shut down via SIGTERM. (SIGHUP still works, and SIGINT now also shuts it down cleanly). In a future release, SIGHUP will probably change meaning to "re-read the configuration files". ** This release was made using autoconf-2.57 and automake-1.7.6 (with a small patch). ** The following new parameters affect how client scheduling works: Penalty per call Penalty per read Max penalty Low penalty Default priority Max priority Default weight Max weight See lyskomd.texi for documentation on the parameters. ** The following parameters have been removed: Idle timeout Max client transmit queue ** Most parameters that specify a time period can now accept a suffix that specifies the unit. If the unit is not given, it defaults to the old unit, which are different for different parameters. Affected parameters: Garb busy postponement Garb timeout Sync timeout Garb interval Sync interval Sync retry interval Stale timeout Connect timeout Login timeout Active timeout ** When updateLysKOM sends an email, it now uses the "sendmail" program. The path is found at configure time, and can be overridden with the parameter "sendmail path". The special value ":" turns off mail delivery. ** The following parameters not mentioned elsewhere have been added: Garb busy postponement Max read_ranges per call Number file Number temp file Statistic name length Max client message size * Bug fixes ** The "Max texts" and "Max conferences" parameters were off by one. ** The server now works on IRIX64 and FreeBSD 4.7. ** The server now stores almost all times and time spans as "struct timeval" or "time_t". This eliminates a number of potential overflows. * Other noteworthy improvements: ** The format of the var/lyskomd.clients file is now documented. ** The server now uses liboop for the event loop. As a result, libisc has been heavily mutilated. Its main function is now to provide output buffering and to handle the details of TCP connection establishment (over both IPv4 and IPv6). The server comes with its own version of liboop. Some modifications had to be made. (They have been sent to the maintainer.) ** The server now uses adns to resolve IP addresses in an asynchronous way. (Since adns doesn't support IPv6 addresses, this only works for IPv4 addresses. The old blocking method is used for IPv6 addresses.) A client that connects can do the initial handshake, up to the point of receiving the string "LysKOM", but after that point the client will be blocked until the DNS resoultion completes. The client will be totally invisible to other clients until the DNS resolution completes (so that the result of get-static-session-info really is static). ** Some general code cleanup and a few small bug fixes has been made. Changes in lyskomd 2.0.7 (Release date 2002-11-03) -------------------------------------------------- * Protocol changes: (changes that affect clients) ** The aux-item send-comments-to has been extended. The value may now contain an optional recipient type. ** The rules for when a membership is visible is now documented in the protocol specification. Previously, different requests used different rules. They are now fixed: *** query-read-texts, query-read-texts-old and sub-member could return the wrong error code in several instances. *** get-membership and get-membership-old didn't always honor the unread-is-secret flag of a person. *** get-members and get-members-old could leak information about secret persons. *** get-unread-confs was very confused about what memberships it returned. * Other client-visible changes: ** If the server fails to save the database, a broadcast message is sent to everyone that is logged in. (As always, an entry is also made in the log file.) * Protocol specification bugs fixed: ** The documentation for the common block of the user area was just plain wrong. ** The documentation for no-of-created-texts in the Person structure was wrong. ** The documentation for the privilege bits create-conf and create-pers was wrong. ** The Protocol A examples for re-z-lookup and lookup-z-name were wrong. * Bug fixes that may affect clients: ** According to the documentation, get-membership and get-membership-old should always have returned the array size even when the want-read argument is false. However, they always reported the array size as 0 in that case. * Protocol specification improvements: ** The documentation for get-person-stat-old was improved. ** Documented the unread-is-secret flag of a person. ** The fact that the last line in a text should not be terminated by a linefeed character is now documented. ** A recommendation on the ordering of misc-info groups has been added. ** A new informative appendix that documents some client-specific aux-items has been added. elisp-client-read-faq and elisp-client-rejected-recommendation are now documented in that appendix. ** Added a recommendation that clients should offer to add the author as a recipient, when the author isn't a member of any of the recipients. ** A few typos were fixed. * Protocol extensions: ** Added a new "language" value to the common block. ** The Message-ID of exported texts is now documented. ** New aux-item: world-readable. ** New client-specific aux-items: elisp-client-read-faq and elisp-client-rejected-recommendation. * Bug fixes: (not visible by clients) ** If a client disconnects after sending the length of an ARRAY Aux-Item-Input, but before sending the "{", the server would crash. ** We now use Xenofarm to compile and test lyskomd automatically on a compile farm of several different machines. Several problems have been fixed, so this release should be more portable than previous versions. Read more about Xenofarm at http://www.lysator.liu.se/lyskom/lyskom-server/xenofarm.html ** The code has been cleaned up so that many compiler warnings are gone. (The regex.c file still generates a lot of warnings.) ** Several minor bugs were fixed, and the code was cleaned up in several ways. See the ChangeLog for all the details. ** The test suite has been extended, primarily with tests for membership visibility. ** The test suite should now work on more hosts. It makes a few less assumptions. It is still not as portable as the rest of the distribution, however. ** Several race conditions in the test suite have been eliminated. ** valgrind has been used to ensure that there are no memory leaks or memory access errors. A few minor problems were found and fixed. (A couple of minor leaks still remains.) The configure options --with-valgrind and --disable-malloc-guards are useful when you want to run the test suite using valgrind. (Don't use --disable-malloc-guards on a production use server. Due to bug 691 it might cause crashes.) ** The "Open files:" setting now works even on hosts that don't have setrlimit, or where setrlimit cannot reduce the number of open files. ** lyskomd now refuses to use more than FD_SETSIZE file descriptors. * Improvements: (not visible by clients) ** The new file etc/connections.txt contains a listing of all sessions, what file descriptor they use, and from where they are connected. If a runaway client hogs the server, the administrator can use tools such as strace or truss to find the file descriptor, and the file descriptor can then be looked up in this file. The name of the file can be changed via the "Connection status file:" configuration parameter. ** DNS lookups blocks the server. If a lookup takes more than 1.5 seconds (configurable via "DNS log threshold:") an entry is made in the log. DNS lookups can also be disabled via "Use DNS:". ** The "-d" option no longer causes lyskomd to run in the foreground; use the new "-f" option for that purpose. By specifying only "-f" and not "-d", it is now possible to run lyskomd in the foreground without increasing the log level. The test suite now uses this to check what lyskomd writes to the log file. ** NFS-mounted databases might fail under some circumstances. A warning about that fact has been added to the README file. This might be fixed in a future release. Changes in lyskomd 2.0.6 (Release date 2002-03-29) -------------------------------------------------- * New aux-item: send-comments-to. * Modified aux-item: faq-text may now be set on a letterbox. * The Protocol A documentation has been enhanced. See the document revision in doc/Protocol-A.texi. It can now be formatted as PDF and DVI. Info is still the best-tested output format. * The splitkomdb utility is now documented. It is useful for taking live backups of the lyskomd data base. * We now use http://bugzilla.lysator.liu.se/ to track bugs and feature requests in lyskomd. All old FIXME comments, TODO files, et c have been entered into that system. A few test cases are expected to fail; they now refer to the corresponding entry in the Bugzilla system. * Many minor bugs and potential portability problem have been fixed, and the code has been cleaned up in several places. See the ChangeLog for details. lyskomd should now compile under Cygwin. Changes in lyskomd 2.0.5 (Release date 2001-09-30) -------------------------------------------------- * New aux-items: mx-mime-belongs-to, mx-mime-part-in, mx-mime-misc, mx-envelope-sender, mx-mime-file-name, canonical-name, mx-list-name. * The supervisor of the object that certain aux-items are attached to can now remove the aux-item. Affected aux-items are redirect, x-face, pgp-public-key, e-mail-address, faq-text and allowed-content-type. This is configured via the new owner-delete attribute of aux-items.conf. * A bug that caused async-new-recipient to not be sent in some cases when passive memberships were involved has been fixed. * The test suite has been updated to use DejaGnu 1.4.2. It has also been slightly expanded. Changes in lyskomd 2.0.4 (Release date 2000-09-09) -------------------------------------------------- * New aux-items: allowed-content-type and recommended-conf. * The distributed aux-items.conf will silently overwrite any previously installed aux-items.conf file when "make install" is run. Take care if you have edited your local copy. * Information about bcc-recpts was sometimes sent when too often, and sometimes too seldom. This has been fixed. * The conference number of secret conferences could leak when information about the current working conference of a user was sent to another user. This has been fixed. * The garb-nice value is internally converted from days to seconds. That conversion previously used integer arithmetic, so it could overflow. This has been fixed. * If the config file contained "Never save: true" the data base was nevertheless saved if lyskomd terminated normally. * A bug that could cause a crash when a client sent over-long aux-item lists to the server has been fixed. * Sending a SIGWINCH signal to the server will cause it to re-read the aux-item definition file. Changes in lyskomd 2.0.3 (Release date 1999-07-25) -------------------------------------------------- * The 2.0.2 release didn't really fix the bug. This release includes a test case that was triggered by the bug, and at least now that test case succeeds. As usual, there are no guarantees, but the bug should be fixed now. Changes in lyskomd 2.0.2 (Release date 1999-07-23) -------------------------------------------------- * Fixed a bug that caused lyskomd to follow a NULL pointer when an empty name was looked up. Changes in lyskomd 2.0.1 (Release date 1999-07-12) -------------------------------------------------- * Protocol changes (changes that affect clients) ** Regexp matching is never ever case insensitive. The behavior of regexp matching in release 2.0.0 was severely broken. We will not change this again. ** The author of a text is allowed to change the recipient type (to recpt, cc-recpt or bcc-recpt) with the add-recipient call. Previously, only the supervisor of the recipient could do this. * Administration and installation changes ** No asynchronous messages are sent to the clients during shutdown of the server. This speeds up the shutdown slightly. * Bug fixes ** A buffer overrun and several minor bugs were fixed. ** The created_texts field of persons were not always properly updated when texts were deleted. You may have to run dbck to fix your database. ** Changes made to the Conference were sometimes forgotten and not saved to disk. dbck can not yet fix all the errors that may have been introduced. * Performance fixes ** The calls that used regexps were very slow. The cause was not the actual regular expression matching, but that the permission checking was done in a broken way. This has been fixed, and should improve performance on many of the calls, but especially for the regexp lookup functions. ** The calls that create, change or delete names of persons and conferences are now much faster. ** Copying data from lyskomd-backup to lyskomd-data no longer uses dynamically allocated memory. Changes in lyskomd 2.0.0 (Release date 1999-06-27) -------------------------------------------------- * Protocol changes (changes that affect clients) ** It is now possible to see when a membership was added and by whom. Memberships come in several different flavors through the addition of a membership type. Currently defined types are secret, passive and invitation. Since protocol version 9 setting a priority of zero in a conference was supposed to indicate passive membership in a conference. It was largely up to the client to implement this. True passive memberships have been introduced in this protocol version through the Membership-type extension to the Membership type. In order to maintain compatibility with clients that interpret priority 0 as passive membership, the old calls perform magic, translating between priorities and membership types. Clients that use the new calls can now once again use priority 0. These new calls include the Membership-type: 98=query-read-texts 99=get-membership 100=add-member 101=get-members 102=set-membership-type ** Error reporting from the server has been improved. The possible error codes from each call have been checked and documented. In the process some calls now return errors they previously did not. Since the error returns were never defined, this should not present a problem for existing clients. The error-status field is set to something semi-useful in all cases. ** Several situations where the server leaked secret information have been fixed. ** The conference type has been extended so that it is possible to forbid secret members in the conference. All old calls that wanted a conference type now accepts both the old-style type and the new-style. This call returns the new conference type: 91=get-conf-stat ** Regexp matching is now case insensitive by default. Case sensitivity is configurable via a config file for the server. This is an incompatible change. ** It is now possible to attach arbitrary data to conferences and texts. This allows simple extensions to server data structures without requiring protocol changes. These data object are called aux-items, and are configured with the aux-items.conf file. There are several predefined aux-items with special meanings; see doc/Protocol-A.texi. These new calls handle aux-items: 86=create-text 87=create-anonymous-text 88=create-conf 89=create-person 90=get-text-stat 92=modify-text-info 93=modify-conf-info 94=get-info 95=modify-system-info 96=query-predefined-aux-items ** A new recipient type, BCC recipient, has been added. BCC recipients are only shown to potential members of the recipient and to the sender. The server accept bcc-recpt on input everywhere where it previously accepted recpt or cc-recpt. This call can return bcc-recpt: 90=get-text-stat ** The server can send asynchronous messages about texts being deleted; recipients being added and removed; and memberships being added. This should help clients with caches to keep them updated. ** There is a call to get the collate table being used by the server. 85=get-collate-table ** A call to set the flags field in a person structure has been added. The new version of create-person also takes flags as a parameter. 89=create-person 106=set-pers-flags ** There is a new parameter (keep_commented) on conferences for tuning the garbage collection process. This tuning is not implemented in the server, but users and clients are encouraged to start using the tuning parameter anyway since the tuning will be implemented in a future release. 91=get-conf-stat 105=set-keep-commented ** There is a parameter (expire) for configuring automatic removal of inactive conferences. This removal is currently not implemented, but users and clients are encouraged to start using it anyway and the automatic conference deletion procedure will be implemented in the near future. 91=get-conf-stat 97=set-expire ** Mapping of local text numbers to global text numbers is now much more efficient, which should lead to significant performance improvements if clients make use of these facilities. 103=local-to-global 104=map-created-texts * Administration and installation changes ** The database format has changed again. Old installations must convert their old database--see README for instructions. ** The komrunning and updateLysKOM utilities are now a C programs that read the configuration file, instead of shell scripts. komrunning now takes "start" or "stop" as argument instead of "up" and "down". ** The undocumented format of the etc/lyskomd.log file, which stores usage statistics, has been changed. ** The server can now reliably handle a lot more than 250 simultaneous clients even platforms where a FILE* only can refer to file descriptor 0-255. ** You can specify which IP number the server should listen to. The default is still to bind all IP numbers of the host that runs lyskomd. ** Support for the MUX protocol has been removed. ** The database is now locked with a lock symlink, so there is less risk of accidentally running a lyskomd and dbck or two lyskomd at the same time. * Bug fixes ** Sanity checks in database and protocol code increase stability and resilience to client errors and sabotage. ** Portability fixes. This release compiles cleanly on systems such as modern Linux systems that define errno as a macro. * Misc ** Documentation has been moved to two Texinfo files, one that specifies LysKOM Protocol A and one that documents lyskomd. The man pages are no longer maintained. ** The protocol documentation is more detailed, converted to Texinfo and written in English. ** The distribution contains a test suite that is used for regression testing the server in development. The test suite should run with no unexpected failures. ** We now use GNU automake. ** GNU malloc is no longer included in the distribution. ** Updated to use libisc 1.00 (with a few minor modifications; see src/libraries/libisc-new/ChangeLog). Changes in lyskomd 1.9.0 (Release date 1996-08-04) -------------------------------------------------- * The database format has changed. Old installations must convert their old database -- see INSTALL for instructions. The database now stores information about which text that is the message-of-the-day, so that information no longer has to be set in the config file. * dbck now uses GNU getopt, and can take long options. See the man page or "dbck --help". * dbck can now be used to reset the password of a single user to the empty string (using the new --clear-password option) or give a user all available privileges. This is handy if you forget the password of the LysKOM user with all privileges, or if you happen to delete that person by mistake. * Portability fixes. This release of lyskomd has been compiled with 4 different compilers on 8 different CPU:s using 9 different OS:s. 3 different make programs have been used. * The server supports idle-time handling using 3 new calls. Clients are expected to use this new functionality shortly. * Anonymous texts are still allowed per default, but it is now possible to set a bit in the conference type of a conference so that anonymous texts are rejected. * New simplified rules for when adding and subtracting comment and footnote links is allowed. * Clients can now tell the server which asynchronous calls they are interrested in receiving. This change can potentially decrease the network bandwidth used by lyskomd in the future. * Forward compatibility: the server now returns a normal error code when the client attempts to use an unsupported call. The client can now reliably try new calls and see if the server supports them. * Several bug fixes. The most important is probably that lyskomd should now stop cleanly when a HUP is received, even if a second HUP signal is received while it is going down. This didn't work on all platforms. Changes in lyskomd 1.8.0 (Release date 1995-11-08) -------------------------------------------------- * If configured with --with-gnu-malloc lyskomd will use the GNU malloc package instead of the system-supplied malloc. GNU malloc is included in the distribution. * The asynchronous message async_rejected_connection is now sent at most once per minute. * Lyskomd 1.8.0 implements protocol A level 8. See doc/prot-A.txt for information about the new features it contains. The database currently still only stores four bits of the conf_type, however, so it is useless to use the new anarchy bit until the next release. * You can now specify where lyskomd should dump core (if that should ever happen) using the "Core directory" parameter. * Can now handle 1500000 texts and 4765 persons/conferences. * Text garbing can now be turned off completely from the config file. * dbck -t now dumps a list of all existing text numbers to stdout. * Some minor portability fixes. Some bug fixes. See the various ChangeLogs for details. Changes in lyskomd 1.7.1 (Release date 1995-01-08) -------------------------------------------------- * doc/prot-A.txt is improved. * Minor portability changes to make lyskomd compile under Solaris 2.4, Ultrix 4.4 and Dynix 3.0.14. * Fixed bugs that caused "./configure;make;make distclean" to fail to remove all created files. * The default installation prefix is now, once again, /usr/lyskom. By accident it was changed to /usr/local in 1.7.0. Changes in lyskomd 1.7.0 (Release date 1994-12-31) -------------------------------------------------- * New calls "re_z_lookup" and "lookup_z_name" allows client to list conference names *fast*. * New call "get_version_info" returns information about the protocol level implemented by the server, the server name, and the server version number. * The call "send_message" now accepts a conference as recipient, and will direct the message to all members of that conference that are currently logged on. * The file doc/prot-A.txt is updated. The current protocol version is (somewhat arbitrarily) defined as 7. * If the file system holding the LysKOM database was full while somebody tried to create a text strange things could happen. Error checking has been added, and the client will now receive a KOM_TEMPFAIL if there is not enough space left on the device. * The 1.6.6 distribution contained some junk files, and others (such as the global ChangeLog) were missing. This has now been fixed. * Autoconf 2.1 has generated the current configure script. * The obsolete asynchronous message i_am_off is no longer sent. Changes in lyskomd 1.6.6 (Release date 1994-11-15) -------------------------------------------------- * Can now handle 1000000 texts and 4765 persons/conferences. * mark_as_read can (hopefully) no longer cause the server to crash. Changes in lyskomd 1.6.5 (Never released, used since 1994-10-24) ----------------------------------------- * New configuration parameter "Open files" can be used on hosts that support setrlimit to increase the limit on simultaneous connections. * New configuration parameter "Force ISO 8859-1" assists in environments where setlocale() is broken or lacks support for ISO 8859-1. * Slightly improved configure.in script. * Many harmless warnings and some errors from apcc removed. * NEWS entry for 1.6.4 was added. Changes in lyskomd 1.6.4 (Release date 1994-06-30) -------------------------------------------------- The call get-last-text now works. It has been broken since 12 oct 1993. It is now impossible to add a text to a conference unless the sender is able to enter texts into it. Changes in lyskomd 1.6.3 (Release date 1994-06-20) -------------------------------------------------- One bug was fixed: it is now possible to compile src/server/simple-cache.c. Changes in lyskomd 1.6.2 (Release date 1994-06-19) -------------------------------------------------- This is a bug-fix release. * The parameter ``Default change name capability'' was ignored, so any person created with release 1.6.1 of the server cannot change his name. Use "dbck -r -c" to set the bit for everyone. * The -c option to dbck is new. * The parameter ``Ident-authentication'' now works, so it is now possible to turn off ident authentication. * find_previous_text_no is now much more efficient if the client tries to search for a very large number. Version L0.12 of the tty-client will probably use find_previous_text_no(MAX_TEXT_NO), so this fix is important. For older news, see the various ChangeLog files. lyskom-server-2.1.2/TODO0000664000015100472110000012076107366572656010542 THIS FILE IS NO LONGER USED THIS FILE IS NO LONGER USED THIS FILE IS NO LONGER USED We now use the Bugzilla installation at Lysator to handle the bugs and feature requests of lyskomd. See the following: http://bugzilla.lysator.liu.se/ The numbers in brackets in this file refers to bug id:s in the bugzilla database. The bugs were copied to Bugzilla during October 2001. THIS FILE IS NO LONGER USED THIS FILE IS NO LONGER USED THIS FILE IS NO LONGER USED This file attempts to list the things that need to be done on this server. * Showstoppers None! * Unsorted. [5] ** New aux-item: text is world-readable without login. See 6839340 with comments. [6] ** New request: get-boottime-info. See 6539796 with comments. [7] ** No async message is sent when a user-area is changed. ** Move this list to a better forum. [8] ** "make dvi" doesn't work. Fix texinfo.tex, or consider using makeinfo as a preprocessor to perform the macro expansion and than running texi2dvi as normal. Don't stop using macros in the source file Protocol-A.texi, since they really do help in maintaining up-to-date documentation. * High priority, but they can wait until after the next release. [9] ** Protocol-A.texi doesn't define what "letterbox" (and similar strings) in the definition of built-in aux-times means. [10] ** Fix dbck so that it can repair the database damage created by lyskomd 2.0.0. Some work done on the "dbckmultiplechoice" branch of dbck.c. [12] ** src/server/testsuite/lyskomd.0/gen-15.py should be enhanced. It only tests a tiny fraction of what should be tested. [11] ** There is no timeout for unused sessions, and we don't use TCP keepalive packets. [13] ** The names of various conferences are suspect. (4219085) [14] ** Implement the aux-item "recommended-conf". [21] ** Write a make-backup-copy shellscript. ** Test the distribution under Red Hat 6.0. ** Features [22] *** Reload configuration. Aux-items are now reloaded on a WINCH signal. Reload other params too. [23] *** Cross references should create a mirror item. [24] *** --with-language should select the collate table. [25] *** Generic mirror-this-aux-item trigger ** Testing [26, 27, 28, 29] *** No test case for attempting to garbage collect a text that has an aux item with a dont-garb flag. No test for cc-recpt preventing garbage collection that would be allowed by recpt. Ditto for bcc-recpt. No test for cc-recpt that permits garbage collection when recpt also does. No test for sent-at preventing garbage collection. ** We still leak secrets [30] *** login, login_old If the person is secret we should return KOM_UNDEF_PERS unless the password is correct or the session has privileges to see the person. Right now we can map out secret persons by attempting to log in with the wrong password. [31] *** change_conference If the conference exists but is secret we return not-member. We should return KOM_UNDEF_CONF. [32] *** create_person_old *** create_person *** change_name *** create_conf *** create_conf_old If we try to use a name to the name of a secret conference we return KOM_CONF_EXISTS. We can't really do a lot to prevent this. [33] *** get_session_info *** get_session_info_ident Returns the number of secret persons and secret conferences even if the viewer has no right to see them. [35] *** set_priv_bits *** set_passwd Does not check if the caller is allowed to see the person. [37] *** get_unread_confs Does not check that the caller is allowed to see the person, and returns the correct result even for secret persons, including secret confs! [38, 39] *** set_user_area *** set_presentation (do_set_presentation) *** set_etc_motd (do_set_etc_motd) Allows us to set user area to any text, even secret ones. Leaks information by returning error for deleted texts and non-error for all other texts. [40] *** lookup_name and similar functions Not really checked. [41] *** get-members Leaks number of secret members since they are not completely deleted from the member list, just zeroed out. [42] *** add_member *** add_member_old Returns KOM_INVALID_MEMBERSHIP if we attempt to add secret person to open conf as secret member when conf does not allow secret members. This allows us to find all secret persons. This check is done before we check if the user making the call is allowed to see the conference, so it lets us find out which secret conferences allow secret members. It is possible to add secret persons as memberships. If the person is already a secret member the call appears to succeed but the membership is still secret, so it is possible to find all persons who are secret members of a conference. [43] *** sub_member No access check on conference or person before attempting to locate membership. As a result we can find out if a conference exists by attempting to sub_member with a nonexistant person. If we get a KOM_UNDEF_PERS, the conference exists. Fix by doing access checks right after getting the conf_c and pers_p from the database. The final if statement is also suspect. [44] *** set_unread *** set_last_read No access check on conference before attempting to locate membership. This means we can locate all secret conferences. [45] *** set_permitted_submitters *** set_supervisor *** set_super_conf Existance check for new supervisor/permitted submitters/super before access check on conference being changed. We can use this to map out all secret conferences. [46] *** set_conf_type No access check on conference before examining conference type. Use this to map out all secret conferences. [47] (Invalid: see http://bugzilla.lysator.liu.se/show_bug.cgi?id=47) *** unmark_text No access check on the text. This is done in do_unmark_text, but is is not immediately obvious why it works (although it does.) Should add an explicit search for the mark before doing anything else. Maybe. [48] *** mark_as_read No access check on conf before attempting to locate membership. We can use this to map out all secret conferences. [49] *** sub_footnote *** sub_comment No read access check on texts before checking if they are comments. This allows us to map out all secret texts and all comment chains (just try sub_comment for all pairs of texts that might be in the system or all secret texts found by some other method.) [50] *** get-last-text May return a secret text since no access checks are made on the result. [51] *** who_is_on_dynamic *** who_is_on_ident *** who_is_on *** who_is_on_old Returns secret persons and secret working conferences. No filtering is done on the result. [52, 54] ** Change read-texts. (4111477) [55] ** modify_conf_info can operate on an rd_protected conf. Perhaps we should have a flag that says an item can be added only by members of the conference? [56] ** get_conf_stat returns aux_items for rd_prot confs. We should almost certainly have a way of filtering out some aux items so they are not visible to non-members. [57] ** Remove src/include/compiler.h and use autoconf tests instead. Is NORETURN used where it should be used? [58] (Fixed: see http://bugzilla.lysator.liu.se/show_bug.cgi?id=58) ** Fix configure.in. The output of ./configure --help isn't as good as it should be. See libisc. [3] ** The configure script fails if neither flex nor lex can be found. [59] ** async-text-deleted (and possibly others) should be sent to recipients of any of the objects linked to the text that is deleted. [61] ** Add an enable_val value to the Person structure, and use it when no session is available. [62] ** Handle timetravel better. [63] ** Add leaks tests for all situtations when the client gets disconnected from the server. [64] ** Statement coverage tests for the aux-item-def parser [65] ** Fix the markup in the Texinfo files [66] ** Consider changing many paths so that it is safe to install lyskomd with prefix=/usr/local. How about saving this for the next release and then support various other path conventions? [67] ** Add a checksum on each object in the database. [69] ** The text-mass file should contain some redundancy. At a minimum, it should store the text number and text length of each text, so that there is absolutely no risk that the wrong text is displayed. (That has actually happened more than once due to faulty hardware or operating systems--we should do better.) [70] ** Should anyone be able to set their letterbox to secret? [ignored] ** Fixa s{kerhetsbuggen vid read_texts et c. Det b|r vara s} att man inte f}r veta mappningen s} ofta som nu. Vilka texter som {r l{sta b|r ocks} vara mer hemligt. Ett nytt anrop, query_unread(), b|r inf|ras. Resultatet {r antalet ol{sat brev och _kanske_ Local_text_no f|r det h|gsta nummret. (Det var l{nge sen jag skrev det h{r, och jag minns inte riktigt vad jag menar, men man borde nog titta p} det h{r s} sm}ningom). [71] ** Asynchronous messages may not be censored enough. Check all messages that contain conf-nos. [72] ** Add triggers have to have the capability of preventing addition. This is difficult since we check the validity of addition before adding the items. The prevention would have to happen in the check phase, when the triggers are not called. The correct solution is probably to implement validation functions in addition to validation strings and let the validation function take care of checking if the item can be added. [6] ** The Info structure should contain statistics about the server (uptime, other interesting stuff.) (from 1991) Implement a new call for this. [73] ** Fix proper ctor/dtor semantics of everything in memory.c. _clear is an abomination. [74] ** Call to s_fcrea_str in prot_a_get_token should be removed. There is really no reason why we can't us a statically allocated string instead (I know, this is microoptimization, but this function gets called a *lot*) Measurements shows that more than 95% of the calls to s_fcrea_str originates from prot_a_get_token. They also show that s_fcrea_str and its descendants uses approximately 22 out of 35000 seconds. [75] ** Change log.c to something better. [76] ** Look over all places where restart_kom is called. Frequently the error is not severe enough to warrant panicing (or so I think.) For example, if cached_create_person fails it is very serious, but all code that calls this function is prepared to deal with the problems. [77] ** Actually remove all man pages. This must wait till after the next release. [78] ** We have to be able to limit creation of certain aux-items to users with special privileges. Most of the import/export items need this. Put in a new flag in the aux-item-definition file, add it to the parser, check it in aux_item_check_add_perm or whatever the hell the function was named. Test it. The biggest problem is to figure out what permissions should be needed. I suppose it's possible that we could let the user specify level and bits in the aux-items.conf file, but that would mean mucking more with the parser. [ignored, again] ** Fixa s{kerhetsbuggen vid read_texts et c. Det b|r vara s} att man inte f}r veta mappningen s} ofta som nu. Vilka texter som {r l{sta b|r ocks} vara mer hemligt. Ett nytt anrop, query_unread(), b|r inf|ras. Resultatet {r antalet ol{sat brev och _kanske_ Local_text_no f|r det h|gsta nummret. (Det var l{nge sen jag skrev det h{r, och jag minns inte riktigt vad jag menar, men man borde nog titta p} det h{r s} sm}ningom). [79] ** param.maxqueuedsize and other ISC configuration is ignored. [80] ** Transaction logging, so that we never lose any data. [81] ** dbck should check that all creation_times of Texts are consecutive, and that all local add-times of texts in confereces are consecutive. [82] ** Fix Nisse's text garbing procedure. See doc/IDEAS for details. [83] ** Proof-read Protocol-A.texi. [84, 85, 86, 87, 88, 89, 90, 91] ** Consider implementing aux-infos that are the "reverse" of a Mark, of the aux-info faq-text, of a presentation, et c. Once that is done, the mark_text field of the Text_stat can be removed. More importantly, it can easily be seen which conference a text is a presentation for (et c). We also get more redundancy that dbck can use. (3490225) I think that we want a more complex mark structure, and have both text and marker know about the marks on a particular text. [92] ** Consider implementing an aux-info that causes comments of a text, or of all texts written by the author, to get a bcc-recpt to the authors letterbox. Make sure that this bcc-recpt is not the only thing that makes it possible for the person to read the text. (3381984, 3382009) [93] ** Define and implement asynchronous messages for cache inconsitency. This is partially done. -- DCB One problematic situation is when a new comment is created, and a conference that is a recipient of the commented text is not a member of the comment. Any user that is a member of that conference will not receive the new_text message, so his cache will not be updated. [94] ** Add an improved internal structure for the text_stat list to avoid a large fixed-size array. [96] ** Document the mark bits. (6390, 24358, 24444, 40876, 42356, 45110, 1111605, 2687219) Better still, implement a more complex mark structure rather than using the current mark number as a bitfield. We need to be able to see what marks are set on a given text. -- DCB [97] ** Document the user area. [98] ** Add a separate subject field (a short string) to the Text-stat. Problems: should the subject be restricted to ISO 8859-1? [100] ** Remove cache_node.s.snapshot (in cache-node.h). It is unused. * Lower priority than the above-mentioned things. [102] ** isc_disable()/isc_enable() should be used, so that a single session cannot starve other sessions. We might need a better mechanism than isc_disable()/isc_enable. [6] ** The Info structure should contain statistics about the server (uptime, other interesting stuff.) (from 1991) [103] ** difftime is not used everywhere where it should be used. There are a few places where '-' is still used to get a diff in seconds. [104] ** Fix something that can replace the user_area. The elisp-client creates a new user-area each time a person creates a permanent filter. What a waste of text numbers! It would be better to have a way to store per-user configuration separately. It should probably be keyed data, but separating it in different sections like we do with the user-area really doesn't make much sense. [82] ** Comments should optionally inhibit the garb (3608307). See IDEAS. [105] ** Do something about how large texts are sent back to the client. We should probably get rid of ISC altogether. See IDEAS. [107] ** Performance enhancement: Don't emit asynchronous messages immediately. Attempt to write, say, 4 KB of data at a time to the clients. The server currently makes a lot of small writes. [85, 86] ** Introduced aux-items that states that "this text is the presentation/motd of conference so-and-so". [108] ** Run the garb at 02:00 (configurable) rather than every 24 hours. [ignored] ** Some generalized way to query the server for (unread) texts with a certain aux-item set. (see 21415 for motivation) [109] ** Write a "lyskomd hackers guide" (requested in 24684). [110] ** Tree-structure for the conferences (41768). Yay! See the IDEAS file for some concrete ideas on how to do this. -- DCB. [111] ** Don't include so much information in the Person and Conference structures internally in the server. A Conference is (probably) used much more often than the large internal lists within it. For active conferences, the l2g map is probably used a lot. However the created-texts map for a person is not used a lot. The read-texts part of memberships get updated a lot. For maximum gains we probably have to split off the created-texts map and make is possible to read individual memberships from disk. The entire thing should be hidden from most of the server by automatically reading bits of maps or memberships on demand from disk. High-level functions shouldn't have to know about this. [ignored -- too big a change] ** Improve the data base. Text 250010 contains some ideas for a grand redesign. [112] ** A better way to "list active conferences" than to get the conference status of every conference and sort them on the last-written field. According to 310351 PortaKOM had the command "Lista aktiva möten". We should be as good as PortaKOM in every aspect. But see text 3604479 which outlines a way to implement this in a client in a reasonably efficient way without support from the server. [113] ** Stack-based slow searching? See 1013917 for some ideas. [114] ** 103=local-to-global and 34=get-map should be able to return more information when applied to e. g. letterboxes. It should return information about all texts that ACTPERS is allowed to read. See 678026 and 678411 for more thoughts about this. [115] ** Re-run the test in 775202 and see if anything can be improved. [116] ** New version of mark_as_read: void mark_as_read(Text_no); All examined clients emulate this call with a loop over all recipients of the text. [117] ** Text parts, so that we can have both audio and text. [118] ** Keyword support on texts. [119] ** Keyword support on conferences (1112142, 1112200). [120] ** Version numbering on calls? (1441352) [122] ** A possibility to ask for conferences created after a certain date. (1622840). Dubious value; the new conferences should have a presentation. [121] ** Add a call to retrieve the highest used conference number, so that a client can loop over all conferences/detect when new conferences have been created while the client wasn't logged on. [123] ** Add get_next_conf/get_previous_conf calls, to be able to loop through the conferences. [124] ** A documented way to store the prefered language in the common block of the user area (1632323). [125] ** Check the rules for when you are allowed to change a recpt to a cc-recpt. (1901530, 2329667, 2329682). (This may already be implemented -- check it.) [92] ** It would be nice if an author could be notified whenever a text written by him was commented. 3381984 and 3382009 outlines a way to implement that using a special aux-info and automatic adding of a bcc-recpt by the server to the new comment. [126] ** There should be a limit on how many texts you can mark as read in a conference to avoid the list becoming too long. This bug has a low priority. Footnote (1991-01-24): When Inge's Numlist package is finished, this won't matter any more. This bug requires no other action. Footnote (1999-01-18): When will the package be done? * Fixed ** mx-foo (4160925) Several mx-related aux-items are now present in Protocol-A.texi. ** Who is allowed to remove an faq-text-aux-item? 6024603. Added owner-delete parameter to aux-item definition as this is a somewhat more general problem. It is getting obvious that the original code for handling access to aux-items is getting stretched beyond its limits. The code could stand a complete rewrite that would allow for detailed control of access to items depending on the type objects they are attached to. DONE by byers --ceder ** Add test cases for recent changes: Delete aux-item with owner-delete when creator, owner, supervisor of creator, supervisor of owner, ENA, and someone else. DONE --ceder ** New predefined aux-items: 31-32, 10100-10104: implement them. DONE --ceder ** mx-date är trasig. Testfall som konstaterar detta behövs. (4171451) DONE --ceder ** Analyze the bug reported in 5970012. Applied the patch. Regrettably it does not break any existing test cases. Embarrassing... Check that we get new text messages when for texts that have recipients we are passive members of. Order with passive conf first, normal second and the reverse. Test cases now written (19.exp, especially when EXTENDED is set to 1). FIXED -- ceder ** 30=add-recpipient: recpt-type is not a complete Misc-Info -- it is only an Info-Type. Problem is: Info-Type is not defined in Protocol-A.texi. Also affects async-new-recipient[16] and async-sub-recipient. DONE -- ceder ** lookup_regex(foo|bar) fails -- the | is translated to an ö! FIXED -- "Regexps use collate table" removed. --ceder ** There is no call to mark_conference_as_changed in create_person_generic after the additions of aux_items. FIXED --ceder ** Remove DISKERR. It was needed for version 0.29 and is still there! DONE --ceder ** Insert "ACTPERS == pers_no ||" into get_unread_confs to get a performance boost. DONE --ceder ** Remove the IMPL macro. Everything is implemented now! DONE --ceder ** No test case for failed locking or failed unlocking of database DONE --ceder (lyskomd.0/11.exp) ** Update/rewrite README. DONE --ceder ** Check that texinfo.tex is included in a proper place by automake. DONE --ceder (se HACKING) ** The protocol revision section of Protocol-A.info is incomplete. DONE --ceder ** Consider locking the database, so that dbck cannot do harm, and so that only one lyskomd can use the database (consider NFS). DONE --ceder ** Document updateLysKOM in lyskomd.texi. There should be an "Invoking updateLysKOM" node. updateLysKOM should use the "Status file" parameter (and other parameters). Use parameters in src/server/updateLysKOM.c`savecore(). DONE --ceder ** Document komrunning in lyskomd.texi. There should be an "Invoking komrunning" node. komrunning should be rewritten i C; it only works with BSD-style ps programs. (DONE, but it no longer displays the process) DONE --ceder ** Test that "% No connections left" works. DONE --ceder ** Document 103=local_to_global DONE --ceder ** Document 104=map_created_texts DONE --ceder ** Missing test cases in 03.exp Calls 100, 101, 102, 103, 104 I've done 100-102. 103 and 104 left. I will do this --ceder DONE ** local_to_global isn't tested enough. Run gcov on it. DONE. We now have 96.39% coverage; only some file error handling is untested. ** Improve the file format for local-to-global.c. Warning: this will cause an incompatible change in the database format. DONE ** Fine-tune the Text_mapping data type (3623903, 3624144, 3624179, 3624173). DONE: range-begin and range-end added to Text-Mapping. ** Merge all changes done to prot-A.txt into Protocol-A.texi. DONE. prot-A.txt removed. ** Remove the man pages for lyskomd and dbck. DONE. All man pages still exists, but they only refer to the Texinfo documentation. We don't want man pages from earlier lyskomd installations to linger around. The should be completely removed in the next release, though. ** Fix dbck so that it can repair Member<->Membership inconsistencies. DONE. Needs to be tested though. ** Implement a test suite that tests all calls successfully at least once. DONE. ** Should the error message be named conference-zero or zero-conference? (Protocol-A.texi) DONE: conference-zero ** 52=get-unread-confs should ignore conferences where you are a passive member. DONE. ** Mention explicitly in the protocol spec that the cient cannot send "0 *" to the server. DONE. ** Protocol-A.texi contains both INT32 and INTEGER. (3228850) DONE. Changed all INTEGER to INT32 ** Protocol-A.texi uses mailbox and letterbox interchangeably. Use one term only, or at least state explicitly that they are the same thing. DONE. Letterbox used in structures, mailbox in text. It's safe to replace all mailboxes with letterbox. ** String-Size is used but not defined in Protocol-A.texi. (3228850) DONE. Use INT32 instead ** Session-No is defined twice in Protocol-A.texi. (3228850) DONE. Removed second definition. ** Check the unused static function regarding aux-infos. DONE. ** ceder thinks that the sender of a BCC recipient group should be allowed to see it, so that the sender can see when the recipient has read the text. (3380375, 3381048) DONE. ** ceder thinks that a BCC recipient group should be visible to anybody that may become a member of the BCC recipient (as opposed to all members and all administrators), lest everybody starts to be passive members of every conference just to be able to see BCC recipients. (3380375, 3381048) DONE. ** The redirect aux-info needs more documentation. See FIXME comment in Protocol-A.texi. FIXED. ** Validation of aux-items. DONE. Regexp validation done. ** Ability to have a callback function when an aux-item is created, removed, changed or resurrected. (This is according to 3053346 critical. Why?) DONE. ** The Membership that is returned by 98=query-read-texts should include the position of the Membership. DONE. Did the same for get-membership. ** Write a Texinfo manual for lyskomd based on the man pages. DONE. Whee! ** The redirect aux-info needs more documentation. See FIXME comment in Protocol-A.texi. DONE. ** Should we really retain deleted aux-items indefinitely? (3490203) DONE. No, and we don't any more. ** disconnect(0) should disconnect the current session. (806239) DONE. Session 0 is now always interpreted as the current session. ** Add the dbck reference to the lyskomd manual. DONE. There is now a dbck Texinfo manual ** An asynchronous message is sent to everybody when a secret conference changes its name. That is an unacceptable leak of sensitive information. (990788, 2804846) FIXED. ** Check that Async 13 is sent at the proper times (see 79208). FIXED. ** Newline terminates requests. Check that a wording similar to that in 1509862 is present in Protocol-A.texi. FIXED. ** 89=create-person should probably not do an automatic login. (Wasn't this discussed in KOM? Yes it was, in 3267591, but there are no surviving comments. Did anybody object? /ceder) DONE. ** Check change-what-am-i-doing very carefully. According to 915974 and 916257 there may be a bug in it, but that is pure speculation. DISMISSED. Tried sending long, short and invalid strings. No dice. Code inspection of functions turn up nothing. ** Should the conference supervisor be able to set the secret bit of a membership type? Probably yes. Maybe no. DONE. Can't set forbid-secret to true if there are secret members. Conference supervisor will have to boot secret members or convince them to convert. ** Create a "server hackers guide" and move the contents of doc/server.extend (and several other files in the doc directory) to it. The "server hackers guide" should probably be an appendix of doc/lyskomd.texi. DONE. ** Test the interpretation of session 0 as the current session. DONE. *** Integrate doc/Bugrapporter into this document. DONE. *** Get rid of tmp-limits.h I'll do this --DCB DONE. ** Let the author of a text add other people's texts as footnotes. (from 1991) REJECT. (ceder & DCB 1999-03-28) ** There is no limit on how much can be queued in a write queue in isc. (from 1991, still an issue.) DONE -- found to be fixed when the code was inspected 1999-03-28 ** get-n-unread as per 1111652. REJECT. (ceder & DCB 1999-03-28) ** If would be cool to be able to do finger @kom.lysator.liu.se and get something like: @finger @lyskom.lysator.liu.se Wed 2-Jan-91 15:27:08 Up 718:34:00 3+2 Jobs Load av 0.20 0.07 0.00 No LysKOM administrator in attendance Job Line Activity User Where 22 p1 Reading ceder LysKOM internals 23 p2 Waiting noppe Inl{gg }t mig 24 p3 Reading pell Hackers (@) Nanny 1 172 LDB OPERATOR 2 173 KOMSTAT Statistikid f|r statistikinsamling REJECT. (ceder & DCB 1999-03-28 -- a client could do this) ** cached_get_garb_nice has nowhere to get garb_nice from. It's not cached. I think this is fixed with small_conf_arr. Ceder, what do you say? --DCB I say it's fixed. /ceder ** There's a long-standing memory leak, probably in ISC. It appears to happen when we queue up lots of junk to clients that have died. Trace what happens if we do isc_oflush and hit the E2BIG bit. I tried lots of crap. I think this will have to wait until we have a leak detection tool and can run the generic test suite on the code. --DCB Even with a leak detection tool no leak was found. The server simply uses a lot of (possibly fragmented) memory. /ceder 1999-03-28 ** Read all texts in LysKOM (-) Systemet, protokollet mm created after 1991 (start at text 170527) and incorporate selected information in this document. DONE. ** Read 45110, 45121, 45284 again and incorporate selected comments in this document. 45110: Membership stuff. Bellman's idea of sorting using anything but priority hasn't taken over the world since 1991. I think we can declare it dead. Membership flags have been added. How a membership breaks the read order is a client matter. I don't think it anything to do with the server. The user area has been implemented. There's another todo item about documenting it. Marks and keywords are covered by another todo item. We're doing external recipients with aux-items. Asynchronous message bit is done. Server info is done. Don't do the mapcar function for this version. We are using latex to document the server. I declare this DONE. 45121: Comments to the above text. Dealt with. 45284: Also comments. Also dealt with. DONE (or REJECTED). ** isc_getnextevent should use a write-set in select. (from 1991) DONE (apparently) ** Fix case errors in type names etc in the documentation (3267160). DONE. ** New version of get-text-stat (et al) where the misc-info-list is removed. (1108039). REJECT: too much work to be worth it. *** Document "%%Unsupported protocol" message DONE. *** Document "%% No connections left" message DONE. *** Fix doc/lyskomdb.texi (Version 1) (see FIXME comments). DONE. *** Document that session number 0 can be used in call 55. DONE. *** There is no way to set the Personal_flags. It's not even obvious where it gets its initial value! This is Not Good At All. DONE. *** If we try to create a pers or conf and have reached the limit of how many confs we can create, lyskomd just dies. Nasty. It should return index-out-of-range, like create-text. DONE. ** When we pass a read-only misc item in create-text we get a protocol error. We should get an illegal-misc. We can't just pass it through since create_text_add_miscs will abort if it sees one of these misc items. DONE. ** Parsing arrays that are longer than the maximum length is not handled very well. Right now we return a protocol error most of the time, but perhaps it would be better to return a protocol error only when the array is insanely long, not just when it is longer than the max. So we could have a global max array length parameter. DONE. ** Make sure that there are no "expected failures" in the test suite. DONE. ** Try sending a too-long aux-item list DONE. ** Send a too-long misc-item list DONE. ** Sending a too-long delete or add list crashes the server. DONE. ** Call add-recipient with really bogus info type DONE. *** Move dbck.texi, hacking.tex and lyskomdb.texi into lyskomd.texi. Two reasons: there are too many manuals, and automake apparently doesn't allow more than one file to include version.texi. DONE. ** Check the FIXME in cached_conf_exists. I am certain that the necessary changes to cached_delete_conf are done, and almost sure that no other changes are required (checked where s.exists is set to zero for existing confs, and that is only in init_cache and cached_delete_conf. See ChangeLog entry for Sat Sep 13 (simple-cache.c). -- DCB But: we found problems with this 1999-03-28, which DCB fixed in his copy of the code. Committed yet? DONE. ** Stoppa in lyskomdb.texi i lyskomd.texi DONE. ** Fråga JSK, Zander, mfl vad deras klienter sätter för client version DONE. ** Check usage of is_supervisor. DONE. *** Remove the text "In all likelihood, the implementation of this flag is screwed up." from lyskomd.texi after checking that supervisor-only works properly. DONE. *** Dump all little doc files into the texinfo manuals. Remaining: disc-cache.spec lyskomd.texi översätt, uppdatera local-to-global.doc lyskomd.texi ceder? prot-a-tankar * prot_a * security-levels.txt Protocol-A.texi DONE what-is-unread.swe Protocol-A.texi DONE KLART. *** Fix the node structure of Protocol-A.texi (3228867). DONE. *** In prot_a_get_token, what is an insane token length? DONE. *** We have to be able to specify that some aux-items can only be created by the server. It's possible that admins should be allowed to create them as well. Perhaps this point and the previous point can be solved as one. DONE. *** When creating an FAQ item create a reverse item on the text. Make sure that they are always added and removed as a pair. Accomplish this with the add, delete and undelete triggers. DONE. *** The mark text trigger has to cause add failure if the text does not exist. DONE. *** Use libisc 1.0. I will do this --ceder DONE. *** Get rid of mux_printf and doc/mux.proto et c. I am doing this --ceder DONE. ** Fix all bitfield parsers to deal with arbitrary lengths. Maybe... DONE. *** Send all async messages with async messages turned off DONE. *** Send all async messages with a client connected that has not sent initial "greeting" DONE. *** Try sending in negative lengths whenever we can send an array. DONE for misc-info-list, add-aux delete-aux *** If we get protocol error while truncating a long list, things will get messed up. I think. DONE. *** Check that we don't leak memory when truncating a long aux_item_list send from the client. DONE. ** We should refuse to start if time has moved backwards. DONE ** Performance enhancement: Don't call gettimeofday() more than once per atomic call. DONE ** Fix lyskomd.0/09.exp DONE. ** Fix this. active_connection is NULL and ENA is mis-used. #0 0x2f064 in fast_access_perm (victim=4975, viewer=119, viewer_p=0x13c70f0) at membership.c:776 #1 0x2b610 in filter_secret_info (result=0xeffffa80, original=0x2f003a8, viewer=0, viewer_p=0x13c70f0, output_bcc=TRUE) at text.c:1238 #2 0x2b89c in send_async_deleted_text (text_no=2014215, text_s=0x2f003a8) at text.c:1350 #3 0x2bd50 in do_delete_text (text_no=2014215, text_s=0x2f003a8) at text.c:1609 #4 0x398bc in garb_text () at text-garb.c:245 #5 0x2809c in end_of_atomic (idle=TRUE) at disk-end-of-atomic.c:81 #6 0x29ef8 in toploop () at connections.c:713 #7 0x1d524 in main (argc=1, argv=0xeffffd7c) at ramkomd.c:535 DONE. ** Remove all setup_xfail DONE ** If ay_sub_recipient is on, but ay_deleted_text is not on, we need to decide which async messages to send before we start subtracting things from the text. The best solution is probably to never send ay_sub_recipient when texts are deleted. DONE ** Add CHK_CONNECTION to remaining RPC handlers. DONE *** modify_conf_info No check for secret confs. Might permit modification of any conf. FIXED. *** modify_text_info No check for read access on text before check if we can delete items. This can be used to map out all secret texts. Deletion proceeds even for secret texts. This is bad, bad, bad. FIXED. ** Regex matching with the collate table does not work. The test for param.regexps_use_collate_table is inverted. It doesn't work anyway. Results are *strange*. FIXED. ** send_async_new_recipient in text.c sends asyncs for BCC recipients. DONE. * In progress ** Document aux-items for mail import/export. (3229403) 3229403 1998-08-17 20:53 /47 rader/ David Byers Kommentar till text 3228797 av Jonas S Karlsson (Palmist) Mottagare: LysKOM; Utvecklingsgruppens interna möte <876> Markerad av 1 person. Ärende: 13, 14, 15 ------------------------------------------------------------ > Hmm, låter som en pik ;) Det menar du inte? Ceder har nog inga beskrivningar som har att göra med import av email. Det som ceder frågade om var en aux-item som används för att säta emailadress på personer, möten eller servern, inte texter. Som jag läser ditt mail så tycker du att följande aux-items behövs och är tillräckliga: 1. Extern mottagare för inlägg Vad innehåller aux-item? En sladdpostadress? Vad används den till? Vem använder den? 2. "Reply-to" på möten En Reply-To header som skall sättas på mail som exporteras från brevlådan. Vem är ansvarig för exporten? Klienten eller en exportör? 3. "From" på möten Se 2. 4. CC på möten Se 2. 5. Adress till mailinglista Kan sättas på möten och innehåller en sladdpostadress dit mail skall skickas. Vem är ansvarig för att skicka mail? En exportör eller klienten? 6. Diverse mailhuvuden på enstaka importerade inlägg Du har nämnt message-id, from, reply-to, to och cc. Jag föreslår att man dessutom har ett item som säger att inlägget är ett importerat mail och att man sparar alla headerrader i inlägget. Det är upp till klienten att besluta om den skall visa dem eller inte. 7. "Spamfilter" En sträng som tolkas av importören. Antagligen vill du ha klientspecifika aux-items för detta, om du inte definierar ett lagom stort och stabilt språk för filtreringen. Är det här tillräckligt? Om så är fallet, checka ut aux-items.def ur lyskomd, skriv in dina definitioner och dokumentera dem i Protocol-A.texi. (3229403) ------------------------------------------ ** Fix aux-item 13, 14 and 15 according to 3228006 and 3228045. 3228006 1998-08-17 14:46 /8 rader/ David Byers Mottagare: LysKOM; Utvecklingsgruppens interna möte <838> Markerad av 1 person. Ärende: 13, 14, 15 ------------------------------------------------------------ 13 och 14 ser bra ut. Jag tycker du tar bort parentesen i slutet av beskrivningen av vad 13 betyder när den är satt på ett möte. Eventuellt skulle man kunna säga på nummer 13 att innehållet får bestå av två saker separerade med space. Det första är i så fall en identifierare. Följande identifierare är definierade: "list-address" och "subscription-address". Eller nåt. Jag vet inte. Skriv något åt det här hållet om du tycker det verkar OK. (3228006) ------------------------------------------ Kommentar i text 3228045 av ceder (Per Cederqvist) 3228045 1998-08-17 14:52 /10 rader/ ceder (Per Cederqvist) Kommentar till text 3228006 av David Byers Mottagare: LysKOM; Utvecklingsgruppens interna möte <839> Markerad av 1 person. Ärende: 13, 14, 15 ------------------------------------------------------------ Jag skulle nog nästan hellre stoppa in en ny aux-item som är moderatoradress. Eller rent av låta list-address och subscription-address vara två nya aux-items, och bara tillåta nummer 13 på brevlådor. Då blir 13 en persons emailaddress. Hmm. För ett möte som "Idonex" vill man kanske stoppa dit en aux-item som är något typ "sales@idonex.se". Renast blir nog om 13 står för emailadresser som hör till en fysisk person, juridisk person, eller liknande. (Filosofisk fråga: är en mailinglista "något liknande" eller något väsensskillt?) (3228045) ------------------------------------------ Local variables: mode: outline End: lyskom-server-2.1.2/acinclude.m40000664000015100472110000000515507721716112012220 dnl $Id: acinclude.m4,v 1.11 2003/08/23 16:38:23 ceder Exp $ dnl Copyright (C) 1994-1995, 1998-1999, 2001-2003 Lysator Academic Computer Association. dnl dnl This file is part of the LysKOM server. dnl dnl LysKOM is free software; you can redistribute it and/or modify it dnl under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 1, or (at your option) dnl any later version. dnl dnl LysKOM is distributed in the hope that it will be useful, but WITHOUT dnl ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or dnl FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License dnl for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with LysKOM; see the file COPYING. If not, write to dnl Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, dnl or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, dnl MA 02139, USA. dnl dnl Please report bugs at http://bugzilla.lysator.liu.se/. dnl dnl dnl Check if an option is acceptable to the C compiler in use. dnl (This is taken verbatim from cmod 1.2. Please don't make even a dnl tiny change to it unless you change the name of all variables! dnl See the cmod source code for more information.) dnl AC_DEFUN([CMOD_CHECK_CC_OPT], [AC_MSG_CHECKING([whether ${CC} accepts $1]) AC_CACHE_VAL([cmod_cv_compiler_]$2, [[cmod_oldflags=$CFLAGS CFLAGS="$CFLAGS $1"] AC_TRY_LINK(,, [cmod_cv_compiler_]$2[=yes], [cmod_cv_compiler_]$2[=no]) [CFLAGS=$cmod_oldflags]])dnl AC_MSG_RESULT([$cmod_cv_compiler_]$2) if test [$cmod_cv_compiler_]$2 = yes; then CFLAGS="$CFLAGS $1" fi])dnl dnl dnl Another frozen defun. dnl AC_DEFUN([CMOD_C_WORKING_ATTRIBUTE_UNUSED], [AC_CACHE_CHECK([[whether $CC understands __attribute__((unused))]], [[cmod_cv_c_working_attribute_unused]], [dnl gcc 2.6.3 understands the __attribute__((unused)) syntax dnl enough that it prints a warning and ignores it when the dnl variable "i" is declared inside the function body, but it dnl barfs on the construct when it is used in a dnl parameter-declaration. That is why we have a function dnl definition in the prologue of AC_LANG_PROGRAM part. AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[int cmod_x(int y __attribute__((unused))) { return 7; }]], [[int i __attribute__((unused));]])], [cmod_cv_c_working_attribute_unused=yes], [cmod_cv_c_working_attribute_unused=no])]) [if test $cmod_cv_c_working_attribute_unused = yes ; then] AC_DEFINE([HAVE_ATTRIBUTE_UNUSED], [1], [Define if your compiler supports __attribute__ ((unused)).]) [fi]])dnl lyskom-server-2.1.2/aclocal.m40000664000015100472110000013566607723707360011711 # generated automatically by aclocal 1.7.6 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 # Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. dnl $Id: acinclude.m4,v 1.11 2003/08/23 16:38:23 ceder Exp $ dnl Copyright (C) 1994-1995, 1998-1999, 2001-2003 Lysator Academic Computer Association. dnl dnl This file is part of the LysKOM server. dnl dnl LysKOM is free software; you can redistribute it and/or modify it dnl under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 1, or (at your option) dnl any later version. dnl dnl LysKOM is distributed in the hope that it will be useful, but WITHOUT dnl ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or dnl FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License dnl for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with LysKOM; see the file COPYING. If not, write to dnl Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, dnl or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, dnl MA 02139, USA. dnl dnl Please report bugs at http://bugzilla.lysator.liu.se/. dnl dnl dnl Check if an option is acceptable to the C compiler in use. dnl (This is taken verbatim from cmod 1.2. Please don't make even a dnl tiny change to it unless you change the name of all variables! dnl See the cmod source code for more information.) dnl AC_DEFUN([CMOD_CHECK_CC_OPT], [AC_MSG_CHECKING([whether ${CC} accepts $1]) AC_CACHE_VAL([cmod_cv_compiler_]$2, [[cmod_oldflags=$CFLAGS CFLAGS="$CFLAGS $1"] AC_TRY_LINK(,, [cmod_cv_compiler_]$2[=yes], [cmod_cv_compiler_]$2[=no]) [CFLAGS=$cmod_oldflags]])dnl AC_MSG_RESULT([$cmod_cv_compiler_]$2) if test [$cmod_cv_compiler_]$2 = yes; then CFLAGS="$CFLAGS $1" fi])dnl dnl dnl Another frozen defun. dnl AC_DEFUN([CMOD_C_WORKING_ATTRIBUTE_UNUSED], [AC_CACHE_CHECK([[whether $CC understands __attribute__((unused))]], [[cmod_cv_c_working_attribute_unused]], [dnl gcc 2.6.3 understands the __attribute__((unused)) syntax dnl enough that it prints a warning and ignores it when the dnl variable "i" is declared inside the function body, but it dnl barfs on the construct when it is used in a dnl parameter-declaration. That is why we have a function dnl definition in the prologue of AC_LANG_PROGRAM part. AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[int cmod_x(int y __attribute__((unused))) { return 7; }]], [[int i __attribute__((unused));]])], [cmod_cv_c_working_attribute_unused=yes], [cmod_cv_c_working_attribute_unused=no])]) [if test $cmod_cv_c_working_attribute_unused = yes ; then] AC_DEFINE([HAVE_ATTRIBUTE_UNUSED], [1], [Define if your compiler supports __attribute__ ((unused)).]) [fi]])dnl # Do all the work for Automake. -*- Autoconf -*- # This macro actually does too much some checks are only needed if # your package does certain things. But this isn't really a big deal. # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 10 AC_PREREQ([2.54]) # Autoconf 2.50 wants to disallow AM_ names. We explicitly allow # the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl # test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AM_MISSING_PROG(AMTAR, tar) AM_PROG_INSTALL_SH AM_PROG_INSTALL_STRIP # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl ]) ]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $1 | $1:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) # Copyright 2002 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.7"]) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION so it can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.7.6])]) # Helper functions for option handling. -*- Autoconf -*- # Copyright 2001, 2002 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 2 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # ------------------------------ # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ---------------------------------- # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # # Check to make sure that the build environment is sane. # # Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 3 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # -*- Autoconf -*- # Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 3 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # AM_AUX_DIR_EXPAND # Copyright 2001 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. # Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50]) AC_DEFUN([AM_AUX_DIR_EXPAND], [ # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. # Copyright 2001 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl install_sh=${install_sh-"$am_aux_dir/install-sh"} AC_SUBST(install_sh)]) # AM_PROG_INSTALL_STRIP # Copyright 2001 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # -*- Autoconf -*- # Copyright (C) 2003 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 1 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # serial 5 -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "GCJ", or "OBJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c : > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # (even with -Werror). So we grep stderr for any message # that says an option was ignored. if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, [ --disable-dependency-tracking Speeds up one-time builds --enable-dependency-tracking Do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH]) ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. #serial 2 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [for mf in $CONFIG_FILES; do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # So let's grep whole file. if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue # Extract the definition of DEP_FILES from the Makefile without # running `make'. DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"` test -z "$DEPDIR" && continue # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n -e '/^U = / s///p' < "$mf"` test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" # We invoke sed twice because it is the simplest approach to # changing $(DEPDIR) to its actual value in the expansion. for file in `sed -n -e ' /^DEP_FILES = .*\\\\$/ { s/^DEP_FILES = // :loop s/\\\\$// p n /\\\\$/ b loop p } /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each `.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 2 # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright 1997, 2000, 2001 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 5 AC_PREREQ(2.52) # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE]) AC_SUBST([$1_FALSE]) if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]) fi])]) # Copyright 1996, 1997, 1998, 2000, 2001, 2002 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 2 AC_DEFUN([AM_C_PROTOTYPES], [AC_REQUIRE([AM_PROG_CC_STDC]) AC_REQUIRE([AC_PROG_CPP]) AC_MSG_CHECKING([for function prototypes]) if test "$am_cv_prog_cc_stdc" != no; then AC_MSG_RESULT(yes) AC_DEFINE(PROTOTYPES,1,[Define if compiler has function prototypes]) U= ANSI2KNR= else AC_MSG_RESULT(no) U=_ ANSI2KNR=./ansi2knr fi # Ensure some checks needed by ansi2knr itself. AC_HEADER_STDC AC_CHECK_HEADERS(string.h) AC_SUBST(U)dnl AC_SUBST(ANSI2KNR)dnl ]) AU_DEFUN([fp_C_PROTOTYPES], [AM_C_PROTOTYPES]) # Copyright 1996, 1997, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 2 # @defmac AC_PROG_CC_STDC # @maindex PROG_CC_STDC # @ovindex CC # If the C compiler in not in ANSI C mode by default, try to add an option # to output variable @code{CC} to make it so. This macro tries various # options that select ANSI C on some system or another. It considers the # compiler to be in ANSI C mode if it handles function prototypes correctly. # # If you use this macro, you should check after calling it whether the C # compiler has been set to accept ANSI C; if not, the shell variable # @code{am_cv_prog_cc_stdc} is set to @samp{no}. If you wrote your source # code in ANSI C, you can make an un-ANSIfied copy of it by using the # program @code{ansi2knr}, which comes with Ghostscript. # @end defmac AC_DEFUN([AM_PROG_CC_STDC], [AC_REQUIRE([AC_PROG_CC]) AC_BEFORE([$0], [AC_C_INLINE]) AC_BEFORE([$0], [AC_C_CONST]) dnl Force this before AC_PROG_CPP. Some cpp's, eg on HPUX, require dnl a magic option to avoid problems with ANSI preprocessor commands dnl like #elif. dnl FIXME: can't do this because then AC_AIX won't work due to a dnl circular dependency. dnl AC_BEFORE([$0], [AC_PROG_CPP]) AC_MSG_CHECKING([for ${CC-cc} option to accept ANSI C]) AC_CACHE_VAL(am_cv_prog_cc_stdc, [am_cv_prog_cc_stdc=no ac_save_CC="$CC" # Don't try gcc -ansi; that turns off useful extensions and # breaks some systems' header files. # AIX -qlanglvl=ansi # Ultrix and OSF/1 -std1 # HP-UX 10.20 and later -Ae # HP-UX older versions -Aa -D_HPUX_SOURCE # SVR4 -Xc -D__EXTENSIONS__ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" AC_TRY_COMPILE( [#include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; ], [ return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ], [am_cv_prog_cc_stdc="$ac_arg"; break]) done CC="$ac_save_CC" ]) if test -z "$am_cv_prog_cc_stdc"; then AC_MSG_RESULT([none needed]) else AC_MSG_RESULT([$am_cv_prog_cc_stdc]) fi case "x$am_cv_prog_cc_stdc" in x|xno) ;; *) CC="$CC $am_cv_prog_cc_stdc" ;; esac ]) AU_DEFUN([fp_PROG_CC_STDC], [AM_PROG_CC_STDC]) # Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # AM_PATH_PYTHON([MINIMUM-VERSION]) # Adds support for distributing Python modules and packages. To # install modules, copy them to $(pythondir), using the python_PYTHON # automake variable. To install a package with the same name as the # automake package, install to $(pkgpythondir), or use the # pkgpython_PYTHON automake variable. # The variables $(pyexecdir) and $(pkgpyexecdir) are provided as # locations to install python extension modules (shared libraries). # Another macro is required to find the appropriate flags to compile # extension modules. # If your package is configured with a different prefix to python, # users will have to add the install directory to the PYTHONPATH # environment variable, or create a .pth file (see the python # documentation for details). # If the MINIUMUM-VERSION argument is passed, AM_PATH_PYTHON will # cause an error if the version of python installed on the system # doesn't meet the requirement. MINIMUM-VERSION should consist of # numbers and dots only. AC_DEFUN([AM_PATH_PYTHON], [ dnl Find a Python interpreter. Python versions prior to 1.5 are not dnl supported because the default installation locations changed from dnl $prefix/lib/site-python in 1.4 to $prefix/lib/python1.5/site-packages dnl in 1.5. m4_define([_AM_PYTHON_INTERPRETER_LIST], [python python2 python2.3 python2.2 python2.1 python2.0 python1.6 python1.5]) m4_if([$1],[],[ dnl No version check is needed. # Find any Python interpreter. AC_PATH_PROG([PYTHON], _AM_PYTHON_INTERPRETER_LIST) am_display_PYTHON=python ], [ dnl A version check is needed. if test -n "$PYTHON"; then # If the user set $PYTHON, use it and don't search something else. AC_MSG_CHECKING([whether $PYTHON version >= $1]) AM_PYTHON_CHECK_VERSION([$PYTHON], [$1], [AC_MSG_RESULT(yes)], [AC_MSG_ERROR(too old)]) else # Otherwise, try each interpreter until we find one that satisfies # VERSION. AC_CACHE_CHECK([for a Python interpreter with version >= $1], [am_cv_pathless_PYTHON],[ for am_cv_pathless_PYTHON in _AM_PYTHON_INTERPRETER_LIST : ; do if test "$am_cv_pathless_PYTHON" = : ; then AC_MSG_ERROR([no suitable Python interpreter found]) fi AM_PYTHON_CHECK_VERSION([$am_cv_pathless_PYTHON], [$1], [break]) done]) # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON. AC_PATH_PROG([PYTHON], [$am_cv_pathless_PYTHON]) am_display_PYTHON=$am_cv_pathless_PYTHON fi ]) dnl Query Python for its version number. Getting [:3] seems to be dnl the best way to do this; it's what "site.py" does in the standard dnl library. [if test -n "$PYTHON"; then] AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version], [am_cv_python_version=`$PYTHON -c "import sys; print sys.version[[:3]]"`]) [else am_cv_python_version=none; fi] AC_SUBST([PYTHON_VERSION], [$am_cv_python_version]) dnl Use the values of $prefix and $exec_prefix for the corresponding dnl values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX. These are made dnl distinct variables so they can be overridden if need be. However, dnl general consensus is that you shouldn't need this ability. AC_SUBST([PYTHON_PREFIX], ['${prefix}']) AC_SUBST([PYTHON_EXEC_PREFIX], ['${exec_prefix}']) dnl At times (like when building shared libraries) you may want dnl to know which OS platform Python thinks this is. [if test -n "$PYTHON"; then] AC_CACHE_CHECK([for $am_display_PYTHON platform], [am_cv_python_platform], [am_cv_python_platform=`$PYTHON -c "import sys; print sys.platform"`]) [else am_cv_python_platform=none; fi] AC_SUBST([PYTHON_PLATFORM], [$am_cv_python_platform]) dnl Set up 4 directories: dnl pythondir -- where to install python scripts. This is the dnl site-packages directory, not the python standard library dnl directory like in previous automake betas. This behaviour dnl is more consistent with lispdir.m4 for example. dnl Query distutils for this directory. distutils does not exist in dnl Python 1.5, so we fall back to the hardcoded directory if it dnl doesn't work. [if test -n "$PYTHON"; then] AC_CACHE_CHECK([for $am_display_PYTHON script directory], [am_cv_python_pythondir], [am_cv_python_pythondir=`$PYTHON -c "from distutils import sysconfig; print sysconfig.get_python_lib(0,0,prefix='$PYTHON_PREFIX')" 2>/dev/null || echo "$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages"`]) [else am_cv_python_pythondir=none; fi] AC_SUBST([pythondir], [$am_cv_python_pythondir]) dnl pkgpythondir -- $PACKAGE directory under pythondir. Was dnl PYTHON_SITE_PACKAGE in previous betas, but this naming is dnl more consistent with the rest of automake. AC_SUBST([pkgpythondir], [\${pythondir}/$PACKAGE]) dnl pyexecdir -- directory for installing python extension modules dnl (shared libraries) dnl Query distutils for this directory. distutils does not exist in dnl Python 1.5, so we fall back to the hardcoded directory if it dnl doesn't work. [if test -n "$PYTHON"; then] AC_CACHE_CHECK([for $am_display_PYTHON extension module directory], [am_cv_python_pyexecdir], [am_cv_python_pyexecdir=`$PYTHON -c "from distutils import sysconfig; print sysconfig.get_python_lib(1,0,prefix='$PYTHON_EXEC_PREFIX')" 2>/dev/null || echo "${PYTHON_EXEC_PREFIX}/lib/python${PYTHON_VERSION}/site-packages"`]) [else am_cv_python_pyexecdir=none; fi] AC_SUBST([pyexecdir], [$am_cv_python_pyexecdir]) dnl pkgpyexecdir -- $(pyexecdir)/$(PACKAGE) AC_SUBST([pkgpyexecdir], [\${pyexecdir}/$PACKAGE]) ]) # AM_PYTHON_CHECK_VERSION(PROG, VERSION, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) # --------------------------------------------------------------------------- # Run ACTION-IF-TRUE if the Python interpreter PROG has version >= VERSION. # Run ACTION-IF-FALSE otherwise. # This test uses sys.hexversion instead of the string equivalant (first # word of sys.version), in order to cope with versions such as 2.2c1. # hexversion has been introduced in Python 1.5.2; it's probably not # worth to support older versions (1.5.1 was released on October 31, 1998). AC_DEFUN([AM_PYTHON_CHECK_VERSION], [prog="import sys, string # split strings by '.' and convert to numeric. Append some zeros # because we need at least 4 digits for the hex conversion. minver = map(int, string.split('$2', '.')) + [[0, 0, 0]] minverhex = 0 for i in xrange(0, 4): minverhex = (minverhex << 8) + minver[[i]] sys.exit(sys.hexversion < minverhex)" AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])]) # Copyright 2001 Free Software Foundation, Inc. -*- Autoconf -*- # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 3 AC_PREREQ(2.50) # AM_PROG_LEX # ----------- # Autoconf leaves LEX=: if lex or flex can't be found. Change that to a # "missing" invocation, for better error output. AC_DEFUN([AM_PROG_LEX], [AC_REQUIRE([AM_MISSING_HAS_RUN])dnl AC_REQUIRE([AC_PROG_LEX])dnl if test "$LEX" = :; then LEX=${am_missing_run}flex fi]) lyskom-server-2.1.2/config.h.in0000664000015100472110000001561007723707374012063 /* config.h.in. Generated from configure.in by autoheader. */ /* This should be defined if you want gcov statistics. It replaces some aborts with exits so coverage data is output. */ #undef AVOID_ABORTS /* Define if your OS has buggy inet_ntoa. If you don't know, define this. */ #undef BUGGY_INET_NTOA /* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP systems. This function is required for `alloca.c' support on those systems. */ #undef CRAY_STACKSEG_END /* Define to 1 if using `alloca.c'. */ #undef C_ALLOCA /* Include special debug requests. Don't use this on a production server. The debug requests are insecure. The test suite uses these calls if they are available to increase the coverage. */ #undef DEBUG_CALLS /* Define if you want encrypted passwords */ #undef ENCRYPT_PASSWORDS /* Define to 1 if you have `alloca', as a function or macro. */ #undef HAVE_ALLOCA /* Define to 1 if you have the header file. */ #undef HAVE_ALLOCA_H /* Define if your compiler supports __attribute__ in printf. */ #undef HAVE_ATTRIBUTE_FORMAT_PRINTF /* Define if your compiler supports __attribute__ ((noreturn)). */ #undef HAVE_ATTRIBUTE_NORETURN /* Define if your compiler supports __attribute__ ((unused)). */ #undef HAVE_ATTRIBUTE_UNUSED /* Define if setrlimit(RLIMIT_NOFILE) does not work. */ #undef HAVE_BROKEN_NOFILE /* Define to 1 if you have the header file. */ #undef HAVE_CRYPT_H /* Define to 1 if you have the `difftime' function. */ #undef HAVE_DIFFTIME /* Define to 1 if you have the `getcwd' function. */ #undef HAVE_GETCWD /* Define to 1 if you have the `getdtablesize' function. */ #undef HAVE_GETDTABLESIZE /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `authuser' library (-lauthuser). */ #undef HAVE_LIBAUTHUSER /* Define to 1 if you have the `crypt' library (-lcrypt). */ #undef HAVE_LIBCRYPT /* Define to 1 if you have the `efence' library (-lefence). */ #undef HAVE_LIBEFENCE /* Define to 1 if you have the `i' library (-li). */ #undef HAVE_LIBI /* Define to 1 if you have the `nsl' library (-lnsl). */ #undef HAVE_LIBNSL /* Define to 1 if you have the `resolv' library (-lresolv). */ #undef HAVE_LIBRESOLV /* Define to 1 if you have the `socket' library (-lsocket). */ #undef HAVE_LIBSOCKET /* Define to 1 if you have the header file. */ #undef HAVE_LOCALE_H /* Define to 1 if you have the `mallinfo' function. */ #undef HAVE_MALLINFO /* Define to 1 if you have the `memchr' function. */ #undef HAVE_MEMCHR /* Define to 1 if you have the `memcmp' function. */ #undef HAVE_MEMCMP /* Define to 1 if you have the `memcpy' function. */ #undef HAVE_MEMCPY /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `memset' function. */ #undef HAVE_MEMSET /* Define to 1 if you have the `remove' function. */ #undef HAVE_REMOVE /* Define if rlimt_t is available. */ #undef HAVE_RLIM_T /* Define to 1 if you have the `setrlimit' function. */ #undef HAVE_SETRLIMIT /* Define to 1 if you have the `setsid' function. */ #undef HAVE_SETSID /* Define to 1 if you have the `snprintf' function. */ #undef HAVE_SNPRINTF /* Define to 1 if you have the header file. */ #undef HAVE_STDARG_H /* Define to 1 if you have the header file. */ #undef HAVE_STDDEF_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strchr' function. */ #undef HAVE_STRCHR /* Define to 1 if you have the `strerror' function. */ #undef HAVE_STRERROR /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define if struct sigaction is available. */ #undef HAVE_STRUCT_SIGACTION /* Define to 1 if you have the `sysconf' function. */ #undef HAVE_SYSCONF /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PARAM_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_RESOURCE_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the header file. */ #undef HAVE_VALUES_H /* Define to 1 if you have the `vfprintf' function. */ #undef HAVE_VFPRINTF /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define if compiler has function prototypes */ #undef PROTOTYPES /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #undef STACK_DIRECTION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define to 1 if you can safely include both and . */ #undef TIME_WITH_SYS_TIME /* Should all allocations be traced? See src/server/ram-smalloc.c. */ #undef TRACED_ALLOCATIONS /* Insert magic number before and after malloced areas. This can help detect buffer overruns. */ #undef USE_MALLOC_GUARDS /* Version number of package */ #undef VERSION /* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a `char[]'. */ #undef YYTEXT_POINTER /* Define to 1 if on AIX 3. System headers sometimes define this. We just want to avoid a redefinition error message. */ #ifndef _ALL_SOURCE # undef _ALL_SOURCE #endif /* Define if on HPUX */ #undef _HPUX_SOURCE /* Define to 1 if on MINIX. */ #undef _MINIX /* Define to 2 if the system does not provide POSIX.1 features except with this defined. */ #undef _POSIX_1_SOURCE /* Define to 1 if you need to in order for `stat' and other things to work. */ #undef _POSIX_SOURCE /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define as `__inline' if that's what the C compiler calls it, or to nothing if it is not supported. */ #undef inline /* Define to `int' if does not define. */ #undef pid_t /* Define this to a type that can be changed atomically from a signal handler if your OS lacks sig_atomic_t. */ #undef sig_atomic_t lyskom-server-2.1.2/configure0000775000015100472110000112413707723707432011750 #! /bin/sh # From configure.in Revision: 1.111 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.57 for lyskom-server 2.1.2. # # Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 # Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi # Support unset when possible. if (FOO=FOO; unset FOO) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" # Sed expression to map a string onto a valid variable name. as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` exec 6>&1 # # Initializations. # ac_default_prefix=/usr/local ac_config_libobj_dir=. cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. # This variable seems obsolete. It should probably be removed, and # only ac_max_sed_lines should be used. : ${ac_max_here_lines=38} # Identity of this package. PACKAGE_NAME='lyskom-server' PACKAGE_TARNAME='lyskom-server' PACKAGE_VERSION='2.1.2' PACKAGE_STRING='lyskom-server 2.1.2' PACKAGE_BUGREPORT='' ac_unique_file="src/server/lyskomd.h" ac_default_prefix=/usr/lyskom # Factoring default headers for most tests. ac_includes_default="\ #include #if HAVE_SYS_TYPES_H # include #endif #if HAVE_SYS_STAT_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_STRING_H # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif # include #endif #if HAVE_STRINGS_H # include #endif #if HAVE_INTTYPES_H # include #else # if HAVE_STDINT_H # include # endif #endif #if HAVE_UNISTD_H # include #endif" ac_subdirs_all="$ac_subdirs_all src/libraries/libisc-new" ac_subdirs_all="$ac_subdirs_all src/libraries/liboop" ac_subdirs_all="$ac_subdirs_all src/libraries/adns" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE am__leading_dot LANGUAGE_SUFFIX VALGRIND AR SENDMAIL CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CPP EGREP U ANSI2KNR PYTHON PYTHON_VERSION PYTHON_PREFIX PYTHON_EXEC_PREFIX PYTHON_PLATFORM pythondir pkgpythondir pyexecdir pkgpyexecdir HAVE_PYTHON_TRUE HAVE_PYTHON_FALSE EFENCE TRACED_ALLOCATIONS DEBUG_CALLS RANLIB ac_ct_RANLIB LN_S YACC LEX LEXLIB LEX_OUTPUT_ROOT BISON FLEX SED ALLOCA LIBOBJS INSURE CHECKER subdirs LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_option in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` eval "enable_$ac_feature=no" ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "enable_$ac_feature='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package| sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "with_$ac_package='$ac_optarg'" ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/-/_/g'` eval "with_$ac_package=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` eval "$ac_envvar='$ac_optarg'" export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute paths. for ac_var in exec_prefix prefix do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* | NONE | '' ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # Be sure to have absolute paths. for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ localstatedir libdir includedir oldincludedir infodir mandir do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_confdir=`(dirname "$0") 2>/dev/null || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 { (exit 1); exit 1; }; } else { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi fi (cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 { (exit 1); exit 1; }; } srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` ac_env_build_alias_set=${build_alias+set} ac_env_build_alias_value=$build_alias ac_cv_env_build_alias_set=${build_alias+set} ac_cv_env_build_alias_value=$build_alias ac_env_host_alias_set=${host_alias+set} ac_env_host_alias_value=$host_alias ac_cv_env_host_alias_set=${host_alias+set} ac_cv_env_host_alias_value=$host_alias ac_env_target_alias_set=${target_alias+set} ac_env_target_alias_value=$target_alias ac_cv_env_target_alias_set=${target_alias+set} ac_cv_env_target_alias_value=$target_alias ac_env_AR_set=${AR+set} ac_env_AR_value=$AR ac_cv_env_AR_set=${AR+set} ac_cv_env_AR_value=$AR ac_env_CC_set=${CC+set} ac_env_CC_value=$CC ac_cv_env_CC_set=${CC+set} ac_cv_env_CC_value=$CC ac_env_CFLAGS_set=${CFLAGS+set} ac_env_CFLAGS_value=$CFLAGS ac_cv_env_CFLAGS_set=${CFLAGS+set} ac_cv_env_CFLAGS_value=$CFLAGS ac_env_LDFLAGS_set=${LDFLAGS+set} ac_env_LDFLAGS_value=$LDFLAGS ac_cv_env_LDFLAGS_set=${LDFLAGS+set} ac_cv_env_LDFLAGS_value=$LDFLAGS ac_env_CPPFLAGS_set=${CPPFLAGS+set} ac_env_CPPFLAGS_value=$CPPFLAGS ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} ac_cv_env_CPPFLAGS_value=$CPPFLAGS ac_env_CPP_set=${CPP+set} ac_env_CPP_value=$CPP ac_cv_env_CPP_set=${CPP+set} ac_cv_env_CPP_value=$CPP # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures lyskom-server 2.1.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] _ACEOF cat <<_ACEOF Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data [PREFIX/share] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --infodir=DIR info documentation [PREFIX/info] --mandir=DIR man documentation [PREFIX/man] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of lyskom-server 2.1.2:";; esac cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-malloc-guards disable defensive guard areas (may crash lyskomd) --enable-ipv6 enable IPv6 support --disable-dependency-tracking Speeds up one-time builds --enable-dependency-tracking Do not reject slow dependency extractors Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-debug-calls compile debug protocol requests --with-efence link with ElectricFence --with-insure++ compile with ParaSoft Insure++ --with-checker compile with Gnu Checker --with-valgrind=PATH use valgrind when running tests --with-gcov instrument for gcov (requires gcc) --with-traced-allocations trace allocations (see src/server/ram-smalloc.c) --with-optimization select level of optimization --with-language=sv select Swedish database (default English) Some influential environment variables: AR ar program to use CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. _ACEOF fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. ac_popdir=`pwd` for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d $ac_dir || continue ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be # absolute. ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` cd $ac_dir # Check for guested configure; otherwise get Cygnus style configure. if test -f $ac_srcdir/configure.gnu; then echo $SHELL $ac_srcdir/configure.gnu --help=recursive elif test -f $ac_srcdir/configure; then echo $SHELL $ac_srcdir/configure --help=recursive elif test -f $ac_srcdir/configure.ac || test -f $ac_srcdir/configure.in; then echo $ac_configure --help else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi cd $ac_popdir done fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF lyskom-server configure 2.1.2 generated by GNU Autoconf 2.57 Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit 0 fi exec 5>config.log cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by lyskom-server $as_me 2.1.2, which was generated by GNU Autoconf 2.57. Invocation command line was $ $0 $@ _ACEOF { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` hostinfo = `(hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_sep= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" # Get rid of the leading space. ac_sep=" " ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Be sure not to use single quotes in there, as some shells, # such as our DU 5.0 friend, will then `close' the trap. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, { (set) 2>&1 | case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in *ac_space=\ *) sed -n \ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" ;; *) sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------- ## ## Output files. ## ## ------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo sed "/^$/d" confdefs.h | sort echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core core.* *.core && rm -rf conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo >confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . $cache_file;; *) . ./$cache_file;; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in `(set) 2>&1 | sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val="\$ac_cv_env_${ac_var}_value" eval ac_new_val="\$ac_env_${ac_var}_value" case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" ac_aux_dir= for ac_dir in scripts $srcdir/scripts; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f $ac_dir/shtool; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in scripts $srcdir/scripts" >&5 echo "$as_me: error: cannot find install-sh or install.sh in scripts $srcdir/scripts" >&2;} { (exit 1); exit 1; }; } fi ac_config_guess="$SHELL $ac_aux_dir/config.guess" ac_config_sub="$SHELL $ac_aux_dir/config.sub" ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. am__api_version="1.7" # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL=$ac_install_sh fi fi echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo "$as_me:$LINENO: checking whether build environment is sane" >&5 echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6 # Just in case sleep 1 echo timestamp > conftest.file # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&5 echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&2;} { (exit 1); exit 1; }; } fi test "$2" = conftest.file ) then # Ok. : else { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! Check your system clock" >&5 echo "$as_me: error: newly created file is older than distributed files! Check your system clock" >&2;} { (exit 1); exit 1; }; } fi echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 test "$program_prefix" != NONE && program_transform_name="s,^,$program_prefix,;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s,\$,$program_suffix,;$program_transform_name" # Double any \ or $. echo might interpret backslashes. # By default was `s,x,x', remove it if useless. cat <<\_ACEOF >conftest.sed s/[\\$]/&&/g;s/;s,x,x,$// _ACEOF program_transform_name=`echo $program_transform_name | sed -f conftest.sed` rm conftest.sed # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_AWK+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then echo "$as_me:$LINENO: result: $AWK" >&5 echo "${ECHO_T}$AWK" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$AWK" && break done echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'` if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.make <<\_ACEOF all: @echo 'ac_maketemp="$(MAKE)"' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` if test -n "$ac_maketemp"; then eval ac_cv_prog_make_${ac_make}_set=yes else eval ac_cv_prog_make_${ac_make}_set=no fi rm -f conftest.make fi if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 SET_MAKE= else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} { (exit 1); exit 1; }; } fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='lyskom-server' VERSION='2.1.2' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} AMTAR=${AMTAR-"${am_missing_run}tar"} install_sh=${install_sh-"$am_aux_dir/install-sh"} # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then echo "$as_me:$LINENO: result: $STRIP" >&5 echo "${ECHO_T}$STRIP" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 echo "${ECHO_T}$ac_ct_STRIP" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi STRIP=$ac_ct_STRIP else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Check whether --with-debug-calls or --without-debug-calls was given. if test "${with_debug_calls+set}" = set; then withval="$with_debug_calls" use_debug_calls=$withval else use_debug_calls=no fi; # Check whether --with-efence or --without-efence was given. if test "${with_efence+set}" = set; then withval="$with_efence" use_efence=$withval else use_efence=no fi; # Check whether --with-insure++ or --without-insure++ was given. if test "${with_insure+++set}" = set; then withval="$with_insure++" use_insure=$withval else use_insure=no fi; # Check whether --with-checker or --without-checker was given. if test "${with_checker+set}" = set; then withval="$with_checker" use_checker=$withval else use_checker=no fi; # Check whether --with-valgrind or --without-valgrind was given. if test "${with_valgrind+set}" = set; then withval="$with_valgrind" use_valgrind=$withval else use_valgrind=no fi; # Check whether --enable-malloc-guards or --disable-malloc-guards was given. if test "${enable_malloc_guards+set}" = set; then enableval="$enable_malloc_guards" use_malloc_guards=$enableval else use_malloc_guards=yes fi; # Check whether --enable-ipv6 or --disable-ipv6 was given. if test "${enable_ipv6+set}" = set; then enableval="$enable_ipv6" use_inet6=yes else use_inet6=no fi; # Check whether --with-gcov or --without-gcov was given. if test "${with_gcov+set}" = set; then withval="$with_gcov" use_gcov=$withval else use_gcov=no fi; # Check whether --with-traced-allocations or --without-traced-allocations was given. if test "${with_traced_allocations+set}" = set; then withval="$with_traced_allocations" use_traced_allocations=$withval else use_traced_allocations=no fi; # Check whether --with-optimization or --without-optimization was given. if test "${with_optimization+set}" = set; then withval="$with_optimization" opt_level=$withval else opt_level="" fi; # Check whether --with-language or --without-language was given. if test "${with_language+set}" = set; then withval="$with_language" language=$withval else language=en fi; case "$language" in en) LANGUAGE_SUFFIX=-en;; sv) LANGUAGE_SUFFIX=;; *) { { echo "$as_me:$LINENO: error: bad value $language for --with-language" >&5 echo "$as_me: error: bad value $language for --with-language" >&2;} { (exit 1); exit 1; }; };; esac if test "$use_valgrind" = "yes" then VALGRIND=valgrind elif test "$use_valgrind" = "no" then VALGRIND= else case "$use_valgrind" in /*) VALGRIND="$use_valgrind";; *) { { echo "$as_me:$LINENO: error: invalid --with-valgrind argument $use_valgrind" >&5 echo "$as_me: error: invalid --with-valgrind argument $use_valgrind" >&2;} { (exit 1); exit 1; }; } ;; esac fi if test "$use_malloc_guards" = "yes" then cat >>confdefs.h <<\_ACEOF #define USE_MALLOC_GUARDS 1 _ACEOF fi # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_path_AR+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $AR in [\\/]* | ?:[\\/]*) ac_cv_path_AR="$AR" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/ccs/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_AR="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done test -z "$ac_cv_path_AR" && ac_cv_path_AR="notfound" ;; esac fi AR=$ac_cv_path_AR if test -n "$AR"; then echo "$as_me:$LINENO: result: $AR" >&5 echo "${ECHO_T}$AR" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi if test "$AR" = "notfound"; then { { echo "$as_me:$LINENO: error: cannot find \`\`ar''" >&5 echo "$as_me: error: cannot find \`\`ar''" >&2;} { (exit 1); exit 1; }; } fi # Extract the first word of "sendmail", so it can be a program name with args. set dummy sendmail; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_path_SENDMAIL+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $SENDMAIL in [\\/]* | ?:[\\/]*) ac_cv_path_SENDMAIL="$SENDMAIL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/lib$PATH_SEPARATOR/usr/sbin$PATH_SEPARATOR/etc do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_SENDMAIL="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done test -z "$ac_cv_path_SENDMAIL" && ac_cv_path_SENDMAIL="no" ;; esac fi SENDMAIL=$ac_cv_path_SENDMAIL if test -n "$SENDMAIL"; then echo "$as_me:$LINENO: result: $SENDMAIL" >&5 echo "${ECHO_T}$SENDMAIL" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi if test "$SENDMAIL" = "no"; then SENDMAIL=: { echo "$as_me:$LINENO: WARNING: updateLysKOM will not send mail since no sendmail was found" >&5 echo "$as_me: WARNING: updateLysKOM will not send mail since no sendmail was found" >&2;} fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$ac_ct_CC" && break done CC=$ac_ct_CC fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO:" \ "checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 (eval $ac_compiler --version &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 (eval $ac_compiler -v &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 (eval $ac_compiler -V &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. echo "$as_me:$LINENO: checking for C compiler default output" >&5 echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6 ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 (eval $ac_link_default) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Find the output, starting from the most likely. This scheme is # not robust to junk in `.', hence go to wildcards (a.*) only as a last # resort. # Be careful to initialize this variable, since it used to be cached. # Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. ac_cv_exeext= # b.out is created by i960 compilers. for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; conftest.$ac_ext ) # This is the source file. ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` # FIXME: I believe we export ac_cv_exeext for Libtool, # but it would be cool to find out if it's true. Does anybody # maintain Libtool? --akim. export ac_cv_exeext break;; * ) break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6 # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether the C compiler works" >&5 echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6 echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` export ac_cv_exeext break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6 rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6 OBJEXT=$ac_cv_objext ac_objext=$OBJEXT echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS CFLAGS="-g" echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_prog_cc_g=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 if test "${ac_cv_prog_cc_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_stdc=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF # Don't try gcc -ansi; that turns off useful extensions and # breaks some systems' header files. # AIX -qlanglvl=ansi # Ultrix and OSF/1 -std1 # HP-UX 10.20 and later -Ae # HP-UX older versions -Aa -D_HPUX_SOURCE # SVR4 -Xc -D__EXTENSIONS__ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_stdc=$ac_arg break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext done rm -f conftest.$ac_ext conftest.$ac_objext CC=$ac_save_CC fi case "x$ac_cv_prog_cc_stdc" in x|xno) echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6 ;; *) echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 CC="$CC $ac_cv_prog_cc_stdc" ;; esac # Some people use a C++ compiler to compile C. Since we use `exit', # in C++ we need to declare it. In case someone uses the same compiler # for both compiling C and C++ we need to have the C++ compiler decide # the declaration of exit, since it's the most demanding environment. cat >conftest.$ac_ext <<_ACEOF #ifndef __cplusplus choke me #endif _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then for ac_declaration in \ ''\ '#include ' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int);' \ 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 continue fi rm -f conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest.$ac_ext done rm -f conftest* if test -n "$ac_declaration"; then echo '#ifdef __cplusplus' >>confdefs.h echo $ac_declaration >>confdefs.h echo '#endif' >>confdefs.h fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6 am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi echo "$as_me:$LINENO: result: $_am_result" >&5 echo "${ECHO_T}$_am_result" >&6 rm -f confinc confmf # Check whether --enable-dependency-tracking or --disable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then enableval="$enable_dependency_tracking" fi; if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c : > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # (even with -Werror). So we grep stderr for any message # that says an option was ignored. if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6 CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$CPP" >&6 ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6 if test "${ac_cv_prog_egrep+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | (grep -E '(a|b)') >/dev/null 2>&1 then ac_cv_prog_egrep='grep -E' else ac_cv_prog_egrep='egrep' fi fi echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 echo "${ECHO_T}$ac_cv_prog_egrep" >&6 EGREP=$ac_cv_prog_egrep echo "$as_me:$LINENO: checking for AIX" >&5 echo $ECHO_N "checking for AIX... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef _AIX yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 cat >>confdefs.h <<\_ACEOF #define _ALL_SOURCE 1 _ACEOF else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi rm -f conftest* echo "$as_me:$LINENO: checking for library containing strerror" >&5 echo $ECHO_N "checking for library containing strerror... $ECHO_C" >&6 if test "${ac_cv_search_strerror+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS ac_cv_search_strerror=no cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char strerror (); int main () { strerror (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_strerror="none required" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext if test "$ac_cv_search_strerror" = no; then for ac_lib in cposix; do LIBS="-l$ac_lib $ac_func_search_save_LIBS" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char strerror (); int main () { strerror (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_strerror="-l$ac_lib" break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext done fi LIBS=$ac_func_search_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_search_strerror" >&5 echo "${ECHO_T}$ac_cv_search_strerror" >&6 if test "$ac_cv_search_strerror" != no; then test "$ac_cv_search_strerror" = "none required" || LIBS="$ac_cv_search_strerror $LIBS" fi echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6 if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done if test "${ac_cv_header_minix_config_h+set}" = set; then echo "$as_me:$LINENO: checking for minix/config.h" >&5 echo $ECHO_N "checking for minix/config.h... $ECHO_C" >&6 if test "${ac_cv_header_minix_config_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5 echo "${ECHO_T}$ac_cv_header_minix_config_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking minix/config.h usability" >&5 echo $ECHO_N "checking minix/config.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking minix/config.h presence" >&5 echo $ECHO_N "checking minix/config.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc in yes:no ) { echo "$as_me:$LINENO: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: minix/config.h: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; no:yes ) { echo "$as_me:$LINENO: WARNING: minix/config.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: minix/config.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: minix/config.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: minix/config.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: minix/config.h: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for minix/config.h" >&5 echo $ECHO_N "checking for minix/config.h... $ECHO_C" >&6 if test "${ac_cv_header_minix_config_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_minix_config_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5 echo "${ECHO_T}$ac_cv_header_minix_config_h" >&6 fi if test $ac_cv_header_minix_config_h = yes; then MINIX=yes else MINIX= fi if test "$MINIX" = yes; then cat >>confdefs.h <<\_ACEOF #define _POSIX_SOURCE 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _POSIX_1_SOURCE 2 _ACEOF cat >>confdefs.h <<\_ACEOF #define _MINIX 1 _ACEOF fi echo "$as_me:$LINENO: checking for ${CC-cc} option to accept ANSI C" >&5 echo $ECHO_N "checking for ${CC-cc} option to accept ANSI C... $ECHO_C" >&6 if test "${am_cv_prog_cc_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else am_cv_prog_cc_stdc=no ac_save_CC="$CC" # Don't try gcc -ansi; that turns off useful extensions and # breaks some systems' header files. # AIX -qlanglvl=ansi # Ultrix and OSF/1 -std1 # HP-UX 10.20 and later -Ae # HP-UX older versions -Aa -D_HPUX_SOURCE # SVR4 -Xc -D__EXTENSIONS__ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then am_cv_prog_cc_stdc="$ac_arg"; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest.$ac_ext done CC="$ac_save_CC" fi if test -z "$am_cv_prog_cc_stdc"; then echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6 else echo "$as_me:$LINENO: result: $am_cv_prog_cc_stdc" >&5 echo "${ECHO_T}$am_cv_prog_cc_stdc" >&6 fi case "x$am_cv_prog_cc_stdc" in x|xno) ;; *) CC="$CC $am_cv_prog_cc_stdc" ;; esac echo "$as_me:$LINENO: checking for function prototypes" >&5 echo $ECHO_N "checking for function prototypes... $ECHO_C" >&6 if test "$am_cv_prog_cc_stdc" != no; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 cat >>confdefs.h <<\_ACEOF #define PROTOTYPES 1 _ACEOF U= ANSI2KNR= else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 U=_ ANSI2KNR=./ansi2knr fi # Ensure some checks needed by ansi2knr itself. echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6 if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi for ac_header in string.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc in yes:no ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; no:yes ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # Find any Python interpreter. # Extract the first word of "python python2 python2.3 python2.2 python2.1 python2.0 python1.6 python1.5", so it can be a program name with args. set dummy python python2 python2.3 python2.2 python2.1 python2.0 python1.6 python1.5; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_path_PYTHON+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $PYTHON in [\\/]* | ?:[\\/]*) ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done ;; esac fi PYTHON=$ac_cv_path_PYTHON if test -n "$PYTHON"; then echo "$as_me:$LINENO: result: $PYTHON" >&5 echo "${ECHO_T}$PYTHON" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi am_display_PYTHON=python if test -n "$PYTHON"; then echo "$as_me:$LINENO: checking for $am_display_PYTHON version" >&5 echo $ECHO_N "checking for $am_display_PYTHON version... $ECHO_C" >&6 if test "${am_cv_python_version+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else am_cv_python_version=`$PYTHON -c "import sys; print sys.version[:3]"` fi echo "$as_me:$LINENO: result: $am_cv_python_version" >&5 echo "${ECHO_T}$am_cv_python_version" >&6 else am_cv_python_version=none; fi PYTHON_VERSION=$am_cv_python_version PYTHON_PREFIX='${prefix}' PYTHON_EXEC_PREFIX='${exec_prefix}' if test -n "$PYTHON"; then echo "$as_me:$LINENO: checking for $am_display_PYTHON platform" >&5 echo $ECHO_N "checking for $am_display_PYTHON platform... $ECHO_C" >&6 if test "${am_cv_python_platform+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else am_cv_python_platform=`$PYTHON -c "import sys; print sys.platform"` fi echo "$as_me:$LINENO: result: $am_cv_python_platform" >&5 echo "${ECHO_T}$am_cv_python_platform" >&6 else am_cv_python_platform=none; fi PYTHON_PLATFORM=$am_cv_python_platform if test -n "$PYTHON"; then echo "$as_me:$LINENO: checking for $am_display_PYTHON script directory" >&5 echo $ECHO_N "checking for $am_display_PYTHON script directory... $ECHO_C" >&6 if test "${am_cv_python_pythondir+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else am_cv_python_pythondir=`$PYTHON -c "from distutils import sysconfig; print sysconfig.get_python_lib(0,0,prefix='$PYTHON_PREFIX')" 2>/dev/null || echo "$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages"` fi echo "$as_me:$LINENO: result: $am_cv_python_pythondir" >&5 echo "${ECHO_T}$am_cv_python_pythondir" >&6 else am_cv_python_pythondir=none; fi pythondir=$am_cv_python_pythondir pkgpythondir=\${pythondir}/$PACKAGE if test -n "$PYTHON"; then echo "$as_me:$LINENO: checking for $am_display_PYTHON extension module directory" >&5 echo $ECHO_N "checking for $am_display_PYTHON extension module directory... $ECHO_C" >&6 if test "${am_cv_python_pyexecdir+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else am_cv_python_pyexecdir=`$PYTHON -c "from distutils import sysconfig; print sysconfig.get_python_lib(1,0,prefix='$PYTHON_EXEC_PREFIX')" 2>/dev/null || echo "${PYTHON_EXEC_PREFIX}/lib/python${PYTHON_VERSION}/site-packages"` fi echo "$as_me:$LINENO: result: $am_cv_python_pyexecdir" >&5 echo "${ECHO_T}$am_cv_python_pyexecdir" >&6 else am_cv_python_pyexecdir=none; fi pyexecdir=$am_cv_python_pyexecdir pkgpyexecdir=\${pyexecdir}/$PACKAGE if test -n "$PYTHON"; then HAVE_PYTHON_TRUE= HAVE_PYTHON_FALSE='#' else HAVE_PYTHON_TRUE='#' HAVE_PYTHON_FALSE= fi if test -n "$GCC"; then CFLAGS="$CFLAGS -Wall -W" echo "$as_me:$LINENO: checking whether ${CC} accepts -Wbad-function-cast" >&5 echo $ECHO_N "checking whether ${CC} accepts -Wbad-function-cast... $ECHO_C" >&6 if test "${cmod_cv_compiler_bad_function_cast+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cmod_oldflags=$CFLAGS CFLAGS="$CFLAGS -Wbad-function-cast" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cmod_cv_compiler_bad_function_cast=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cmod_cv_compiler_bad_function_cast=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext CFLAGS=$cmod_oldflags fi echo "$as_me:$LINENO: result: $cmod_cv_compiler_bad_function_cast" >&5 echo "${ECHO_T}$cmod_cv_compiler_bad_function_cast" >&6 if test $cmod_cv_compiler_bad_function_cast = yes; then CFLAGS="$CFLAGS -Wbad-function-cast" fi echo "$as_me:$LINENO: checking whether ${CC} accepts -Wcast-align" >&5 echo $ECHO_N "checking whether ${CC} accepts -Wcast-align... $ECHO_C" >&6 if test "${cmod_cv_compiler_cast_align+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cmod_oldflags=$CFLAGS CFLAGS="$CFLAGS -Wcast-align" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cmod_cv_compiler_cast_align=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cmod_cv_compiler_cast_align=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext CFLAGS=$cmod_oldflags fi echo "$as_me:$LINENO: result: $cmod_cv_compiler_cast_align" >&5 echo "${ECHO_T}$cmod_cv_compiler_cast_align" >&6 if test $cmod_cv_compiler_cast_align = yes; then CFLAGS="$CFLAGS -Wcast-align" fi echo "$as_me:$LINENO: checking whether ${CC} accepts -Wwrite-strings" >&5 echo $ECHO_N "checking whether ${CC} accepts -Wwrite-strings... $ECHO_C" >&6 if test "${cmod_cv_compiler_write_strings+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cmod_oldflags=$CFLAGS CFLAGS="$CFLAGS -Wwrite-strings" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cmod_cv_compiler_write_strings=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cmod_cv_compiler_write_strings=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext CFLAGS=$cmod_oldflags fi echo "$as_me:$LINENO: result: $cmod_cv_compiler_write_strings" >&5 echo "${ECHO_T}$cmod_cv_compiler_write_strings" >&6 if test $cmod_cv_compiler_write_strings = yes; then CFLAGS="$CFLAGS -Wwrite-strings" fi echo "$as_me:$LINENO: checking whether ${CC} accepts -Wstrict-prototypes" >&5 echo $ECHO_N "checking whether ${CC} accepts -Wstrict-prototypes... $ECHO_C" >&6 if test "${cmod_cv_compiler_strict_prototypes+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cmod_oldflags=$CFLAGS CFLAGS="$CFLAGS -Wstrict-prototypes" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cmod_cv_compiler_strict_prototypes=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cmod_cv_compiler_strict_prototypes=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext CFLAGS=$cmod_oldflags fi echo "$as_me:$LINENO: result: $cmod_cv_compiler_strict_prototypes" >&5 echo "${ECHO_T}$cmod_cv_compiler_strict_prototypes" >&6 if test $cmod_cv_compiler_strict_prototypes = yes; then CFLAGS="$CFLAGS -Wstrict-prototypes" fi echo "$as_me:$LINENO: checking whether ${CC} accepts -Wmissing-prototypes" >&5 echo $ECHO_N "checking whether ${CC} accepts -Wmissing-prototypes... $ECHO_C" >&6 if test "${cmod_cv_compiler_missing_prototypes+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cmod_oldflags=$CFLAGS CFLAGS="$CFLAGS -Wmissing-prototypes" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cmod_cv_compiler_missing_prototypes=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cmod_cv_compiler_missing_prototypes=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext CFLAGS=$cmod_oldflags fi echo "$as_me:$LINENO: result: $cmod_cv_compiler_missing_prototypes" >&5 echo "${ECHO_T}$cmod_cv_compiler_missing_prototypes" >&6 if test $cmod_cv_compiler_missing_prototypes = yes; then CFLAGS="$CFLAGS -Wmissing-prototypes" fi echo "$as_me:$LINENO: checking whether ${CC} accepts -Wmissing-declarations" >&5 echo $ECHO_N "checking whether ${CC} accepts -Wmissing-declarations... $ECHO_C" >&6 if test "${cmod_cv_compiler_missing_declarations+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cmod_oldflags=$CFLAGS CFLAGS="$CFLAGS -Wmissing-declarations" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cmod_cv_compiler_missing_declarations=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cmod_cv_compiler_missing_declarations=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext CFLAGS=$cmod_oldflags fi echo "$as_me:$LINENO: result: $cmod_cv_compiler_missing_declarations" >&5 echo "${ECHO_T}$cmod_cv_compiler_missing_declarations" >&6 if test $cmod_cv_compiler_missing_declarations = yes; then CFLAGS="$CFLAGS -Wmissing-declarations" fi echo "$as_me:$LINENO: checking whether ${CC} accepts -Wfloat-equal" >&5 echo $ECHO_N "checking whether ${CC} accepts -Wfloat-equal... $ECHO_C" >&6 if test "${cmod_cv_compiler_float_equal+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cmod_oldflags=$CFLAGS CFLAGS="$CFLAGS -Wfloat-equal" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cmod_cv_compiler_float_equal=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cmod_cv_compiler_float_equal=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext CFLAGS=$cmod_oldflags fi echo "$as_me:$LINENO: result: $cmod_cv_compiler_float_equal" >&5 echo "${ECHO_T}$cmod_cv_compiler_float_equal" >&6 if test $cmod_cv_compiler_float_equal = yes; then CFLAGS="$CFLAGS -Wfloat-equal" fi echo "$as_me:$LINENO: checking whether ${CC} accepts -pipe" >&5 echo $ECHO_N "checking whether ${CC} accepts -pipe... $ECHO_C" >&6 if test "${cmod_cv_compiler_pipe+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cmod_oldflags=$CFLAGS CFLAGS="$CFLAGS -pipe" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cmod_cv_compiler_pipe=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cmod_cv_compiler_pipe=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext CFLAGS=$cmod_oldflags fi echo "$as_me:$LINENO: result: $cmod_cv_compiler_pipe" >&5 echo "${ECHO_T}$cmod_cv_compiler_pipe" >&6 if test $cmod_cv_compiler_pipe = yes; then CFLAGS="$CFLAGS -pipe" fi fi if test "$use_efence" = "yes" then echo "$as_me:$LINENO: checking for malloc in -lefence" >&5 echo $ECHO_N "checking for malloc in -lefence... $ECHO_C" >&6 if test "${ac_cv_lib_efence_malloc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lefence $LIBS" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char malloc (); int main () { malloc (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_efence_malloc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_efence_malloc=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_efence_malloc" >&5 echo "${ECHO_T}$ac_cv_lib_efence_malloc" >&6 if test $ac_cv_lib_efence_malloc = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBEFENCE 1 _ACEOF LIBS="-lefence $LIBS" fi EFENCE=1 fi if test "$use_traced_allocations" = "yes" then cat >>confdefs.h <<\_ACEOF #define TRACED_ALLOCATIONS 1 _ACEOF fi if test "$use_debug_calls" = "yes" then cat >>confdefs.h <<\_ACEOF #define DEBUG_CALLS 1 _ACEOF for ac_func in mallinfo do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done fi if test "$use_gcov" = "yes" && test -n "$GCC"; then echo "$as_me:$LINENO: checking whether ${CC} accepts -ftest-coverage" >&5 echo $ECHO_N "checking whether ${CC} accepts -ftest-coverage... $ECHO_C" >&6 if test "${cmod_cv_compiler_test_coverage+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cmod_oldflags=$CFLAGS CFLAGS="$CFLAGS -ftest-coverage" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cmod_cv_compiler_test_coverage=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cmod_cv_compiler_test_coverage=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext CFLAGS=$cmod_oldflags fi echo "$as_me:$LINENO: result: $cmod_cv_compiler_test_coverage" >&5 echo "${ECHO_T}$cmod_cv_compiler_test_coverage" >&6 if test $cmod_cv_compiler_test_coverage = yes; then CFLAGS="$CFLAGS -ftest-coverage" fi echo "$as_me:$LINENO: checking whether ${CC} accepts -fprofile-arcs" >&5 echo $ECHO_N "checking whether ${CC} accepts -fprofile-arcs... $ECHO_C" >&6 if test "${cmod_cv_compiler_profile_arcs+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cmod_oldflags=$CFLAGS CFLAGS="$CFLAGS -fprofile-arcs" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cmod_cv_compiler_profile_arcs=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cmod_cv_compiler_profile_arcs=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext CFLAGS=$cmod_oldflags fi echo "$as_me:$LINENO: result: $cmod_cv_compiler_profile_arcs" >&5 echo "${ECHO_T}$cmod_cv_compiler_profile_arcs" >&6 if test $cmod_cv_compiler_profile_arcs = yes; then CFLAGS="$CFLAGS -fprofile-arcs" fi cat >>confdefs.h <<\_ACEOF #define AVOID_ABORTS 1 _ACEOF fi if test -n "$opt_level" -a "$opt_level" != "yes" ; then CFLAGS=`echo "$CFLAGS" | sed "s/-O[0-9]*//"` if test "$opt_level" != "no" ; then CFLAGS="$CFLAGS -O$opt_level" fi fi # Do this test early since it may define _POSIX_SOURCE, which may # affect future tests. # FIXME (bug 210): is this needed, now that we use AM_C_PROTOTYPES? echo "$as_me:$LINENO: checking if defines struct sigaction" >&5 echo $ECHO_N "checking if defines struct sigaction... $ECHO_C" >&6 if test "${kom_cv_header_posix_source_needed+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # This default may be overridden below. kom_cv_header_posix_source_needed=no fi if test "${kom_cv_struct_sigaction+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { struct sigaction foosig; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then kom_cv_struct_sigaction=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 kom_cv_struct_sigaction=no fi rm -f conftest.$ac_objext conftest.$ac_ext if test $kom_cv_struct_sigaction = no ; then cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _POSIX_SOURCE #include int main () { struct sigaction barsig; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then kom_cv_struct_sigaction=yes kom_cv_header_posix_source_needed=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 kom_cv_struct_sigaction=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi fi if test $kom_cv_header_posix_source_needed = yes ; then echo "$as_me:$LINENO: result: yes, but _POSIX_SOURCE was needed" >&5 echo "${ECHO_T}yes, but _POSIX_SOURCE was needed" >&6 cat >>confdefs.h <<\_ACEOF #define _POSIX_SOURCE 1 _ACEOF else echo "$as_me:$LINENO: result: $kom_cv_struct_sigaction" >&5 echo "${ECHO_T}$kom_cv_struct_sigaction" >&6 fi if test $kom_cv_struct_sigaction = yes ; then cat >>confdefs.h <<\_ACEOF #define HAVE_STRUCT_SIGACTION 1 _ACEOF fi echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6 if test "${ac_cv_c_const+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { /* FIXME: Include the comments suggested by Paul. */ #ifndef __cplusplus /* Ultrix mips cc rejects this. */ typedef int charset[2]; const charset x; /* SunOS 4.1.1 cc rejects this. */ char const *const *ccp; char **p; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; ccp = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++ccp; p = (char**) ccp; ccp = (char const *const *) p; { /* SCO 3.2v4 cc rejects this. */ char *t; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; }; struct s *b; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; } #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_const=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_const=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 echo "${ECHO_T}$ac_cv_c_const" >&6 if test $ac_cv_c_const = no; then cat >>confdefs.h <<\_ACEOF #define const _ACEOF fi echo "$as_me:$LINENO: checking for inline" >&5 echo $ECHO_N "checking for inline... $ECHO_C" >&6 if test "${ac_cv_c_inline+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_inline=$ac_kw; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest.$ac_ext done fi echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 echo "${ECHO_T}$ac_cv_c_inline" >&6 case $ac_cv_c_inline in inline | yes) ;; no) cat >>confdefs.h <<\_ACEOF #define inline _ACEOF ;; *) cat >>confdefs.h <<_ACEOF #define inline $ac_cv_c_inline _ACEOF ;; esac echo "$as_me:$LINENO: checking whether $CC understands __attribute__((unused))" >&5 echo $ECHO_N "checking whether $CC understands __attribute__((unused))... $ECHO_C" >&6 if test "${cmod_cv_c_working_attribute_unused+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int cmod_x(int y __attribute__((unused))) { return 7; } int main () { int i __attribute__((unused)); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cmod_cv_c_working_attribute_unused=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cmod_cv_c_working_attribute_unused=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $cmod_cv_c_working_attribute_unused" >&5 echo "${ECHO_T}$cmod_cv_c_working_attribute_unused" >&6 if test $cmod_cv_c_working_attribute_unused = yes ; then cat >>confdefs.h <<\_ACEOF #define HAVE_ATTRIBUTE_UNUSED 1 _ACEOF fi echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6 if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi echo "$as_me:$LINENO: checking for pid_t" >&5 echo $ECHO_N "checking for pid_t... $ECHO_C" >&6 if test "${ac_cv_type_pid_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if ((pid_t *) 0) return 0; if (sizeof (pid_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_pid_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_pid_t=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5 echo "${ECHO_T}$ac_cv_type_pid_t" >&6 if test $ac_cv_type_pid_t = yes; then : else cat >>confdefs.h <<_ACEOF #define pid_t int _ACEOF fi echo "$as_me:$LINENO: checking if sig_atomic_t exists" >&5 echo $ECHO_N "checking if sig_atomic_t exists... $ECHO_C" >&6 if test "${kom_cv_type_sig_atomic_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { sig_atomic_t t; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then kom_cv_type_sig_atomic_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 kom_cv_type_sig_atomic_t=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $kom_cv_type_sig_atomic_t" >&5 echo "${ECHO_T}$kom_cv_type_sig_atomic_t" >&6 if test $kom_cv_type_sig_atomic_t = no then cat >>confdefs.h <<\_ACEOF #define sig_atomic_t int _ACEOF fi # FIXME (bug 209): is this needed now that we use AM_C_PROTOTYPES? echo "$as_me:$LINENO: checking if _HPUX_SOURCE needs to be defined" >&5 echo $ECHO_N "checking if _HPUX_SOURCE needs to be defined... $ECHO_C" >&6 if test "${kom_cv_sys_hpux_source+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { struct sockaddr foo; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then kom_cv_sys_hpux_source=no else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _HPUX_SOURCE #include #include int main () { struct sockaddr foo; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then kom_cv_sys_hpux_source=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 kom_cv_sys_hpux_source=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $kom_cv_sys_hpux_source" >&5 echo "${ECHO_T}$kom_cv_sys_hpux_source" >&6 if test $kom_cv_sys_hpux_source = yes ; then cat >>confdefs.h <<\_ACEOF #define _HPUX_SOURCE 1 _ACEOF fi echo "$as_me:$LINENO: checking if the compiler understands __attribute__ ((format))" >&5 echo $ECHO_N "checking if the compiler understands __attribute__ ((format))... $ECHO_C" >&6 if test "${kom_cv_c_attribute_format_printf+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ extern void log (const char *f, ...) __attribute__ ((format (printf, 1, 2))); int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then kom_cv_c_attribute_format_printf=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 kom_cv_c_attribute_format_printf=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $kom_cv_c_attribute_format_printf" >&5 echo "${ECHO_T}$kom_cv_c_attribute_format_printf" >&6 if test $kom_cv_c_attribute_format_printf = yes ; then cat >>confdefs.h <<\_ACEOF #define HAVE_ATTRIBUTE_FORMAT_PRINTF 1 _ACEOF fi echo "$as_me:$LINENO: checking if the compiler understands __attribute__ ((__noreturn__))" >&5 echo $ECHO_N "checking if the compiler understands __attribute__ ((__noreturn__))... $ECHO_C" >&6 if test "${kom_cv_c_attribute_noreturn+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ extern void log (const char *f, ...) __attribute__ ((__noreturn__)); int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then kom_cv_c_attribute_noreturn=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 kom_cv_c_attribute_noreturn=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $kom_cv_c_attribute_noreturn" >&5 echo "${ECHO_T}$kom_cv_c_attribute_noreturn" >&6 if test $kom_cv_c_attribute_noreturn = yes ; then cat >>confdefs.h <<\_ACEOF #define HAVE_ATTRIBUTE_NORETURN 1 _ACEOF fi # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL=$ac_install_sh fi fi echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then echo "$as_me:$LINENO: result: $RANLIB" >&5 echo "${ECHO_T}$RANLIB" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 echo "${ECHO_T}$ac_ct_RANLIB" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi RANLIB=$ac_ct_RANLIB else RANLIB="$ac_cv_prog_RANLIB" fi for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_AWK+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then echo "$as_me:$LINENO: result: $AWK" >&5 echo "${ECHO_T}$AWK" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$AWK" && break done echo "$as_me:$LINENO: checking whether ln -s works" >&5 echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6 LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 else echo "$as_me:$LINENO: result: no, using $LN_S" >&5 echo "${ECHO_T}no, using $LN_S" >&6 fi for ac_prog in 'bison -y' byacc do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_YACC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$YACC"; then ac_cv_prog_YACC="$YACC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_YACC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi YACC=$ac_cv_prog_YACC if test -n "$YACC"; then echo "$as_me:$LINENO: result: $YACC" >&5 echo "${ECHO_T}$YACC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$YACC" && break done test -n "$YACC" || YACC="yacc" for ac_prog in flex lex do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_LEX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$LEX"; then ac_cv_prog_LEX="$LEX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LEX="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi LEX=$ac_cv_prog_LEX if test -n "$LEX"; then echo "$as_me:$LINENO: result: $LEX" >&5 echo "${ECHO_T}$LEX" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$LEX" && break done test -n "$LEX" || LEX=":" if test -z "$LEXLIB" then echo "$as_me:$LINENO: checking for yywrap in -lfl" >&5 echo $ECHO_N "checking for yywrap in -lfl... $ECHO_C" >&6 if test "${ac_cv_lib_fl_yywrap+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lfl $LIBS" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char yywrap (); int main () { yywrap (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_fl_yywrap=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_fl_yywrap=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_fl_yywrap" >&5 echo "${ECHO_T}$ac_cv_lib_fl_yywrap" >&6 if test $ac_cv_lib_fl_yywrap = yes; then LEXLIB="-lfl" else echo "$as_me:$LINENO: checking for yywrap in -ll" >&5 echo $ECHO_N "checking for yywrap in -ll... $ECHO_C" >&6 if test "${ac_cv_lib_l_yywrap+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ll $LIBS" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char yywrap (); int main () { yywrap (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_l_yywrap=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_l_yywrap=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_l_yywrap" >&5 echo "${ECHO_T}$ac_cv_lib_l_yywrap" >&6 if test $ac_cv_lib_l_yywrap = yes; then LEXLIB="-ll" fi fi fi if test "x$LEX" != "x:"; then echo "$as_me:$LINENO: checking lex output file root" >&5 echo $ECHO_N "checking lex output file root... $ECHO_C" >&6 if test "${ac_cv_prog_lex_root+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # The minimal lex program is just a single line: %%. But some broken lexes # (Solaris, I think it was) want two %% lines, so accommodate them. cat >conftest.l <<_ACEOF %% %% _ACEOF { (eval echo "$as_me:$LINENO: \"$LEX conftest.l\"") >&5 (eval $LEX conftest.l) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } if test -f lex.yy.c; then ac_cv_prog_lex_root=lex.yy elif test -f lexyy.c; then ac_cv_prog_lex_root=lexyy else { { echo "$as_me:$LINENO: error: cannot find output from $LEX; giving up" >&5 echo "$as_me: error: cannot find output from $LEX; giving up" >&2;} { (exit 1); exit 1; }; } fi fi echo "$as_me:$LINENO: result: $ac_cv_prog_lex_root" >&5 echo "${ECHO_T}$ac_cv_prog_lex_root" >&6 rm -f conftest.l LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root echo "$as_me:$LINENO: checking whether yytext is a pointer" >&5 echo $ECHO_N "checking whether yytext is a pointer... $ECHO_C" >&6 if test "${ac_cv_prog_lex_yytext_pointer+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # POSIX says lex can declare yytext either as a pointer or an array; the # default is implementation-dependent. Figure out which it is, since # not all implementations provide the %pointer and %array declarations. ac_cv_prog_lex_yytext_pointer=no echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c ac_save_LIBS=$LIBS LIBS="$LIBS $LEXLIB" cat >conftest.$ac_ext <<_ACEOF `cat $LEX_OUTPUT_ROOT.c` _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_lex_yytext_pointer=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext LIBS=$ac_save_LIBS rm -f "${LEX_OUTPUT_ROOT}.c" fi echo "$as_me:$LINENO: result: $ac_cv_prog_lex_yytext_pointer" >&5 echo "${ECHO_T}$ac_cv_prog_lex_yytext_pointer" >&6 if test $ac_cv_prog_lex_yytext_pointer = yes; then cat >>confdefs.h <<\_ACEOF #define YYTEXT_POINTER 1 _ACEOF fi fi if test "$LEX" = :; then LEX=${am_missing_run}flex fi for ac_prog in bison do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_BISON+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$BISON"; then ac_cv_prog_BISON="$BISON" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_BISON="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi BISON=$ac_cv_prog_BISON if test -n "$BISON"; then echo "$as_me:$LINENO: result: $BISON" >&5 echo "${ECHO_T}$BISON" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$BISON" && break done for ac_prog in flex do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_FLEX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$FLEX"; then ac_cv_prog_FLEX="$FLEX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_FLEX="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi FLEX=$ac_cv_prog_FLEX if test -n "$FLEX"; then echo "$as_me:$LINENO: result: $FLEX" >&5 echo "${ECHO_T}$FLEX" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$FLEX" && break done for ac_prog in sed do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_SED+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$SED"; then ac_cv_prog_SED="$SED" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_SED="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi SED=$ac_cv_prog_SED if test -n "$SED"; then echo "$as_me:$LINENO: result: $SED" >&5 echo "${ECHO_T}$SED" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$SED" && break done for ac_header in string.h memory.h strings.h sys/param.h sys/time.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc in yes:no ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; no:yes ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in stdarg.h stdlib.h stddef.h locale.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc in yes:no ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; no:yes ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in crypt.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc in yes:no ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; no:yes ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in values.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc in yes:no ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; no:yes ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in stdint.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc in yes:no ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; no:yes ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6 if test "${ac_cv_header_time+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include int main () { if ((struct tm *) 0) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_time=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_time=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 echo "${ECHO_T}$ac_cv_header_time" >&6 if test $ac_cv_header_time = yes; then cat >>confdefs.h <<\_ACEOF #define TIME_WITH_SYS_TIME 1 _ACEOF fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! echo "$as_me:$LINENO: checking for working alloca.h" >&5 echo $ECHO_N "checking for working alloca.h... $ECHO_C" >&6 if test "${ac_cv_working_alloca_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { char *p = (char *) alloca (2 * sizeof (int)); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_working_alloca_h=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_working_alloca_h=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5 echo "${ECHO_T}$ac_cv_working_alloca_h" >&6 if test $ac_cv_working_alloca_h = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_ALLOCA_H 1 _ACEOF fi echo "$as_me:$LINENO: checking for alloca" >&5 echo $ECHO_N "checking for alloca... $ECHO_C" >&6 if test "${ac_cv_func_alloca_works+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __GNUC__ # define alloca __builtin_alloca #else # ifdef _MSC_VER # include # define alloca _alloca # else # if HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ char *alloca (); # endif # endif # endif # endif #endif int main () { char *p = (char *) alloca (1); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_alloca_works=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_alloca_works=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5 echo "${ECHO_T}$ac_cv_func_alloca_works" >&6 if test $ac_cv_func_alloca_works = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_ALLOCA 1 _ACEOF else # The SVR3 libPW and SVR4 libucb both contain incompatible functions # that cause trouble. Some versions do not even contain alloca or # contain a buggy version. If you still want to use their alloca, # use ar to extract alloca.o from them instead of compiling alloca.c. ALLOCA=alloca.$ac_objext cat >>confdefs.h <<\_ACEOF #define C_ALLOCA 1 _ACEOF echo "$as_me:$LINENO: checking whether \`alloca.c' needs Cray hooks" >&5 echo $ECHO_N "checking whether \`alloca.c' needs Cray hooks... $ECHO_C" >&6 if test "${ac_cv_os_cray+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #if defined(CRAY) && ! defined(CRAY2) webecray #else wenotbecray #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "webecray" >/dev/null 2>&1; then ac_cv_os_cray=yes else ac_cv_os_cray=no fi rm -f conftest* fi echo "$as_me:$LINENO: result: $ac_cv_os_cray" >&5 echo "${ECHO_T}$ac_cv_os_cray" >&6 if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define CRAY_STACKSEG_END $ac_func _ACEOF break fi done fi echo "$as_me:$LINENO: checking stack direction for C alloca" >&5 echo $ECHO_N "checking stack direction for C alloca... $ECHO_C" >&6 if test "${ac_cv_c_stack_direction+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then ac_cv_c_stack_direction=0 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int find_stack_direction () { static char *addr = 0; auto char dummy; if (addr == 0) { addr = &dummy; return find_stack_direction (); } else return (&dummy > addr) ? 1 : -1; } int main () { exit (find_stack_direction () < 0); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_stack_direction=1 else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_c_stack_direction=-1 fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $ac_cv_c_stack_direction" >&5 echo "${ECHO_T}$ac_cv_c_stack_direction" >&6 cat >>confdefs.h <<_ACEOF #define STACK_DIRECTION $ac_cv_c_stack_direction _ACEOF fi for ac_header in sys/resource.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef TIME_WITH_SYS_TIME # include # include #else # ifdef HAVE_SYS_TIME_H # include # else # include # endif #endif #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done echo "$as_me:$LINENO: checking for rlim_t" >&5 echo $ECHO_N "checking for rlim_t... $ECHO_C" >&6 if test "${ac_cv_type_rlim_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_SYS_RESOURCE_H # ifdef TIME_WITH_SYS_TIME # include # include # else # ifdef HAVE_SYS_TIME_H # include # else # include # endif # endif # include #endif int main () { if ((rlim_t *) 0) return 0; if (sizeof (rlim_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_rlim_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_rlim_t=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_rlim_t" >&5 echo "${ECHO_T}$ac_cv_type_rlim_t" >&6 if test $ac_cv_type_rlim_t = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_RLIM_T 1 _ACEOF fi echo "$as_me:$LINENO: checking for intptr_t" >&5 echo $ECHO_N "checking for intptr_t... $ECHO_C" >&6 if test "${ac_cv_type_intptr_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if ((intptr_t *) 0) return 0; if (sizeof (intptr_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_intptr_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_intptr_t=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_intptr_t" >&5 echo "${ECHO_T}$ac_cv_type_intptr_t" >&6 echo "$as_me:$LINENO: checking for intmax_t" >&5 echo $ECHO_N "checking for intmax_t... $ECHO_C" >&6 if test "${ac_cv_type_intmax_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if ((intmax_t *) 0) return 0; if (sizeof (intmax_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_intmax_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_intmax_t=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_intmax_t" >&5 echo "${ECHO_T}$ac_cv_type_intmax_t" >&6 echo "$as_me:$LINENO: checking for size_t" >&5 echo $ECHO_N "checking for size_t... $ECHO_C" >&6 if test "${ac_cv_type_size_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if ((size_t *) 0) return 0; if (sizeof (size_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_size_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_size_t=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 echo "${ECHO_T}$ac_cv_type_size_t" >&6 echo "$as_me:$LINENO: checking for main in -lresolv" >&5 echo $ECHO_N "checking for main in -lresolv... $ECHO_C" >&6 if test "${ac_cv_lib_resolv_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lresolv $LIBS" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_resolv_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_resolv_main=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_main" >&5 echo "${ECHO_T}$ac_cv_lib_resolv_main" >&6 if test $ac_cv_lib_resolv_main = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBRESOLV 1 _ACEOF LIBS="-lresolv $LIBS" fi echo "$as_me:$LINENO: checking for auth_tcpuser3 in -lauthuser" >&5 echo $ECHO_N "checking for auth_tcpuser3 in -lauthuser... $ECHO_C" >&6 if test "${ac_cv_lib_authuser_auth_tcpuser3+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lauthuser $LIBS" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char auth_tcpuser3 (); int main () { auth_tcpuser3 (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_authuser_auth_tcpuser3=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_authuser_auth_tcpuser3=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_authuser_auth_tcpuser3" >&5 echo "${ECHO_T}$ac_cv_lib_authuser_auth_tcpuser3" >&6 if test $ac_cv_lib_authuser_auth_tcpuser3 = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBAUTHUSER 1 _ACEOF LIBS="-lauthuser $LIBS" fi echo "$as_me:$LINENO: checking for gethostbyname" >&5 echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6 if test "${ac_cv_func_gethostbyname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* System header to define __stub macros and hopefully few prototypes, which can conflict with char gethostbyname (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostbyname (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_gethostbyname) || defined (__stub___gethostbyname) choke me #else char (*f) () = gethostbyname; #endif #ifdef __cplusplus } #endif int main () { return f != gethostbyname; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_gethostbyname=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_gethostbyname=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5 echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6 if test $ac_cv_func_gethostbyname = no then echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5 echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6 if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostbyname (); int main () { gethostbyname (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_nsl_gethostbyname=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_nsl_gethostbyname=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5 echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6 if test $ac_cv_lib_nsl_gethostbyname = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBNSL 1 _ACEOF LIBS="-lnsl $LIBS" fi fi echo "$as_me:$LINENO: checking for socket" >&5 echo $ECHO_N "checking for socket... $ECHO_C" >&6 if test "${ac_cv_func_socket+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* System header to define __stub macros and hopefully few prototypes, which can conflict with char socket (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char socket (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_socket) || defined (__stub___socket) choke me #else char (*f) () = socket; #endif #ifdef __cplusplus } #endif int main () { return f != socket; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_socket=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_socket=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_socket" >&5 echo "${ECHO_T}$ac_cv_func_socket" >&6 if test $ac_cv_func_socket = no then echo "$as_me:$LINENO: checking for socket in -lsocket" >&5 echo $ECHO_N "checking for socket in -lsocket... $ECHO_C" >&6 if test "${ac_cv_lib_socket_socket+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char socket (); int main () { socket (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_socket_socket=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_socket_socket=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_socket_socket" >&5 echo "${ECHO_T}$ac_cv_lib_socket_socket" >&6 if test $ac_cv_lib_socket_socket = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBSOCKET 1 _ACEOF LIBS="-lsocket $LIBS" fi fi echo "$as_me:$LINENO: checking for setlocale in -li" >&5 echo $ECHO_N "checking for setlocale in -li... $ECHO_C" >&6 if test "${ac_cv_lib_i_setlocale+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-li $LIBS" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char setlocale (); int main () { setlocale (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_i_setlocale=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_i_setlocale=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_i_setlocale" >&5 echo "${ECHO_T}$ac_cv_lib_i_setlocale" >&6 if test $ac_cv_lib_i_setlocale = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBI 1 _ACEOF LIBS="-li $LIBS" fi echo "$as_me:$LINENO: checking for crypt" >&5 echo $ECHO_N "checking for crypt... $ECHO_C" >&6 if test "${ac_cv_func_crypt+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* System header to define __stub macros and hopefully few prototypes, which can conflict with char crypt (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char crypt (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_crypt) || defined (__stub___crypt) choke me #else char (*f) () = crypt; #endif #ifdef __cplusplus } #endif int main () { return f != crypt; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_crypt=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_crypt=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_crypt" >&5 echo "${ECHO_T}$ac_cv_func_crypt" >&6 if test $ac_cv_func_crypt = no then echo "$as_me:$LINENO: checking for crypt in -lcrypt" >&5 echo $ECHO_N "checking for crypt in -lcrypt... $ECHO_C" >&6 if test "${ac_cv_lib_crypt_crypt+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char crypt (); int main () { crypt (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_crypt_crypt=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_crypt_crypt=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_crypt_crypt" >&5 echo "${ECHO_T}$ac_cv_lib_crypt_crypt" >&6 if test $ac_cv_lib_crypt_crypt = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBCRYPT 1 _ACEOF LIBS="-lcrypt $LIBS" fi fi for ac_func in difftime getdtablesize sysconf strchr getcwd vfprintf do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in setrlimit do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in snprintf do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in memcpy strerror remove memset memchr memcmp setsid do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF else LIBOBJS="$LIBOBJS $ac_func.$ac_objext" fi done if test $ac_cv_func_setrlimit = yes then echo "$as_me:$LINENO: checking for working setrlimit(RLIMIT_NOFILE, ...)" >&5 echo $ECHO_N "checking for working setrlimit(RLIMIT_NOFILE, ...)... $ECHO_C" >&6 if test "${kom_cv_func_rlimit_nofile+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then kom_cv_func_rlimit_nofile=no else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #ifdef HAVE_SYS_RESOURCE_H # ifdef TIME_WITH_SYS_TIME # include # include # else # ifdef HAVE_SYS_TIME_H # include # else # include # endif # endif # include #else # include #endif #include #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_OFILE) && !defined(RLIMIT_NOFILE) # define RLIMIT_NOFILE RLIMIT_OFILE #endif #if !HAVE_RLIM_T typedef int rlim_t; #endif int main() { #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE) struct rlimit rlim; int i; int fd; if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) { perror("getrlimit(RLIMIT_NOFILE) failed"); return 1; } rlim.rlim_cur = 20; if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) { perror("setrlimit(RLIMIT_NOFILE) failed"); return 1; } if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) { perror("second getrlimit(RLIMIT_NOFILE) failed"); return 1; } if (rlim.rlim_cur != 20) { fprintf(stderr, "NOFILE set to %ld, not 20\n", (long)rlim.rlim_cur); return 1; } for (i = 0; i < 25; i++) if ((fd = open("/dev/null", O_WRONLY)) > 19) { fprintf(stderr, "NOFILE doesn't limit files; got fd %d\n", fd); return 1; } return 0; #else fprintf(stderr, "setrlimit not available\n"); return 1; #endif } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then kom_cv_func_rlimit_nofile=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) kom_cv_func_rlimit_nofile=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi echo "$as_me:$LINENO: result: $kom_cv_func_rlimit_nofile" >&5 echo "${ECHO_T}$kom_cv_func_rlimit_nofile" >&6 if test $kom_cv_func_rlimit_nofile = no then cat >>confdefs.h <<\_ACEOF #define HAVE_BROKEN_NOFILE 1 _ACEOF fi fi cat >>confdefs.h <<\_ACEOF #define BUGGY_INET_NTOA 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define ENCRYPT_PASSWORDS 1 _ACEOF for ac_header in alloca.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc in yes:no ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; no:yes ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done if test "$use_insure" = "yes" then for ac_prog in insure do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_INSURE+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$INSURE"; then ac_cv_prog_INSURE="$INSURE" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_INSURE="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi INSURE=$ac_cv_prog_INSURE if test -n "$INSURE"; then echo "$as_me:$LINENO: result: $INSURE" >&5 echo "${ECHO_T}$INSURE" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$INSURE" && break done CC="insure" LDFLAGS="-Zsl $LDFLAGS" fi if test "$use_checker" = "yes" then for ac_prog in checker do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CHECKER+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CHECKER"; then ac_cv_prog_CHECKER="$CHECKER" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CHECKER="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CHECKER=$ac_cv_prog_CHECKER if test -n "$CHECKER"; then echo "$as_me:$LINENO: result: $CHECKER" >&5 echo "${ECHO_T}$CHECKER" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$CHECKER" && break done CC="checker $CC" LIBS="-lchkr_m $LIBS" fi subdirs="$subdirs src/libraries/libisc-new" subdirs="$subdirs src/libraries/liboop" subdirs="$subdirs src/libraries/adns" ac_config_files="$ac_config_files Makefile db-crypt/Makefile db-crypt/db/Makefile doc/Makefile doc/man/Makefile scripts/Makefile src/Makefile src/include/Makefile src/include/server/Makefile src/libraries/Makefile src/libraries/libansi/Makefile src/libraries/libcommon/Makefile src/libraries/libeintr/Makefile src/libraries/libmisc/Makefile src/libraries/regex/Makefile src/libraries/regex/doc/Makefile src/libraries/regex/test/Makefile src/server/Makefile src/server/testsuite/Makefile src/server/testsuite/config/Makefile src/server/testsuite/lyskomd.0/Makefile run-support/Makefile" ac_config_commands="$ac_config_commands default" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. { (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } | sed ' t clear : clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ : end' >>confcache if diff $cache_file confcache >/dev/null 2>&1; then :; else if test -w $cache_file; then test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" cat confcache >$cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/; s/:*\${srcdir}:*/:/; s/:*@srcdir@:*/:/; s/^\([^=]*=[ ]*\):*/\1/; s/:*$//; s/^[^=]*=[ ]*$//; }' fi DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_i=`echo "$ac_i" | sed 's/\$U\././;s/\.o$//;s/\.obj$//'` # 2. Add them. ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${HAVE_PYTHON_TRUE}" && test -z "${HAVE_PYTHON_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"HAVE_PYTHON\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"HAVE_PYTHON\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi # Support unset when possible. if (FOO=FOO; unset FOO) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" # Sed expression to map a string onto a valid variable name. as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH exec 6>&1 # Open the log real soon, to keep \$[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. Logging --version etc. is OK. exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX } >&5 cat >&5 <<_CSEOF This file was extended by lyskom-server $as_me 2.1.2, which was generated by GNU Autoconf 2.57. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ _CSEOF echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 echo >&5 _ACEOF # Files that config.status was made for. if test -n "$ac_config_files"; then echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS fi if test -n "$ac_config_headers"; then echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS fi if test -n "$ac_config_links"; then echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS fi if test -n "$ac_config_commands"; then echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS fi cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ lyskom-server config.status 2.1.2 configured by $0, generated by GNU Autoconf 2.57, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." srcdir=$srcdir INSTALL="$INSTALL" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "x$1" : 'x\([^=]*\)='` ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` ac_shift=: ;; -*) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; *) # This is not an option, so the user has probably given explicit # arguments. ac_option=$1 ac_need_defaults=false;; esac case $ac_option in # Handling of the options. _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --vers* | -V ) echo "$ac_cs_version"; exit 0 ;; --he | --h) # Conflict between --help and --header { { echo "$as_me:$LINENO: error: ambiguous option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; };; --help | --hel | -h ) echo "$ac_cs_usage"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # INIT-COMMANDS section. # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" language=$language _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_config_target in $ac_config_targets do case "$ac_config_target" in # Handling of arguments. "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; "db-crypt/Makefile" ) CONFIG_FILES="$CONFIG_FILES db-crypt/Makefile" ;; "db-crypt/db/Makefile" ) CONFIG_FILES="$CONFIG_FILES db-crypt/db/Makefile" ;; "doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "doc/man/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/man/Makefile" ;; "scripts/Makefile" ) CONFIG_FILES="$CONFIG_FILES scripts/Makefile" ;; "src/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/include/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/include/Makefile" ;; "src/include/server/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/include/server/Makefile" ;; "src/libraries/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/libraries/Makefile" ;; "src/libraries/libansi/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/libraries/libansi/Makefile" ;; "src/libraries/libcommon/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/libraries/libcommon/Makefile" ;; "src/libraries/libeintr/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/libraries/libeintr/Makefile" ;; "src/libraries/libmisc/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/libraries/libmisc/Makefile" ;; "src/libraries/regex/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/libraries/regex/Makefile" ;; "src/libraries/regex/doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/libraries/regex/doc/Makefile" ;; "src/libraries/regex/test/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/libraries/regex/test/Makefile" ;; "src/server/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/server/Makefile" ;; "src/server/testsuite/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/server/testsuite/Makefile" ;; "src/server/testsuite/config/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/server/testsuite/config/Makefile" ;; "src/server/testsuite/lyskomd.0/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/server/testsuite/lyskomd.0/Makefile" ;; "run-support/Makefile" ) CONFIG_FILES="$CONFIG_FILES run-support/Makefile" ;; "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "default" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;; "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason to put it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Create a temporary directory, and hook for its removal unless debugging. $debug || { trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./confstat$$-$RANDOM (umask 077 && mkdir $tmp) } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "\$CONFIG_FILES"; then # Protect against being on the right side of a sed subst in config.status. sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF s,@SHELL@,$SHELL,;t t s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t s,@exec_prefix@,$exec_prefix,;t t s,@prefix@,$prefix,;t t s,@program_transform_name@,$program_transform_name,;t t s,@bindir@,$bindir,;t t s,@sbindir@,$sbindir,;t t s,@libexecdir@,$libexecdir,;t t s,@datadir@,$datadir,;t t s,@sysconfdir@,$sysconfdir,;t t s,@sharedstatedir@,$sharedstatedir,;t t s,@localstatedir@,$localstatedir,;t t s,@libdir@,$libdir,;t t s,@includedir@,$includedir,;t t s,@oldincludedir@,$oldincludedir,;t t s,@infodir@,$infodir,;t t s,@mandir@,$mandir,;t t s,@build_alias@,$build_alias,;t t s,@host_alias@,$host_alias,;t t s,@target_alias@,$target_alias,;t t s,@DEFS@,$DEFS,;t t s,@ECHO_C@,$ECHO_C,;t t s,@ECHO_N@,$ECHO_N,;t t s,@ECHO_T@,$ECHO_T,;t t s,@LIBS@,$LIBS,;t t s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t s,@INSTALL_DATA@,$INSTALL_DATA,;t t s,@CYGPATH_W@,$CYGPATH_W,;t t s,@PACKAGE@,$PACKAGE,;t t s,@VERSION@,$VERSION,;t t s,@ACLOCAL@,$ACLOCAL,;t t s,@AUTOCONF@,$AUTOCONF,;t t s,@AUTOMAKE@,$AUTOMAKE,;t t s,@AUTOHEADER@,$AUTOHEADER,;t t s,@MAKEINFO@,$MAKEINFO,;t t s,@AMTAR@,$AMTAR,;t t s,@install_sh@,$install_sh,;t t s,@STRIP@,$STRIP,;t t s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t s,@AWK@,$AWK,;t t s,@SET_MAKE@,$SET_MAKE,;t t s,@am__leading_dot@,$am__leading_dot,;t t s,@LANGUAGE_SUFFIX@,$LANGUAGE_SUFFIX,;t t s,@VALGRIND@,$VALGRIND,;t t s,@AR@,$AR,;t t s,@SENDMAIL@,$SENDMAIL,;t t s,@CC@,$CC,;t t s,@CFLAGS@,$CFLAGS,;t t s,@LDFLAGS@,$LDFLAGS,;t t s,@CPPFLAGS@,$CPPFLAGS,;t t s,@ac_ct_CC@,$ac_ct_CC,;t t s,@EXEEXT@,$EXEEXT,;t t s,@OBJEXT@,$OBJEXT,;t t s,@DEPDIR@,$DEPDIR,;t t s,@am__include@,$am__include,;t t s,@am__quote@,$am__quote,;t t s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t s,@CCDEPMODE@,$CCDEPMODE,;t t s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t s,@CPP@,$CPP,;t t s,@EGREP@,$EGREP,;t t s,@U@,$U,;t t s,@ANSI2KNR@,$ANSI2KNR,;t t s,@PYTHON@,$PYTHON,;t t s,@PYTHON_VERSION@,$PYTHON_VERSION,;t t s,@PYTHON_PREFIX@,$PYTHON_PREFIX,;t t s,@PYTHON_EXEC_PREFIX@,$PYTHON_EXEC_PREFIX,;t t s,@PYTHON_PLATFORM@,$PYTHON_PLATFORM,;t t s,@pythondir@,$pythondir,;t t s,@pkgpythondir@,$pkgpythondir,;t t s,@pyexecdir@,$pyexecdir,;t t s,@pkgpyexecdir@,$pkgpyexecdir,;t t s,@HAVE_PYTHON_TRUE@,$HAVE_PYTHON_TRUE,;t t s,@HAVE_PYTHON_FALSE@,$HAVE_PYTHON_FALSE,;t t s,@EFENCE@,$EFENCE,;t t s,@TRACED_ALLOCATIONS@,$TRACED_ALLOCATIONS,;t t s,@DEBUG_CALLS@,$DEBUG_CALLS,;t t s,@RANLIB@,$RANLIB,;t t s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t s,@LN_S@,$LN_S,;t t s,@YACC@,$YACC,;t t s,@LEX@,$LEX,;t t s,@LEXLIB@,$LEXLIB,;t t s,@LEX_OUTPUT_ROOT@,$LEX_OUTPUT_ROOT,;t t s,@BISON@,$BISON,;t t s,@FLEX@,$FLEX,;t t s,@SED@,$SED,;t t s,@ALLOCA@,$ALLOCA,;t t s,@LIBOBJS@,$LIBOBJS,;t t s,@INSURE@,$INSURE,;t t s,@CHECKER@,$CHECKER,;t t s,@subdirs@,$subdirs,;t t s,@LTLIBOBJS@,$LTLIBOBJS,;t t CEOF _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_lines=48 ac_sed_frag=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_lines # Line after last line for current file. ac_more_lines=: ac_sed_cmds= while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag else sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag fi if test ! -s $tmp/subs.frag; then ac_more_lines=false else # The purpose of the label and of the branching condition is to # speed up the sed processing (if there are no `@' at all, there # is no need to browse any of the substitutions). # These are the two extra sed commands mentioned above. (echo ':t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" else ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" fi ac_sed_frag=`expr $ac_sed_frag + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_lines` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi fi # test -n "$CONFIG_FILES" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case $ac_file in - | *:- | *:-:* ) # input from stdin cat >$tmp/stdin ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; * ) ac_file_in=$ac_file.in ;; esac # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be # absolute. ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_builddir$INSTALL ;; esac if test x"$ac_file" != x-; then { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} rm -f "$ac_file" fi # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ if test x"$ac_file" = x-; then configure_input= else configure_input="$ac_file. " fi configure_input=$configure_input"Generated from `echo $ac_file_in | sed 's,.*/,,'` by configure." # First look for the input files in the build tree, otherwise in the # src tree. ac_file_inputs=`IFS=: for f in $ac_file_in; do case $f in -) echo $tmp/stdin ;; [\\/$]*) # Absolute (can't be DOS-style, as IFS=:) test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } echo $f;; *) # Relative if test -f "$f"; then # Build tree echo $f elif test -f "$srcdir/$f"; then # Source tree echo $srcdir/$f else # /dev/null tree { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } fi;; esac done` || { (exit 1); exit 1; } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s,@configure_input@,$configure_input,;t t s,@srcdir@,$ac_srcdir,;t t s,@abs_srcdir@,$ac_abs_srcdir,;t t s,@top_srcdir@,$ac_top_srcdir,;t t s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t s,@builddir@,$ac_builddir,;t t s,@abs_builddir@,$ac_abs_builddir,;t t s,@top_builddir@,$ac_top_builddir,;t t s,@abs_top_builddir@,$ac_abs_top_builddir,;t t s,@INSTALL@,$ac_INSTALL,;t t " $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out rm -f $tmp/stdin if test x"$ac_file" != x-; then mv $tmp/out $ac_file else cat $tmp/out rm -f $tmp/out fi done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # # CONFIG_HEADER section. # # These sed commands are passed to sed as "A NAME B NAME C VALUE D", where # NAME is the cpp macro being defined and VALUE is the value it is being given. # # ac_d sets the value in "#define NAME VALUE" lines. ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' ac_dB='[ ].*$,\1#\2' ac_dC=' ' ac_dD=',;t' # ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_uB='$,\1#\2define\3' ac_uC=' ' ac_uD=',;t' for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case $ac_file in - | *:- | *:-:* ) # input from stdin cat >$tmp/stdin ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; * ) ac_file_in=$ac_file.in ;; esac test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} # First look for the input files in the build tree, otherwise in the # src tree. ac_file_inputs=`IFS=: for f in $ac_file_in; do case $f in -) echo $tmp/stdin ;; [\\/$]*) # Absolute (can't be DOS-style, as IFS=:) test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } echo $f;; *) # Relative if test -f "$f"; then # Build tree echo $f elif test -f "$srcdir/$f"; then # Source tree echo $srcdir/$f else # /dev/null tree { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } fi;; esac done` || { (exit 1); exit 1; } # Remove the trailing spaces. sed 's/[ ]*$//' $ac_file_inputs >$tmp/in _ACEOF # Transform confdefs.h into two sed scripts, `conftest.defines' and # `conftest.undefs', that substitutes the proper values into # config.h.in to produce config.h. The first handles `#define' # templates, and the second `#undef' templates. # And first: Protect against being on the right side of a sed subst in # config.status. Protect against being in an unquoted here document # in config.status. rm -f conftest.defines conftest.undefs # Using a here document instead of a string reduces the quoting nightmare. # Putting comments in sed scripts is not portable. # # `end' is used to avoid that the second main sed command (meant for # 0-ary CPP macros) applies to n-ary macro definitions. # See the Autoconf documentation for `clear'. cat >confdef2sed.sed <<\_ACEOF s/[\\&,]/\\&/g s,[\\$`],\\&,g t clear : clear s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp t end s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp : end _ACEOF # If some macros were called several times there might be several times # the same #defines, which is useless. Nevertheless, we may not want to # sort them, since we want the *last* AC-DEFINE to be honored. uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs rm -f confdef2sed.sed # This sed command replaces #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. cat >>conftest.undefs <<\_ACEOF s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, _ACEOF # Break up conftest.defines because some shells have a limit on the size # of here documents, and old seds have small limits too (100 cmds). echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS echo ' :' >>$CONFIG_STATUS rm -f conftest.tail while grep . conftest.defines >/dev/null do # Write a limited-size here document to $tmp/defines.sed. echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS # Speed up: don't consider the non `#define' lines. echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS # Work around the forget-to-reset-the-flag bug. echo 't clr' >>$CONFIG_STATUS echo ': clr' >>$CONFIG_STATUS sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS echo 'CEOF sed -f $tmp/defines.sed $tmp/in >$tmp/out rm -f $tmp/in mv $tmp/out $tmp/in ' >>$CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail rm -f conftest.defines mv conftest.tail conftest.defines done rm -f conftest.defines echo ' fi # grep' >>$CONFIG_STATUS echo >>$CONFIG_STATUS # Break up conftest.undefs because some shells have a limit on the size # of here documents, and old seds have small limits too (100 cmds). echo ' # Handle all the #undef templates' >>$CONFIG_STATUS rm -f conftest.tail while grep . conftest.undefs >/dev/null do # Write a limited-size here document to $tmp/undefs.sed. echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS # Speed up: don't consider the non `#undef' echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS # Work around the forget-to-reset-the-flag bug. echo 't clr' >>$CONFIG_STATUS echo ': clr' >>$CONFIG_STATUS sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS echo 'CEOF sed -f $tmp/undefs.sed $tmp/in >$tmp/out rm -f $tmp/in mv $tmp/out $tmp/in ' >>$CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail rm -f conftest.undefs mv conftest.tail conftest.undefs done rm -f conftest.undefs cat >>$CONFIG_STATUS <<\_ACEOF # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ if test x"$ac_file" = x-; then echo "/* Generated by configure. */" >$tmp/config.h else echo "/* $ac_file. Generated by configure. */" >$tmp/config.h fi cat $tmp/in >>$tmp/config.h rm -f $tmp/in if test x"$ac_file" != x-; then if diff $ac_file $tmp/config.h >/dev/null 2>&1; then { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 echo "$as_me: $ac_file is unchanged" >&6;} else ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } rm -f $ac_file mv $tmp/config.h $ac_file fi else cat $tmp/config.h rm -f $tmp/config.h fi # Compute $ac_file's index in $config_headers. _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $ac_file | $ac_file:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null || $as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X$ac_file : 'X\(//\)[^/]' \| \ X$ac_file : 'X\(//\)$' \| \ X$ac_file : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X$ac_file | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'`/stamp-h$_am_stamp_count done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # # CONFIG_COMMANDS section. # for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue ac_dest=`echo "$ac_file" | sed 's,:.*,,'` ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_dir=`(dirname "$ac_dest") 2>/dev/null || $as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_dest" : 'X\(//\)[^/]' \| \ X"$ac_dest" : 'X\(//\)$' \| \ X"$ac_dest" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_dest" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be # absolute. ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 echo "$as_me: executing $ac_dest commands" >&6;} case $ac_dest in depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # So let's grep whole file. if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then dirpart=`(dirname "$mf") 2>/dev/null || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` else continue fi grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue # Extract the definition of DEP_FILES from the Makefile without # running `make'. DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"` test -z "$DEPDIR" && continue # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n -e '/^U = / s///p' < "$mf"` test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" # We invoke sed twice because it is the simplest approach to # changing $(DEPDIR) to its actual value in the expansion. for file in `sed -n -e ' /^DEP_FILES = .*\\\\$/ { s/^DEP_FILES = // :loop s/\\\\$// p n /\\\\$/ b loop p } /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`(dirname "$file") 2>/dev/null || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p $dirpart/$fdir else as_dir=$dirpart/$fdir as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5 echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;} { (exit 1); exit 1; }; }; } # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ;; default ) echo echo " Selected language: $language" echo ;; esac done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi # # CONFIG_SUBDIRS section. # if test "$no_recursion" != yes; then # Remove --cache-file and --srcdir arguments so they do not pile up. ac_sub_configure_args= ac_prev= for ac_arg in $ac_configure_args; do if test -n "$ac_prev"; then ac_prev= continue fi case $ac_arg in -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \ | --c=*) ;; --config-cache | -C) ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) ;; *) ac_sub_configure_args="$ac_sub_configure_args $ac_arg" ;; esac done # Always prepend --prefix to ensure using the same prefix # in subdir configurations. ac_sub_configure_args="--prefix=$prefix $ac_sub_configure_args" ac_popdir=`pwd` for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue # Do not complain, so a configure script can configure whichever # parts of a large source tree are present. test -d $srcdir/$ac_dir || continue { echo "$as_me:$LINENO: configuring in $ac_dir" >&5 echo "$as_me: configuring in $ac_dir" >&6;} { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be # absolute. ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` cd $ac_dir # Check for guested configure; otherwise get Cygnus style configure. if test -f $ac_srcdir/configure.gnu; then ac_sub_configure="$SHELL '$ac_srcdir/configure.gnu'" elif test -f $ac_srcdir/configure; then ac_sub_configure="$SHELL '$ac_srcdir/configure'" elif test -f $ac_srcdir/configure.in; then ac_sub_configure=$ac_configure else { echo "$as_me:$LINENO: WARNING: no configuration information is in $ac_dir" >&5 echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;} ac_sub_configure= fi # The recursion is here. if test -n "$ac_sub_configure"; then # Make the cache file name correct relative to the subdirectory. case $cache_file in [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;; *) # Relative path. ac_sub_cache_file=$ac_top_builddir$cache_file ;; esac { echo "$as_me:$LINENO: running $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5 echo "$as_me: running $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;} # The eval makes quoting arguments work. eval $ac_sub_configure $ac_sub_configure_args \ --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir || { { echo "$as_me:$LINENO: error: $ac_sub_configure failed for $ac_dir" >&5 echo "$as_me: error: $ac_sub_configure failed for $ac_dir" >&2;} { (exit 1); exit 1; }; } fi cd $ac_popdir done fi lyskom-server-2.1.2/configure.in0000664000015100472110000003737407723633366012363 dnl $Id: configure.in,v 1.111 2003/08/29 11:14:31 ceder Exp $ dnl Configuration for LysKOM dnl Copyright (C) 1993-2003 Lysator Academic Computer Association. dnl dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 2, or (at your option) dnl any later version. dnl dnl This program is distributed in the hope that it will be useful, dnl but WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the dnl GNU General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. dnl dnl Please report bugs at http://bugzilla.lysator.liu.se/. dnl AC_REVISION($Revision: 1.111 $) AC_PREREQ(2.57) AC_INIT([lyskom-server], [2.1.2]) AC_CONFIG_SRCDIR([src/server/lyskomd.h]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_AUX_DIR(scripts) AM_INIT_AUTOMAKE AC_ARG_WITH([debug-calls], AC_HELP_STRING([--with-debug-calls], [compile debug protocol requests]), [use_debug_calls=$withval], [use_debug_calls=no]) AC_ARG_WITH([efence], AC_HELP_STRING([--with-efence], [link with ElectricFence]), [use_efence=$withval], [use_efence=no]) AC_ARG_WITH([insure++], AC_HELP_STRING([--with-insure++], [compile with ParaSoft Insure++]), [use_insure=$withval], [use_insure=no]) AC_ARG_WITH([checker], AC_HELP_STRING([--with-checker], [compile with Gnu Checker]), [use_checker=$withval], [use_checker=no]) AC_ARG_WITH([valgrind], AC_HELP_STRING([--with-valgrind[=PATH]], [use valgrind when running tests]), [use_valgrind=$withval], [use_valgrind=no]) AC_ARG_ENABLE([malloc-guards], AC_HELP_STRING([--disable-malloc-guards], [disable defensive guard areas (may crash lyskomd)]), [use_malloc_guards=$enableval], [use_malloc_guards=yes]) dnl The IPv6 support is currently only handled in ISC. The only reason dnl to include this AC_ARG_ENABLE statement in this configure.in is to dnl display the help text when "./configure --help" is run. AC_ARG_ENABLE([ipv6], AC_HELP_STRING([--enable-ipv6], [enable IPv6 support]), [use_inet6=yes], [use_inet6=no]) AC_ARG_WITH([gcov], AC_HELP_STRING([--with-gcov], [instrument for gcov (requires gcc)]), [use_gcov=$withval], [use_gcov=no]) AC_ARG_WITH([traced-allocations], AC_HELP_STRING([--with-traced-allocations], [trace allocations (see src/server/ram-smalloc.c)]), [use_traced_allocations=$withval], [use_traced_allocations=no]) AC_ARG_WITH([optimization], AC_HELP_STRING([--with-optimization], [select level of optimization]), [opt_level=$withval], [opt_level=""]) AC_ARG_WITH([language], AC_HELP_STRING([--with-language=sv], [select Swedish database (default English)]), [language=$withval], [language=en]) AC_SUBST(LANGUAGE_SUFFIX) [case "$language" in en) LANGUAGE_SUFFIX=-en;; sv) LANGUAGE_SUFFIX=;;] *) AC_MSG_ERROR(bad value $language for --with-language)[;; esac] AC_SUBST(VALGRIND) [if test "$use_valgrind" = "yes" then VALGRIND=valgrind elif test "$use_valgrind" = "no" then VALGRIND= else case "$use_valgrind" in /*) VALGRIND="$use_valgrind";; *) ] AC_MSG_ERROR([invalid --with-valgrind argument $use_valgrind]) [ ;; esac fi] [if test "$use_malloc_guards" = "yes" then] AC_DEFINE([USE_MALLOC_GUARDS], 1, [Insert magic number before and after malloced areas. This can help detect buffer overruns.]) [fi] AC_PREFIX_DEFAULT(/usr/lyskom) AC_PATH_PROG([AR], [ar], [notfound], [$PATH$PATH_SEPARATOR/usr/ccs/bin]) AC_ARG_VAR([AR], [ar program to use]) [if test "$AR" = "notfound"; then] AC_MSG_ERROR([cannot find ``ar'']) [fi] AC_PATH_PROG([SENDMAIL], [sendmail], [no], [$PATH$PATH_SEPARATOR/usr/lib$PATH_SEPARATOR/usr/sbin$PATH_SEPARATOR/etc]) [if test "$SENDMAIL" = "no"; then SENDMAIL=:] AC_MSG_WARN([updateLysKOM will not send mail since no sendmail was found]) [fi] AC_PROG_CC AC_AIX AC_ISC_POSIX AC_MINIX AM_C_PROTOTYPES AM_PATH_PYTHON AM_CONDITIONAL(HAVE_PYTHON, test -n "$PYTHON") [if test -n "$GCC"; then] dnl "-Wshadow" could be useful, but it gives too many false dnl warnings. dnl "-Wtraditional" isn't really useful: we don't support dnl pre-c89-compilers. [CFLAGS="$CFLAGS -Wall -W"] dnl AC_DEFINE(_GNU_SOURCE) CMOD_CHECK_CC_OPT([-Wbad-function-cast], [bad_function_cast]) dnl dnl This gives too many false warnings, but it may be proper dnl to use this once in a while. dnl CMOD_CHECK_CC_OPT([-Wcast-qual], [cast_qual]) dnl CMOD_CHECK_CC_OPT([-Wcast-align], [cast_align]) CMOD_CHECK_CC_OPT([-Wwrite-strings], [write_strings]) CMOD_CHECK_CC_OPT([-Wstrict-prototypes], [strict_prototypes]) CMOD_CHECK_CC_OPT([-Wmissing-prototypes], [missing_prototypes]) CMOD_CHECK_CC_OPT([-Wmissing-declarations], [missing_declarations]) CMOD_CHECK_CC_OPT([-Wfloat-equal], [float_equal]) dnl dnl This gives too many false warnings, especially in dbck, dnl but it may be proper to use it once in a while. dbck dnl should be fixed so that we get rid of the warnings there. dnl CMOD_CHECK_CC_OPT([-Wnested-externs], [nested_externs]) dnl CMOD_CHECK_CC_OPT([-pipe], [pipe]) [ fi] AC_SUBST(EFENCE) [if test "$use_efence" = "yes" then] AC_CHECK_LIB(efence,malloc) EFENCE=1 [fi] AC_SUBST(TRACED_ALLOCATIONS) [if test "$use_traced_allocations" = "yes" then] AC_DEFINE([TRACED_ALLOCATIONS], 1, [Should all allocations be traced? See src/server/ram-smalloc.c.]) [fi] AC_SUBST(DEBUG_CALLS) [if test "$use_debug_calls" = "yes" then] AC_DEFINE([DEBUG_CALLS], 1, [Include special debug requests. Don't use this on a production server. The debug requests are insecure. The test suite uses these calls if they are available to increase the coverage.]) AC_CHECK_FUNCS(mallinfo) [fi] [if test "$use_gcov" = "yes" && test -n "$GCC"; then] CMOD_CHECK_CC_OPT([-ftest-coverage], [test_coverage]) CMOD_CHECK_CC_OPT([-fprofile-arcs], [profile_arcs]) AC_DEFINE([AVOID_ABORTS], 1, [This should be defined if you want gcov statistics. It replaces some aborts with exits so coverage data is output.]) [fi] [if test -n "$opt_level" -a "$opt_level" != "yes" ; then CFLAGS=`echo "$CFLAGS" | sed "s/-O[0-9]*//"` if test "$opt_level" != "no" ; then CFLAGS="$CFLAGS -O$opt_level" fi fi] # Do this test early since it may define _POSIX_SOURCE, which may # affect future tests. # FIXME (bug 210): is this needed, now that we use AM_C_PROTOTYPES? AC_MSG_CHECKING([if defines struct sigaction]) AC_CACHE_VAL([kom_cv_header_posix_source_needed], [# This default may be overridden below. kom_cv_header_posix_source_needed=no]) AC_CACHE_VAL([kom_cv_struct_sigaction], AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[struct sigaction foosig;]])], [kom_cv_struct_sigaction=yes], [kom_cv_struct_sigaction=no]) [if test $kom_cv_struct_sigaction = no ; then] AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[#define _POSIX_SOURCE #include ]], [[struct sigaction barsig;]])], [kom_cv_struct_sigaction=yes kom_cv_header_posix_source_needed=yes], [kom_cv_struct_sigaction=no]) [fi]) [if test $kom_cv_header_posix_source_needed = yes ; then] AC_MSG_RESULT([yes, but _POSIX_SOURCE was needed]) AC_DEFINE(_POSIX_SOURCE) [else] AC_MSG_RESULT($kom_cv_struct_sigaction) [fi] [if test $kom_cv_struct_sigaction = yes ; then] AC_DEFINE([HAVE_STRUCT_SIGACTION], 1, [Define if struct sigaction is available.]) [fi] AC_C_CONST AC_C_INLINE CMOD_C_WORKING_ATTRIBUTE_UNUSED AC_HEADER_STDC AC_TYPE_PID_T dnl dnl Check for sig_atomic_t dnl AC_CACHE_CHECK([if sig_atomic_t exists], kom_cv_type_sig_atomic_t, [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[sig_atomic_t t;]])], [kom_cv_type_sig_atomic_t=yes], [kom_cv_type_sig_atomic_t=no])]) [if test $kom_cv_type_sig_atomic_t = no then] AC_DEFINE([sig_atomic_t], [int], [Define this to a type that can be changed atomically from a signal handler if your OS lacks sig_atomic_t.]) [fi] dnl # FIXME (bug 209): is this needed now that we use AM_C_PROTOTYPES? AC_MSG_CHECKING([if _HPUX_SOURCE needs to be defined]) AC_CACHE_VAL([kom_cv_sys_hpux_source], [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[struct sockaddr foo;]])], [kom_cv_sys_hpux_source=no], [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#define _HPUX_SOURCE #include #include ]], [[struct sockaddr foo;]])], [kom_cv_sys_hpux_source=yes], [kom_cv_sys_hpux_source=no])])]) AC_MSG_RESULT($kom_cv_sys_hpux_source) [if test $kom_cv_sys_hpux_source = yes ; then] AC_DEFINE([_HPUX_SOURCE], 1, [Define if on HPUX]) [fi] dnl dnl AC_MSG_CHECKING([if the compiler understands __attribute__ ((format))]) AC_CACHE_VAL([kom_cv_c_attribute_format_printf], [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[extern void log (const char *f, ...) __attribute__ ((format (printf, 1, 2)));]], [[]])], [kom_cv_c_attribute_format_printf=yes], [kom_cv_c_attribute_format_printf=no])]) AC_MSG_RESULT($kom_cv_c_attribute_format_printf) [if test $kom_cv_c_attribute_format_printf = yes ; then] AC_DEFINE([HAVE_ATTRIBUTE_FORMAT_PRINTF], 1, [Define if your compiler supports __attribute__ in printf.]) [fi] AC_MSG_CHECKING([if the compiler understands __attribute__ ((__noreturn__))]) AC_CACHE_VAL([kom_cv_c_attribute_noreturn], [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[extern void log (const char *f, ...) __attribute__ ((__noreturn__));]], [[]])], [kom_cv_c_attribute_noreturn=yes], [kom_cv_c_attribute_noreturn=no])]) AC_MSG_RESULT($kom_cv_c_attribute_noreturn) [if test $kom_cv_c_attribute_noreturn = yes ; then] AC_DEFINE([HAVE_ATTRIBUTE_NORETURN], 1, [Define if your compiler supports __attribute__ ((noreturn)).]) [fi] AC_PROG_INSTALL AC_PROG_RANLIB AC_PROG_AWK AC_PROG_LN_S AC_PROG_YACC AM_PROG_LEX AC_CHECK_PROGS(BISON, bison) AC_CHECK_PROGS(FLEX, flex) AC_CHECK_PROGS(SED, sed) AC_CHECK_HEADERS(string.h memory.h strings.h sys/param.h sys/time.h) AC_CHECK_HEADERS(stdarg.h stdlib.h stddef.h locale.h) AC_CHECK_HEADERS(crypt.h unistd.h) AC_CHECK_HEADERS(values.h) dnl libmisc/pom.c AC_CHECK_HEADERS(stdint.h) AC_HEADER_TIME AC_FUNC_ALLOCA dnl AC_CHECK_HEADERS(sys/resource.h,,, [#ifdef TIME_WITH_SYS_TIME # include # include #else # ifdef HAVE_SYS_TIME_H # include # else # include # endif #endif]) dnl AC_CHECK_TYPE([rlim_t], AC_DEFINE([HAVE_RLIM_T], [1], [Define if rlimt_t is available.]),,[ #ifdef HAVE_SYS_RESOURCE_H # ifdef TIME_WITH_SYS_TIME # include # include # else # ifdef HAVE_SYS_TIME_H # include # else # include # endif # endif # include #endif]) AC_CHECK_TYPE(intptr_t) AC_CHECK_TYPE(intmax_t) AC_CHECK_TYPE(size_t) dnl AC_CHECK_LIB(resolv,main) dnl Host name lookup. AC_CHECK_LIB(authuser,auth_tcpuser3) dnl User authentication according to RFC 931. dnl Low-level networking code on Solaris 2. AC_CHECK_FUNC(gethostbyname) [if test $ac_cv_func_gethostbyname = no then] AC_CHECK_LIB(nsl, gethostbyname) [fi] dnl socket() et c on Solaris 2. AC_CHECK_FUNC(socket) [if test $ac_cv_func_socket = no then] AC_CHECK_LIB(socket, socket) [fi] AC_CHECK_LIB(i,setlocale) dnl For setlocale() on Ultrix. AC_CHECK_FUNC(crypt) [if test $ac_cv_func_crypt = no then] AC_CHECK_LIB(crypt,crypt) dnl For crypt() on Sparc NetBSD 1.1 [fi] AC_CHECK_FUNCS(difftime getdtablesize sysconf strchr getcwd vfprintf) AC_CHECK_FUNCS(setrlimit) AC_CHECK_FUNCS(snprintf) AC_REPLACE_FUNCS(memcpy strerror remove memset memchr memcmp setsid) dnl dnl On AIX 4.2, setrlimit(RLIMIT_NOFILE) doesn't work. The dnl RLIMIT_NOFILE limit is ignored, and getrlimit(RLIMIT_NOFILE) dnl always returns 2147483647. Not very helpful. [if test $ac_cv_func_setrlimit = yes then] AC_CACHE_CHECK([for working setrlimit(RLIMIT_NOFILE, ...)], kom_cv_func_rlimit_nofile, AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #ifdef HAVE_SYS_RESOURCE_H # ifdef TIME_WITH_SYS_TIME # include # include # else # ifdef HAVE_SYS_TIME_H # include # else # include # endif # endif # include #else # include #endif #include #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_OFILE) && !defined(RLIMIT_NOFILE) # define RLIMIT_NOFILE RLIMIT_OFILE #endif #if !HAVE_RLIM_T typedef int rlim_t; #endif int main() { #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE) struct rlimit rlim; int i; int fd; if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) { perror("getrlimit(RLIMIT_NOFILE) failed"); return 1; } rlim.rlim_cur = 20; if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) { perror("setrlimit(RLIMIT_NOFILE) failed"); return 1; } if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) { perror("second getrlimit(RLIMIT_NOFILE) failed"); return 1; } if (rlim.rlim_cur != 20) { fprintf(stderr, "NOFILE set to %ld, not 20\n", (long)rlim.rlim_cur); return 1; } for (i = 0; i < 25; i++) if ((fd = open("/dev/null", O_WRONLY)) > 19) { fprintf(stderr, "NOFILE doesn't limit files; got fd %d\n", fd); return 1; } return 0; #else fprintf(stderr, "setrlimit not available\n"); return 1; #endif }]])], [kom_cv_func_rlimit_nofile=yes], [kom_cv_func_rlimit_nofile=no], [kom_cv_func_rlimit_nofile=no])) [if test $kom_cv_func_rlimit_nofile = no then] AC_DEFINE([HAVE_BROKEN_NOFILE], [1], [Define if setrlimit(RLIMIT_NOFILE) does not work.]) [fi fi] dnl dnl strdup() is not currently used, but we have a replacement function dnl since it was used a while ago. No need to take up time looking dnl for it, though. Remove strdup.c from EXTRA_DIST in dnl src/libraries/libansi/Makefile.am if strdup is ever used again. dnl AC_REPLACE_FUNCS(strdup) dnl dnl I don't know how to test for buggy inet_ntoa functions dnl programmatically, but the supplied substitute should always work, dnl so we define BUGGY_INET_NTOA unconditionally. AC_DEFINE([BUGGY_INET_NTOA], 1, [Define if your OS has buggy inet_ntoa. If you don't know, define this.]) dnl dnl Unencrypted passwords are no longer supported. AC_DEFINE([ENCRYPT_PASSWORDS], 1, [Define if you want encrypted passwords]) dnl dnl Tests for GNU getopt (used in dbck) AC_CHECK_HEADERS(alloca.h) dnl dnl Check for use of Gnu checker dnl [if test "$use_insure" = "yes" then] AC_CHECK_PROGS(INSURE, insure) [ CC="insure" LDFLAGS="-Zsl $LDFLAGS" ] [fi] [if test "$use_checker" = "yes" then] AC_CHECK_PROGS(CHECKER, checker) [ CC="checker $CC" LIBS="-lchkr_m $LIBS" ] [fi] AC_CONFIG_SUBDIRS(src/libraries/libisc-new) AC_CONFIG_SUBDIRS(src/libraries/liboop) AC_CONFIG_SUBDIRS(src/libraries/adns) AC_CONFIG_FILES([Makefile db-crypt/Makefile db-crypt/db/Makefile doc/Makefile doc/man/Makefile scripts/Makefile src/Makefile src/include/Makefile src/include/server/Makefile src/libraries/Makefile src/libraries/libansi/Makefile src/libraries/libcommon/Makefile src/libraries/libeintr/Makefile src/libraries/libmisc/Makefile src/libraries/regex/Makefile src/libraries/regex/doc/Makefile src/libraries/regex/test/Makefile src/server/Makefile src/server/testsuite/Makefile src/server/testsuite/config/Makefile src/server/testsuite/lyskomd.0/Makefile run-support/Makefile]) AC_CONFIG_COMMANDS([default],[[echo echo " Selected language: $language" echo]],[[language=$language]]) AC_OUTPUT lyskom-server-2.1.2/.cvsignore0000664000015100472110000000024407451137325012024 Makefile Makefile.in aclocal.m4 autom4te.cache confdefs.h config.cache config.h config.h.in config.log config.status configure gmon.out stamp-h stamp-h.in stamp-h1 lyskom-server-2.1.2/ChangeLog.10000664000015100472110000011261306721242466011743 Sun Aug 4 00:35:18 1996 Per Cederqvist * Release 1.9.0. * NEWS: Updated for release 1.9.0. * INSTALL: Updated for release 1.9.0. * doc/prot-A.txt: This is specification 9.0. Editorial changes. * scripts/makedist.sh: Don't distribute komrunning, savecore, .gdbinit, call-switch.incl, fnc-def-init.incl, fncdef-no-str-limit.txt, prot-a-parse-arg.c, prot-a-parse-arg.h, updateLysKOM, Makefile or dependencies. * Portability fixes: * scripts/mkmi.m4 (EXTRAARFLAGS): New variable. Use it in the $(LIBNAME) target. * run-support/Makefile.src (doinstall): Use "test -f file" instead of "[ -f file ]" to avoid problems with OSF1 3.2 make. * configure.in (EXTRAARFLAGS): Added. Set to "rv" if make doesn't set ARFLAGS. Sat Aug 3 02:29:00 1996 Per Cederqvist * doc/prot-A.txt: Warn that bitstrings may have variable length in the future. (83=who-is-on-dynamic): New argument: active-last. * Portability fixes: * scripts/mkmi.m4 (LK_descend): Make the makefiles more portable by using FORCE as well as .PHONY. * src/libraries/libansi/memcmp.c: New file. * configure.in: Check for sys/select.h and libcrypt. (DEPENDFLAG): SparcWorks wants it set to -xM1. Added AC_REPLACE_FUNCS(memcmp). * scripts/makedist.sh: Don't distribute isc-new.h, com.h, version-info.c, db-nocrypt, lyskomd or dbck. * db-crypt/db/lyskomd-data: Converted to database format 1. Names changed to ISO 8859-1. * scripts/lyskomd-copyrights: Don't update README.FSF, run-support/savecore or src/server/TAGS. * doc/prot-A.txt: Renamed "pepsi" to "change-conference" and "anarchy" to "allow_anon". Fri Aug 2 02:09:09 1996 Per Cederqvist * versions (SERVER-COMPAT-VERSION): 10900. (SERVER-VERSION): 1.9.0. (PROTOCOL-A-LEVEL): 9. * Handle idle-time: * doc/prot-A.txt: Changed some underscores to dashes. (64=get-session-info-ident): Marked as obsolete. (63=who-is-on-ident): Marked as obsolete. (82=user-active): New call. (83=who-is-on-dynamic): New call. (84=get-static-session-info): New call. (Session-Flags): New type. (Dynamic-Session-Info): New type. (Dynamic-Session-Info-List): New type. (Static-Session-Info): New type. (Version-Info): This type was apparently not documented even though it should have been. Thu Aug 1 00:58:56 1996 Per Cederqvist * configure.in (AC_OUTPUT): Touch all dependencies files to avoid warnings (or even errors) from make. * doc/prot-A.txt: Protocol A is not run over Telnet/TCP/IP, but rather TCP/IP. It requires an 8-bit-clean connection. Messages should be newline-terminated in both directions. * run-support/config: Default to hard-coded ISO 8859-1. Remove the echo statement. Wed Jul 31 21:31:38 1996 Per Cederqvist * README.FSF: New file. Tue Jul 30 16:26:38 1996 Per Cederqvist * configure.in: Don't use "-ansi" in compilations -- it appears to be impossible to get both struct sigaction and struct linger on SunOS 5.4 with it. (HAVE_STRUCT_SIGACTION): Define it if struct sigaction can be found. (_POSIX_SOURCE): Define it if needed to get struct sigaction. Mon Jul 29 00:11:06 1996 Per Cederqvist * configure.in (HAVE_ATTRIBUTE_FORMAT_PRINTF): Define it if the compiler supports the "__attribute__((format (printf, 1, 2)))" construct (which is a GNU C extension). Fri Jul 26 02:51:48 1996 Per Cederqvist * doc/prot-A.txt: Documented error code 46=long-array. 60=find-next-text-no and 61=find-previous-text-no are recommended, not experimental. Sat Jul 27 13:42:08 1996 David Byers * doc/Protocol-A.texi: Documented Version-Info and a few more calls. Fri Jul 26 16:38:00 1996 David Byers * doc/lyskomd-database-format: Removed $ as terminating character of database format version 1. It's not used anymore. Sat Jul 13 15:53:04 1996 Per Cederqvist (ceder@lysator.liu.se) * doc/prot-A.txt: Fixed a couple of typos. Fri Jun 14 17:24:39 1996 David Byers * doc/Protocol-A.texi (query-async): Documented calls 15-19 or so. Added complete dependency on special fonts. Included disgusting TeX hack. Oh what joy! Mon Jun 10 14:16:13 1996 David Byers * doc/prot-A.txt: Documented call 80 and 81 (accept-async and query-async). * doc/server-async.extend: Updated description. * configure.in: Transposed checks for nsl and socket so things work a little bit better on Solaris 2.5 Sun Jun 9 10:40:57 1996 David Byers * doc/prot-A.txt: Documented prot-A.txt * configure.in: Check for crypt.h, unistd.h Tue May 21 22:39:46 1996 Per Cederqvist (ceder@lysator.liu.se) * doc/prot-A.txt (30=add-recipient): The third argument is now officially a BOOL. The protocol has not changed, but the documentation was bogus. Mon Feb 19 20:22:00 1996 Per Cederqvist (ceder@lysator.liu.se) * doc/man/dbck.8: Updated with long option names and the new options --clear-password and --grant-all. * configure.in: Check for alloca.h (since GNU getopt wants it). Wed Nov 8 19:59:52 1995 Per Cederqvist (ceder@lysator.liu.se) * Release 1.8.0. * doc/prot-A.txt: This document is now frozen as 8.0. * doc/ADMINISTRATION: Updated for 1.8.0. * NEWS, INSTALL: Updated for 1.8.0. * versions (SERVER-VERSION): 1.8.0. (SERVER-COMPAT-VERSION): 10800. * doc/man/lyskomd.8: Documented parameter "Force ISO 8859-1". Thu Nov 2 20:40:58 1995 Per Cederqvist (ceder@lysator.liu.se) * NEWS: Added preliminary news for 1.8.0. * scripts/lyskomd-copyrights: Don't update libraries/gnumalloc. * configure.in: Define MEMMOVE_MISSING if it is missing and we are using GNU malloc. * doc/man/dbck.8: Documented the -t flag. * src/libraries/libansi/strerror.c (strerror): Added a cast to avoid a warning. * Optionally use GNU Malloc. * configure.in: Handle --with-gnu-malloc. * scripts/makedist.sh: Include gnumalloc. Avoid distributing files named *.tmp. * mkmi: Generate src/libraries/gnumalloc/Makefile. * src/libraries/Makefile.src (SUBDIRS): Include @GNUMALLOC@. * scripts/mkmi.m4 (ALL_CFLAGS): Don't include "-I@BUILDTOPDIR@/include/server". Mon Oct 23 07:56:26 1995 Per Cederqvist (ceder@lysator.liu.se) * versions (PROTOCOL-A-LEVEL): Level 8. * configure.in: Define _GNU_SOURCE if using gcc. Sat Oct 7 15:24:45 1995 Per Cederqvist (ceder@lysator.liu.se) * doc/prot-A.txt: 30=add-recipient can change recpt to cc_recpt and back. * doc/man/lyskomd.8: Document parameter "Garb". Tue Sep 5 20:50:55 1995 Per Cederqvist (ceder@lysator.liu.se) * run-support/Makefile.src: Install savecore. * run-support/savecore.sh: New file. Sun Jan 8 12:13:14 1995 Per Cederqvist (ceder@lysator.liu.se) * Release 1.7.1. * scripts/update-copyright: Preserve the executable bit. * configure.in: Added AC_PREFIX_DEFAULT(/usr/lyskom). * INSTALL: Updated the list of tested systems. Sat Jan 7 20:13:44 1995 Per Cederqvist (ceder@lysator.liu.se) * Pre-release 1.7.0.pre.2. * doc/prot-A.txt: New chapters: protocol and document history. For each call, document in which protocol version it was introduced. * configure.in: Portability fix for Dynix: (AC_TYPE_PID_T): Added. (AC_REPLACE_FUNCS(setsid)): Added. * src/libraries/libansi/setsid.c (setsid): New file. Setsid is not really implemented, but maybe it will work anyhow. Sun Jan 1 14:15:05 1995 Per Cederqvist (ceder@lysator.liu.se) * scripts/update-copyright: Cosmetic improvements. * Makefile.src (dodistclean): Remove $(INCLUDEDIR). (domostlyclean): Remove libraries and installed include files. * configure.in (nsl): Fixed braino. * doc/prot-A.txt: Document type BOOL. Use NUL, not NULL, when talking about the character '\0'. * run-support/Makefile.src (doinstall): Minor cleanup. * scripts/mkmi.m4 (GENERIC-MOSTLYCLEAN): Remove $(SCRIPTS). (LK_INSTALL_BUILT_HDRS): Arrange for the headers to be removed by "make mostlyclean". Sat Dec 31 12:39:17 1994 Per Cederqvist (ceder@lysator.liu.se) * Release 1.7.0. * doc/prot-A.txt: Many updates by me and Pell Pell Pell. Specification level is now 7.0. Tue Dec 27 00:18:17 1994 Per Cederqvist (ceder@lysator.liu.se) * versions: New file. * scripts/mkmi.m4 (GENERIC-MOSTLYCLEAN): Remove *.tmp. (GENERIC-DISTCLEAN): Remove config.log and config.cache. (LK_DEPEND): Don't forget to "include dependencies" in the generated Makefiles. (LK_STD): Changes for Autoconf 2. * scripts/install-sh: New file (from the Autoconf 2.1 distribution). * doc/prot-A.txt: Changes from Pell Pell Pell and me. * aclocal.m4: Rewritten for Autoconf 2. * configure.in: Updated for Autoconf 2. * Makefile.src (SERVER-VER): Definition removed. (dodistclean): Remove makedist. (dist): Use makedist instead of a long embedded shellscript. (makedist): New target, built from scripits/makedist.sh. * scripts/makedist.sh: New file, extracted from Makefile.src. * INSTALL: Updated since we now use autoconf version 2. Sat Nov 19 15:48:15 1994 Per Cederqvist (ceder@lysator.liu.se) * Makefile.src (dist): Remove *.orig from the distribution. Tue Nov 15 00:42:19 1994 Per Cederqvist (ceder@lysator.liu.se) * Release 1.6.6. * doc/ADMINISTRATION: * Makefile.src, Makefile.in (SERVER-VER): 1.6.6. * NEWS: Added news for 1.6.5 and 1.6.6. * configure.in: Check for sys/resource.h and setrlimit. Sun Oct 23 17:09:08 1994 Per Cederqvist (ceder@lysator.liu.se) * doc/man/lyskomd.8: Document parameter "Open files". Mon Aug 29 19:32:31 1994 Per Cederqvist (ceder@lysator.liu.se) * aclocal.m4: New file. * configure.in: Use AC_VERBOSE instead of testing $verbose. Test if gcc accepts -pipe - don't assume it does. Test if $(CC) accepts -g - don't assume it does, unless it is gcc. Move AC_AIX, AC_ISC_POSIX, AC_MINIX, AC_DYNIX_SEQ and AC_IRIX_SUN to a better position. Sat Aug 20 00:00:18 1994 Per Cederqvist (ceder@lysator.liu.se) * configure.in: Improved testing for HPUX and struct sockadr. * NEWS: Changes for release 1.6.4 documented. They were unfortunately not distributed with 1.6.4. Thu Jun 30 09:12:03 1994 Per Cederqvist (ceder@lysator.liu.se) * Release 1.6.4. * Build: Removed. * Makefile.src (dist): Don't try to distribute Build. * doc/man/lyskomd.8, doc/ADMINISTRATION * Makefile.src, Makefile.in (SERVER-VER): 1.6.4. Mon Jun 20 12:13:38 1994 Per Cederqvist (ceder@lysator.liu.se) * Release 1.6.3. * doc/man/lyskomd.8, doc/ADMINISTRATION * Makefile.src, Makefile.in (SERVER-VER): 1.6.3. Sat Jun 18 22:44:22 1994 Per Cederqvist (ceder@lysator.liu.se) * Release 1.6.2. * NEWS: New file. * INSTALL: Document that the -DNDEBUG, -DNDEFENSIVE_CHECKS and -DLOGACCESSES can be sent to the configure script. * doc/man/dbck.8, doc/man/lyskomd.8: Updated to 1.6.2. * Makefile.src, Makefile.in (SERVER-VER): 1.6.2. (dist): Include the NEWS file. * configure: Re-generated with autoconf 1.11. Tue Apr 5 21:59:32 1994 Per Cederqvist (ceder@lysator.liu.se) * Release 1.6.1. Mon Apr 4 15:46:25 1994 Per Cederqvist (ceder@lysator.liu.se) * doc/ADMINISTRATION: Updated for 1.6.1. * INSTALL: Document new updateLysKOM behavior. * run-support/start_kom.sh: Deleted. run-support/stop_kom.sh: Deleted. run-support/komrunning.sh: Replaces start_kom and stop_kom. run-support/Makefile.src: Install komrunning, not start_kom or stop_kom. * doc/man/lyskomd.8: Document parameter "Log file". Fixed spelling error. * src/libraries/libansi/tmp-difftime.h: Removed. src/libraries/libansi/difftime.c: Removed. src/libraries/libansi/Makefile.src: Don't install tmp-difftime.h. configure.in: Don't AC_REPLACE_FUNCS(difftime). Wed Mar 9 02:57:20 1994 Per Cederqvist (ceder@lysator.liu.se) * run-support/Makefile.src: Install the config file from $(srcdir). * mkmi: Insert "Generated from:" string in the generated Makefile.in files. * Makefile.src (dist): Include scripts/mkinstalldirs. Tue Mar 8 23:48:55 1994 Per Cederqvist (ceder@lysator.liu.se) * scripts/mkmi.m4 (LK_QUOTE): New macro. * doc/man/lyskomd.8: Mention the version number this file is for. Fixed typo. * run-support/config: New file. * run-support/Makefile.src (doinstall): Install it in $(etcdir), but don't overwrite any previously installed config file. Sun Mar 6 02:13:55 1994 Per Cederqvist (ceder@lysator.liu.se) * Release 1.6. * doc/ADMINISTRATION: Talked about start_kom, stop_kom and the program updateLysKOM. * INSTALL: Updated/rewritten for LysKOM 1.6. * scripts/mkmi.m4 (LK_STD): Now takes an optional argument: what `all' should depend on. Defaults to `libraries'. * Makefile.src (LK_STD): Make `all' depend on includes, stamp-depend, libraries and binaries. (stamp-depend): New target. (depend): No longer depends on includes. (dodistclean): Remove stamp-depend. (dist): Remove stamp-* from the distribution. * src/Makefile.src (LK_STD): Make `all' depend on includes, libraries and binaries. * scripts/Depend.make, scripts/Parallell-depend.make, scripts/RCS-depend.make, scripts/Single-depend.make, scripts/install-includes.make, scripts/sub-binaries.make, scripts/sub-clean.make, scripts/sub-depend.make, scripts/sub-includes.make, scripts/sub-install.make, scripts/sub-libraries.make: Removed. * doc/man/Makefile.src (doinstall): mkinstalldirs before trying to install the man-pages. * scripts/mkinstalldirs: New script, imported from GNU m4 1.1. * configure.in (strchr): Call AC_HAVE_FUNCS instead of AC_REPLACE_FUNCS on it. (AC_OUTPUT): Generate run-support/Makefile. * mkmi: Generate run-support/Makefile.in. * Makefile.src (SUBDIRS): Added run-support. (doinstall): New target. (dist): Partially rewritten. * src/libraries/libansi/mktime.c: Removed. * src/libraries/libansi/strchr.c: Removed. * src/include/ansi: Directory, and all subdirectories, removed. * scripts/mkmi.m4 (LK_SCRIPTS): New macro. * run-support/updateLysKOM: Removed. Superseded by src/server/updateLysKOM.c. * run-support/start_kom.sh, run-support/stop_kom.sh, run-support/Makefile.src: New files. Sat Mar 5 18:08:08 1994 Per Cederqvist (ceder@lysator.liu.se) * Makefile.src (dist): Was formerly known as distribution. * configure.in (LDFLAGS): AC_SUBST them. * mkmi: New file, used to built Makefile.in from Makefile.src. * scripts/mkmi.m4: Several fixes and improvements. * */Makefile.src: New file. Thu Mar 3 01:45:07 1994 Per Cederqvist (ceder@lysator.liu.se) * doc/ADMINISTRATION: Updated for lyskomd 1.6. * scripts/mkmi.m4: New file. * configure.in (INCLUDE_CURRENT): Was formerly include_current. (SRCTOPDIR, BUILDTOPDIR, INCLUDE_CURRENT): AC_SUBST them. (descend, @CLEAN@, GENERIC-MOSTLYCLEAN, GENERIC-DISTCLEAN, *_DESCEND, @CFLAGS@, @STDLYSKOM@ and others): Removed. The functionality is now in mkmi.m4. (AC_OUTPUT): Don't generate src/libraries/regex/{doc,test}/Makefile. * doc/coding-standards.txt: Removed, since it was totally out of sync with reality. Sun Feb 27 16:23:14 1994 Per Cederqvist (ceder@lysator.liu.se) * config/*: All files removed, since they are no longer used. * doc/server-config.extend: New file. * doc/man/lyskomd.8: Documented the configuration parameters ``Ident-authentcation'' and ``Log login''. Thu Feb 24 11:08:47 1994 Per Cederqvist (ceder@lysator.liu.se) * configure.in: Removed AC_USG, since GNU regex 0.12 no longer needs it. * doc/man/: All subdirectories removed. Source to the man pages now reside in doc/man. * doc/man/man3/isc3.x: Removed. Better man-pages exists in src/libraries/libisc-new/man. Wed Jan 12 02:22:42 1994 Per Cederqvist (ceder@lysator.liu.se) * doc/man/man8/lyskomd.8: lyskomd now uses a configuration file. Document it. Sat Oct 16 17:30:32 1993 Per Cederqvist (ceder@lysator.liu.se) * configure.in: Added AC_CONST. (include_current): Added. : AC_HAVE_HEADERS(stddef.h). * configure.in: Added support for DEPENDFLAG. * scripts/Single-depend.make: Use $(DEPENDFLAG) instead of -M. * scripts/Parallell-depend.make: Use $(DEPENDFLAG) instead of -M. * Config: Deleted. Use configure instead. Thu Oct 14 23:13:57 1993 Per Cederqvist (ceder@lysator.liu.se) * src/libraries/libansi/{memchr,memset,remove,strchr}.c: New files, with simple-minded implementations. Wed Oct 13 00:19:47 1993 Per Cederqvist (ceder@lysator.liu.se) * src/libraries/libansi/mktime.c (mktime): Comment out everything, since it is unused. * src/libraries/libansi/empty.c (neveruse): The linker of Solaris 2 doesn't like empty tables of contents, so put something in it. * configure.in: Added check for HPUX and struct sockaddr. * Added AC_HAVE_FUNCS(vfprintf). * Added AC_REPLACE_FUNCS(remove strchr memset memchr). Tue Oct 12 16:33:26 1993 Per Cederqvist (ceder@lysator.liu.se) * configure.in: Added AC_HAVE_HEADERS(locale.h stdlib.h). * Added AC_HAVE_LIBRARY(socket nsl). * Removed AC_REPLACE_FUNCS(mktime), since mktime is never used. * Don't remove $BUILDTOPDIR/include. * src/libraries/libansi/mktime.c: This file seems to be obsolete and unused. Added a comment to that effect, and commented out everything. Mon Oct 11 13:15:32 1993 Per Cederqvist (ceder@lysator.liu.se) * configure.in (AC_AIX, AC_ISC_POSIX, AC_MINIX): Use this macro immediately after AC_PROG_CC. Sun Oct 10 12:55:56 1993 Per Cederqvist (ceder@lysator.liu.se) * src/libraries/libansi/Makefile.in (LIBOBJS): Always include empty.o, so that libansi.a is never empty. * src/libraries/libansi/empty.c: New file, containing nothing but an rcsid. * scripts/install-includes.make, scripts/Parallell-depend.make, scripts/Single-depend.make: Fixes for --srcdir. Fri Oct 8 00:13:00 1993 Per Cederqvist (ceder@lysator.liu.se) * configure.in: Fix rule for getdtablesize. Insert a dummy entry in tables that descend directories (if SUBDIR should ever be empty). * Use autoconf. All Makefiles replaced by Makefile.in. * configure.in: New file, used in the server distribution. * src/include/config.h: m-config.h is no longer included. * src/libraries/libansi/difftime.c (difftime): From src/server/missing-ansi.c. * src/libraries/libansi/memcpy.c (memcpy): dito. * src/libraries/libansi/mktime.c (mktime): dito. * src/libraries/libansi/tmp-difftime.h: moved here from src/server. Wed Oct 6 10:08:13 1993 Per Cederqvist (ceder@lysator.liu.se) * src/libraries/libansi/vprintf.c: Removed. It didn't contain anything useful. Tue Sep 28 01:01:14 1993 Per Cederqvist (ceder@lysator.liu.se) * Makefile (distribution): Include src/libraries/regex in the distribution (thanks to Bo Kullmar). Fri Sep 24 18:46:45 1993 Per Cederqvist (ceder@lysator.liu.se) * Makefile: Server version is 1.4.1 (limited distribution). Sat Dec 19 01:10:21 1992 Per Cederqvist (ceder@mauritz) * src/libraries/regex: The GNU regexp package, now used in the server. * Config: Run ./configure in src/libraries/regex. * src/libraries/Makefile: Enter the regex subdir. Sun Sep 6 20:25:48 1992 Per Cederqvist (ceder@robert) * Makefile: Server version is 1.2.5 (released beta). * Makefile: Include libisc-new instead of libisc in the server distribution. * config/sun4os4-defs.make: For the distribution: use LIBDIR, ANSIDIR and INCLUDEDIR inside the source tree. Tue May 19 01:16:07 1992 Per Cederqvist (ceder@lysator) * Makefile: Server version is 1.2.0 (never released for ftp). Mon Feb 10 03:07:33 1992 Linus Tolke Y (linus at robin) * Config: The installation of config files is now the responsibility of the source directory. The makefiles in the config dir and in the src/include/ansi/ have new targets config to handle this. Fri Jan 24 19:23:36 1992 Per Cederqvist (ceder at robin) * (scripts/install-includes.make): Install include files without read permisson, to prevent editing of the copies. Sun Jan 5 19:05:31 1992 Per Cederqvist (ceder at lysator) * (INSTALL): Stronger warning about using -lresolv on SunOS 4.1.1. * (Build): Changed the all-too-optimisitic message "All binaries built succesfully." to "All binaries should be built." * LIBRESOLV (config/*-defs.make): New define. Wed Dec 18 00:09:29 1991 Per Cederqvist (ceder at lysator) * Version 1.0.4 was never released. New version: 1.1.0. Tue Oct 29 04:18:26 1991 Per Cederqvist (ceder at lysator) * Makefile: next server-version is 1.0.4. Wed Oct 16 18:04:46 1991 Per Cederqvist (ceder at robert) * INSTALL: Better instructions on the elisp-client installation procedure. Wed Sep 25 12:38:03 1991 Per Cederqvist (ceder at lysator) * Makefile: Server version is 1.0.3. Sat Sep 21 03:23:30 1991 Per Cederqvist (ceder at lysator) * Makefile: Server version is 1.0.2. * run-support/updateLysKOM: lyskomd, not ramkomd! * Makefile (distribution): Copy the man pages to doc/man, not doc/man/man. * INSTALL: Told about how to select the port (/etc/services). Fri Sep 20 20:18:02 1991 Per Cederqvist (ceder at lysator) * Makefile: Current serverversion is 1.0.1. * db-{no,}crypt/db/ramkomd-*: Name changed from ram* to lys*. Mon Sep 16 19:20:12 1991 Per Cederqvist (ceder at lysator) * Released LysKOM server v1.0. * Makefile: Added COPYING. * Makefile: Added README-serverrelease. * INSTALL: Ber{ttade om tmp-limits.h. Fri Sep 13 22:17:26 1991 Per Cederqvist (ceder at lysator) * Makefile: ta inte med all doc n{r man g|r distribution. * Build: Exportera inte TOPDIR. Topdir.make inkluderas ju i Makefilen. Tue Mar 5 17:13:25 1991 Per Cederqvist (ceder at lave) * Depend.make: Bytt -MM mot -M, eftersom vi har includefiler inom <> som {ndrar p} sig. Thu Feb 14 03:39:16 1991 Linus Tolke (linus at laila) * include/kom-types.h: Lagt till EMPTY_CONF_NO_LIST_i och EMPTY_CONF_NO_LIST. Sat Dec 15 20:46:41 1990 Per Cederqvist (ceder at laila) * Depend.make: Jag bytte @\{63\} mot @@@* som {r mer portabelt. Tue Sep 18 20:46:42 1990 Per Cederqvist (ceder at lave) * get_time(): nytt format. Se services.h. Thu Sep 13 21:32:41 1990 Per Cederqvist (ceder at lave) * Ny port: 4894. Jag vill kunna k|ra nya ramkomd och gamla ramkomd p} lave samtidigt... Tue Aug 28 13:53:36 1990 Per Cederqvist (ceder at lave) * Datafilerna heter nu ramkomd-data-2 och ramkomd-backup-2. De anv{nds av den nya servern och inneh}ller de nya formaten p} tider och textstatusar. De gamla filerna ramkomd-data och ramkomd-backup finns fortfarande kvar och anv{nds av den gamla servern. Personer som skapas i den kommer inte att finnas i den nya servern... Sun Aug 26 16:40:58 1990 Per Cederqvist (ceder at lage) * En klient i elisp har p}b|rjats. Den ligger under 2kom/elisp-client/. * [ndringar p}g}r i servern. Just nu g}r den inte att k|ra. Jag byter externt format p} Text_stat och time_t. I forts{ttningen blir det en struct tm som |verf|rs. Tue Aug 21 19:27:07 1990 Per Cederqvist (ceder at lave) * get_text() tar nu tv} nya parametrar som anger f|rsta och sista tecken i texten som man h{mtar. (Normalt torde det l|na sig att h{mta hela texten p} en g}ng. Det {r nog bara om man k|r |ver atlantlinan som det kanske blir segt.) Sat Aug 11 00:31:32 1990 Per Cederqvist (ceder at lave) * Nya funktioner: get_membership(), get_created_texts() och get_members(). * Namnbyte: query_unread() heter nu query_read_texts(). S} sm}ningom kommer jag att skriva en annan query_unread() som returnerar antalet ol{sta brev en person har. * Till slut s} lyckades jag f} allt genom kompilatorn. Det gick }t en del tid efter alla odokumenterade omorganisationer... Nu {r bara fr}gan hur mycket som fungerar i verkligheten... * kom-types.c {r flyttad till server/ resp. isc-client/. Det gick inte att ha det i samma fil l{ngre. Thu Aug 9 05:20:20 1990 Thomas Bellman (bellman at laila) * Makefilen {nnu mer f|rb{ttrad. Make depend mycket snyggare, anv{nder ${MAKE} i st f make direkt. * Makefilen i toppdirret f|rb{ttrad, likaledes ig}r. Make clean i toppdirret g}r nu ner och g|r make clean i underdirren ocks}. Diverse andra f|rb{ttringar ocks} gjorda. * Lite omorganisationer gjorda ig}r. En del grejer nedflyttade i directories f|r att f} ett renare toppdir. Fri Jul 27 01:21:45 1990 Per Cederqvist (ceder at lage) * Nu {r funktionerna i services.h dokumenterade, i alla fall lite grann. Kommentarerna finns i server/services.c. De borde v{l kopieras till services.h ocks}. Vi f}r v{l se om jag hinner det n}gon g}ng p} denna sida ny}r... Wed Jul 25 14:35:52 1990 Per Cederqvist (ceder at lave) * F|ljande filer installerade: /usr/local/etc/ramkomd /usr/local/etc/updateLysKOM /usr/local/bin/kompost /usr/local/bin/komlisten * ramkomd sparar numera alla texter, m|ten och personer var 15:e minut. Det {r programmet /usr/local/etc/updateLysKOM som kopplar upp sig och skickar anropet kom_sync() som vem som helst kan g|ra. (Man beh|ver inte ens vara inloggad). updateLysKOM startas fr}n min crontab p} lave. stdout skickas till 2kom/stdout, stderr till 2kom/stderr. Alla logg-meddelanden kommer till stderr. Om ramkomd inte {r ig}ng f|rs|ker updateLysKOM starta om ramkomd. Data lagras i filerna /usr/local/src/2kom/db/ramkomd-data och ramkomd-backup. Tue Jul 24 13:37:03 1990 Per Cederqvist (ceder at lave) * komlisten - ett program f|r att lyssna p} de asynkrona meddelanden som skickas. 'komlisten lave 5 pw' eller 'komlisten lave'. Den f|rsta varianten loggar in som person nummer 5 med l|sen 'pw'. P} s} s{tt f}r den se alla texter som skapas i m|ten d{r p 5 {r medlem. Mon Jul 23 04:01:55 1990 Per Cederqvist (ceder at lave) * kompost - ett program f|r att kolla om man har n}gon post i kom. 'kompost lave 5' ser efter hur m}nga ol{sta brev person 5 har p} det kom som k|r p} lave. Sun Jul 22 02:17:57 1990 Per Cederqvist (ceder at lave) * I kom/isc-client/ ligger k{llkoden till klient-sidan. Synopsis: #define CLIENT #include "/usr/local/2kom/services.h" cc main.o ... -L/usr/local/2kom -lyskom * isc b|rjar bli klart (tror jag). Jag har i alla fall lyckats koppla upp en micro-klient mot servern och skapat en person och ett m|tet, och l}tit personen g} med i m|tet. Fri Jul 20 01:00:00 1990 Thomas Bellman (bellman at laila) * Backup tagen av hela LysKOM p} Inge Wallins optiska disk. F|rhoppningsvis {r det helt i on|dan... Tue Jul 17 15:19:29 1990 Per Cederqvist (ceder at lave) * kom-types.h: Sista (?) {ndringen i Person-structen: confs och no_of_confs har slagits ihop till Membership_list conferences. Nu har vi inga pekare i Person-structen. Alla 'array/listor' ligger inbakade i en list-typ. Det {r bara f|rvirrande att ha det p} olika s{tt. Jag har just suttit i ett halvt dygn och letat felet innan jag kom p} att confs pekade p} en variabel lista... Sun Jul 15 04:43:20 1990 Thomas Bellman (bellman at laila) * Eftersom serverskrivarna (l{s Ceder) hade en del underliga |nskem}l om att f} anv{nda konstiga funktioner som smalloc och annat f|r minneshantering {ven i str{ngfunktionerna, tvingar jag dem nu att anropa funktionen s_set_storage_management() f|r att ange vilka funktioner som ska anv{ndas i st{llet f|r de vanliga. Tyv{rr m}ste jag sj{lv g|ra det ocks}, men det {r betydligt snyggare {n det s{tt som det l|stes p} innan. Fri Jul 13 13:12:23 1990 Per Cederqvist (ceder at laila) * kom-types.h: Jag lade till ett antal bitar i Personal_flags och Priv_bits f|r framtida bruk. * kom-types.h: Person-structen: f{ltet 'texts' har bytt namn och typ till 'Text_list created_texts'. * OMORGANISATION!!! Saker som l}g i kom-types.h som ska se olika ut f|r server och klient, {r flyttade fr}n client/client-types.h resp. server/server-types.h tillbaka till kom-types.h. client/client-types.h och server/server-types.h {r borttagna. Sat Jul 7 07:44:45 1990 Per Cederqvist (ceder at lave) * Det gick inte alls bra. Tydligen m}ste filerna som man cat:ar ihop utg} fr}n samma directory... :-( * TAGS-filerna: I varje directory g|rs en TAGS-fil p} de filer som finns d{r. I kom:/ g|rs en total TAGS-fil genom att cat:a ihop dom. Jag {r inte helt s{ker p} att det {r s} smart, men vi f}r se hur det g}r. Thu Jul 5 13:13:41 1990 Per Cederqvist (ceder at laila) * services.h: Ny funktion: delete_text(Text_no text_no); Tue Jul 3 01:12:50 1990 Thomas Bellman (bellman at laila) * services.h: Ny maskbit f|r get_person_stat(), GETP_READ_TEXTS, som inneb{r att man vill ha listorna av l{sta texter tillsammans med medlemskapslistan. Dessa ska inte skickas med om man inte explicit ber om det; det finns query_unread(). Wed Jun 27 05:13:01 1990 Thomas Bellman (bellman at lave) * services.h: Alla funktionsdeklarationer {r omg{rdade av makrot KOM_ som ser till att funktionerna heter 'kom_foo' p} klientsidan och 'foo' p} serversidan. Detta {r beroende p} om makrona CLIENT respektive SERVER {r definierade. Detta f|r att vi ska slippa ha tv} services.h att underh}lla. Wed Jun 6 00:14:35 1990 Per Cederqvist (ceder at laila) * services.h: [ndrade 'String' till 'const String' i alla funktionshuvuden. * glue: Directory som inneh}ller klister f|r att klistra ihop en klient med servern. * services.h: Alla funktioner som f|rut hette 'foo' heter nu 'kom_foo'. Anledningen {r att man vill kunna l{nka ihop klienten och servern och f} ett singeluserkom innan Peter {r klar med sitt paket... ;-) Tue May 29 16:17:53 1990 Per Cederqvist (ceder at lave) * services.h {r nu splittrad. server/services.h inneh}ller funktionerna som de ser ut p} server-sidan, services.h som de ser ut f|r klienten. Mon May 28 23:02:24 1990 Thomas Bellman (bellman at laila) * Summarize-Headers: Shell-script f|r att sammanfatta inneh}llet i en .h-fil. * (Egentligen den 26:e) FileList inf|rd! En fil som inneh}ller beskrivningar p} alla filer i ett dir. Shell-scriptet List-Files f|r att lista vilka filer som inte {r beskrivna. * s-string.[ch]: Fler funktioner: s_skip_blanks(), s_strtol(). Sat May 26 15:02:48 1990 Per Cederqvist (ceder at laila) * Mailinglist: Ny fil som inneh}ller email-adresser p} alla de som svarat p} mitt inl{gg i Linus-kom om mailinglistan. Det vore fint om n}gon skickar ett mail till dom n{r LysKom {r ig}ng... Tills vidare tar jag p} mig ansvaret f|r utskicken. Sat May 26 01:36:02 1990 Thomas Bellman (bellman at laila) * s-string.[hc]: Nya funktioner s_strhead() och s_usr_strhead(). Testar om en str{ng {r en b|rjan p} en annan. Fri May 25 02:37:55 1990 Per Cederqvist (ceder at lave) * s-string.h: Nytt macro s_empty(str) som returnerar TRUE omm str {r tom. * kom-types.h: Tog bort f{ltet 'Conf_type type' ur Membership-structen. Det visar sig att det {r b{ttre att cacha Conf_type tillsammans med namnet. Tue May 15 17:49:47 1990 Per Cederqvist (ceder at laila) * kom-types.h: Info_type och Info_datum: Ny typ: sent_at. S} att man vet n{r en text {r skickad n{r den skickas i efterhand. Mon May 14 08:59:14 1990 Thomas Bellman (bellman at laila) * Biblioteket kom:/ansi-include skapat. Detta bibliotek genoms|kes av cpp enligt Makefile (Template). I biblioteket finns {n s} l{nge stdio.h, malloc.h och string.h. Strunta i filen kom:/ansi.h. NU ska vi v{l {ntligen slippa ifr}n alla problem vi haft med include-filer och odeklarerade funktioner. Fyll g{rna p} med fler generella .h-filer. Sun May 13 23:12:23 1990 Per Cederqvist (ceder at lage) * kom-errno.[hc]: s} heter den nu. Sun May 13 23:05:23 1990 Thomas Bellman (bellman at laila) * s-string.[ch]: Skapad. V}r egen str{ngtyp (String) samt funktioner f|r att manipulera dessa. Thu May 10 16:27:35 1990 Per Cederqvist (ceder at lage) * config.h: DEFENSIVE_CHECKS - definierad om vi {r defensiva. Wed May 9 17:34:31 1990 Linus Tolke (linus at laila) * Person-strukten anv{nder String och Mark_list ist{llet f|r char * och Mark * Jag justerade ordningen f|r filerna som argument till etags. Jag vill n{mligen n} typen Person p} mindre {n 3 steg! Tue May 8 19:36:44 1990 Per Cederqvist (ceder at lage) * bool heter numera Bool. * Ny typ: Success. Att anv{ndas av alla funktioner som returnerar OK eller FAILURE. Fri May 4 01:25:23 1990 Per Cederqvist (ceder at lage) * services.h: create_conf tar nu {ven Conf_type type som argument. P} s} vis kan ett hemligt m|te vara hemligt fr}n b|rjan. Thu May 3 00:56:35 1990 Per Cederqvist (ceder at lage) * kom-types.h: Nytt f{lt i Membership: Conf_type type * jin_errno heter numera kom_errno. * query_unread_mail heter numera query_unread och {r lite mer flexibel - man kan fr}ga hur mycket ol{sta en viss person har i ett visst m|te. Thu Apr 26 01:52:51 1990 Thomas Bellman (bellman at lage) * P{rm f|r listningar inskaffad. Gamla listningar av 2kom/ och 2kom/client/ finns insatta. N{r ni tar ut listningar, s{tt in dem i p{rmen. Den ligger i hyllan ovanf|r LLL. En gul p{rm m{rkt "LysKOM". Observera att listningarna som sitter i den just nu {r inaktuella, p g a.... * OMORGANISATION!!! Saker som l}g i kom-types.h som ska se olika ut f|r server och klient, {r flyttade till client/client-types.h resp. server/server-types.h. Samtidigt togs types.h bort. * Listor i Person- och Conference-structarna {r nu egna typer. * 'get_person_stat()' och 'get_conf_stat()' tar numera en pekare till en area d{r resultatet ska l{ggas. Dessutom skickar man med en mask som talar om hur mycket information man vill ha. Wed Apr 25 02:38:32 1990 Thomas Bellman (bellman at laila) * Lade till 'footnote to' och 'footnote in' i misc_info. * Skapade 'kom-types.c' som typiskt inneh}ller konstanter och annat som man tycker borde ligga i en .h-fil, men som inte kan g|ra det om filen inkluderas i mer {n en k{llkodsfil. Wed Apr 25 00:49:01 1990 Per Cederqvist (ceder at laila) * services.h: add_member tar numera tv} parametrar f|r att ange prioritet p} m|tet. add_member anv{nds {ven f|r att {ndra prioritet p} ett m|te man redan {r med i. Sat Apr 21 13:52:12 1990 Per Cederqvist (ceder at lave) * Fixade en Makefile som generarar en TAGS-fil som inneh}ller allt till servern. * kom-types.h: Nya privilegiebitar: admin och statistic. Fri Apr 20 14:09:26 1990 Per Cederqvist (ceder at lage) * kom-types.h: Ny typ Conf_nos. * services.h: Ny definition av lookup_name. Nu returneras en lista med alla konferenser som matchar argumentet. * P} beg{ran av Bellman {r nu jin_errno en enum. Thu Apr 19 02:47:05 1990 Per Cederqvist (ceder at lave) * kom-types.h: Conf_type: nytt f{lt "no_stat". Sec_bits: ny typ som anger vad en person vill h}lla hemligt. Person: nytt f{lt "flags". Wed Apr 18 00:08:22 1990 Per Cederqvist (ceder at lage) * services.h: get_marks har nu ingen parameter. Man kan bara titta p} sina egna markeringar. * kom-types.h inkluderar nu {ven * Skapade jin_errno.h. * services.h: alla funktioner som returnerade en struct returnerar nu en pekare till motsvarande struct. * Ny funktion i services: query_unread_mail. (Se m 230) Wed Apr 18 00:08:22 1990 Per Cederqvist (ceder at lage) Det SIST SKRIVNA hamnar F\RST I FILEN /Aronsson. Loggfil d{r man skriver vad man g|r. Det {r b{ttre att du skriver lite {n inte alls (mest riktat till mig sj{lv...). /lw 900402 ---------------------------------------------------------------------- 3 juni 1991 Aronsson Uppdaterat prot-A.txt och i denna inkluderat prot-A.bnf. Satt prot-A.bnf till att vara en symbolisk l{nk till txt-filen. 14 oktober 1990 Aronsson was here Lagt hit nedanst}ende filer. Originalen beh}ller jag hemma hos mig. prot-A.txt Spec protokoll A. Textdelen. Svensk font. prot-A.bnf Spec protokoll A. Koddelen. Engelsk font. version Hantering av {ndringsf|rslag och versioner. 1990-04-17 /ceder Tog bort den felaktiga definitionen av typen Connection ur kom-types.h. Den riktiga finns i server/server.h. Flyttade definitioner av Persons, Marks, String och Map till kom-types.h. B|rjade anv{nda M-X Add-change-log-entry i st{llet. 900407 /lw Det h{r {r c. Allts} b|r active_connection vara en pekare! (har {ndrat) Flyttade smalloc ("s{ker" malloc) till cache.c. Nu sparar ldb.c {ven texts-f{ltet i person-structen... 1990-04-04 /ceder [ndrade i Person-structen: Tog bort created_texts. La till first_text, last_text och texts (en lista med globala textnummer de globala textnummer som personen har skapat.) active_connection (server.h) {r index i arrayen connections (connections.c). Skapade filen doc/security-levels.txt d{r det anges vad de olika priv-bitarna inneb{r. 900404 /lw [ndrade ldb:s felhantering. Nu finns den! Fortfarande inte speciellt snygg, men n}got b{ttre {n tidigare. Returnerar intern felkod i ldb_errno och filhandtag till felande filen i ldb_errfileno. 1990-04-02 /ceder Fr}n och med nu anv{nder vi ISO-standard f|r datum. (:-) kom-types.h: Tog bort flags och lade till user_area i Person-structen. 900402 /lw Vi flyttade om filerna. Under ldb ligger nu i princip endast ldb.c och ldb.h. Under client ligger de filer som {r specifika f|r klienten och under server ligger de server-specifika filerna. doc-directoryt inneh}ller dokumentationen f|r det vi h}ller p} med. Direkt under 2kom ligger f|r n{rvarande allt som {r gemensamt f|r s}v{l klient som server. Det {r types.h och kom-types.h (varf|r {r det uppdelat i tv} filer?) samt services.h som tidigare hette atomic.h. Jag har f|rresten tagit bort parametern connection som alla funktioner i atomic.h hade. Fr}n klientens synvinkel finns inte den parametern och det verkar f}nigt att ha den i servern. Om man har samma parameter till samtliga funktioner tycker jag det {r ganska vettigt att i st{llet anv{nda en global variabel. lyskom-server-2.1.2/README.FSF0000664000015100472110000000032306177762166011332 The Free Software Foundation has a new address. Many files in this distribution contain the old address. The new one is Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. lyskom-server-2.1.2/HACKING0000664000015100472110000001224707721746274011032 This file contains some information intended for the developers of lyskomd. It is probably only useful if you have access to the CVS repository (there is no anoncvs access at this time) or if you are about to make a new release of lyskomd. See also doc/lyskomd.texi. Support programs ================ It is important to use the correct version of some support programs when creating the distribution. (This section is not relevant if you are using a normal release -- these tools are only needed when creating the distribution.) Automake 1.7.6 -------- Automake 1.7.6 is recommended. To get decent handling of locating the python binary you need to apply a patch that can be found at http://sources.redhat.com/cgi-bin/gnatsweb.pl?database=automake. The relevant problem report number is 398. The CVS version of automake contains a better fix, but the lyskomd code is not yet updated to use it. Autoconf 2.56 -------- Autoconf 2.56 is recommended. 2.55 might be good enough. Perl 5.6.1 ---- The perl version should not matter. Python 2.1 ------ The version of Python should not matter. 1.5 should be good enough. Go with Python 2.1, Python 2.2.1 or newer. Bison and flex -------------- You may need the Gnu tools bison and flex. The standard lex and yacc are not flexible enough. You should have bison version 1.35 or later and flex version 2.5.4 or later. DejaGnu 1.4.2 ------- You need a recent DejaGnu release. DejaGnu in turn needs TCL and expect. See README. Texinfo 4.2 ------- You need a recent version of GNU texinfo to process the documentation. Version 4.2 is recommended. Version 4.0 is too old. Release generation ================== Follow these steps: * Check that all bugs refered to in doc/Protocol-A.texi are still open. (Search for "bugzilla" to find them.) * Run make distcheck and make sure it works. * Check that you can unpack the resulting archive, and then run ./configure --prefix=/tmp/foo make install Note that the "-C" option isn't used, and that there is no intermediate "make" step (those more normal methods of compilation are tested thoroughly by the Xenofarm). * Check that the following files are updated: doc/Protocol-A.texi doc/lyskomd.texi README NEWS * Run doc/Protocol-A.texi through M-x ispell. * Run the testsuite with the EXTENDED tests (search for EXTENDED in src/server/testsuite/lyskomd.0/gen-*.py). This requires some patience. Be sure to reset EXTENDED to 0 when you are done. * Define TYPE_CHECK_COMPILATION in misc-types.h and recompile. Check that the error messages are sane. Undo the change. * Use src/server/testsuite/lyskomd.0/summarize.sh * Move all unresolved bugs for the milestone, if any, to a new milestone. * Set the version number in these files: versions configure.in doc/Protocol-A.texi * Fix the Copyright statement in these files: scripts/update-copyright scripts/lyskomd-copyrights * Write a note such as "* Release 1.9.0." in ChangeLog. * Make sure the release date is properly set in NEWS and doc/Protocol-A.texi. * Commit everything. * Update the copyright statements by running scripts/lyskomd-copyrights repeatedly until nothing happens. * Commit everything. * Wait until the Xenofarm has built the package and tested it. * Run these commands: ./mkmi ./configure -C make distclean # We want to recompute all dependencies. ./configure -C make check # Recompute them. make distcheck Make sure that the host where you do this have TeX installed, so that you ensure that the dvi target is working. * Compare the resulting file with the file in the Xenofarm build. There should be no noteworthy differences. Discard the resulting file and use the distribution from Xenofarm, as that is the distribution that has received a lot of testing. * Compare the distribution with the previous release, and ensure that no unexpected differences exists. * Test the distribution on u137 and possibly more machines. Repeat until no failure. * Sign the archive using GPG: gpg -s -b lyskom-server-2.0.7.tar.gz * Set a tag: cvs tag server-2-0-0 * Copy the tar file and the GPG signature to the FTP server and the Web server: /lysator/ftp/pub/lyskom/server/ /lysator/www/www-pages/html/lyskom/ * Create a diff. tar xfz /lysator/ftp/pub/lyskom/server/lyskom-server-1.9.0.tar.gz tar xfz /lysator/ftp/pub/lyskom/server/lyskom-server-2.0.0.tar.gz diff -u --recursive --unidirectional-new-file \ lyskom-1.9.0 lyskom-server-2.0.0 Publish the diff only if it works and is small enough. * Add the new version number to Bugzilla. * Mark all resolved and verified bugs for the milestone as closed. * Update /lysator/www/www-pages/html/lyskom/index.html * Update /lysator/www/www-pages/html/lyskom/index-en.html * Update /lysator/www/www-pages/html/lyskom/lyskom-server/index.html * Update /lysator/www/www-pages/html/lyskom/lyskom-server/NEWS.txt * Publish the protocol specification using the update-www target of doc/Makefile. Be careful! Check that nothing in the WWW setup has changed before running the make target. * Announce the release in "Nyheter (om) LysKOM". * Announce the release on Freshmeat. * Announce the release in "News about LysKOM" in com.lysator.liu.se. lyskom-server-2.1.2/mkmi0000775000015100472110000000347307721716112010713 #!/bin/sh # $Id: mkmi,v 1.19 2003/08/23 16:38:23 ceder Exp $ # Generate Makefile.in from Makefile.src template # Copyright (C) 1994-1996, 1998-1999, 2003 Lysator Academic Computer Association. # # 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 2, 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, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. [ -f src/server/lyskomd.h ] || { echo $0: must be run from top of the source directory >&2 exit 1 } # Remove these files so that we pick up the correct versions from # automake. We rely on the automake maintainer to make sure that # these files are always up-to-date as long as we install the latest # automake. rm -f \ scripts/install-sh \ scripts/missing \ scripts/texinfo.tex \ scripts/mkinstalldirs \ scripts/depcomp \ scripts/mdate-sh \ INSTALL aclocal autoheader automake -a autoconf (cd src/libraries/libisc-new && aclocal) (cd src/libraries/libisc-new && automake -a) (cd src/libraries/libisc-new && autoconf) (cd src/libraries/liboop && aclocal) (cd src/libraries/liboop && automake -a) (cd src/libraries/liboop && autoconf) (cd src/libraries/adns && aclocal) (cd src/libraries/adns && autoheader) (cd src/libraries/adns && automake -a) (cd src/libraries/adns && autoconf) lyskom-server-2.1.2/versions0000664000015100472110000000354507723633366011636 # versions -- This file specifies various version numbers for lyskomd. # $Id: versions,v 1.30 2003/08/29 11:14:11 ceder Exp $ # Copyright (C) 1994-1997, 1999-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Be careful when editing this file. This file is used by rules in # ./Makefile.src and ./src/server/Makefile.src. The '#' character # does currently *not* introduce comments, it only looks that way. # Version of prot-A.txt that this server implements: PROTOCOL-A-LEVEL: 11 # Name of the LysKOM server software: SERVER-SOFTWARE: lyskomd # Version of the LysKOM server software. This can be any string. If # you make an unofficial distribution, *please* change this to # something unique! Suggestion: suffix it with your initials, # e.g. 1.7.0.ppp.1 SERVER-VERSION: 2.1.2 # Old clients don't know how to get the version number as a string, so # they are stuck with this old-format integer version number. This # should be 10000*x+100*y+z (if the version number is written on x.y.z # form). SERVER-COMPAT-VERSION: 20102 lyskom-server-2.1.2/doc/0000777000015100472110000000000007723710264010654 5lyskom-server-2.1.2/doc/Makefile.am0000664000015100472110000002666407723644645012655 # $Id: Makefile.am,v 1.61 2003/08/29 12:37:16 ceder Exp $ # Copyright (C) 1998-1999, 2001-2002 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # include $(top_srcdir)/scripts/common.make SUBDIRS = man info_TEXINFOS = Protocol-A.texi lyskomd.texi MOSTLYCLEANFILES = Protocol-A.notab lyskomd.notab *.tmp \ protocol-a.texi protocol-a.aux protocol-a.fns protocol-a.log \ protocol-a.toc protocol-a.am protocol-a.cp protocol-a.fn \ protocol-a.ky protocol-a.pg protocol-a.tp protocol-a.vr \ Protocol-A.dvi DISTCLEANFILES = Protocol-A.pdf protocol-a-current.txt \ protocol-a-recommended.txt protocol-a-full.txt EXTRA_DIST = .cvsignore \ IDEAS \ checkargs.py \ cmsltt12.mf \ constructs.expected \ filterlines.py \ kom-style.el \ tac.py # Automake does not yet support these targets automatically. pdf: Protocol-A.pdf html: protocol-a/index.html protocol-a.html # Automake tries to generate this rule automatically, but it fails # because of the capital letters in the file name of the source file. protocol-a.info: Protocol-A.texi $(RM) $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9] $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ -o $@ `test -f '$<' || echo '$(srcdir)/'`$< # The TeX implementation cannot cope with Protocol-A.texi. We use too # many macros in too complex ways. But if we expand a few of them # with a simple sed-script, texinfo.tex will do a fair job. # Unfortunately, this means that the automake magic fails, so we # disable it with a explicit targets for the dvi and pdf output. Protocol-A.dvi: protocol-a.texi TEXINPUTS="$(top_srcdir)/scripts:$$TEXINPUTS" \ MAKEINFO='makeinfo -I .' \ texi2dvi protocol-a.texi mv protocol-a.dvi $@ Protocol-A.pdf: protocol-a.texi TEXINPUTS="$(top_srcdir)/scripts:$$TEXINPUTS" \ MAKEINFO='makeinfo -I .' \ texi2dvi --pdf protocol-a.texi mv protocol-a.pdf $@ protocol-a.texi: Protocol-A.texi ## This sed script works with texinfo.tex version 2002-03-26.08. ## With any luck, this could be replaced by a simple "cp" when ## a future version of texinfo.tex is created. sed < $(srcdir)/Protocol-A.texi \ -e 's/@holl{\([^,]*\),\([^}]*\)}/\1H\2/g' \ -e 's/@value{IAM}/Inl@"agg @}t mig/g' \ -e 's/@lt{\([^}]*\)}/\1/g' \ > $@.tmp chmod 444 $@.tmp $(RM) $@ mv $@.tmp $@ SUFFIXES = .texi .notab .texi.notab: ## Mixing tabs and non-tabs may cause the info file to look ## ugly. Ban tabs. $(RM) $@ if grep -n ' ' $< /dev/null ; then echo tabs detected ; exit 1; fi $(AWK) 'length($0) > 79 {print FILENAME ":" NR ": too long line"; e=1}\ END {exit(e)}' $< echo no tabs found > $@ protocol-a/index.html: Protocol-A.texi makeinfo --html $(srcdir)/Protocol-A.texi protocol-a.html: Protocol-A.texi makeinfo --html --no-split $(srcdir)/Protocol-A.texi # The stuff below is used to update the official WWW pages at # http://www.lysator.liu.se/lyskom/protocol/ WWWROOT=/lysator/www/www-pages/html/lyskom/protocol PROTOEDITION=`sed -n 's/^@set PROTOEDITION //p' < $(srcdir)/Protocol-A.texi` WWWREV=$(WWWROOT)/$(PROTOEDITION) update-www: protocol-a.info protocol-a.html protocol-a/index.html \ Protocol-A.dvi Protocol-A.pdf protocol-a-full.txt cd $(WWWROOT) || false rm -rf $(WWWREV) \ Protocol-A-$(PROTOEDITION)-info \ $(WWWROOT)/Protocol-A-$(PROTOEDITION)-info.tar \ $(WWWROOT)/Protocol-A-$(PROTOEDITION)-info.tar.gz mkdir $(WWWREV) mkdir Protocol-A-$(PROTOEDITION)-info cp protocol-a.info* Protocol-A-$(PROTOEDITION)-info tar cvf $(WWWROOT)/Protocol-A-$(PROTOEDITION)-info.tar \ Protocol-A-$(PROTOEDITION)-info echo Protocol-A-$(PROTOEDITION)-info.tar|(cd $(WWWROOT)&&xargs gzip -9) cp $(srcdir)/Protocol-A.texi $(WWWROOT)/Protocol-A-$(PROTOEDITION).texi rm -r Protocol-A-$(PROTOEDITION)-info cp Protocol-A.dvi $(WWWROOT)/Protocol-A-$(PROTOEDITION).dvi cp Protocol-A.pdf $(WWWROOT)/Protocol-A-$(PROTOEDITION).pdf ln -s ../Protocol-A-$(PROTOEDITION).texi $(WWWREV)/Protocol-A.texi cp protocol-a.html $(WWWREV)/protocol-a.html cp protocol-a/* $(WWWREV)/ cp protocol-a-*.txt $(WWWREV)/ echo "Don't forget to edit $(WWWROOT)/index.html" check: check-doc pdf dvi protocol-a-full.txt: Protocol-A.texi checkargs.py $(MAKE) check-doc check-doc: Protocol-A.notab lyskomd.notab info if HAVE_PYTHON ## Create a list of all aux-items. sed -n 's/[0-9][0-9]* : \([^ ]*\) (.*/\1/p' \ $(top_srcdir)/run-support/aux-items.conf \ | tee aux-items.tmp \ | sed 's/.*/@aux{&}/' \ | LANG=C LC_ALL=C LC_COLLATE=C LC_CTYPE=C sort \ > aux-items-@.tmp ## Create a list of client-specific aux items. sed -n '/^@c BEGIN-EXTRA-AUX$$/,/^@c END-EXTRA-AUX$$/s/^@item \(.*\) \[[0-9]*\] (.*)$$/@aux{\1}/p' \ < $(srcdir)/Protocol-A.texi \ | LANG=C LC_ALL=C LC_COLLATE=C LC_CTYPE=C sort \ > aux-items-extra-@.tmp ## Check for any overlap between the aux-item lists. $(PYTHON) $(srcdir)/filterlines.py aux-items-extra-@.tmp \ < aux-items-@.tmp \ | diff -c aux-items-@.tmp - $(PYTHON) $(srcdir)/filterlines.py aux-items-@.tmp \ < aux-items-extra-@.tmp \ | diff -c aux-items-extra-@.tmp - ## Create a list of all requests. sed -e '/^#ifdef/,/^#endif/d' \ -e '/^#/d' \ -e '/^$$/d' \ < $(top_srcdir)/src/server/fncdef.txt \ | awk '{print $$1, $$3}' \ | sed 's/_/-/g' \ | tee requests-numbered.tmp \ | awk '{print $$2}' \ | tee requests.tmp \ | sed 's/.*/@req{&}/' \ > requests-@.tmp sed 's/.*/@reqlink{&}/' \ < requests.tmp >> requests-@.tmp sed 's/.*/@reqdlink{&}/' \ < requests.tmp >> requests-@.tmp ## Create a list of all async messages. sed -n -e '/^#if 0/,/^#endif/d' \ -e '/^#ifdef/,/^#endif/d' \ -e 's/[ ]*ay_\([^ ]*\) = \([0-9]*\).*/\2 async_\1/p' \ $(top_srcdir)/src/server/async.h \ | sed 's/_/-/g' \ | tee asyncs-numbered.tmp \ | awk '{print $$2}' \ | tee asyncs.tmp \ | sed 's/.*/@async{&}/' \ > async-@.tmp sed 's/.*/@asynclink{&}/' \ < asyncs.tmp >> async-@.tmp sed 's/.*/@asyncdlink{&}/' \ < asyncs.tmp >> async-@.tmp ## Create a list of all miscinfos. cat $(top_srcdir)/src/include/kom-types.h \ | sed -e '/^enum info_type {/,/};/!d' \ | sed -n -e 's/ *\([^ ]*\)[ ]*= *\([0-9]*\),.*/\2 \1/p' \ | sed 's/_/-/g' \ | grep -v unknown-info \ | tee miscs-numbered.tmp \ | sed 's/[0-9]* //' \ | tee miscs.tmp \ | sed 's/.*/@misc{&}/' \ > miscs-@.tmp ## Create a list of all conf-type bits. $(PYTHON) $(srcdir)/tac.py < $(top_srcdir)/src/include/kom-types.h \ | sed -e '/} Conf_type/,/typedef/!d' \ | sed -n -e 's/.*unsigned int[ ]*\([^ :]*\)[ ]*:.*/\1/p' \ | sed -e 's/_/-/g' \ -e 's/allow-anon/allow-anonymous/' \ -e 's/letter-box/letterbox/' \ | tee conftypes.tmp \ | sed 's/.*/@conftype{&}/' \ > conftypes-@.tmp ## Create a list of all types. We do this from the ## documentation, and not the source, since the source has its ## own funny names in a few places. sed -n 's/@tindex //p' < $(srcdir)/Protocol-A.texi \ | tee types.tmp \ | sed 's/.*/@type{&}/' \ > types-@.tmp ## Create a list of all error codes. cat $(top_srcdir)/src/include/kom-errno.h \ | sed -n -e '/enum kom_err/,/};/!d' \ -e 's/ *KOM_\([A-Z_]*\) *= *\([0-9]*\),.*/\2 \1/p' \ | tr '[A-Z]' '[a-z]' \ | sed -e 's/_/-/g' \ -e 's/ not-impl$$/ not-implemented/' \ -e 's/ obsolete$$/ obsolete-call/' \ -e 's/ pwd$$/ invalid-password/' \ -e 's/ long-str$$/ string-too-long/' \ -e 's/ login$$/ login-first/' \ -e 's/ conf-zero$$/ conference-zero/' \ -e 's/ undef-conf$$/ undefined-conference/' \ -e 's/ undef-pers$$/ undefined-person/' \ -e 's/ access$$/ access-denied/' \ -e 's/ perm$$/ permission-denied/' \ -e 's/ conf-exists$$/ conference-exists/' \ -e 's/ pers-exists$$/ person-exists/' \ -e 's/ letter-box$$/ letterbox/' \ -e 's/ ldb-err$$/ ldb-error/' \ -e 's/ ill-misc$$/ illegal-misc/' \ -e 's/ comm-limit$$/ comment-limit/' \ -e 's/ foot-limit$$/ footnote-limit/' \ -e 's/ undef-session$$/ undefined-session/' \ -e 's/ tempfail$$/ temporary-failure/' \ -e 's/ anon-rejected$$/ anonymous-rejected/' \ -e 's/ ill-aux$$/ illegal-aux-item/' \ -e 's/ aux-perm$$/ aux-item-permission/' \ | tee errorcodes-numbered.tmp \ | sed 's/[0-9]* //' \ | tee errorcodes.tmp \ | sed 's/.*/@errorcode{&}/' \ > errorcodes-@.tmp ## Create a list of all privilege bits. $(PYTHON) $(srcdir)/tac.py < $(top_srcdir)/src/include/kom-types.h \ | sed -n -e '/} Priv_bits;/,/typedef[ ]struct/!d' \ -e 's/_/-/g' \ -e 's/.* int[ ]\([-a-z0-9]*\)[ ]*:.*/\1/p' \ | tee privbits.tmp \ | sed 's/.*/@priv{&}/' \ > privbits-@.tmp ## Create a list of all @x{}-constructs used. sed -e '/@bye/,$$d' \ -e '/^@c /d' \ -e '/^@c$$/d' \ -e '/^@comment /d' \ -e '/^@macro /,/@end macro/d' \ -e 's/@{//g' \ -e 's/@}//g' \ -e "`echo s/@/\\\\ ;echo @/g`" \ $(srcdir)/Protocol-A.texi \ | sed -n 's/\(@[^{}]*{[^}]*}\).*/\1/p' \ | grep -v '^@holl{' \ | grep -v '^@badspell{' \ | LANG=C LC_ALL=C LC_COLLATE=C LC_CTYPE=C sort \ | LANG=C LC_ALL=C LC_COLLATE=C LC_CTYPE=C uniq \ > constructs.tmp ## Remove the expected stuff. @rarg{} and @aarg{} constructs ## are checked below, so ignore them here. Various @ref ## constructs are checked by makeinfo, so we ignore them as ## well. @t{} are not interresting. cat constructs.tmp \ | grep -v '@rarg{' \ | grep -v '@aarg{' \ | grep -v '@ref{' \ | grep -v '@xref{' \ | grep -v '@pxref{' \ | grep -v '@t{' \ | grep -v '@footnote{' \ | grep -v '@field{' \ | grep -v '@anchor{' \ | grep -v '@lt{' \ | $(PYTHON) $(srcdir)/filterlines.py \ aux-items-@.tmp \ aux-items-extra-@.tmp \ requests-@.tmp \ types-@.tmp \ async-@.tmp \ miscs-@.tmp \ conftypes-@.tmp \ errorcodes-@.tmp \ privbits-@.tmp \ > constructs-@.tmp ## If the diff command below finds any differences, you have to ## check that they are expected, and then manually update ## constructs.expected. Please be careful when you examine the ## diff. diff -c $(srcdir)/constructs.expected constructs-@.tmp ## Check @rarg{} and @aarg{} constructs. They are only allowed ## to refer to named arguments of the call they are documenting. $(PYTHON) $(srcdir)/checkargs.py $(srcdir)/Protocol-A.texi else @echo >&2 @echo WARNING: no python interpreter was found by configure, so >&2 @echo most documentation tests could not be run. >&2 @echo >&2 endif # The targets below are for the benefit of the Xenofarm automated # builds. They provide information for the build summary. See # http://www.lysator.liu.se/lyskom/lyskom-server/xenofarm.html ident-makeinfo: @echo '$$(MAKEINFO):' $(MAKEINFO) @-type makeinfo @echo Obtaining version: -makeinfo --version @echo Obtaining version: -$(MAKEINFO) --version lyskom-server-2.1.2/doc/Makefile.in0000664000015100472110000007645707723707421012663 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # $Id: Makefile.am,v 1.61 2003/08/29 12:37:16 ceder Exp $ # Copyright (C) 1998-1999, 2001-2002 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEBUG_CALLS = @DEBUG_CALLS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EFENCE = @EFENCE@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FLEX = @FLEX@ HAVE_PYTHON_FALSE = @HAVE_PYTHON_FALSE@ HAVE_PYTHON_TRUE = @HAVE_PYTHON_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSURE = @INSURE@ LANGUAGE_SUFFIX = @LANGUAGE_SUFFIX@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ SED = @SED@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRACED_ALLOCATIONS = @TRACED_ALLOCATIONS@ U = @U@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ YACC = @YACC@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ RM = rm -f dbdir = $(localstatedir)/lyskomd/db exportdir = $(localstatedir)/lyskomd/exportdb SUBDIRS = man info_TEXINFOS = Protocol-A.texi lyskomd.texi MOSTLYCLEANFILES = Protocol-A.notab lyskomd.notab *.tmp \ protocol-a.texi protocol-a.aux protocol-a.fns protocol-a.log \ protocol-a.toc protocol-a.am protocol-a.cp protocol-a.fn \ protocol-a.ky protocol-a.pg protocol-a.tp protocol-a.vr \ Protocol-A.dvi DISTCLEANFILES = Protocol-A.pdf protocol-a-current.txt \ protocol-a-recommended.txt protocol-a-full.txt EXTRA_DIST = .cvsignore \ IDEAS \ checkargs.py \ cmsltt12.mf \ constructs.expected \ filterlines.py \ kom-style.el \ tac.py SUFFIXES = .texi .notab # The stuff below is used to update the official WWW pages at # http://www.lysator.liu.se/lyskom/protocol/ WWWROOT = /lysator/www/www-pages/html/lyskom/protocol PROTOEDITION = `sed -n 's/^@set PROTOEDITION //p' < $(srcdir)/Protocol-A.texi` WWWREV = $(WWWROOT)/$(PROTOEDITION) subdir = doc ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = DIST_SOURCES = TEXINFO_TEX = $(top_srcdir)/scripts/texinfo.tex am__TEXINFO_TEX_DIR = $(top_srcdir)/scripts INFO_DEPS = protocol-a.info lyskomd.info DVIS = Protocol-A.dvi lyskomd.dvi PDFS = Protocol-A.pdf lyskomd.pdf PSS = Protocol-A.ps lyskomd.ps TEXINFOS = Protocol-A.texi lyskomd.texi RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \ ps-recursive install-info-recursive uninstall-info-recursive \ all-recursive install-data-recursive install-exec-recursive \ installdirs-recursive install-recursive uninstall-recursive \ check-recursive installcheck-recursive DIST_COMMON = $(top_srcdir)/scripts/common.make Makefile.am Makefile.in \ stamp-vti version.texi DIST_SUBDIRS = $(SUBDIRS) all: all-recursive .SUFFIXES: .SUFFIXES: .texi .notab .dvi .info .pdf .ps $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/scripts/common.make $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) .texi.info: @rm -f $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9] $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ -o $@ `test -f '$<' || echo '$(srcdir)/'`$< .texi.dvi: TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ $(TEXI2DVI) `test -f '$<' || echo '$(srcdir)/'`$< .texi.pdf: TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ $(TEXI2PDF) `test -f '$<' || echo '$(srcdir)/'`$< protocol-a.dvi: Protocol-A.texi protocol-a.pdf: Protocol-A.texi lyskomd.info: lyskomd.texi version.texi lyskomd.dvi: lyskomd.texi version.texi lyskomd.pdf: lyskomd.texi version.texi version.texi: stamp-vti stamp-vti: lyskomd.texi $(top_srcdir)/configure @(dir=.; test -f ./lyskomd.texi || dir=$(srcdir); \ set `$(SHELL) $(top_srcdir)/scripts/mdate-sh $$dir/lyskomd.texi`; \ echo "@set UPDATED $$1 $$2 $$3"; \ echo "@set UPDATED-MONTH $$2 $$3"; \ echo "@set EDITION $(VERSION)"; \ echo "@set VERSION $(VERSION)") > vti.tmp @cmp -s vti.tmp version.texi \ || (echo "Updating version.texi"; \ cp vti.tmp version.texi) -@rm -f vti.tmp @cp version.texi $@ mostlyclean-vti: -rm -f vti.tmp maintainer-clean-vti: -rm -f stamp-vti version.texi TEXI2DVI = texi2dvi TEXI2PDF = $(TEXI2DVI) --pdf --batch DVIPS = dvips .dvi.ps: $(DVIPS) -o $@ $< uninstall-info-am: $(PRE_UNINSTALL) @if (install-info --version && \ install-info --version | grep -i -v debian) >/dev/null 2>&1; then \ list='$(INFO_DEPS)'; \ for file in $$list; do \ relfile=`echo "$$file" | sed 's|^.*/||'`; \ echo " install-info --info-dir=$(DESTDIR)$(infodir) --remove $(DESTDIR)$(infodir)/$$relfile"; \ install-info --info-dir=$(DESTDIR)$(infodir) --remove $(DESTDIR)$(infodir)/$$relfile; \ done; \ else :; fi @$(NORMAL_UNINSTALL) @list='$(INFO_DEPS)'; \ for file in $$list; do \ relfile=`echo "$$file" | sed 's|^.*/||'`; \ relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \ (if cd $(DESTDIR)$(infodir); then \ echo " rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9])"; \ rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \ else :; fi); \ done dist-info: $(INFO_DEPS) list='$(INFO_DEPS)'; \ for base in $$list; do \ if test -f $$base; then d=.; else d=$(srcdir); fi; \ for file in $$d/$$base*; do \ relfile=`expr "$$file" : "$$d/\(.*\)"`; \ test -f $(distdir)/$$relfile || \ cp -p $$file $(distdir)/$$relfile; \ done; \ done mostlyclean-aminfo: -rm -f Protocol-A.am Protocol-A.aux Protocol-A.cp Protocol-A.fn Protocol-A.fns \ Protocol-A.ky Protocol-A.kys Protocol-A.log Protocol-A.pg \ Protocol-A.pgs Protocol-A.tmp Protocol-A.toc Protocol-A.tp \ Protocol-A.vr Protocol-A.vrs protocol-a.dvi protocol-a.pdf \ protocol-a.ps lyskomd.aux lyskomd.cp lyskomd.cps lyskomd.fn \ lyskomd.fns lyskomd.ky lyskomd.kys lyskomd.log lyskomd.pg \ lyskomd.pgs lyskomd.tmp lyskomd.toc lyskomd.tp lyskomd.tps \ lyskomd.vr lyskomd.vrs lyskomd.dvi lyskomd.pdf lyskomd.ps maintainer-clean-aminfo: @list='$(INFO_DEPS)'; for i in $$list; do \ i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \ echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \ rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \ done # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ETAGS = etags ETAGSFLAGS = CTAGS = ctags CTAGSFLAGS = tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if (etags --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ else \ include_option=--include; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -f $$subdir/TAGS && \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$tags$$unique" \ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = .. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) $(mkinstalldirs) $(distdir)/../scripts @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d $(distdir)/$$subdir \ || mkdir $(distdir)/$$subdir \ || exit 1; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" \ distdir=../$(distdir)/$$subdir \ distdir) \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-info check-am: all-am check: check-recursive all-am: Makefile $(INFO_DEPS) installdirs: installdirs-recursive installdirs-am: $(mkinstalldirs) $(DESTDIR)$(infodir) install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: $(DVIS) info: info-recursive info-am: $(INFO_DEPS) install-data-am: install-info-am install-exec-am: install-info: install-info-recursive install-info-am: $(INFO_DEPS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(infodir) @list='$(INFO_DEPS)'; \ for file in $$list; do \ if test -f $$file; then d=.; else d=$(srcdir); fi; \ file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \ for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \ $$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \ if test -f $$ifile; then \ relfile=`echo "$$ifile" | sed 's|^.*/||'`; \ echo " $(INSTALL_DATA) $$ifile $(DESTDIR)$(infodir)/$$relfile"; \ $(INSTALL_DATA) $$ifile $(DESTDIR)$(infodir)/$$relfile; \ else : ; fi; \ done; \ done @$(POST_INSTALL) @if (install-info --version && \ install-info --version | grep -i -v debian) >/dev/null 2>&1; then \ list='$(INFO_DEPS)'; \ for file in $$list; do \ relfile=`echo "$$file" | sed 's|^.*/||'`; \ echo " install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$relfile";\ install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$relfile || :;\ done; \ else : ; fi install-man: installcheck-am: maintainer-clean: maintainer-clean-recursive maintainer-clean-am: distclean-am maintainer-clean-aminfo \ maintainer-clean-generic maintainer-clean-vti mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-aminfo mostlyclean-generic mostlyclean-vti pdf: pdf-recursive pdf-am: $(PDFS) ps: ps-recursive ps-am: $(PSS) uninstall-am: uninstall-info-am uninstall-info: uninstall-info-recursive .PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \ clean-generic clean-recursive ctags ctags-recursive dist-info \ distclean distclean-generic distclean-recursive distclean-tags \ distdir dvi dvi-am dvi-recursive info info-am info-recursive \ install install-am install-data install-data-am \ install-data-recursive install-exec install-exec-am \ install-exec-recursive install-info install-info-am \ install-info-recursive install-man install-recursive \ install-strip installcheck installcheck-am installdirs \ installdirs-am installdirs-recursive maintainer-clean \ maintainer-clean-aminfo maintainer-clean-generic \ maintainer-clean-recursive maintainer-clean-vti mostlyclean \ mostlyclean-aminfo mostlyclean-generic mostlyclean-recursive \ mostlyclean-vti pdf pdf-am pdf-recursive ps ps-am ps-recursive \ tags tags-recursive uninstall uninstall-am uninstall-info-am \ uninstall-info-recursive uninstall-recursive # Automake does not yet support these targets automatically. pdf: Protocol-A.pdf html: protocol-a/index.html protocol-a.html # Automake tries to generate this rule automatically, but it fails # because of the capital letters in the file name of the source file. protocol-a.info: Protocol-A.texi $(RM) $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9] $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ -o $@ `test -f '$<' || echo '$(srcdir)/'`$< # The TeX implementation cannot cope with Protocol-A.texi. We use too # many macros in too complex ways. But if we expand a few of them # with a simple sed-script, texinfo.tex will do a fair job. # Unfortunately, this means that the automake magic fails, so we # disable it with a explicit targets for the dvi and pdf output. Protocol-A.dvi: protocol-a.texi TEXINPUTS="$(top_srcdir)/scripts:$$TEXINPUTS" \ MAKEINFO='makeinfo -I .' \ texi2dvi protocol-a.texi mv protocol-a.dvi $@ Protocol-A.pdf: protocol-a.texi TEXINPUTS="$(top_srcdir)/scripts:$$TEXINPUTS" \ MAKEINFO='makeinfo -I .' \ texi2dvi --pdf protocol-a.texi mv protocol-a.pdf $@ protocol-a.texi: Protocol-A.texi sed < $(srcdir)/Protocol-A.texi \ -e 's/@holl{\([^,]*\),\([^}]*\)}/\1H\2/g' \ -e 's/@value{IAM}/Inl@"agg @}t mig/g' \ -e 's/@lt{\([^}]*\)}/\1/g' \ > $@.tmp chmod 444 $@.tmp $(RM) $@ mv $@.tmp $@ .texi.notab: $(RM) $@ if grep -n ' ' $< /dev/null ; then echo tabs detected ; exit 1; fi $(AWK) 'length($0) > 79 {print FILENAME ":" NR ": too long line"; e=1}\ END {exit(e)}' $< echo no tabs found > $@ protocol-a/index.html: Protocol-A.texi makeinfo --html $(srcdir)/Protocol-A.texi protocol-a.html: Protocol-A.texi makeinfo --html --no-split $(srcdir)/Protocol-A.texi update-www: protocol-a.info protocol-a.html protocol-a/index.html \ Protocol-A.dvi Protocol-A.pdf protocol-a-full.txt cd $(WWWROOT) || false rm -rf $(WWWREV) \ Protocol-A-$(PROTOEDITION)-info \ $(WWWROOT)/Protocol-A-$(PROTOEDITION)-info.tar \ $(WWWROOT)/Protocol-A-$(PROTOEDITION)-info.tar.gz mkdir $(WWWREV) mkdir Protocol-A-$(PROTOEDITION)-info cp protocol-a.info* Protocol-A-$(PROTOEDITION)-info tar cvf $(WWWROOT)/Protocol-A-$(PROTOEDITION)-info.tar \ Protocol-A-$(PROTOEDITION)-info echo Protocol-A-$(PROTOEDITION)-info.tar|(cd $(WWWROOT)&&xargs gzip -9) cp $(srcdir)/Protocol-A.texi $(WWWROOT)/Protocol-A-$(PROTOEDITION).texi rm -r Protocol-A-$(PROTOEDITION)-info cp Protocol-A.dvi $(WWWROOT)/Protocol-A-$(PROTOEDITION).dvi cp Protocol-A.pdf $(WWWROOT)/Protocol-A-$(PROTOEDITION).pdf ln -s ../Protocol-A-$(PROTOEDITION).texi $(WWWREV)/Protocol-A.texi cp protocol-a.html $(WWWREV)/protocol-a.html cp protocol-a/* $(WWWREV)/ cp protocol-a-*.txt $(WWWREV)/ echo "Don't forget to edit $(WWWROOT)/index.html" check: check-doc pdf dvi protocol-a-full.txt: Protocol-A.texi checkargs.py $(MAKE) check-doc check-doc: Protocol-A.notab lyskomd.notab info @HAVE_PYTHON_TRUE@ sed -n 's/[0-9][0-9]* : \([^ ]*\) (.*/\1/p' \ @HAVE_PYTHON_TRUE@ $(top_srcdir)/run-support/aux-items.conf \ @HAVE_PYTHON_TRUE@ | tee aux-items.tmp \ @HAVE_PYTHON_TRUE@ | sed 's/.*/@aux{&}/' \ @HAVE_PYTHON_TRUE@ | LANG=C LC_ALL=C LC_COLLATE=C LC_CTYPE=C sort \ @HAVE_PYTHON_TRUE@ > aux-items-@.tmp @HAVE_PYTHON_TRUE@ sed -n '/^@c BEGIN-EXTRA-AUX$$/,/^@c END-EXTRA-AUX$$/s/^@item \(.*\) \[[0-9]*\] (.*)$$/@aux{\1}/p' \ @HAVE_PYTHON_TRUE@ < $(srcdir)/Protocol-A.texi \ @HAVE_PYTHON_TRUE@ | LANG=C LC_ALL=C LC_COLLATE=C LC_CTYPE=C sort \ @HAVE_PYTHON_TRUE@ > aux-items-extra-@.tmp @HAVE_PYTHON_TRUE@ $(PYTHON) $(srcdir)/filterlines.py aux-items-extra-@.tmp \ @HAVE_PYTHON_TRUE@ < aux-items-@.tmp \ @HAVE_PYTHON_TRUE@ | diff -c aux-items-@.tmp - @HAVE_PYTHON_TRUE@ $(PYTHON) $(srcdir)/filterlines.py aux-items-@.tmp \ @HAVE_PYTHON_TRUE@ < aux-items-extra-@.tmp \ @HAVE_PYTHON_TRUE@ | diff -c aux-items-extra-@.tmp - @HAVE_PYTHON_TRUE@ sed -e '/^#ifdef/,/^#endif/d' \ @HAVE_PYTHON_TRUE@ -e '/^#/d' \ @HAVE_PYTHON_TRUE@ -e '/^$$/d' \ @HAVE_PYTHON_TRUE@ < $(top_srcdir)/src/server/fncdef.txt \ @HAVE_PYTHON_TRUE@ | awk '{print $$1, $$3}' \ @HAVE_PYTHON_TRUE@ | sed 's/_/-/g' \ @HAVE_PYTHON_TRUE@ | tee requests-numbered.tmp \ @HAVE_PYTHON_TRUE@ | awk '{print $$2}' \ @HAVE_PYTHON_TRUE@ | tee requests.tmp \ @HAVE_PYTHON_TRUE@ | sed 's/.*/@req{&}/' \ @HAVE_PYTHON_TRUE@ > requests-@.tmp @HAVE_PYTHON_TRUE@ sed 's/.*/@reqlink{&}/' \ @HAVE_PYTHON_TRUE@ < requests.tmp >> requests-@.tmp @HAVE_PYTHON_TRUE@ sed 's/.*/@reqdlink{&}/' \ @HAVE_PYTHON_TRUE@ < requests.tmp >> requests-@.tmp @HAVE_PYTHON_TRUE@ sed -n -e '/^#if 0/,/^#endif/d' \ @HAVE_PYTHON_TRUE@ -e '/^#ifdef/,/^#endif/d' \ @HAVE_PYTHON_TRUE@ -e 's/[ ]*ay_\([^ ]*\) = \([0-9]*\).*/\2 async_\1/p' \ @HAVE_PYTHON_TRUE@ $(top_srcdir)/src/server/async.h \ @HAVE_PYTHON_TRUE@ | sed 's/_/-/g' \ @HAVE_PYTHON_TRUE@ | tee asyncs-numbered.tmp \ @HAVE_PYTHON_TRUE@ | awk '{print $$2}' \ @HAVE_PYTHON_TRUE@ | tee asyncs.tmp \ @HAVE_PYTHON_TRUE@ | sed 's/.*/@async{&}/' \ @HAVE_PYTHON_TRUE@ > async-@.tmp @HAVE_PYTHON_TRUE@ sed 's/.*/@asynclink{&}/' \ @HAVE_PYTHON_TRUE@ < asyncs.tmp >> async-@.tmp @HAVE_PYTHON_TRUE@ sed 's/.*/@asyncdlink{&}/' \ @HAVE_PYTHON_TRUE@ < asyncs.tmp >> async-@.tmp @HAVE_PYTHON_TRUE@ cat $(top_srcdir)/src/include/kom-types.h \ @HAVE_PYTHON_TRUE@ | sed -e '/^enum info_type {/,/};/!d' \ @HAVE_PYTHON_TRUE@ | sed -n -e 's/ *\([^ ]*\)[ ]*= *\([0-9]*\),.*/\2 \1/p' \ @HAVE_PYTHON_TRUE@ | sed 's/_/-/g' \ @HAVE_PYTHON_TRUE@ | grep -v unknown-info \ @HAVE_PYTHON_TRUE@ | tee miscs-numbered.tmp \ @HAVE_PYTHON_TRUE@ | sed 's/[0-9]* //' \ @HAVE_PYTHON_TRUE@ | tee miscs.tmp \ @HAVE_PYTHON_TRUE@ | sed 's/.*/@misc{&}/' \ @HAVE_PYTHON_TRUE@ > miscs-@.tmp @HAVE_PYTHON_TRUE@ $(PYTHON) $(srcdir)/tac.py < $(top_srcdir)/src/include/kom-types.h \ @HAVE_PYTHON_TRUE@ | sed -e '/} Conf_type/,/typedef/!d' \ @HAVE_PYTHON_TRUE@ | sed -n -e 's/.*unsigned int[ ]*\([^ :]*\)[ ]*:.*/\1/p' \ @HAVE_PYTHON_TRUE@ | sed -e 's/_/-/g' \ @HAVE_PYTHON_TRUE@ -e 's/allow-anon/allow-anonymous/' \ @HAVE_PYTHON_TRUE@ -e 's/letter-box/letterbox/' \ @HAVE_PYTHON_TRUE@ | tee conftypes.tmp \ @HAVE_PYTHON_TRUE@ | sed 's/.*/@conftype{&}/' \ @HAVE_PYTHON_TRUE@ > conftypes-@.tmp @HAVE_PYTHON_TRUE@ sed -n 's/@tindex //p' < $(srcdir)/Protocol-A.texi \ @HAVE_PYTHON_TRUE@ | tee types.tmp \ @HAVE_PYTHON_TRUE@ | sed 's/.*/@type{&}/' \ @HAVE_PYTHON_TRUE@ > types-@.tmp @HAVE_PYTHON_TRUE@ cat $(top_srcdir)/src/include/kom-errno.h \ @HAVE_PYTHON_TRUE@ | sed -n -e '/enum kom_err/,/};/!d' \ @HAVE_PYTHON_TRUE@ -e 's/ *KOM_\([A-Z_]*\) *= *\([0-9]*\),.*/\2 \1/p' \ @HAVE_PYTHON_TRUE@ | tr '[A-Z]' '[a-z]' \ @HAVE_PYTHON_TRUE@ | sed -e 's/_/-/g' \ @HAVE_PYTHON_TRUE@ -e 's/ not-impl$$/ not-implemented/' \ @HAVE_PYTHON_TRUE@ -e 's/ obsolete$$/ obsolete-call/' \ @HAVE_PYTHON_TRUE@ -e 's/ pwd$$/ invalid-password/' \ @HAVE_PYTHON_TRUE@ -e 's/ long-str$$/ string-too-long/' \ @HAVE_PYTHON_TRUE@ -e 's/ login$$/ login-first/' \ @HAVE_PYTHON_TRUE@ -e 's/ conf-zero$$/ conference-zero/' \ @HAVE_PYTHON_TRUE@ -e 's/ undef-conf$$/ undefined-conference/' \ @HAVE_PYTHON_TRUE@ -e 's/ undef-pers$$/ undefined-person/' \ @HAVE_PYTHON_TRUE@ -e 's/ access$$/ access-denied/' \ @HAVE_PYTHON_TRUE@ -e 's/ perm$$/ permission-denied/' \ @HAVE_PYTHON_TRUE@ -e 's/ conf-exists$$/ conference-exists/' \ @HAVE_PYTHON_TRUE@ -e 's/ pers-exists$$/ person-exists/' \ @HAVE_PYTHON_TRUE@ -e 's/ letter-box$$/ letterbox/' \ @HAVE_PYTHON_TRUE@ -e 's/ ldb-err$$/ ldb-error/' \ @HAVE_PYTHON_TRUE@ -e 's/ ill-misc$$/ illegal-misc/' \ @HAVE_PYTHON_TRUE@ -e 's/ comm-limit$$/ comment-limit/' \ @HAVE_PYTHON_TRUE@ -e 's/ foot-limit$$/ footnote-limit/' \ @HAVE_PYTHON_TRUE@ -e 's/ undef-session$$/ undefined-session/' \ @HAVE_PYTHON_TRUE@ -e 's/ tempfail$$/ temporary-failure/' \ @HAVE_PYTHON_TRUE@ -e 's/ anon-rejected$$/ anonymous-rejected/' \ @HAVE_PYTHON_TRUE@ -e 's/ ill-aux$$/ illegal-aux-item/' \ @HAVE_PYTHON_TRUE@ -e 's/ aux-perm$$/ aux-item-permission/' \ @HAVE_PYTHON_TRUE@ | tee errorcodes-numbered.tmp \ @HAVE_PYTHON_TRUE@ | sed 's/[0-9]* //' \ @HAVE_PYTHON_TRUE@ | tee errorcodes.tmp \ @HAVE_PYTHON_TRUE@ | sed 's/.*/@errorcode{&}/' \ @HAVE_PYTHON_TRUE@ > errorcodes-@.tmp @HAVE_PYTHON_TRUE@ $(PYTHON) $(srcdir)/tac.py < $(top_srcdir)/src/include/kom-types.h \ @HAVE_PYTHON_TRUE@ | sed -n -e '/} Priv_bits;/,/typedef[ ]struct/!d' \ @HAVE_PYTHON_TRUE@ -e 's/_/-/g' \ @HAVE_PYTHON_TRUE@ -e 's/.* int[ ]\([-a-z0-9]*\)[ ]*:.*/\1/p' \ @HAVE_PYTHON_TRUE@ | tee privbits.tmp \ @HAVE_PYTHON_TRUE@ | sed 's/.*/@priv{&}/' \ @HAVE_PYTHON_TRUE@ > privbits-@.tmp @HAVE_PYTHON_TRUE@ sed -e '/@bye/,$$d' \ @HAVE_PYTHON_TRUE@ -e '/^@c /d' \ @HAVE_PYTHON_TRUE@ -e '/^@c$$/d' \ @HAVE_PYTHON_TRUE@ -e '/^@comment /d' \ @HAVE_PYTHON_TRUE@ -e '/^@macro /,/@end macro/d' \ @HAVE_PYTHON_TRUE@ -e 's/@{//g' \ @HAVE_PYTHON_TRUE@ -e 's/@}//g' \ @HAVE_PYTHON_TRUE@ -e "`echo s/@/\\\\ ;echo @/g`" \ @HAVE_PYTHON_TRUE@ $(srcdir)/Protocol-A.texi \ @HAVE_PYTHON_TRUE@ | sed -n 's/\(@[^{}]*{[^}]*}\).*/\1/p' \ @HAVE_PYTHON_TRUE@ | grep -v '^@holl{' \ @HAVE_PYTHON_TRUE@ | grep -v '^@badspell{' \ @HAVE_PYTHON_TRUE@ | LANG=C LC_ALL=C LC_COLLATE=C LC_CTYPE=C sort \ @HAVE_PYTHON_TRUE@ | LANG=C LC_ALL=C LC_COLLATE=C LC_CTYPE=C uniq \ @HAVE_PYTHON_TRUE@ > constructs.tmp @HAVE_PYTHON_TRUE@ cat constructs.tmp \ @HAVE_PYTHON_TRUE@ | grep -v '@rarg{' \ @HAVE_PYTHON_TRUE@ | grep -v '@aarg{' \ @HAVE_PYTHON_TRUE@ | grep -v '@ref{' \ @HAVE_PYTHON_TRUE@ | grep -v '@xref{' \ @HAVE_PYTHON_TRUE@ | grep -v '@pxref{' \ @HAVE_PYTHON_TRUE@ | grep -v '@t{' \ @HAVE_PYTHON_TRUE@ | grep -v '@footnote{' \ @HAVE_PYTHON_TRUE@ | grep -v '@field{' \ @HAVE_PYTHON_TRUE@ | grep -v '@anchor{' \ @HAVE_PYTHON_TRUE@ | grep -v '@lt{' \ @HAVE_PYTHON_TRUE@ | $(PYTHON) $(srcdir)/filterlines.py \ @HAVE_PYTHON_TRUE@ aux-items-@.tmp \ @HAVE_PYTHON_TRUE@ aux-items-extra-@.tmp \ @HAVE_PYTHON_TRUE@ requests-@.tmp \ @HAVE_PYTHON_TRUE@ types-@.tmp \ @HAVE_PYTHON_TRUE@ async-@.tmp \ @HAVE_PYTHON_TRUE@ miscs-@.tmp \ @HAVE_PYTHON_TRUE@ conftypes-@.tmp \ @HAVE_PYTHON_TRUE@ errorcodes-@.tmp \ @HAVE_PYTHON_TRUE@ privbits-@.tmp \ @HAVE_PYTHON_TRUE@ > constructs-@.tmp @HAVE_PYTHON_TRUE@ diff -c $(srcdir)/constructs.expected constructs-@.tmp @HAVE_PYTHON_TRUE@ $(PYTHON) $(srcdir)/checkargs.py $(srcdir)/Protocol-A.texi @HAVE_PYTHON_FALSE@ @echo >&2 @HAVE_PYTHON_FALSE@ @echo WARNING: no python interpreter was found by configure, so >&2 @HAVE_PYTHON_FALSE@ @echo most documentation tests could not be run. >&2 @HAVE_PYTHON_FALSE@ @echo >&2 # The targets below are for the benefit of the Xenofarm automated # builds. They provide information for the build summary. See # http://www.lysator.liu.se/lyskom/lyskom-server/xenofarm.html ident-makeinfo: @echo '$$(MAKEINFO):' $(MAKEINFO) @-type makeinfo @echo Obtaining version: -makeinfo --version @echo Obtaining version: -$(MAKEINFO) --version # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/doc/stamp-vti0000664000015100472110000000014107723710256012436 @set UPDATED 29 August 2003 @set UPDATED-MONTH August 2003 @set EDITION 2.1.2 @set VERSION 2.1.2 lyskom-server-2.1.2/doc/version.texi0000664000015100472110000000014107723710256013147 @set UPDATED 29 August 2003 @set UPDATED-MONTH August 2003 @set EDITION 2.1.2 @set VERSION 2.1.2 lyskom-server-2.1.2/doc/Protocol-A.texi0000664000015100472110000141273707723644645013474 \input texinfo @c -*-texinfo-*- @c @c %**start of header @setfilename protocol-a.info @settitle LysKOM Protocol A @setchapternewpage odd @c @afourpaper @set PROTOEDITION 11.1 @set PROTOVER 11 @set VERSION 2.1.2 @c @holl{l, s} is used to construct Hollerith strings. The main @c reason to use this macro is to help the spell checker. @macro holl {l, s} \l\H\s\ @end macro @c @c Define a few strings that contains characters from ISO Latin-1. @c @iftex @c ispell-ignore @set IAM Inl@"agg @}t mig @set Pell P@"ar Emanuelsson @set Kent Kent Eng@-str@"om@penalty-10000 @set presconf @holl{27,Presentation (av nya) m@"oten} @c ispell-end-ignore @end iftex @ifnottex @c ispell-ignore @set IAM Inlägg @}t mig @set Pell Pär Emanuelsson @set Kent Kent Engström @set presconf @holl{27,Presentation (av nya) möten} @c ispell-end-ignore @end ifnottex @c @c Index setup @c @c Index for asynchronous messages. @defcodeindex am @c Merge all indices. @syncodeindex am fn @syncodeindex tp fn @syncodeindex cp fn @c @c Special markup for this document. @c @c Indicate something that shouldn't be spell-checked @macro badspell{s} \s\ @end macro @c @req{login} is used for protocol requests. @macro req {n} @code{\n\} @end macro @c @reqlink{login} is used for protocol requests, that should be linked. @ifhtml @macro reqlink {n} @code{@ref{\n\}} @end macro @end ifhtml @ifnothtml @macro reqlink {n} @code{\n\} (@pxref{\n\}) @end macro @end ifnothtml @c @reqdlink{login}...@linkhere{} is used for protocol requests, that @c should be linked, where the link should occur a few words after the @c request itself. @ifhtml @c HTML version: make the word a link. @macro reqdlink {n} @code{@ref{\n\}} @unmacro linkhere @macro linkhere @end macro @end macro @end ifhtml @ifnothtml @ifnottex @c Info version: create @linkhere as a macro that contains a reference. @macro reqdlink {n} @code{\n\} @unmacro linkhere @macro linkhere (@pxref{\n\}) @end macro @end macro @end ifnottex @iftex @c TeX version: this produces output similar to the Info version. @c ispell-ignore @tex \gdef\reqdlink#1{% \code{#1}% \gdef\linkhere{ (\pxref{#1})}% } @end tex @c ispell-end-ignore @end iftex @end ifnothtml @c @aux{mx-allow-filter} is used for aux-item names. @macro aux {n} @code{\n\} @end macro @c @async{async-login} is used for async names. @macro async {n} @code{\n\} @end macro @c @asynclink{async-login} is used for async names, that should be linked. @ifhtml @macro asynclink {n} @code{@ref{\n\}} @end macro @end ifhtml @ifnothtml @macro asynclink {n} @code{\n\} (@pxref{\n\}) @end macro @end ifnothtml @c @asyncdlink{async-login}...@linkhere{} is used for async messages, @c that should be linked, where the link should occur a few words after @c the async name itself. @ifhtml @c HTML version: make the word a link. @macro asyncdlink {n} @code{@ref{\n\}} @unmacro linkhere @macro linkhere @end macro @end macro @end ifhtml @ifnothtml @ifnottex @c Info version: create @linkhere as a macro that contains a reference. @macro asyncdlink {n} @code{\n\} @unmacro linkhere @macro linkhere (@pxref{\n\}) @end macro @end macro @end ifnottex @iftex @c TeX version: this produces output similar to the Info version. @c ispell-ignore @tex \gdef\asyncdlink#1{% \code{#1}% \gdef\linkhere{ (\pxref{#1})}% } @end tex @c ispell-end-ignore @end iftex @end ifnothtml @c @type{Conference} is used for LysKOM types. @macro type {n} @code{\n\} @end macro @c @lt{Conference} is used for linked types. The link is only present @c when it is unobtrusive. It should only be used inside @c @example...@end example. @ifhtml @macro lt {n} @ref{\n\} @end macro @end ifhtml @ifnothtml @macro lt {n} \n\ @end macro @end ifnothtml @c @priv{wheel} is used for privilege bits. @macro priv {n} @code{\n\} @end macro @c @conftype{rd-prot} is used for conference type bits. @macro conftype {n} @code{\n\} @end macro @c @misc{bcc-recpt} is used for misc-info names. @macro misc {n} @code{\n\} @end macro @c @rarg{passwd} is used to reference arguments of requests. This is @c *only* used in the nodes that defines the requests. @macro rarg {n} @code{\n\} @end macro @c @aarg{text-no} is used to reference arguments of asynchronous @c messages. This is *only* used in the nodes that defines the @c relevant asynchronous message. @macro aarg {n} @code{\n\} @end macro @c @errorcode{no-such-text} is used to mark error codes. @macro errorcode {n} @code{\n\} @end macro @c @field{ident-user} is used to mark fields of struct types. @macro field {n} @code{\n\} @end macro @c @reqexample is used immediately before Protocol-A example @c fragments. @macro reqexample @need 2000 @i{Example:} @end macro @c @c Define strings that can be encoded as macros instead of with @set. @c @macro daemon @badspell{d@ae{}mon} @end macro @c %**end of header @copying This is the LysKOM Protocol A specification, edition @value{PROTOEDITION}. It specifies version @value{PROTOVER} of the protocol. It was first distributed with version @value{VERSION} of lyskomd. Copyright @copyright{} 1995-2003 Lysator ACS. @quotation Permission is granted to make and distribute verbatim copies of this specification provided the copyright notice and this permission notice are preserved on all copies. @c Permission is granted to process this file through TeX @c and print the results, provided the printed document @c carries a copying permission notice identical to this @c one except for the removal of this paragraph (this @c paragraph not being relevant to the printed manual). Modified versions of this document may be redistributed with the added condition that all modifications not cleared with the LysKOM development group are clearly marked and that the entire modified work be redistributed under the same conditions as the original. Permission is granted to copy and distribute translations of this manual into another language under the same conditions as for modified versions. @end quotation @end copying @c ispell-ignore @iftex @c @c Don't indent the first line of paragraphs. @parindent 0pt @c @c Define @t{} so that it switches from slanted to regular to slanted @c typewriter text as usages are nested. For example: @c @c @t{A @t{B @t{C} D} E} @c @c will set A, C and E slanted and B and D as regular typewriter text. @c This makes @t sort of the typewriter equivalent of LaTeX \em @c (emphasis is italic, emphasized emphasis is roman). @c @c Helpers: @c \tensltt: switch to the cmsltt10 font (Computer Modern, @c Slanted, Typewriter, 10pt). @c \rett: switch to typewriter text and define @c \t as an alias for \sltt. @c \sltt: switch to slanted typewriter text and defines @c \t as an alias for \rett. @c @c Finally \t is defined as an alias for \sltt. @c @tex \global\font\tensltt=cmsltt10 \global\def\rett#1{{\let\t\sltt\tt #1}} \global\def\sltt#1{{\fam\ttfam\tensltt\let\t\rett #1}} \global\let\t\sltt @end tex @end iftex @c ispell-end-ignore @titlepage @title{LysKOM Protocol A} @subtitle{Protocol version @value{PROTOVER}} @subtitle{Edition @value{PROTOEDITION}} @subtitle{(lyskomd @value{VERSION})} @author by the LysKOM Developers @page @c ispell-ignore @vskip 0pt plus 1filll @c ispell-end-ignore @insertcopying @end titlepage @ifnothtml @contents @end ifnothtml @dircategory LysKOM @direntry * Protocol A: (protocol-a). The LysKOM Protocol A specification. @end direntry @c ispell-ignore @ifhtml @html Lysator LysKOM
@end html @end ifhtml @c ispell-end-ignore @node Top @top LysKOM Protocol A This document specifies version @value{PROTOVER} of LysKOM Protocol A. This is edition @value{PROTOEDITION} of the specification. It was first distributed with version @value{VERSION} of lyskomd. The most up-to-date version if this document can always be found at @uref{http://www.lysator.liu.se/lyskom/protocol/}. @menu * About this document:: Copyright information. * Preface:: What is LysKOM? Who wrote this document? * Concepts:: Articles, conferences, aux-items, @dots{} * Fundamentals:: The building blocks of Protocol A. * LysKOM Data Types:: Domain-specific data types used in Protocol A. * Protocol Requests:: Each request explained in depth. * Asynchronous Messages:: Unsolicited information from the server. * Error Codes:: All error codes with explanations. * Aux-Item Types:: All predefined aux-item types. * Name Expansion:: Looking up the name of a conference or person. * LysKOM Content Types:: Predefined content types for articles. * The User Area:: Store client-specific settings in the server. * Membership visibility:: How the security features interacts. * Garb:: Old texts are deleted automatically. * Measured Properties:: Load average, number of processed requests... * Extracted grammar:: If you want to generate code, read this. * Writing Clients:: A few tips for client writers. * Importing and Exporting E-Mail:: A few thoughts on e-mail integration. * Some Client-specific Aux-Item Types:: Informative info about more aux-items. * Future changes:: The protocol is not yet perfect. * Protocol Version History:: The protocol was even less perfect before. * Document Edition History:: Changes in this document. * Index:: Index of protocol elements. @end menu @ifnottex @node About this document @chapter About this document @insertcopying @end ifnottex @ifnottex @node Preface @chapter Preface @end ifnottex LysKOM is a conferencing system@footnote{Or in modern terms, enabling technology for Computer-Supported Cooperative Work (CSCW).}. Similar systems were QZ-KOM and PortaCOM@footnote{Also known as ``PottaKOM'' and ``BortaKOM.''}. The LysKOM system is copyrighted by Lysator Academic Computing Society and distributed under conditions of the GNU Public License. LysKOM and its documentation is provided ``as is'' without warranty of any kind. Anything described here as ``unspecified'' is liable to change in future protocol versions. This specification is the work of several people. The main contributors have been Per Cederqvist @email{ceder@@lysator.liu.se}, David Byers @email{byers@@lysator.liu.se}, @value{Pell} @email{pell@@lysator.liu.se}, Thomas Bellman @email{bellman@@lysator.liu.se}, Lars Aronsson @email{aronsson@@lysator.liu.se}, Linus Tolke @email{linus@@lysator.liu.se} and @value{Kent} @email{kent@@lysator.liu.se}. The LysKOM developers can be reached by email to @email{lyskom@@lysator.liu.se}. If you find any errors in this document, please report them at @uref{http://bugzilla.lysator.liu.se/}. Use @samp{lyskomd} as the product, and @samp{documentation} as component. @node Concepts @chapter Concepts used in LysKOM This chapter introduces the concepts used in LysKOM, such as articles, conferences and sessions. @menu * Articles:: Reading and writing articles is what LysKOM is about. * Conferences:: Articles are organized in conferences. * Persons and Sessions:: Persons log on to the LysKOM system. * The Misc-Info List:: How articles are organized in comment chains and in conferences. * The Aux-Item List:: A generic extension mechanism. * Security:: Some persons have more privileges than others. * Membership and Reading:: You don't have to read anything twice. @end menu @node Articles @section Articles An article is represented as a value of the type @type{Text-Stat} and a string containing the article contents. An article will usually have one or more recipients and may be a comment or footnote to other articles. Each article is kept in the database until it is older than the @field{nice} value of each of its recipients and it is not marked by any user. There is an array of @type{Misc-Info} included in the @type{Text-Stat}. This array contains information about recipients, senders, comments and footnotes. Each article is identified by a number, the global@footnote{The number is not truly global; it is local to a specific LysKOM server.} article number (the @type{Text-No}). Global numbers are assigned in ascending order to new articles, and are never reused. If an article has recipients it will also have a local number for each recipient (the @type{Local-Text-No}). Local numbers are used in some data structures to provide more compact storage and to provide an ordering of articles for a particular recipient. Local numbers are assigned in ascending order and are never reused for a particular recipient, though different recipients will have articles with the same local numbers. Occasionally it is necessary to map between local and global numbers. The server call @reqdlink{local-to-global} does this@linkhere{}. @node Conferences @section Conferences Conferences hold articles. They are represented in the protocol as a data type called @type{Conference}. Each conference has a @dfn{creator}, the person who created the conference, and a @dfn{supervisor}, a conference whose members can modify the conference. If the supervisor is a person, the members of that person's mailbox are supervisors, which in most cases is only that person. Persons are a special case: in addition to those who are supervisors for a certain person because of the @field{supervisor} field, the person is always a supervisor of himself. There is one exception to this special case: the person cannot use @reqlink{set-supervisor} to change who is his supervisor. We have also introduced a type called @type{UConference} (pronounced micro-conf-stat) which holds a subset of the information contained in the full @type{Conference} type. Use the @type{UConference} type whenever possible since it places a much smaller load on the LysKOM server. Each conference has a type, which is essentially a collection of boolean flags. Currently the flags @conftype{rd-prot}, @conftype{letterbox}, @conftype{secret}, @conftype{original}, @conftype{allow-anonymous} and @conftype{forbid-secret} are defined. @table @conftype @item rd-prot The conference is protected from reading by non-members. Persons become members by having one of the existing members or supervisors add him or her to the conference. This restriction is enforced by the server. @item original Conferences of this type are intended for original articles only. Comments are to be redirected to the @field{super-conf} instead. This restriction is not enforced by the server; clients must implement this functionality. (@xref{Recipients of comments}, for a summary of how a client should select the recipients of a comment.) @item letterbox Conferences of this type are connected to persons. Letters to a person are sent to the mailbox and the name of the mailbox is synchronized with the person name. It is currently not possible to explicitly set or clear this flag on a conference. @item secret Conferences of this type are secret. The server will not divulge any information about the existence of the conference to persons who are not members or supervisors of the conference. If a mailbox is made secret, that person cannot log in using the person name, but must specify a person number instead. @item allow-anonymous Conferences of this type accept anonymous articles. Other conferences will reject anonymous articles. @item forbid-secret Conferences of this type do not allow secret members. If a conference is changed to this type, preexisting secret members remain secret. @end table @node Persons and Sessions @section Persons and Sessions Persons are represented in the protocol by values of the type @type{Person}. Associated with persons are statistics, a set of personal flags and a set of privileges (@pxref{Security}). Persons are also associated with a conference that has the same number as the person and the @conftype{letterbox} bit set. Connections to the server are represented as values of the type @type{Static-Session-Info}, @type{Session-Info-Ident} or @type{Session-Info}. Sessions have session number that are unique for each session in the lifetime of the server execution. A single user can have several sessions running at once. The session is not released until the network connection is closed; a user can log in and out repeatedly in a single session. @node The Misc-Info List @section The Misc-Info List The @type{Misc-Info} list contains tagged data. The fields are sent in groups pertaining to a particular type of information: information about recipient; carbon copy recipient; blank carbon copy recipient; comment to; footnote to; comment in and footnote in. The information groups may be sent in any order and there may be any number of groups. Within each group the elements are always sent in the order listed below. @subsection Recipient @table @misc @item recpt Starts a recipient group. It contains the conference number of a recipient of the article. @item loc-no Always present within a recipient group. It contains the local text number of the article in the conference specified by the preceding @misc{recpt} field. @item rec-time If the recipient is a person, this element is added by the server when the recipient marks the article as read. It contains the time when the text was read. @item sent-by Present when the recipient was added by a person other than the author (after the article was created.) It contains the person number of the person who added the recipient. @item sent-at Present when the recipient was added after the article was created. It contains the time when the recipient was added. @end table @subsection Carbon Copy (CC) Recipient The carbon-copy recipient group is identical to the recipient group above. The difference is how new comments to an article with a recipient or carbon-copy recipient are treated. A comment to an article is sent to all recipients, but not to carbon-copy recipients of the original article. This difference is enforced by the clients. @table @misc @item cc-recpt Starts a carbon-copy recipient group. It contains the conference number of a carbon-copy recipient of the article. @item loc-no Always present in a CC recipient group. It contains the local text number of the article in the conference specified by the most recent @misc{cc-recpt} field. @item rec-time Present after the CC recipient has read the article. It contains the time when the article was read. Since only persons can read articles this will only be seen if the CC recipient is a person. @item sent-by Present when a CC recipient was added by a person other than the author after the article had been created. It contains the person number of the person who added the CC recipient. @item sent-at Present when a CC recipient was added after the article had been created. It is the time when the CC recipient was added. @end table @subsection Blank Carbon Copy (BCC) Recipient The blank carbon-copy recipient group is identical to the carbon-copy recipient group above. The difference is the visibility of the information. A carbon-copy recipient group is visible to anyone that is allowed to fetch both the text status of the involved text and the conference status of the involved conference. (That is, as long as the conference isn't secret everybody is allowed to see the carbon-copy recipient group.) A BCC recipient group is basically only visible to members and supervisors of the recipient. Persons that have the right to become a member of the recipient can also see it, as can the author of the text (unless the recipient is secret to him). This is enforced by the server. This type of group was introduced in protocol version 10. When old-style calls such as @reqlink{get-text-stat-old} are used this will be converted to a CC recipient group by the server for the benefit of clients that don't understand this group. (This conversion will of course only be performed when the user is allowed to se the blank carbon copy.) @table @misc @item bcc-recpt Starts a blank carbon-copy recipient group. It contains the conference number of a blank carbon-copy recipient of the article. @item loc-no Always present in a BCC recipient group. It contains the local text number of the article in the conference specified by the most recent @misc{bcc-recpt} field. @item rec-time Present after the BCC recipient has read the article. It contains the time when the article was read. Since only persons can read articles this will only be seen if the BCC recipient is a person. @item sent-by Present when a BCC recipient was added by a person other than the author after the article had been created. It contains the person number of the person who added the BCC recipient. @item sent-at Present when a BCC recipient was added after the article had been created. It is the time when the BCC recipient was added. @end table @subsection Comment To @table @misc @item comm-to Always present when the article is a comment to another article. @item sent-by Present when the article was added as a comment by a person other than the author, after the article had been created. It contains the person number of the person who added the article as a comment. @item sent-at Present when the article was added as a comment after the article had been created. It contains the time when it was added as a comment. @end table @subsection Footnote To @table @misc @item footn-to Always present when the article is a footnote to another article. @item sent-at Present when the article was added as a footnote after the article had been created. It contains the time when it was added as a footnote. @end table @subsection Comment in @table @misc @item comm-in Present when there are comments to this article. It contains the article number which is a comment to this article. @end table @subsection Footnote in @table @misc @item footn-in Present when there are footnotes to this article. It contains the article number which is a footnote to this article. @end table @node The Aux-Item List @section The Aux-Item List The aux-item list is used as a generic extension mechanism in the LysKOM server and in protocol A. @menu * About Aux-Items:: An introduction to aux-items. * Aux-Item Inheritance:: Comments can inherit aux items. * Predefined Aux-Item Types:: Predefined aux-items are part of the protocol. * Client-Specific Aux-Item Types:: Clients can allocate aux-items for their private use. * Experimental Aux-Item Types:: A block of aux-items are reserved for experimental use. * Defining New Aux-Item Types:: Creating new aux-item types is easy. @end menu @node About Aux-Items @subsection About Aux-Items Aux-items were introduced in protocol version 10 as a mechanism for extending the conference, text and server information structures without changing the protocol. (There is no need for aux-items on persons -- just add an aux-item to the corresponding mailbox.) The exact structure of an aux item is specified elsewhere (@pxref{Auxiliary Information}). The important fields here are the @field{aux-no}, @field{tag} and @field{data} fields. The @field{aux-no} field is used to identify an item. The @field{aux-no} together with a text or conference number uniquely identifies a particular aux item. Items are numbered from one and up within each item list. Once assigned, the @field{aux-no} for an item is never changed. New items are guaranteed to be assigned numbers that have never been used before within a particular list. The @field{tag} field identifies the type of aux item. It is used by the server and by clients to figure out how to interpret the data field, and by the server to decide if the item needs special treatment. The @field{data} field is a simple string. The meaning of the string is determined by the @field{tag} field, but since it is a string, clients that have no understanding of the contents can successfully parse the item anyway (in contrast to items in the misc-info list.) @node Aux-Item Inheritance @subsection Aux-Item Inheritance An aux item that is placed on a text can be inherited. This means that if a comment or footnote to the text is created, an almost identical item will be created on the new text. The @field{tag}, @field{creator}, @field{flags} and @field{data} field will be inherited unchanged. The @field{aux-no} might be given a different value. A non-zero @field{inherit-limit} field will be decremented. The @field{created-at} timestamp will be set to the time when the new comment or footnote is created. Inheritance only happens at text creation time. If a comment or footnote link is added later with @reqlink{add-comment} or @reqlink{add-footnote}, no items will be inherited. Also, if the link is removed (via @reqlink{sub-comment} or @reqlink{sub-footnote}), the inherited items will still be in place. Inheritance only happens when the @field{inherit} bit is set, and if @field{inherit-limit} is 0 or greater than 1. @xref{Auxiliary Information}, for more information. Inheritance has no meaning for items placed on the server or on a conference. It is possible for a predefined aux-item to behave in a way that isn't consistent with the description in this section. The documentation for the specific aux-item should document any deviations. @node Predefined Aux-Item Types @subsection Predefined Aux-Item Types Predefined Aux-Item types are part of Protocol A, and clients should support all of them. As with other parts of the protocol, changes to these definitions will be made backwards-compatible, if possible. Creation and deletion of items with a predefined type can cause arbitrarily complex and wondrous behavior in the server. Furthermore, the server may place constraints on the items with regard to content, flags, who can create them, to what objects they can be attached and so forth. The server may also silently enforce specific values for any field of an item, regardless of what the client requests. All items with tags in the range 1-9999 and 30000 and up are considered predefined. If a client attempts to create an item with a tag in this range, but the server has no idea what that tag means, the server will return an error (@errorcode{illegal-aux-item}). Some items with tags in the range 10000-19999 are also predefined. They are items that initially were reserved for private use for a specific client, but where it was later discovered that the tag was generally useful. They should ideally have been assigned a number in the 1-9999 range from the beginning, but if they already have a widespread use they can be redefined to be predefined. Such redefinition will always be made in cooperation with the client writer. @xref{Aux-Item Types}, for the complete list of predefined Aux-Item types. @node Client-Specific Aux-Item Types @subsection Client-Specific Aux-Item Types Client-specific items do not cause the server to perform any magic. All the flags (except the delete flag) are left untouched, the data is not validated in any way, and anyone can create any item. If you need more server support than this, your item should be on the predefined list. All tags in the range 10000-19999 are reserved for clients. Blocks of 100 numbers at a time can be assigned to specific clients. A client should never create items with tags in a range assigned to another client or in an unassigned range. Assigned ranges will never change, except that specific aux-items may be redefined as predefined, as explained in @ref{Predefined Aux-Item Types}. Currently, the following ranges are assigned to clients: @itemize @bullet @item 10000-10099: The Elisp Client @item 10100-10199: komimportmail @item 10200-10299: Private test use (should never be used on a public server) @end itemize If you want a range of numbers, send e-mail to the LysKOM development group, or request it via Bugzilla. @node Experimental Aux-Item Types @subsection Experimental Aux-Item Types Experimental numbers are free for all. Use @badspell{'em} any way you want. All numbers in the range 20000-29999 are for experimental use. @node Defining New Aux-Item Types @subsection Defining New Aux-Item Types If you want a new predefined item type, just document what it does, what the data format looks like and what the server is to do with the item and send this to the LysKOM development group. We'll assign a number to your item and put the documentation in this document. If you're not sure what you want the data to look like yet, make a note in your documentation that the data format might change. Once you have a data format you're happy with, update the documentation so others may use your item. If you need serious magic in the server (more than can be specified with the lyskomd configuration file), you'll probably have to write the code yourself, or hope that the development group thinks your idea is so cool we do the job for you. The idea is not to reject any type of item, unless there's already an item type that does the job just as well. Adding item types should be a much less painful process than adding new calls. @node Security @section Security Security in LysKOM is based on two components. Each person has a set of privileges and each session has a security level. Rights in the system require both the sufficient privileges and a sufficient security level. The privileges currently available are @priv{wheel}, @priv{admin}, @priv{statistic}, @priv{create-conf}, @priv{create-pers} and @priv{change-name}. Security levels range from 0 to 255. @table @priv @item wheel @emph{Normally not assigned} @table @asis @item Level 0 Person may always log in, even when LysKOM is crowded. @item Level 6 Person may set Priv-Bits for all persons. @item Level 7 Person may set password for all persons. @item Level 8 Person acts as supervisor for everything. @item Level 10 Person can read all articles. @end table @item admin @emph{Normally not assigned} @table @asis @item Level 1 Shut down the server@* Set motd-of-kom@* Read last-login @item Level 2 Read status of secret conferences and persons@* Read the protected parts of person and conference statuses@* Read the entire text status, even when there are secret recipients @item Level 3 Change everybody's names @item Level 4 Add/remove members@* Add/remove recipients to articles @item Level 5 Set super-conference@* Remove articles @item Level 6 Set administrator @end table @item statistic @emph{Normally not assigned} @table @asis @item Level 2 Read the statistics portions of persons, even if protected @end table @item create-conf @emph{Normally not assigned}@footnote{The LysKOM server is normally configured so that anybody can create new conferences, even if they do not have this privilege.} @table @asis @item Level 0 Create conferences @end table @item create-pers @emph{Normally not assigned}@footnote{The LysKOM server is normally configured so that anybody can create new persons, even if they do not have this privilege.} @table @asis @item Level 0 Create persons @end table @item change-name @emph{Normally assigned} @table @asis @item Level 0 Change names of conferences he is supervisor for @end table @end table @node Membership and Reading @section Membership and Reading Persons' memberships in conferences are represented in the protocol as arrays of @type{Membership}-typed values. This structure contains information about how and when the membership was created and which texts have been read in the conference. There are two kinds of memberships. An active membership indicates that the person is actively participating in the conference, wants to know if there are unread texts and wants to receive messages send to the conference. A passive membership is similar to no membership at all. The person is still a member but will not receive messages sent to the conference and will not be notified when there are new texts. From the user's perspective, passive membership should be like no membership at all, but the server still remembers what the user has read in the conference while he or she was an active member. Since protocol version 10 a bit in the membership type field of the membership structure indicates the type of membership. Previously the server did not support passive memberships, but there was a convention that clients should treat the priority level zero as a passive membership. The membership record indicates which texts have been read through the @field{read-ranges} field, which contains a list of ranges of local text numbers that has been read. Finding out which articles a person has read in a particular conference requires a few calls. Normally, a client will retrieve a batch of perhaps 50 articles at a time. The outline of the process is as follows: @enumerate @item Fetch the membership to get the @field{read-ranges}. @item Use @reqlink{local-to-global} to translate a number of local numbers to global numbers. @item Remove the global numbers corresponding to local numbers contained in @field{read-texts} from the result. @item Get and translate more texts as needed. @end enumerate The process is complicated because of the translation between local and global text numbers. If the server does not implement the @reqdlink{local-to-global} call@linkhere{}, it is possible to use the less efficient but perfectly serviceable @reqdlink{get-map} call instead@linkhere{}. @node Fundamentals @chapter Fundamentals of Protocol A The data types in protocol A come in two flavors. The first (vanilla) are the simple data types from which the LysKOM (chocolate) data types are built. Simple data types include things like integers and strings while complex data types include things such as conferences and people. @menu * Notation:: The grammar used in this document. * Simple Data Types:: BOOL, INT32, ARRAY, @dots{} * Connecting to the Server:: The initial handshake. * Client-Server Dialog:: Requests, replies, asynchronous messages. * Protocol Error Messages:: How the server reacts to syntax errors. @end menu @node Notation @section Notation This specification uses a BNF-like grammar to describe the protocol and its data elements. Data fields have been given names that start with a lower-case letter. Fundamental data types have names in all-caps (such as @type{INT32} and @type{ARRAY}). Derived data types have names that start with an upper-case letter. (If the type contains more than one word, all words start with an upper-case letter, like this: @type{Text-Stat}.) The operator @code{::=} defines the name to its left. Comments start with @code{!} (exclamation mark) and alternatives are separated by a @code{|} (vertical bar.) A @code{;} (semicolon) terminates statements in the grammar. In some specifications there are literal strings. There is to be no whitespace before or after literal strings unless there is whitespace in the literal itself. @node Simple Data Types @section Simple Data Types @anchor{INT32} @anchor{INT16} @anchor{INT8} @anchor{BOOL} @subsection Integers @tindex INT32 @tindex INT16 @tindex INT8 @tindex BOOL @type{INT32}, @type{INT16}, @type{INT8} and @type{BOOL} are non-negative integers which must fit in 32, 16, 8 and 1 bits, respectively. They are transmitted to the server in ASCII-encoded decimal notation. @anchor{FLOAT} @subsection Floating point numbers @tindex FLOAT @type{FLOAT} are floating point numbers. They are represented as if printed via @code{printf("%g", val);} in C. See @cite{7.19.6.1 The fprintf function} in @cite{ISO/IEC 9899:1999 Programming languages - C} for the details. @xref{Floating-Point Conversions, , The %g conversion, libc, The GNU C Library Reference Manual}, if you don't have the C standard handy. @anchor{HOLLERITH} @subsection Strings @tindex HOLLERITH @type{HOLLERITH} denotes character strings of arbitrary length. They are transmitted as @code{@var{n}H@var{text}} where @var{text} is the string and @var{n} is the number of characters in @var{text} in decimal notation. All byte values are allowed in the string itself, including nulls. Long live FORTRAN! @cindex character set @cindex Unicode The character set used in the strings is not yet specified by Protocol A. In the future, some Unicode encoding will probably be used, but it is not yet decided which one or how the transition will be handled. @uref{http://bugzilla.lysator.liu.se/show_bug.cgi?id=99, Bug 99} is about the need for a Unicode roadmap; check that bug for the current state of the plans. For now, which character set to use is a local policy of each server installation. There is not yet any way in the protocol to specify the character set that a certain server uses. Most clients currently assume that ISO 8859-1 (Latin-1) is used, and the default collate table of lyskomd also assumes ISO 8859-1. Conference names must currently use an 8-bit character set encoding where whitespace is defined as in ASCII, or conference matching won't work. @reqlink{get-collate-table} contains some more information about character set issues. @anchor{BITSTRING} @subsection Bit Strings @tindex BITSTRING @type{BITSTRING} is a string of bits, commonly used for a set of boolean-valued flags. Bit strings are denoted as @example BITSTRING ( name-1; name-2; name-3; @dots{} ) @end example in this specification. They are transmitted as a sequence of ASCII ones and zeroes in the order the fields are listed. For instance, given the specification @example shape-of-world ::= BITSTRING ( is-flat; is-round; is-2d; is-3d; ) @end example most peoples idea of @code{shape-of-world} would be sent as @code{0101} (round and three-dimensional.) @anchor{ENUMERATION} @subsection Enumerations @tindex ENUMERATION @type{ENUMERATION} is an integer constant. It is transmitted as an INT32, but only fixed values are permitted. Clients should be prepared to receive numbers outside the enumeration and either handle this gracefully as an error or use a reasonable default value in place of an invalid enumeration value. An enumeration is specified as @example ENUMERATION ( name-1=value-1; name-2=value-2; name-3=value-3; @dots{} ) @end example This specification states that name-1 is represented by the integer value-1, name-2 is represented by value-2 and name-3 is represented by value-3. An enumeration can also be inherited from a SELECTION data type: @example Info-type ::= ENUMERATION-OF(Misc-Info) @end example This means that Info-type is an enumeration, that contains the same keys and values as the SELECTION Misc-Info. For example, in the following specification, the constant guwal will be transmitted as the integer 2, ciokwe as the integer 3, and hopi as the integer 5. @example language ::= ENUMERATION ( hakka = 1; guwal = 2; ciokwe = 3; yoruba = 4; hopi = 5; ) @end example @anchor{ARRAY} @subsection Arrays @tindex ARRAY @type{ARRAY} is a list of a fixed number of elements of a single type. The specification for an array is @code{ARRAY @var{type}} where @var{type} is the type of the array elements. Arrays are transmitted as an @code{@var{n} @{ @var{element} @var{element} @dots{} @}} where @var{n} is the number of elements and each @var{element} is an element of the array. A special case is when the array is empty, in which case the server transmits it as @code{0 *}. Note that the client must always transmit empty arrays as @code{0 @{ @}}. In some calls the client can ask the server not to send the array contents, only its length. In these cases the array is transmitted as @code{@var{n} *} where @var{n} is the number of elements in the array. @anchor{SELECTION} @subsection Selection @tindex SELECTION @type{SELECTION} is tagged data. It consists of an INT32 selector followed by a tail of an arbitrary type and is specified as @example SELECTION ( @var{n}=@var{name} @var{tail} : @var{type}; @var{n}=@var{name} @var{tail} : @var{type}; @dots{} ) @end example where each @var{n} is the selector value, @var{name} the selector name and @var{tail} the name of the selector tail and @var{type} its type. @var{name} and @var{tail} are often very similar, such as @samp{sent-by} and @samp{sender}. When transmitted, the selector is transmitted as an INT32 followed by the tail belonging to that selector. For instance, given the specification @example description ::= SELECTION ( 1=name the_name : HOLLERITH; 2=age years : INT32; ) @end example two legal messages of the type @code{description} are @samp{1 @holl{4,John}} and @samp{2 18}. @anchor{RPC} @subsection RPC @tindex RPC @type{RPC} is a notation used to specify calls to the server. An RPC specification has the following form: @example RPC ( @var{call} [@var{n}] ( @var{request} ) -> ( @var{reply} ) ; @var{call} [@var{n}] ( @var{request} ) -> ( @var{reply} ) ; ) @end example where each @var{call} is the name of a call, @var{n} is the call number, @var{request} is a single data element sent as a request and @var{reply} is a single data element sent in reply from the server. RPC calls are transmitted as @var{n} @var{request} where @var{n} and @var{request} have the same meaning as above. Note that in the client-server dialog a reference number must also be supplied with each request. This reference number is not part of the RPC itself, but is required for communications; see @ref{Client-Server Dialog}. @subsection Structure Structures are collections of several data items. In the specification they are written as @example ( @var{name} : @var{type} ; @var{name} : @var{type} ; @dots{} ) @end example where each @var{name} is the name of a data field and the corresponding @var{type} is its type. Structures are transmitted as a sequence of their fields. @node Connecting to the Server @section Connecting to the Server The client-server dialog consists of two phases, establishing the connection and the LysKOM session itself. A connection to the server is initiated by connecting to the appropriate network port@footnote{The default port for a LysKOM server is 4894. That port was registered with IANA 2001-06-20.} and sending a single letter which is used to select a protocol version. This letter should always be @samp{A}@footnote{In the early 1990s there was much discussion about the next generation LysKOM protocol, called ``Protocol B'', and at one point in time it was believed that ``Protocol B'' would arrive at the same time as ``Emacs 19''. ``Emacs 19'' arrived and was obsoleted by new versions. Meanwhile, it was discovered that ``Protocol A'' was more extensible that first believed. ``Protocol A'' will continue to evolve, but it is unlikely that it will ever be superseded by ``Protocol B''.}. The protocol version letter should be followed by connection information required by that protocol. In protocol A the connection information is a @type{HOLLERITH} string saying who the user connecting is followed by a linefeed character. The format of the string should be @samp{@var{username} % @var{hostname}}. When the server has accepted the connection it replies with the string @code{LysKOM} on a single line. @example % telnet kom.lysator.liu.se 4894 Trying 130.236.254.151 ... Connected to varg.lysator.liu.se. @c This comment matches the bracket on the next line: [ Escape character is '^]'. A@holl{26,byers%kajsa.lysator.liu.se} LysKOM @end example Besides the string @samp{LysKOM}, the server may respond with @samp{%%LysKOM unsupported protocol.} or @samp{%% No connections left.}. The @samp{%%LysKOM unsupported protocol.} reply is sent if the server does not understand the requested protocol, that is, if the first character is anything but an @samp{A}. The connection will be closed by the server as soon as this string has been sent. The @samp{%% No connections left.} reply is sent if the server is not accepting additional connections. This error is transient. The next connection attempt may succeed. Clients should wait a few seconds before attempting to make another connection after receiving this error. The connection will be closed by the server as soon as this string has been sent. @node Client-Server Dialog @section Client-Server Dialog After connecting (@pxref{Connecting to the Server}), calls to the server can be made. Most calls require the user to log in, but some calls can be made without a log-in. Calls to the server are made by sending a reference number followed by the call as specified. The call @emph{must} be terminated with a linefeed character (ASCII 0x0A). @example server-call ::= ( ref-no : INT32; request : Protocol-Request; ) @end example The client may send several requests without waiting for the replies. However, the server will only buffer a limited amount of replies, so the client must check for pending replies from the server at least each time it sends requests to the server. At some future point the server will reply with the result of the request or an error code preceded by an indicator and the reference number. The replies will be sent in the same order as the requests@footnote{Client writers are encouraged to write the clients so that they are prepared for replies that are sent out-of-order. @xref{Future changes}, for speculations about how that may benefit the client in the future.}. @example server-reply ::= ok-reply | error-reply | protocol-error; ok-reply ::= ( "=" ref-no : INT32; reply-data; ) error-reply ::= ( "%" ref-no : INT32; error-code : INT32; error-status : INT32; ) protocol-error ::= "%% LysKOM protocol error." | "%%Insane token length." | "%%Insane array size." @end example Our notation is not flexible enough to specify the two-way nature of the communication. @field{ref-no} in the reply is always the same as @field{ref-no} in the corresponding request. @field{reply-data} depends on which request was made and is specified together with each request. Note that there is no whitespace after the initial indicator in the reply. Data elements sent from the client to the server are separated by one or more space characters (ASCII 32). An entire call is terminated by a linefeed character (ASCII 10). Earlier versions of the protocol specified that data elements could be separated by any number of linefeed (ASCII 10), return (ASCII 13), tab (ASCII 9) or space (ASCII 32) characters. Servers should be forgiving and understand requests using the older conventions, but clients must conform to the current convention of separating data elements with spaces and terminating all requests with a linefeed character. The @errorcode{not-implemented} error code will not be returned properly unless the client follows this requirement. The server may return two different types of errors. Normal @code{error-reply} errors are replies to syntactically correct calls to the server, while @code{protocol-error} are replies to syntactically incorrect calls. @xref{Protocol Error Messages}, for more information about @code{protocol-error}. If a call cannot complete successfully, LysKOM will respond with an @code{error-reply}. The meaning of @field{error-code} and @field{error-status} varies depending on the request; see @ref{Error Codes}, and the documentation for each call, for a list of available @field{error-code} values and what they mean. A client should be prepared for any error code in response to any call, no matter if the response makes any sense or not. The value returned in @field{error-status} was more or less undefined before protocol version 10. For protocol version 10 or newer, the meaning of @field{error-status} is defined in this document. The meaning of @field{error-status} can be modified by any call. In particular the calls that deal with Misc-Info lists set @field{error-status} to the index of the misc item that caused the error (if the error was caused by a misc item.) Client should handle the error messages listed with each call in a graceful manner. In addition, the following error types should always be handled gracefully: @errorcode{temporary-failure}, @errorcode{internal-error}, @errorcode{feature-disabled}, @errorcode{not-implemented}, @errorcode{obsolete-call}, @errorcode{ldb-error}, @errorcode{out-of-memory}. Client should also be able to handle any error in any situation without choking completely since bugs might cause the wrong error message to be sent or new errors might be added later on. The server may send asynchronous messages (@pxref{Asynchronous Messages}) to the client at any time (but not in the middle of a reply). Two important asynchronous messages are @async{async-new-text} (@pxref{async-new-text}) and @async{async-send-message} (@pxref{async-send-message}). @node Protocol Error Messages @section Protocol Error Messages Protocol error messages are sent in reply to syntactically incorrect calls to the server. These should never appear in the client-server dialog. If they do, there is probably a bug in the client. @table @asis @item "%% LysKOM protocol error." The client has sent a request that does not comply with protocol A. The server will attempt to recover from this error, but additional calls may be silently lost, and the server may send replies that the client does not expect, and in some cases recovery may not be possible. This error is also returned when the client sends an array that is longer than the maximum allowed by the server. @item "%%Insane token length." The client has sent a single token that is insanely long. Typically this means that the client has sent several kilobytes worth of digits, or something similar. This is never returned for long strings. The server will automatically disconnect a client who sends a token with an insane length. @item "%%Insane array size." The client has send an array with a negative length. The server is not easily fooled. The server will automatically disconnect a client who sends an array with an insane length. @end table @node LysKOM Data Types @chapter LysKOM Data Types In this section the data types specific to LysKOM are defined. Most of these will probably make very little sense until you know what calls there are. This section does not include the server calls or asynchronous messages, even though these are also data types. Since the types defined here are all based on the simple types, the definitions are more concise in this section. @menu * Common Types:: Simple types used over and over again. * Auxiliary Information:: Aux-items and related types. * Conference Types:: A few flags for conferences. * Conference Search Results:: Name lookup returns these types. * Conference Status Types:: Information about a conference. * Archaic way to list conferences:: Archaic name lookup result type. * Mapping Local to Global Text Numbers:: The Text-Mapping type. * Server Information:: Information about an installation. * Person Status Types:: Information about a person. * Membership Information:: Persons are members of conferences. * Article Marks:: Persons can mark articles. * Article Information:: Information about an article. * Who Information:: Old-style info about logged-on users. * Session Information:: New-style info about logged-on users. * Statistics:: The server measures several things. @end menu @node Common Types @section Common Types The types defined in this section are fairly simple and used in many of the more complex data types. @anchor{Time} @subsection Time @tindex Time @example Time ::= ( seconds : @lt{INT32}; minutes : @lt{INT32}; hours : @lt{INT32}; day : @lt{INT32}; month : @lt{INT32}; year : @lt{INT32}; day-of-week : @lt{INT32}; day-of-year : @lt{INT32}; is-dst : @lt{BOOL}; ) @end example @type{Time} is used to specify times in several data structures. The fields @field{seconds}, @field{minutes} and @field{hours} give wall clock time. @field{day} is the day of month and @field{month} is the current month, starting with zero for January. @field{year} is the number of years since 1900. @field{day-of-week} is the current weekday, with zero used for Sunday. @field{day-of-year} is how many days of the year have passed starting with zero and @field{is-dst} is true when the time indicated is daylight savings time. When the server receives a @type{Time} structure from a client it ignores the @field{day-of-week} and @field{day-of-year} fields. All times are expressed in the time zone of the server, unless the @reqdlink{set-connection-time-format} request is used@linkhere{}. @anchor{Conf-No} @subsection Conference Numbers @tindex Conf-No @example Conf-No ::= @lt{INT16}; @end example This type denotes a conference number. @need 1511 @anchor{Text-No} @anchor{Local-Text-No} @anchor{Text-List} @subsection Text Numbers @tindex Text-No @tindex Local-Text-No @tindex Text-List @example Text-No ::= @lt{INT32}; Local-Text-No ::= @lt{INT32}; Text-List ::= ( first-local-no : @lt{Local-Text-No}; texts : @lt{ARRAY} @lt{Text-No}; ) @end example These three types are used to indicate articles in the LysKOM database. @type{Text-No} is a global text number and @type{Local-Text-No} a local text number. @type{Text-List} is used when a mapping from local to global numbers are required. @anchor{Pers-No} @anchor{Session-No} @subsection Person and Session Numbers @tindex Pers-No @tindex Session-No @example Pers-No ::= @lt{Conf-No}; Session-No ::= @lt{INT32}; @end example @type{Pers-No} is used to indicate a person. @type{Session-No} is used in a few data structures relating to information about active LysKOM sessions. @node Auxiliary Information @section Auxiliary Information @anchor{Aux-No} @anchor{Aux-Item} @anchor{Aux-Item-Input} @anchor{Aux-Item-Flags} @tindex Aux-No @tindex Aux-Item @tindex Aux-Item-Input @tindex Aux-Item-Flags @example Aux-No ::= @lt{INT32}; Aux-Item ::= ( aux-no : @lt{Aux-No}; tag : @lt{INT32}; creator : @lt{Pers-No}; created-at : @lt{Time}; flags : @lt{Aux-Item-Flags}; inherit-limit : @lt{INT32}; data : @lt{HOLLERITH}; ) Aux-Item-Input ::= ( tag : @lt{INT32}; flags : @lt{Aux-Item-Flags}; inherit-limit : @lt{INT32}; data : @lt{HOLLERITH}; ) @need 2200 Aux-Item-Flags ::= BITSTRING ( deleted; inherit; secret; hide-creator; dont-garb; reserved2; reserved3; reserved4; ) @end example Aux-Item-Input contains a subset of the fields of an Aux-Item. It is used when the client wants to send an Aux-Item to the server, and it only contains the elements that the client can affect. The fields in Aux-Item and Aux-Item-Input have the following meaning: @table @field @item aux-no The number of the item within the list where it is found. This number together with a conference or text number uniquely identifies a particular aux-item. (There is also a global list of Aux-Items for the server. That list is manipulated via the @reqdlink{modify-system-info} request@linkhere{}, and when using that request the @field{aux-no} is enough to uniquely identify the aux-item.) This field is not present in @type{Aux-Item-Input}. It is assigned by the server. @item tag The item tag. The tag determines what the data means. @xref{Aux-Item Types}. @item creator The person who created the item, or zero if the item was created anonymously or if the owner is being withheld. This field is not present in @type{Aux-Item-Input}. It is assigned by the server. @item created-at The time when the item was created. This field is not present in @type{Aux-Item-Input}. It is assigned by the server. @item flags The item flags (see below). @item inherit-limit Determines how many times (how deep) an item may be inherited. If zero, the item is inherited an unlimited number of times. If nonzero it is @emph{one more} than the number of additional times the item may be inherited. Thus, 1 means that inheritance will be blocked and 2 means that the item will be inherited only to the next level. @item data The item data. @end table The flags that can be set on an aux-item have the following meaning: @table @field @item deleted The item has been deleted, and should not be used for anything. @item inherit The item will be inherited (if the inherit-limit field allows it.) @item secret The item will not be revealed to anyone but the item's creator and supervisors of the creator. @item hide-creator The item creator will be withheld from everyone but the item's creator and supervisors of the creator. @item dont-garb The object the item is set on will not be garbage-collected. @end table @node Conference Types @section Conference Types @anchor{Conf-Type} @anchor{Extended-Conf-Type} @anchor{Any-Conf-Type} @tindex Conf-Type @tindex Extended-Conf-Type @tindex Any-Conf-Type @example Conf-Type ::= BITSTRING ( rd-prot; original; secret; letterbox; ) Extended-Conf-Type ::= BITSTRING ( rd-prot; original; secret; letterbox; allow-anonymous; forbid-secret; reserved2; reserved3; ) Any-Conf-Type ::= @lt{Conf-Type} | @lt{Extended-Conf-Type}; @end example These types are used to specify the type of a conference. @type{Conf-Type} is used in data types and calls that were created before version 8.0 of the protocol and has been augmented in @type{Extended-Conf-Type}. The type @type{Any-Conf-Type} is used when either is admissible. The bits have the following meaning (@pxref{Conferences}, for more info.) @table @conftype @item rd-prot If unset anyone can add themselves as members to the conference. @item original If set, comments are not allowed in the conference. @item secret If set the conference is secret. It's existence will only be revealed to members and supervisors. @item letterbox Set if the conference is a person's mailbox. @item allow-anonymous Set if anonymous articles are allowed in the conference. @item forbid-secret If set, secret members cannot be added to the conference. @itemx reserved2 @itemx reserved3 Reserved for future use. The values of these bits should be never be modified or used by clients who do not know their meaning. When a new conference is created these should always be set to zero. @end table @node Conference Search Results @section Conference Search Results @anchor{Conf-Z-Info} @tindex Conf-Z-Info @example Conf-Z-Info ::= ( name : @lt{HOLLERITH}; type : @lt{Conf-Type}; conf-no : @lt{Conf-No}; ) @end example These types are used for the result of some calls that search for conferences based on their names. @node Conference Status Types @section Conference Status Types @anchor{Garb-Nice} @anchor{Conference-Old} @tindex Garb-Nice @tindex Conference-Old @tindex Conference @tindex UConference @example Garb-Nice ::= @lt{INT32}; Conference-Old ::= ( name : @lt{HOLLERITH}; type : @lt{Conf-Type}; creation-time : @lt{Time}; last-written : @lt{Time}; creator : @lt{Pers-No}; presentation : @lt{Text-No}; supervisor : @lt{Conf-No}; permitted-submitters : @lt{Conf-No}; super-conf : @lt{Conf-No}; msg-of-day : @lt{Text-No}; nice : @lt{Garb-Nice}; no-of-members : @lt{INT16}; first-local-no : @lt{Local-Text-No}; no-of-texts : @lt{INT32}; ) @anchor{Conference} Conference ::= ( name : @lt{HOLLERITH}; type : @lt{Extended-Conf-Type}; creation-time : @lt{Time}; last-written : @lt{Time}; creator : @lt{Pers-No}; presentation : @lt{Text-No}; supervisor : @lt{Conf-No}; permitted-submitters : @lt{Conf-No}; super-conf : @lt{Conf-No}; msg-of-day : @lt{Text-No}; nice : @lt{Garb-Nice}; keep-commented : @lt{Garb-Nice}; no-of-members : @lt{INT16}; first-local-no : @lt{Local-Text-No}; no-of-texts : @lt{INT32}; expire : @lt{Garb-Nice}; aux-items : @lt{ARRAY} @lt{Aux-Item}; ) @anchor{UConference} UConference ::= ( name : @lt{HOLLERITH}; type : @lt{Extended-Conf-Type}; highest-local-no : @lt{Local-Text-No}; nice : @lt{Garb-Nice}; ) @end example These three types are used to specify information about a conference. @type{Garb-Nice} is a quantity used to specify how long articled are kept in a conference before being removed. @type{Conference} is the full information about a conference and @type{UConference} is brief information about a conference. The fields of @type{Conference} are @table @field @item name The name of this conference. @item type The type of the conference. @item creation-time The date and time when the conference was created. @item last-written The date when something was last written in the conference. @item creator The person who created the conference. @item presentation The article containing the conference presentation or zero if the conference has no presentation. @item supervisor The conference@footnote{The @field{supervisor} may be a person, in which case the members of that person's mailbox become supervisors.} who supervises this conference. @item permitted-submitters The conference whose members@footnote{@field{permitted-submitters} can be a person, in which case all persons who are members of the associated mailbox are allowed to submit articles to the conference.} may submit articles to the conference, or zero if anyone may do so. @item super-conf This field has two unrelated uses. If the @conftype{original} bit is set, clients should send comments to this conference (@pxref{Recipients of comments}). If the @field{permitted-submitters} field rejects a text@footnote{This is true if the text is created using @reqlink{create-text}, @reqlink{create-anonymous-text}, @reqlink{create-anonymous-text-old} or @reqlink{create-text-old}. Future requests that create texts may have other semantics.}, the server will silently send the text to the @field{super-conf} conference instead. This redirection mechanism is applied repeatedly until conference that accepts the text is found, or an implementation-defined limit is reached. @item msg-of-day The conference notice, if any. @item nice The number of days an article should be kept before being removed from the conference. @item keep-commented A text that has comments no older than this number of days will not be removed from the conference. @item no-of-members The number of members of this conference. @item first-local-no The local number of the oldest existing article in the conference. @item no-of-texts The number of articles in the conference. @item expire This field will be used to control when a conference expires. It is not used at the moment, and should be set to zero for future compatibility. @item aux-items The conference's aux item list. @end table The fields of @type{UConference} are @table @field @item name The name of this conference. @item type The conference type. Note that this is an extended conference type, unlike the type field of @type{Conference}. @item highest-local-no The local number of the newest article in the conference. @item nice The number of days an article should be kept before being removed from the conference. @end table @node Archaic way to list conferences @section Archaic way to list conferences @anchor{Conf-List-Archaic} The result of request number 12, lookup-name, cannot be expressed in the grammar used in this document. This is as close as it gets: @tindex Conf-List-Archaic @example Conf-List-Archaic ::= ( conf-nos : @lt{ARRAY} @lt{Conf-No}; conf-types : @lt{ARRAY} @lt{Conf-Type}; ! Sans @var{n}; see below ) @end example The two arrays @field{conf-nos} and @field{conf-types} are always the same size. For some obscure reason the size of the second array is not actually transmitted. See also the example in @ref{lookup-name}. @node Mapping Local to Global Text Numbers @section Mapping Local to Global Text Numbers @anchor{Text-Mapping} @tindex Text-Mapping @tindex Local-To-Global-Block @tindex Text-Number-Pair @example Text-Mapping ::= ( range-begin : @lt{Local-Text-No}; range-end : @lt{Local-Text-No}; more-texts-exists : @lt{BOOL}; block : @lt{Local-To-Global-Block}; ) @anchor{Local-To-Global-Block} Local-To-Global-Block ::= SELECTION ( 0=sparse sparse-block : @lt{ARRAY} @lt{Text-Number-Pair}; 1=dense dense-block : @lt{Text-List}; ) @anchor{Text-Number-Pair} Text-Number-Pair ::= ( local-number : @lt{Local-Text-No}; global-number : @lt{Text-No}; ) @end example A @type{Text-Mapping} is used when the client needs to look up which global @type{Text-No} that corresponds to a @type{Local-Text-No}. The client uses @reqlink{local-to-global} to ask for information about a few texts starting a a certain local text number, and the server returns the information in a @type{Text-Mapping}. @table @field @item range-begin The first local text number that the @type{Text-Mapping} says anything about. @item range-end The first local text number that the reply doesn't say anything about. This @type{Text-Mapping} tells the client about all existing texts from @field{range-begin} to (but not including) @field{range-end}. @item more-texts-exists This is true if there are more texts in the conference after this block. If a request such as @reqlink{local-to-global-reverse} which searches backwards, this will instead be true if there are more texts before this block. @item block The block can be sent i two formats. The server is free to choose which format to use as it pleases; clients must be prepared for any of them. @itemize @bullet @item The @dfn{sparse} format is useful when many local text number no longer exists. It starts with a @code{0} that indicates that the sparse format is used, and is followed by an array of @type{Text-Number-Pair}. The array will always be sorted so that @field{local-number} always increases. @item The @dfn{dense} format is good when most of the local text numbers exist. It starts with a @code{1} that indicates that the dense format is used, and is followed by a @type{Text-List}. The @type{Text-List} contains @field{first-local-no} and an array of @type{Text-No}. The local text number @field{first-local-no} corresponds to the first @type{Text-No} in the array, @field{first-local-no} + 1 corresponds to the second entry in the array, and so on. The array contains a zero to indicate that a certain local text number doesn't exist. @end itemize @end table @node Server Information @section Server Information @anchor{Info} @tindex Info @tindex Info-Old @tindex Version-Info @tindex Static-Server-Info @example Info ::= ( version : @lt{INT32}; conf-pres-conf : @lt{Conf-No}; pers-pres-conf : @lt{Conf-No}; motd-conf : @lt{Conf-No}; kom-news-conf : @lt{Conf-No}; motd-of-lyskom : @lt{Text-No}; aux-item-list : @lt{ARRAY} @lt{Aux-Item}; ) @anchor{Info-Old} Info-Old ::= ( version : @lt{INT32}; conf-pres-conf : @lt{Conf-No}; pers-pres-conf : @lt{Conf-No}; motd-conf : @lt{Conf-No}; kom-news-conf : @lt{Conf-No}; motd-of-lyskom : @lt{Text-No}; ) @anchor{Version-Info} Version-Info ::= ( protocol-version : @lt{INT32}; server-software : @lt{HOLLERITH}; software-version : @lt{HOLLERITH}; ) @anchor{Static-Server-Info} Static-Server-Info ::= ( boot-time : @lt{Time}; save-time : @lt{Time}; db-status : @lt{HOLLERITH}; existing-texts : @lt{INT32}; highest-text-no : @lt{Text-No}; existing-confs : @lt{INT32}; existing-persons : @lt{INT32}; highest-conf-no : @lt{Conf-No}; ) @end example These data types contain information about the LysKOM server. The fields of @type{Info} and @type{Info-Old} are: @table @field @item version The server version encoded as a number @var{@badspell{aa}}@var{@badspell{bb}}@var{@badspell{cc}} where @var{@badspell{aa}} is the major version number, @var{@badspell{bb}} the minor number and @var{@badspell{cc}} the secondary minor version. For instance, @code{10607} is version 1.6.7 of the server. If greater than 10699 the @reqlink{get-version-info} should be used instead. @item conf-pres-conf The conference that contains conference presentations. @item pers-pres-conf The conference that contains person presentations. @item motd-conf The conference that contains conference and person notices. @item kom-news-conf The conference that contains news about LysKOM. @item motd-of-lyskom The number of an article to display when LysKOM is entered or zero if there is none. @item aux-item-list (Not present in @type{Info-Old}.) A list of aux-items that belong to the server. @end table The fields of @type{Version-Info} are: @table @field @item protocol-version The version of protocol A the server is using. This may be used to ascertain which calls are available. @item server-software Human-readable name of the server software. @item software-version Human-readable name of the server software version. @end table The @type{Static-Server-Info} contains information about the state of the server when it started. It contains the following fields: @table @field @item boot-time When did the server start? @item save-time When the server starts, it examines the database to see when it was saved. That information is available here. @item db-status The status of the database that the server found on startup. The value is implementation-defined. lyskomd reports @code{clean} (if the previous invocation of the server was shut down cleanly) or @code{backup} (which means that some information may have been lost in the last restart). Clients should be prepared to find other values here. @item existing-texts Number of texts that existed on startup. (To find out how many texts exists right now, you can use the @reqdlink{get-stats} call with @code{what} set to @code{texts}@linkhere{}.) @item highest-text-no The highest text number that existed on startup. (To find the highest text number that exists right now, use the @reqlink{first-unused-text-no} and @reqlink{find-previous-text-no} calls.) @item existing-confs Number of conferences (including letterboxes) that existed on startup. (To find out how many conferences exists right now, you can use the @reqdlink{get-stats} call with @code{what} set to @code{confs}@linkhere{}.) @item existing-persons Number of persons that existed on startup. (To find out how many persons exists right now, you can use the @reqdlink{get-stats} call with @code{what} set to @code{persons}@linkhere{}.) @item highest-conf-no The highest conference number that existed on startup. (To find the highest conference number that exists right now, use the @reqlink{first-unused-conf-no} and @reqlink{find-previous-conf-no} calls.) @end table @node Person Status Types @section Person Status Types @anchor{Person} @tindex Person @tindex Personal-Flags @tindex Priv-Bits @example Person ::= ( username : @lt{HOLLERITH}; privileges : @lt{Priv-Bits}; flags : @lt{Personal-Flags}; last-login : @lt{Time}; user-area : @lt{Text-No}; total-time-present : @lt{INT32}; sessions : @lt{INT32}; created-lines : @lt{INT32}; created-bytes : @lt{INT32}; read-texts : @lt{INT32}; no-of-text-fetches : @lt{INT32}; created-persons : @lt{INT16}; created-confs : @lt{INT16}; first-created-local-no : @lt{INT32}; no-of-created-texts : @lt{INT32}; no-of-marks : @lt{INT16}; no-of-confs : @lt{INT16}; ) @anchor{Personal-Flags} Personal-Flags ::= BITSTRING ( unread-is-secret; flg2; flg3; flg4; flg5; flg6; flg7; flg8; ) @anchor{Priv-Bits} Priv-Bits ::= BITSTRING ( wheel; admin; statistic; create-pers; create-conf; change-name; flg7; flg8; flg9; flg10; flg11; flg12; flg13; flg14; flg15; flg16; ) @end example These types are used to specify information about persons. @type{Person} contains the information about a person, @type{Personal-Flags} contains flags set by the user and @type{Priv-Bits} contains the person's privileges (@pxref{Security}). The fields of @type{Person} are @table @field @item username The name of the user. @c FIXME (bug 196): this is wrong/needs explanation/should be renamed. @item privileges The privileges of the person. @item flags Flags set by the user. @item last-login The time when the person last logged on or off. @item user-area The text number of the person's user area or zero if the person has no user area. @item total-time-present The number of seconds the person has been using LysKOM. @item sessions The number of sessions the person has initiated. @item created-lines The number of lines of articles the person has written. @item created-bytes The number of characters the person has written. @item read-texts The number of articles the person has read. @item no-of-text-fetches The number of texts the person has retrieved from the server. @item created-persons The number of other persons this person has created. @item created-confs This holds the number of conferences created by the person. @item first-created-local-no The local number of the earliest existing article written by the person. The local number applies to a local-to-global mapping containing all articles written by the person. @item no-of-created-texts This holds the number of articles written by the person, not counting the articles created before the earliest existing article written by the person. To get the true number of created articles, compute @field{first-created-local-no} + @field{no-of-created-texts} - 1. @item no-of-marks The number of marked texts this person has. @item no-of-confs The number of conferences the person is a member of. @end table The fields of @type{Personal-Flags} are @table @field @item unread-is-secret If this is set, only the person and his supervisors can see how many texts this persons have read in a certain conference. The server will clear the @field{read-ranges} field of @type{Membership} (and @field{read-texts}, @field{last-time-read} and @field{last-text-read} fields of @type{Membership-10} and @type{Membership-Old}) when other persons asks about the information. @item flg2 @itemx flg3 @itemx flg4 @itemx flg5 @itemx flg6 @itemx flg7 @itemx flg8 Reserved for the future. Set them to 0, and ignore the values they have. @end table @node Membership Information @section Membership Information @anchor{Membership-Type} @tindex Membership-Type @example Membership-Type ::= BITSTRING ( invitation; passive; secret; passive-message-invert; reserved2; reserved3; reserved4; reserved5; ) @end example The @type{Membership-Type} type contains flags that modify a membership. It is passed as part of both @type{Member} and @type{Membership} (and obsolete versions of those types). The flags are: @table @field @item invitation The member has been invited, but has not yet accepted membership. Clients should set this flag when adding other users as members. The server may force this flag to be set when adding another person as a member of a conference. @item passive The member is not actively participating in the conference. Passive members do not receive messages (@pxref{async-send-message}) and should not be displayed as active members by clients. See also @field{passive-message-invert}. @item secret The member does not wish to disclose the membership. Secret memberships and members are cleared before being returned to a person who is not a supervisor of the member or has sufficient privileges enabled. @item passive-message-invert If this bit is set, the @field{passive} bit is inverted when checking for messages (@pxref{async-send-message}) to this conference. In other words, messages are blocked if one (but not both) of the bits @field{passive} and @field{passive-message-invert} are set. @end table The remaining flags in the @type{Membership-Type} structure are reserved and should be set to false on all new memberships and retained on all existing memberships. @anchor{Member} @tindex Member @example Member ::= ( member : @lt{Pers-No}; added-by : @lt{Pers-No}; added-at : @lt{Time}; type : @lt{Membership-Type}; ) @end example The @type{Member} structure encodes information about a member in a conference. It is returned by the @reqdlink{get-members} call@linkhere{}. The fields of a @type{Member} structure are @table @field @item member The person who is a member of the conference. @item added-by The person who created the membership. This field is zero only if the membership was created before protocol version 10 was introduced. @item added-at The time when the membership was created. This field is meaningless if added-by is zero. @item type Flags modifying the membership. @end table The contents of a @type{Member} structure can be cleared (all fields set to zero) if the person requesting the record has insufficient privileges to see the contents of the structure. @anchor{Membership} @anchor{Read-Range} @tindex Membership-Old @tindex Membership @tindex Read-Range @tindex Membership-10 @example Read-Range ::= ( first-read : @lt{Local-Text-No}; last-read : @lt{Local-Text-No}; ) Membership ::= ( position : @lt{INT32}; last-time-read : @lt{Time}; conference : @lt{Conf-No}; priority : @lt{INT8}; read-ranges : @lt{ARRAY} @lt{Read-Range}; added-by : @lt{Pers-No}; added-at : @lt{Time}; type : @lt{Membership-Type}; ) @anchor{Membership-Old} Membership-Old ::= ( last-time-read : @lt{Time}; conference : @lt{Conf-No}; priority : @lt{INT8}; last-text-read : @lt{Local-Text-No}; read-texts : @lt{ARRAY} @lt{Local-Text-No}; ) @anchor{Membership-10} Membership-10 ::= ( position : @lt{INT32}; last-time-read : @lt{Time}; conference : @lt{Conf-No}; priority : @lt{INT8}; last-text-read : @lt{Local-Text-No}; read-texts : @lt{ARRAY} @lt{Local-Text-No}; added-by : @lt{Pers-No}; added-at : @lt{Time}; type : @lt{Membership-Type}; ) @end example The @type{Membership} structure encodes information about a person's membership in a conference. It is returned by the @reqlink{query-read-texts} and @reqdlink{get-membership} calls@linkhere{}. The @type{Membership-10} and @type{Membership-Old} types are obsolete variants of the same type, returned by older requests. @type{Membership-Old} contains less information. The encoding of the read texts in @type{Membership-10} is very inefficient in the common case where you have read many texts after the first unread text. @table @field @item position The position of this membership in the membership list. @item last-time-read The time when the person last read anything from the conference. This will contain the start of the epoch if the @field{unread-is-secret} bit of the @type{Personal-Flags} is set and you don't have enough privileges to get the info anyhow. @item conference The conference this membership data pertains to. @item priority The priority the person has assigned to the conference. The higher the number, the higher the priority. In the past, priority zero indicated a passive membership. This usage is now obsolete. @item last-text-read The local number of last text read in the conference. This will be set to 0 if @field{unread-is-secret} is set, unless you have access to the data anyhow. This field is not available in @type{Membership}, but you can easily derive the same information from @field{read-ranges}. @item read-texts Additional texts beyond @field{last-text-read} that have also been read. This will be empty if @field{unread-is-secret} is set, unless you have access to the data anyhow. @item read-ranges A list of ranges of all read texts. This will be empty if @field{unread-is-secret} is set, unless you have access to the data anyhow. @item added-by The person who created the membership. This field is zero if the membership was created before protocol version 10 was introduced. @item added-at The time when the membership was created. This field is meaningless if added-by is zero. @item type Flags modifying the membership. @end table A membership record may be cleared by the server (all fields set to zero) if the person requesting the membership has insufficient privileges to see the contents membership, but has sufficient privileges to know about the person. @node Article Marks @section Article Marks @anchor{Mark} @tindex Mark @example Mark ::= ( text-no : @lt{Text-No}; type : @lt{INT8}; ) @end example This data type hold information about a person's marks on articles. The fields of @type{Mark} are @table @field @item text-no The text number marked. @item type The mark value. @end table Before version eight of protocol A, the meaning of the mark value was unspecified. Work is underway to specify the meaning of certain mark values. @node Article Information @section Article Information @anchor{Misc-Info} @tindex Misc-Info @tindex Text-Stat-Old @tindex Text-Stat @tindex Info-Type @example Misc-Info ::= SELECTION ( 0=recpt recipient : @lt{Conf-No}; 1=cc-recpt cc-recipient : @lt{Conf-No}; 2=comm-to comment-to : @lt{Text-No}; 3=comm-in commented-in : @lt{Text-No}; 4=footn-to footnote-to : @lt{Text-No}; 5=footn-in footnoted-in : @lt{Text-No}; 6=loc-no local-no : @lt{Local-Text-No}; 7=rec-time received-at : @lt{Time}; 8=sent-by sender : @lt{Pers-No}; 9=sent-at sent-at : @lt{Time}; 15=bcc-recpt bcc-recipient : @lt{Conf-No}; ) @anchor{Info-Type} Info-Type ::= ENUMERATION-OF(@lt{Misc-Info}) @anchor{Text-Stat-Old} Text-Stat-Old ::= ( creation-time : @lt{Time}; author : @lt{Pers-No}; no-of-lines : @lt{INT32}; no-of-chars : @lt{INT32}; no-of-marks : @lt{INT16}; misc-info : @lt{ARRAY} @lt{Misc-Info}; ) @anchor{Text-Stat} Text-Stat ::= ( creation-time : @lt{Time}; author : @lt{Pers-No}; no-of-lines : @lt{INT32}; no-of-chars : @lt{INT32}; no-of-marks : @lt{INT16}; misc-info : @lt{ARRAY} @lt{Misc-Info}; aux-items : @lt{ARRAY} @lt{Aux-Item}; ) @end example These two structures contain information about a single article. @type{Text-Stat} contains core information about the article and @type{Misc-Info} contains miscellaneous information related to the article. A @type{Text-Stat} consists of the following: @table @field @item creation-time The time when the article was created. @item author The author of the article. @item no-of-lines The number of lines in the article. @item no-of-chars The number of characters in the article. @item no-of-marks The number of marks added to this article by persons. @item misc-info The @type{Misc-Info} list for this article. @item aux-items The list of aux items for this article. @end table @type{Misc-Info}, when sent to the client, is sent in a particular order (@pxref{The Misc-Info List}). The variants @type{Misc-Info} are (briefly): @table @misc @item recpt Used to specify recipients of the article. @item cc-recpt Specifies recipients who have received a copy of the article but who will not receive comments. @item comm-to Specifies an article this article is a comment to. @item comm-in Specifies an article in which there are comments to this article. @item footn-to Specifies an article this article is a footnote to. @item footn-in Specifies an article to which this article is a footnote. @item loc-no Specifies the local text number of this article in the conference specified by @misc{recpt}, @misc{cc-recpt} or @misc{bcc-recpt}. @item rec-time Specifies the time when this article was received by the conference specified by @misc{recpt}, @misc{cc-recpt} or @misc{bcc-recpt}. @item sent-by Specifies who sent this article to the conference specified by @misc{recpt}, @misc{cc-recpt} or @misc{bcc-recpt}. @item sent-at Specifies when the article was sent to the conference specified by @misc{recpt}, @misc{cc-recpt} or @misc{bcc-recpt}. @item bcc-recpt Specifies a blind carbon copy recipient. This item is only accepted by protocol version 10 servers and is only sent in responses and messages introduced in protocol version 10 or later. @end table @node Who Information @section Who Information @anchor{Who-Info-Old} @anchor{Who-Info} @anchor{Who-Info-Ident} @tindex Who-Info-Old @tindex Who-Info @tindex Who-Info-Ident @example Who-Info-Old ::= ( person : @lt{Pers-No}; working-conference : @lt{Conf-No}; what-am-i-doing : @lt{HOLLERITH}; ) Who-Info ::= ( person : @lt{Pers-No}; working-conference : @lt{Conf-No}; session : @lt{Session-No}; what-am-i-doing : @lt{HOLLERITH}; username : @lt{HOLLERITH}; ) Who-Info-Ident ::= ( person : @lt{Pers-No}; working-conference : @lt{Conf-No}; session : @lt{Session-No}; what-am-i-doing : @lt{HOLLERITH}; username : @lt{HOLLERITH}; hostname : @lt{HOLLERITH}; ident-user : @lt{HOLLERITH}; ) @end example These structures are used to retrieve information on who is currently using LysKOM. All the requests using these types are obsolete, but @type{Who-Info} is used by @async{async-i-am-on} (@pxref{async-i-am-on}). The fields of @type{Who-Info-Old} are @table @field @item person The person the information is about. @item working-conference The conference the person is currently in. @item what-am-i-doing A client-supplied string saying what the person is doing. @end table The fields of @type{Who-Info} are @table @field @item person The person the information is about. @item working-conference The conference the person is currently in. @item session The person's session number. @item what-am-i-doing A client-supplied string saying what the person is doing. @item username The name of the ``real'' user constructed from @field{hostname} and @field{ident-user} (see below) and information from the client. @c FIXME (bug 196): define the format @end table The fields of @type{Who-Info-Ident} are @table @field @item person The person the information is about. @item working-conference The conference the person is currently in. @item session The person's session number. @item what-am-i-doing A client-supplied string saying what the person is doing. @item username The name of the ``real'' user constructed from @field{hostname} and @field{ident-user}. @c FIXME (bug 196): define the format @item hostname The host the connection originated at. @item ident-user The user name according to the Ident @daemon{} at the user's machine or ``unknown'' if Ident was not used. @end table @node Session Information @section Session Information @anchor{Session-Info} @anchor{Session-Info-Ident} @tindex Session-Info @tindex Session-Info-Ident @tindex Static-Session-Info @tindex Session-Flags @tindex Dynamic-Session-Info @tindex Scheduling-Info @example Session-Info ::= ( person : @lt{Pers-No}; working-conference : @lt{Conf-No}; session : @lt{Session-No}; what-am-i-doing : @lt{HOLLERITH}; username : @lt{HOLLERITH}; idle-time : @lt{INT32}; connection-time : @lt{Time}; ) Session-Info-Ident ::= ( person : @lt{Pers-No}; working-conference : @lt{Conf-No}; session : @lt{Session-No}; what-am-i-doing : @lt{HOLLERITH}; username : @lt{HOLLERITH}; hostname : @lt{HOLLERITH}; ident-user : @lt{HOLLERITH}; idle-time : @lt{INT32}; connection-time : @lt{Time}; ) @anchor{Static-Session-Info} Static-Session-Info ::= ( username : @lt{HOLLERITH}; hostname : @lt{HOLLERITH}; ident-user : @lt{HOLLERITH}; connection-time : @lt{Time}; ) @anchor{Session-Flags} Session-Flags ::= BITSTRING ( invisible; user-active-used; user-absent; reserved3; reserved4; reserved5; reserved6; reserved7; ) @anchor{Dynamic-Session-Info} Dynamic-Session-Info ::= ( session : @lt{Session-No}; person : @lt{Pers-No}; working-conference : @lt{Conf-No}; idle-time : @lt{INT32}; flags : @lt{Session-Flags}; what-am-i-doing : @lt{HOLLERITH}; ) @anchor{Scheduling-Info} Scheduling-Info ::= ( priority : @lt{INT16}; weight : @lt{INT16}; ) @end example These data types give information about a particular LysKOM session. The types @type{Session-Info} and @type{Session-Info-Ident} have been superseded by @type{Static-Session-Info} and @type{Dynamic-Session-Info}. The static session info represents information about a session that does not change during the lifetime of the session. Therefore static session infos can be aggressively cached by the client. The fields of @type{Session-Info} are @table @field @item person The person using this session. @item working-conference The conference the session is currently in. @item session The number of this session. @item what-am-i-doing A client-supplied string saying what the person is currently doing. @item username The name of the ``real'' user (see @type{Who-Info} above.) @item idle-time The number of seconds since @reqdlink{user-active} was used by this session@linkhere{}, or since the session was created if @req{user-active} has not been used yet. See also @field{user-active-used} below. @item connection-time The time when the connection was initiated. This is not the same as the amount of time the person has been on. @end table The fields of @type{Session-Info-Ident} are @table @field @item person The person using this session. @item working-conference The conference the session is currently in. @item session The number of this session. @item what-am-i-doing A client-supplied string saying what the person is currently doing. @item username The name of the ``real'' user (see @type{Who-Info-Ident} above.) @item hostname The host the connection originated at. @item ident-user The user name according to the Ident @daemon{} at the user's machine or ``unknown'' if Ident was not used. @item idle-time The number of seconds since @reqdlink{user-active} was used by this session@linkhere{}, or since the session was created if @req{user-active} has not been used yet. See also @field{user-active-used} below. @item connection-time The time when the connection was initiated. This is not the same as the amount of time the person has been on. @end table The fields of @type{Static-Session-Info} are @table @field @item username The name of the ``real'' user (see @type{Who-Info-Ident} above.) @item hostname The host the connection originated at. @item ident-user The user name according to the Ident @daemon{} at the user's machine or ``unknown'' if Ident was not used. @item connection-time The time when the connection was initiated. This is not the same as the amount of time the person has been on. @end table The bits in @type{Session-Flags} are: @table @field @item invisible When true, the user requested an invisible session (@pxref{login}). Sessions where no-one is logged in also have the @field{invisible} flag set. @item user-active-used When true, the @reqdlink{user-active} call@linkhere{} has been issued by the session, which in turn means that @field{idle-time} fields of @type{Dynamic-Session-Info}, @type{Session-Info} and @type{Session-Info-Ident} are valid. When false, the @field{idle-time} fields contains the number of seconds since the session was created. @item user-absent This flag is currently not used. @end table The fields of a @type{Dynamic-Session-Info} are @table @field @item session The session number of the session. @item person The person currently logged on, or zero if the session has not yet logged on. @item working-conference The conference the session is currently in. @item idle-time The number of seconds since @reqdlink{user-active} was used by this session@linkhere{}, or since the session was created if @req{user-active} has not been used yet. See also @field{user-active-used} above. @item flags The dynamic session flags (see above.) @item what-am-i-doing What the client is doing. This string is set by the client. @end table The @type{Scheduling-Info} type determines how the resources are shared between different sessions@footnote{RFC 2782 (DNS SRV) provided inspiration when the @type{Scheduling-Info} structure was defined.}. See @reqlink{get-scheduling} and @reqlink{set-scheduling} for more information. It contains these fields: @table @field @item priority Clients with a numerically lower @field{priority} value will have priority over other clients. A client with @field{priority} set to 0 can totally starve clients with @field{priority} set to 1, 2 or anything higher. @item weight Within a priority class, the resources are shared in proportion to the @field{weight} value. If one client has a weight of 200 and another of 50, the first client will get roughly four times as much work done (assuming that the server is the limiting factor). @end table @node Statistics @section Statistics @anchor{Stats} @anchor{Stats-Description} @tindex Stats @tindex Stats-Description @example Stats ::= ( average : @lt{FLOAT}; ascent-rate : @lt{FLOAT}; descent-rate : @lt{FLOAT}; ) Stats-Description ::= ( what : @lt{ARRAY} @lt{HOLLERITH}; when : @lt{ARRAY} @lt{INT32}; ) @end example The @type{Stats} structure returns information about a measured value. @table @field @item average The @field{average} is the average value for the measurement period. If the measurement period is 0, this is instead the current value. @item ascent-rate @itemx descent-rate These fields indicate the activity for this value, measured in units per second. If the measured value is pending DNS requests, the @field{ascent-rate} would be the average number of issued requests per second, and the @field{descent-rate} would be the average number of received replies (or timeouts, errors, or other reasons why the request is no longer pending). When calculating the @field{ascent-rate}, only events that cause the value to increase are considered. Likewise, the @field{descent-rate} only considers events that decrease the value. Example: if the measurement period is 60 seconds, the value starts at 5, and it is increased by one 90 times and decreased by one 60 times during the measurement period, the value will of course be 35 when the period ends. The ascent rate will be 1.5 per second, and the descent rate 1.0 per second. If the measurement period is 0, both @field{ascent-rate} and @field{descent-rate} are set to 0. @end table The @type{Stats-Description} structure returns information about what kind of statistical information that the server gathers. It contains these fields: @table @field @item what A list of all things that the server collect statistics about. @ref{Measured Properties}, for a list of things that might be included in this list. @item when The statistics returned by @reqlink{get-stats} is a number of values collected during various periods of time. This array contains the periods, measured in seconds. The value 0 means that the current value is returned. The values are only returned in ascending order, so if 0 is included it will be the first value. @ref{Measured Properties}, for more info. @end table @node Protocol Requests @chapter Protocol Requests This chapter documents all calls that can be made to the server. All calls are annotated with the protocol version in which they appeared and their current status. @menu * Protocol Notation:: The notation used when describing the requests and their replies. * login-old:: O Log in to LysKOM. Call 62 is preferred (0) * logout:: r Log out. Call 62 to log in again (1) * change-conference:: r Change current conference (2) * change-name:: r Change name of a conference or person (3) * change-what-i-am-doing:: r Change what-am-i-doing in who information (4) * create-person-old:: O Create a person (5) * get-person-stat-old:: O Get person information. Use call 49 (6) * set-priv-bits:: r Set privileges of a person (7) * set-passwd:: r Set password of a person (8) * query-read-texts-old:: O Get info on what is read (9) * create-conf-old:: O Create a conference (10) * delete-conf:: r Delete a conference (11) * lookup-name:: O Look up a name. Replaced by call 76 (12) * get-conf-stat-older:: O Get conference information. Use call 50 (13) * add-member-old:: O Add a member to a conference (14) * sub-member:: r Remove a member from a conference (15) * set-presentation:: r Set the presentation of a conference (16) * set-etc-motd:: r Set conference notice (17) * set-supervisor:: r Set supervisor of a conference (18) * set-permitted-submitters:: r Set permitted submitters of a conference (19) * set-super-conf:: r Set super-conference of a conference (20) * set-conf-type:: r Set the type of a conference (21) * set-garb-nice:: r Set garb-nice of a conference (22) * get-marks:: r Get marks for a person (23) * mark-text-old:: O Mark a text. Replaced by calls 72 and 73 (24) * get-text:: r Get an article or part of an article (25) * get-text-stat-old:: O Get text status information (26) * mark-as-read:: r Mark an article as read in a conference (27) * create-text-old:: O Create an article (28) * delete-text:: r Delete an article (29) * add-recipient:: r Add a recipient to an article (30) * sub-recipient:: r Remove a recipient from an article (31) * add-comment:: r Add a comment to an article (32) * sub-comment:: r Remove a comment from an article (33) * get-map:: O Map local text nos to global. Use 103 (34) * get-time:: r Get the current time (35) * get-info-old:: O Get server information (36) * add-footnote:: r Add an article as a footnote to another (37) * sub-footnote:: r Remove a footnote from an article (38) * who-is-on-old:: O Get active sessions. Replaced by call 63 (39) * set-unread:: r Set number of unread in a conference (40) * set-motd-of-lyskom:: r Set LysKOM message of the day (41) * enable:: r Set security level (42) * sync-kom:: r Save the database (43) * shutdown-kom:: r Shut LysKOM down (44) * broadcast:: O Broadcast a message. Replaced by call 53 (45) * get-membership-old:: O Get membership for a person. Use call 99 (46) * get-created-texts:: O Get texts created by a user. Use 104 (47) * get-members-old:: O Get members of a conference. Use 101 (48) * get-person-stat:: r Get status information for a person (49) * get-conf-stat-old:: O Get status information for a conference (50) * who-is-on:: O Get current sessions. Use call 63 (51) * get-unread-confs:: r Get conferences with unread articles (52) * send-message:: r Send a personal message (53) * get-session-info:: O Get session information. Use call 64 (54) * disconnect:: r Disconnect a session (55) * who-am-i:: r Get current session number (56) * set-user-area:: r Set a person's user area (57) * get-last-text:: r Get text created before a certain time (58) * create-anonymous-text-old:: O Create an anonymous text (59) * find-next-text-no:: r Get next text number (60) * find-previous-text-no:: r Get previous text number (61) * login:: r Log in to LysKOM (62) * who-is-on-ident:: O Get current sessions (63) * get-session-info-ident:: O Get session information (64) * re-lookup-person:: O Look up a person based on name (65) * re-lookup-conf:: O Look up a conference based on name (66) * lookup-person:: O Find persons matching abbreviated name (67) * lookup-conf:: O Find conference matching abbrev'd name (68) * set-client-version:: r Set the name and version the client (69) * get-client-name:: r Get the name of the client (70) * get-client-version:: r Get the version of the client (71) * mark-text:: r Mark a text (72) * unmark-text:: r Unmark a text (73) * re-z-lookup:: r Lookup for conferences and persons (74) * get-version-info:: r Get protocol version of server (75) * lookup-z-name:: r Look up an abbreviated name (76) * set-last-read:: r Set text last read in a conference (77) * get-uconf-stat:: r Get abbreviated conference status (78) * set-info:: r Set server information (79) * accept-async:: r Select asynchronous messages to receive (80) * query-async:: r Ask server which async messages are sent (81) * user-active:: r Tell the server that the user is active (82) * who-is-on-dynamic:: r Get a list of active users (83) * get-static-session-info:: r Get static information about a session (84) * get-collate-table:: r Get the current collate table (85) * create-text:: r Create a text (86) * create-anonymous-text:: r Create an anonymous text (87) * create-conf:: r Create a conference (88) * create-person:: r Create a person (89) * get-text-stat:: r Get text status information (90) * get-conf-stat:: r Get conference status information (91) * modify-text-info:: r Add or delete text aux items (92) * modify-conf-info:: r Add or delete conference aux items (93) * get-info:: r Get server information (94) * modify-system-info:: r Add or delete system aux items (95) * query-predefined-aux-items:: r Get list of aux-items the server knows (96) * set-expire:: e Set the expire field of a conference (97) * query-read-texts-10:: O Get info on what is read (98) * get-membership-10:: O Get membership for a person (99) * add-member:: r Add a member to a conference (100) * get-members:: r Get members of a conference (101) * set-membership-type:: r Modify the type of conference (102) * local-to-global:: r Map local text numbers to global ones (103) * map-created-texts:: r Map texts created by a person to global (104) * set-keep-commented:: r Set how new comments protect old texts (105) * set-pers-flags:: r Set personal flags (106) * query-read-texts:: r Get info on what is read (107) * get-membership:: r Get membership for a person (108) * mark-as-unread:: r Mark a text as not read (109) * set-read-ranges:: r Specify which texts that are read (110) * get-stats-description:: r Get a list of measured properties (111) * get-stats:: r Get a measurement (112) * get-boottime-info:: r Get server startup status information (113) * first-unused-conf-no:: r Get first unused conference number (114) * first-unused-text-no:: r Get first unused text number (115) * find-next-conf-no:: r Get next conference number (116) * find-previous-conf-no:: r Get previous conference number (117) * get-scheduling:: e Get client priority information (118) * set-scheduling:: e Alter client priority (119) * set-connection-time-format:: r Use UTC or local timezone of server? (120) * local-to-global-reverse:: r Map local text numbers to global ones (121) * map-created-texts-reverse:: r Map texts created by a person to global (122) @end menu @ifnottex @node Protocol Notation @section Protocol Notation @end ifnottex The heading for each call looks something like this: @display create-person-old [5] (1) Obsolete (10) @end display The heading consists of several parts: @table @asis @item The name: @samp{create-person-old} This is the name of the call. The name is not considered part of the protocol. It may change in future versions of this document. Since the name is never sent over the network it doesn't matter that much. @item The call number: @samp{[5]} The call number is what really matters, since it is sent over the network. It will never change. @item Introduced: @samp{(1)} The protocol version when the call was first implemented. Some calls added more functionality in a later protocol version. The description for those calls describes such changes. @item The status: @samp{Obsolete} The status of the call (see below). @item Made obsolete: @samp{(10)} This figure is only present for some obsolete calls, and it states in which protocol version the call was obsoleted. @end table The status of a call can be any of: @table @samp @item Experimental The call is experimental. No client should rely on the existence of this call. Experimental calls that are useful will usually become recommended in future versions. @item Recommended The call is a standard call. Clients are recommended to use these calls rather than experimental or obsolete ones. Servers are required to implement all recommended calls. @item Obsolete The call should no longer be used by clients. Servers should implement these, or they will be incompatible with old client versions. @emph{Please note:} the documentation for the obsolete calls may be incomplete. Many of them perform compatibility magic to ensure that they never return anything that old clients don't expect. This compatibility magic is often documented, but we may have forgotten to document it in some places. @end table @i{A note about the examples:} The examples consist of a number of calls and replies. @iftex Calls are set in a normal typewriter font. Replies are set in a slanted typewriter font. @end iftex Extra newlines are sometimes inserted in the examples to avoid overly long lines. @node login-old @section login-old [0] (1) Obsolete (4) @findex login-old @example login-old [0] (( person : @lt{Pers-No}; passwd : @lt{HOLLERITH} )) -> ( ); @end example Log in as a person. This call has been replaced by @reqlink{login}. @subheading Error codes @table @errorcode @item undefined-person @rarg{person} is not an existing person. @item login-disallowed Logins are not allowed and @rarg{person} does not have the @priv{wheel} bit set. @item invalid-password @rarg{passwd} is not the correct password for @rarg{person}. The @field{error-status} indicates the person number. @end table @node logout @section logout [1] (1) Recommended @findex logout @example logout [1] ( ) -> ( ); @end example Log out from LysKOM. This call does not disconnect the session; use @reqdlink{disconnect} for that@linkhere{}. After issuing a @req{logout} call the client can reconnect as the same or a different person using the @reqdlink{login} call@linkhere{}. For a client that needs to log in as several different users, issuing multiple logout and login requests during one session is faster and places less load on the server than does creating new sessions. @subheading Error codes This call never fails. @node change-conference @section change-conference [2] (1) Recommended @findex change-conference @example change-conference [2] ( conference : @lt{Conf-No} ) -> ( ) ; @end example Change current conference of a session. This call used to be called pepsi (the name was a very obscure and not very funny joke.) @subheading Error codes @table @errorcode @item login-first The session is not logged in yet. @item undefined-conference Conference @rarg{conference} does not exist or is secret. @item conference-zero @rarg{conference} is zero. @item not-member The user currently logged in is not a member of @rarg{conference}. @end table @node change-name @section change-name [3] (1) Recommended @findex change-name @example change-name [3] (( conference : @lt{Conf-No}; new-name : @lt{HOLLERITH} )) -> ( ) ; @end example This call changes the name of a conference or a person. To change the name of a conference the session issuing the call must be logged in as a person who either has special privileges or is the supervisor of the conference. @subheading Error codes @table @errorcode @item login-first The session is not logged in yet. @item undefined-conference Conference @rarg{conference} does not exist or is secret. @item conference-zero @rarg{conference} is zero. @item permission-denied Permission denied. The @priv{change-name} bit is not set or the user does not have enough access to @rarg{conference}. @item conference-exists @rarg{new-name} is already occupied by another conference. @item string-too-long @rarg{new-name} is too long for a valid conference name. @item bad-name There are invalid characters in @rarg{new-name}. @end table @node change-what-i-am-doing @section change-what-i-am-doing [4] (1) Recommended @findex change-what-i-am-doing @example change-what-i-am-doing [4] ( what-am-i-doing : @lt{HOLLERITH} ) -> ( ); @end example This call tells the server what the logged-in user is doing. The string is usually displayed when a user requests that a client list who is using LysKOM. Clients are encouraged to use this call creatively. @subheading Error codes @table @errorcode @item string-too-long @rarg{what-am-i-doing} is too long. @end table @node create-person-old @section create-person-old [5] (1) Obsolete (10) @findex create-person-old @example create-person-old [5] (( name : @lt{HOLLERITH}; passwd : @lt{HOLLERITH} )) -> ( @lt{Pers-No} ); @end example This call requests that the server create a new person with the name and password given as arguments. To create a person the session may have to be logged in as a person with sufficient privileges, if the server is configured that way. If the session was not logged in an automatic visible login to the new person will be performed. The new person will be a member of exactly one conference: the associated mailbox. That membership will have priority 255 and (of course) position 0. All flags of the membership will be 0. @reqexample @example 1 5 @holl{24,LysKOM Statistics Daemon} @holl{6,secret} @t{=1 6} @end example This example creates a new person named ``LysKOM statistics Daemon'' with the password ``secret''. The server has returned the person number six for the person. @subheading Error codes @table @errorcode @item login-first The session is not logged in and the server does not allow person creation before logging in. @item permission-denied The server does not allow everyone to create person and the person currently logged on does not have the @priv{create-pers} bit set. @item conference-exists There is already a conference named @rarg{name}. @item invalid-password The string @rarg{passwd} is not a valid password. @item index-out-of-range Attempt to create a person failed because we reached the maximum number of conferences permitted. The @field{error-status} indicates the person number that should have been created if the limit hadn't been reached. @end table @node get-person-stat-old @section get-person-stat-old [6] (1) Obsolete (1) @findex get-person-stat-old @example get-person-stat-old [6] (( person : @lt{Pers-No}; mask : @lt{INT32} )) -> ( @lt{Person} ); @end example This call returns information about a person. If the low bit of @rarg{mask} is not set, the empty string is returned instead of the @field{username} field. This call is obsolete and has been replaced by @reqlink{get-person-stat}. @subheading Error codes @table @errorcode @item login-first This call can't be executed without logging in first. @item undefined-person Person @rarg{person} does not exist. @item undefined-conference Conference @rarg{person} does not exist or is secret. @item conference-zero @rarg{person} is zero. @end table @node set-priv-bits @section set-priv-bits [7] (1) Recommended @findex set-priv-bits @example set-priv-bits [7] (( person : @lt{Pers-No}; privileges : @lt{Priv-Bits} )) -> ( ); @end example This call sets the privileges of @rarg{person} to @rarg{privileges}. @xref{Security}. To successfully issue this call the session must be logged in as a person with sufficient privileges. @reqexample @example 1 7 6 0010000000000000 @t{=1} @end example This example sets the privileges of person 6 to nothing but @priv{statistic}. This particular set of privileges might be useful for a person used by a statistics-collecting @daemon{}. @subheading Error codes @table @errorcode @item login-first This call can't be executed without logging in first. @item undefined-person @rarg{person} is not a valid person. @item permission-denied The person currently logged in does not have the @priv{wheel} bit set and privilege level set to 6 or higher. @end table @node set-passwd @section set-passwd [8] (1) Recommended @findex set-passwd @example set-passwd [8] (( person : @lt{Pers-No}; old-pwd : @lt{HOLLERITH}; new-pwd : @lt{HOLLERITH} )) -> ( ); @end example This call is used to set the password of @rarg{person} to @rarg{new-pwd}. Any person may set it's own password. In addition persons with sufficient privileges may set other persons' passwords. The password of the person currently logged in must match @rarg{old-pwd}. @reqexample @example 1 8 5 @holl{6,gazonk} @holl{7,a9go8Hz} @t{=1} @end example This example sets the password of the LysKOM administrator to ``a9go8Hz'' provided that the old password was ``gazonk''. @subheading Error codes @table @errorcode @item login-first This call cannot be executed without logging in. @item undefined-person @rarg{person} is not a valid person. @item permission-denied Attempt to change password of another person without being the supervisor of that person and without the @priv{wheel} bit set and privilege level 7 or higher enabled. @item invalid-password @rarg{old-pwd} is invalid or @rarg{new-pwd} is invalid as a password. @end table @node query-read-texts-old @section query-read-texts-old [9] (1) Obsolete (10) @findex query-read-texts-old @example query-read-texts-old [9] (( person : @lt{Pers-No}; conference : @lt{Conf-No} )) -> ( @lt{Membership-Old} ); @end example This call is used to find the number of unread texts in a conference. The data it returns is actually a membership structure which specifies which texts have been read. It is up to the client to transform the data to a more usable form. @rarg{person} is the person being queried and @rarg{conference} is the conference in question. Calling @req{query-read-texts-old} does not require the session to be logged in. @reqexample @example 1 9 6 1 @t{=1 32 5 11 12 7 93 1 193 1 1 20 133 3 @{ 135 136 137 @}} @end example This example finds the read texts for user 6 in conference 1. The returned data indicates that the user last read conference 1 (the tenth number) on Monday July 12th, 1993 at 11:05:32 (the first nine numbers), that the person has assigned priority 20 to the conference (the eleventh number) and that all articles up to and including local number 133 plus articles 135, 136 and 137 have been read. @subheading Error codes @table @errorcode @item undefined-person @rarg{person} does not exist, or no access to person. @item undefined-conference Conference @rarg{conference} does not exist, or is secret. @item conference-zero @rarg{conference} is zero. @item not-member @rarg{person} is not a member of @rarg{conference}. @end table @node create-conf-old @section create-conf-old [10] (1) Obsolete (10) @findex create-conf-old @example create-conf-old [10] (( name : @lt{HOLLERITH}; type : @lt{Any-Conf-Type} )) -> ( @lt{Conf-No} ); @end example This call is used to create new conferences. @rarg{name} is the name of the new conference and @rarg{type} is its type. If successful, the call returns the conference number of the newly created conference. To use this call the session must have logged in as a user with privileges to create conferences (@pxref{Security}). @reqexample @example 1 50 8 @t{%1 9 0} 1 10 @holl{13,@value{IAM}} 00001000 @t{=1 8} 1 50 8 @t{=1 @holl{13,@value{IAM}} 0000 43 9 17 14 5 96 5 165 1 43 9 17 14 5 96 5 165 1 5 0 5 0 5 0 77 0 1 0} @end example This example creates a new conference named ``@value{IAM}''@footnote{This conference is a standard Lysator conference. It's all Padrone's fault.} which accepts all users as members and accepts anonymous articles. The server returns 7 as the new conference number. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item permission-denied The server does not allow everyone to create a conference and user does not have the @req{create-conf} bit set. @item conference-exists A conference named @rarg{name} already exists. @item bad-name @rarg{name} contains invalid characters. @item string-to-long @rarg{name} is too long to be used as a conference name. @item secret-public The conference type @rarg{type} has the @conftype{secret} bit set, but the @conftype{rd-prot} bit is cleared. @item index-out-of-range Attempt to create a conference failed because we reached the maximum number of conferences permitted. The @field{error-status} indicates the conference number that should have been created if the limit hadn't been reached. @end table @node delete-conf @section delete-conf [11] (1) Recommended @findex delete-conf @example delete-conf [11] ( conf : @lt{Conf-No} ) -> ( ); @end example This call deletes the conference @rarg{conf} from the LysKOM database. Only privileged users and the supervisors of a conference may delete it. If the conference is a mailbox the corresponding person will also be deleted. @reqexample @example 1 50 7 @t{=1 @holl{4,Test} 1001 16 4 19 10 5 96 1 161 1 16 4 19 10 5 96 1 161 1 7 0 7 0 0 0 77 1 1 0} 1 11 7 @t{=1} 1 50 7 @t{%1 9 0} @end example This example shows the successful deletion of conference number seven. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference @rarg{conf} does not exist or is secret. @item conference-zero @rarg{conf} is zero. @item permission-denied Not supervisor of @rarg{conf} and not enough privileges enabled. @item undefined-person @rarg{conf} is a mailbox but does not exist as a person (the database is corrupt.) @end table @node lookup-name @section lookup-name [12] (1) Obsolete (7) @findex lookup-name @example lookup-name [12] ( name : @lt{HOLLERITH} ) -> ( @lt{Conf-List-Archaic} ); @end example This call returns a list of conferences matching the string @rarg{name}. lookup-name has been superseded by @reqlink{lookup-z-name}. @c ispell-ignore @reqexample @example 1 12 @holl{3,a d} @t{=1 3 @{ 217 674 1582 @} @{ 0000 1001 0000 @}} 2 12 @holl{3,:::} @t{=2 0 * *} 3 76 @holl{3,a d} 1 1 @t{=3 3 @{ @holl{31,Alkohol- (och annan) drogdebatt} 0000 217 @holl{13,Anna Degerman} 1001 674 @holl{27,Anarchy discussion (import)} 0000 1582 @}} 4 76 @holl{3,:::} 1 1 @t{=4 0 *} @end example @c ispell-end-ignore This example shows two attempts to look up a name. The first example looks up @samp{a d} and finds three matches (the middle, number 674, is a person). The second example looks up @samp{:::} which doesn't match any conference (or person). Call number 3 and 4 issues the same lookup using the @reqdlink{lookup-z-name} call@linkhere{}. (The return value for call number 3 has been broken into three lines to fit on the page.) @subheading Error codes This call always succeeds. @node get-conf-stat-older @section get-conf-stat-older [13] (1) Obsolete (1) @findex get-conf-stat-older @example get-conf-stat-older [13] (( conf-no : @lt{Conf-No}; mask : @lt{INT32} )) -> ( @lt{Conference-Old} ); @end example This call retrieves the information associated with conference @rarg{conf-no} in the LysKOM server. This call should no longer be used; use @reqdlink{get-conf-stat} instead@linkhere{}. The @rarg{mask} argument determines if the name is returned or not. If the lowest bit is 1 the name is returned, otherwise the empty string is returned instead of the name. @subheading Error codes @table @errorcode @item undefined-conference @rarg{conf-no} does not exist or is secret. @item conference-zero @rarg{conf-no} is zero. @end table @node add-member-old @section add-member-old [14] (1) Obsolete (10) @findex add-member-old @example add-member-old [14] (( conf-no : @lt{Conf-No}; pers-no : @lt{Pers-No}; priority : @lt{INT8}; where : @lt{INT16} )) -> ( ); @end example Make the person @rarg{pers-no} a member of conference @rarg{conf-no}. The membership priority is set to @rarg{priority} and its position in the membership list is set to @rarg{where}. This call can be used to change the priority and position of a conference in the person's membership list if the person is already a member of the conference. In protocol version 10, setting the priority to zero sets the passive bit in the membership. The actual priority is not changed. @reqexample @example 1 46 119 0 10 0 @t{=1 1 @{ 49 14 17 13 8 91 5 255 1 119 255 0 0 * @}} 1 14 1 119 250 0 @t{=1} 1 46 119 0 10 0 @t{=1 2 @{ 52 30 14 11 5 96 2 162 1 1 250 0 0 * 49 14 17 13 8 91 5 255 1 119 255 0 0 * @}} @end example This example makes person 119 (me) a member of conference number 1. The priority is set to 250 and the conference is placed first in the membership list. The first and last calls of the example show the membership list for person 119 before and after the call. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference Conference @rarg{conf-no} does not exist or is secret. @item conference-zero @rarg{conf-no} is zero. @item undefined-person Person @rarg{pers-no} does not exist @item access-denied Not enough permissions or privileges to add members to conference @rarg{conf-no}. @item permission-denied Person @rarg{pers-no} is already a member of conference @rarg{conf-no}, but the person logged on is not a supervisor and does not have enough privileges to change the priorities of person @rarg{pers-no}. @end table @node sub-member @section sub-member [15] (1) Recommended @findex sub-member @example sub-member [15] (( conf-no : @lt{Conf-No}; pers-no : @lt{Pers-No} )) -> ( ); @end example Removes the person @rarg{pers-no} from the membership list of conference @rarg{conf-no} and remove the conference from the person's list of memberships. @reqexample @example 1 46 5 0 100 0 @t{=1 2 @{ 44 14 19 10 5 96 1 161 1 1 0 0 0 * 49 14 17 13 8 91 5 255 1 5 255 0 0 * @}} 1 15 1 5 @t{=1} 1 46 5 0 100 0 @t{=1 1 @{ 49 14 17 13 8 91 5 255 1 5 255 0 0 * @}} @end example This example shows how person 5 is removed from conference one. The calls to @req{get-membership-old} demonstrate the effects on the LysKOM database. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference Conference @rarg{conf-no} does not exist or is secret. @item conference-zero @rarg{conf-no} is zero. @item undefined-person Person @rarg{pers-no} does not exist. @item not-member Person @rarg{pers-no} is not a member of conference @rarg{conf-no}. @item permission-denied Not supervisor of conference @rarg{conf-no} or not supervisor of person @rarg{pers-no} and not enough privileges to issue the call anyway. @field{error-status} contains the conference number. @end table @node set-presentation @section set-presentation [16] (1) Recommended @findex set-presentation @example set-presentation [16] (( conf-no : @lt{Conf-No}; text-no : @lt{Text-No} )) -> ( ); @end example This call sets the presentation text of the conference or person @rarg{conf-no} to the text @rarg{text-no}. To remove a presentation, use a @rarg{text-no} of zero. This call protects the new presentation from being deleted automatically and removes such protection from the old presentation. In lyskomd this is implemented by increasing the mark count on presentation texts. @reqexample @example 1 50 6 @t{=1 @holl{11,David Byers} 1001 26 15 11 9 5 96 0 160 1 26 15 11 9 5 96 0 160 1 5 0 5 0 5 0 77 1 1 0} 1 16 6 1 @t{=1} 1 50 6 @t{=1 @holl{11,David Byers} 1001 26 15 11 9 5 96 0 160 1 26 15 11 9 5 96 0 160 1 5 1 5 0 5 0 77 1 1 0} @end example This example shows how the presentation of person 6 is being changed. To start with, the person had no presentation, as is shown by the @reqdlink{get-conf-stat-old} call@linkhere{}. Later, after @req{set-presentation} has been called, the presentation field has changed. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference Conference @rarg{conf-no} does not exist or is secret. @item conference-zero @rarg{conf-no} is zero. @item permission-denied Not enough permissions to change presentation of conference @rarg{conf-no}. @item no-such-text Text @rarg{text-no} does not exist or no read permission. @item mark-limit Adding a mark to text @rarg{text-no} would cause it to have too many marks. @end table @node set-etc-motd @section set-etc-motd [17] (1) Recommended @findex set-etc-motd @example set-etc-motd [17] (( conf-no : @lt{Conf-No}; text-no : @lt{Text-No} )) -> ( ); @end example This call sets the message of the day on the conference or person @rarg{conf-no} to the article @rarg{text-no} and removes the old message. To remove an old message without setting a new one, use a @rarg{text-no} of zero. This call protects the new message from automatic deletion and removes such protection from the old message just as @reqlink{set-presentation}. @reqexample @example 1 50 6 @t{=1 @holl{11,David Byers} 1001 26 15 11 9 5 96 0 160 1 26 15 11 9 5 96 0 160 1 5 0 5 0 5 0 77 1 1 0} 1 17 6 1 @t{=1} 1 50 6 @t{=1 @holl{11,David Byers} 1001 26 15 11 9 5 96 0 160 1 26 15 11 9 5 96 0 160 1 5 0 5 0 5 1 77 1 1 0} @end example This example shows how text number one is used as the message of the day for conference six (which happens to be a mailbox.) The @req{get-conf-stat-old} calls before and after demonstrate the change in the conference structure. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference Conference @rarg{conf-no} does not exist or is secret. @item conference-zero @rarg{conf-no} is zero. @item permission-denied Not enough permissions to set the MOTD of conference @rarg{conf-no}. @item mark-limit Adding a mark to text @rarg{text-no} would cause it to have too many marks. @end table @node set-supervisor @section set-supervisor [18] (1) Recommended @findex set-supervisor @example set-supervisor [18] (( conf-no : @lt{Conf-No}; admin : @lt{Conf-No} )) -> ( ); @end example The @req{set-supervisor} call changes the supervisor of an existing conference. The result is that all members of the conference @rarg{admin} become supervisors of the conference @rarg{conf-no}. Typically, but not always, @rarg{admin} will be a mailbox. @reqexample @example 1 50 4 @t{=1 @holl{17,Nyheter om LysKOM} 0000 48 11 17 13 8 91 5 255 1 15 12 11 9 5 96 0 160 1 0 0 0 0 0 0 77 1 1 1} 1 18 4 6 @t{=1} 1 50 4 @t{=1 @holl{17,Nyheter om LysKOM} 0000 48 11 17 13 8 91 5 255 1 15 12 11 9 5 96 0 160 1 0 0 6 0 0 0 77 1 1 1} @end example This example makes the members of conference six supervisors of conference four (which is usually the ``News about LysKOM'' conference). The change in the conference structure is evident from the @reqdlink{get-conf-stat-old} calls@linkhere{} before and after the @req{set-supervisor} call. Note that the original supervisor was not set. In order to change the supervisor of such a conference, the session issuing the call must have administration privileges. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference Conference @rarg{conf-no} or conference @rarg{admin} does not exist or is secret. @item conference-zero @rarg{conf-no} is zero. @item permission-denied Not enough permissions or privileges to change the supervisor of conference @rarg{conf-no}. @end table @node set-permitted-submitters @section set-permitted-submitters [19] (1) Recommended @findex set-permitted-submitters @example set-permitted-submitters [19] (( conf-no : @lt{Conf-No}; perm-sub : @lt{Conf-No} )) -> ( ); @end example This call grants the right to send articles to the conference @rarg{conf-no} to all members of the conference @rarg{perm-sub}. If @rarg{perm-sub} is 0, everybody can send articles to the conference. (This is the default setting of new conferences and persons.) When a person tries to submit an article but does not have the right to do so, the server will send the article to the super-conference instead. @reqexample @example 1 50 4 @t{=1 @holl{17,Nyheter om LysKOM} 0000 48 11 17 13 8 91 5 255 1 15 12 11 9 5 96 0 160 1 0 0 6 0 0 0 77 1 1 1} 1 19 4 1 @t{=1} 1 50 4 @t{=1 @holl{17,Nyheter om LysKOM} 0000 48 11 17 13 8 91 5 255 1 15 12 11 9 5 96 0 160 1 0 0 6 1 0 0 77 1 1 1} @end example This example shows how all members of conference one are given permission to send articles to conference four. From the beginning, only members of conference four were permitted to submit articles. The change is evident from the @reqdlink{get-conf-stat-old} calls@linkhere{} before and after the @req{set-permitted-submitters} call. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference Conference @rarg{conf-no} or conference @rarg{perm-sub} does not exist or is secret. @item conference-zero @rarg{conf-no} is zero. @item permission-denied Not enough permissions to change the permitted submitters of conference @rarg{conf-no}. @end table @node set-super-conf @section set-super-conf [20] (1) Recommended @findex set-super-conf @example set-super-conf [20] (( conf-no : @lt{Conf-No}; super-conf : @lt{Conf-No} )) -> ( ); @end example Makes the conference @rarg{super-conf} the super-conference of the conference @rarg{conf-no}. @xref{Conference Status Types}, for more info on what this field is used for. @reqexample @example 1 50 4 @t{=1 @holl{17,Nyheter om LysKOM} 0000 48 11 17 13 8 91 5 255 1 15 12 11 9 5 96 0 160 1 0 0 6 0 0 0 77 1 1 1} 2 20 4 8 @t{=2} 3 50 4 @t{=3 @holl{17,Nyheter om LysKOM} 0000 48 11 17 13 8 91 5 255 1 15 12 11 9 5 96 0 160 1 0 0 6 0 8 0 77 1 1 1} @end example This example demonstrates how the super-conference of conference 1 is set to conference 8. The calls to @reqlink{get-conf-stat-old} demonstrate the change in the conference structure. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference Conference @rarg{conf-no} or conference @rarg{super-conf} does not exist or is secret. @item conference-zero @rarg{conf-no} is zero. @item permission-denied Not enough permissions to change super-conference of conference @rarg{conf-no}. @end table @node set-conf-type @section set-conf-type [21] (1) Recommended @findex set-conf-type @example set-conf-type [21] (( conf-no : @lt{Conf-No}; type : @lt{Any-Conf-Type} )) -> ( ); @end example Sets the conference type of conference @rarg{conf-no} to @rarg{type}. Before protocol version 8, @rarg{type} could only be four bits. Starting with protocol version 8, either a four-bit @type{Conf-Type} or an eight-bit @type{Extended-Conf-Type} is allowed. @reqexample @example 1 78 4 @t{=1 @holl{17,Nyheter om LysKOM} 00001000 1 77} 1 21 4 00000000 @t{=1} 1 78 4 @t{=1 @holl{17,Nyheter om LysKOM} 00000000 1 77} @end example This example shows a user removing the @conftype{allow-anonymous} bit from conference four. The @reqdlink{get-uconf-stat} call@linkhere{} shows all eight bits of the conference type before and after the @req{set-conf-type} call. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference Conference @rarg{conf-no} does not exist or is secret. @item conference-zero @rarg{conf-no} is zero. @item secret-public @rarg{type} has @conftype{secret} bit but not @conftype{rd-prot}. @item permission-denied Not enough permissions or privileges to change the conference type of conference @rarg{conf-no}. @item letterbox Attempt to change the @conftype{letterbox} flag. @item invalid-membership-type Attempt to change to a conference type that is not compatible with one of more members of the conference (for example, attempting to set @conftype{forbid-secret} on a conference with a secret member.) @field{error-status} is the id of the first person with an incompatible membership type. @end table @node set-garb-nice @section set-garb-nice [22] (1) Recommended @findex set-garb-nice @example set-garb-nice [22] (( conf-no : @lt{Conf-No}; nice : @lt{Garb-Nice} )) -> ( ); @end example Sets the expiration time for articles in conference @rarg{conf-no} to @rarg{nice} days. An article that is older than the maximum expiration time of each conference it is sent to may be deleted by the LysKOM server unless it has marks. @reqexample @example 1 78 4 @t{=1 @holl{17,Nyheter om LysKOM} 00000000 1 77} 1 22 4 7 @t{=1} 1 78 4 @t{=1 @holl{17,Nyheter om LysKOM} 00000000 1 7} @end example This example shows the expiration time of conference four being lowered from 77 to just seven days. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference Conference @rarg{conf-no} does not exist or is secret. @item conference-zero @rarg{conf-no} is zero. @item permission-denied Not enough permissions to change the expiration time for conference @rarg{conf-no}. @end table @node get-marks @section get-marks [23] (1) Recommended @findex get-marks @example get-marks [23] ( ) -> ( @lt{ARRAY} @lt{Mark} ); @end example This call returns the list of marks the current user has set. @reqexample @example 1 23 @t{=1 3 @{ 13020 100 13043 95 12213 95 @}} @end example In this example, the current user has three marks, one on text 13020 with mark type 100, one on text 13042 with mark type 95 and one on text 12213 with mark type 95. The maximum number of marks may be arbitrarily limited in the LysKOM server. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @end table @node mark-text-old @section mark-text-old [24] (1) Obsolete (4) @findex mark-text-old @example mark-text-old [24] (( text : @lt{Text-No}; mark-type : @lt{INT8} )) -> ( ); @end example This call has been replaced by @reqlink{mark-text} and @reqlink{unmark-text} and should no longer be used. This call can only set @rarg{mark-type} to a value in the range 1 to 255 (inclusive). If @rarg{mark-type} is set to 0 the mark will be removed. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item no-such-text The text @rarg{text} does not exist. @item permission-denied No read permission on text @rarg{text}. @item undefined-person The person currently logged in does not exist (can't happen error.) @item too-many-marks Marking the text would cause the person doing the marking to have too many marks, or cause the text to have too many marks. @end table @node get-text @section get-text [25] (1) Recommended @findex get-text @example get-text [25] (( text : @lt{Text-No}; start-char : @lt{INT32}; end-char : @lt{INT32} )) -> ( @lt{HOLLERITH} ); @end example Retrieve text number @rarg{text} from the LysKOM database, starting at position @rarg{start-char} and ending at position @rarg{end-char}. The first character in the text is numbered 0 and the last can be retrieved using @reqlink{get-text-stat}. It is also permitted to request a character position beyond the actual end of the text, in which case as much text as is available will be returned. @reqexample @example 1 25 100 0 32766 @t{=1 @holl{25,Yawn@bullet{}Nothing is happening}} 2 25 100 5 32766 @t{=2 @holl{20,Nothing is happening}} 3 25 100 0 3 @t{=3 @holl{4,Yawn}} @end example In the example, @code{@bullet{}} represents a linefeed. In this example, text 100 is requested three times, first from position 0 to position 32766, then from position 5 to position 32766 and finally from position 0 to position 4. The first reply contains the entire text, the following two contain only the requested portion. @subheading Error codes @table @errorcode @item no-such-text The text @rarg{text} does not exits or no read permission. This error code will also be used when attempting to fetch texts without logging in first. (There are some texts that are readable without logging in: the motd-of-lyskom (@pxref{set-motd-of-lyskom}), and texts with the @aux{world-readable} aux item set on them.) @item text-zero Attempt to retrieve text number 0. @item index-out-of-range @rarg{start-char} is larger than the length of the text. @end table @node get-text-stat-old @section get-text-stat-old [26] (1) Obsolete (10) @findex get-text-stat-old @example get-text-stat-old [26] ( text-no : @lt{Text-No} ) -> ( @lt{Text-Stat-Old} ); @end example Get information about text number @rarg{text-no}. The text-stat contains information about the size of the text, its recipients, comments, author and more. For compatibility reasons this call will only return the misc-infos 0=recpt, 1=cc-recpt, 2=comm-to, 3=comm-in, 4=footn-to, 5=footn-in, 6=loc-no, 7=rec-time, 8=sent-by and 9=sent-at. Newer misc-infos will either be removed or converted to a similar one. Specifically, 15=bcc-recpt may (at the servers discretion) be converted to 1=cc-recpt or omitted entirely. @reqexample @example 1 26 100 @t{=1 7 35 16 15 6 96 1 196 1 14 1 22 1 7 @{ 0 7 6 85 0 15 6 1 8 13 9 12 37 16 15 6 96 1 196 1 3 311 @}} @end example In this example, text number 100 was created by person 7 at approximately 4:35PM on July 15 1996. Its recipients are conferences 7 and 15, and it was sent to conference 15 by person 13 at 16:37 on the day it was created. The text has a single comment: text 311. @subheading Error codes @table @errorcode @item no-such-text The text @rarg{text-no} does not exist, or no read access. This error code will also be used when attempting to fetch texts without logging in first. (There are some texts that are readable without logging in: the motd-of-lyskom (@pxref{set-motd-of-lyskom}), and texts with the @aux{world-readable} aux item set on them.) @item text-zero Attempt to retrieve text number 0. @end table @node mark-as-read @section mark-as-read [27] (1) Recommended @findex mark-as-read @example mark-as-read [27] (( conference : @lt{Conf-No}; text : @lt{ARRAY} @lt{Local-Text-No} )) -> ( ); @end example Marks text @rarg{text} in conference number @rarg{conference} as read for the current user. This call updates the membership record for the user. @reqexample @example 1 9 6 7 @t{=1 20 32 11 17 6 96 3 198 1 7 1 240 0 *} 1 78 7 @t{=1 @holl{13,@value{IAM}} 00001000 241 1} 1 27 7 1 @{ 241 @} @t{=1} 1 9 6 7 @t{=1 20 32 11 17 6 96 3 198 1 7 1 241 0 *} @end example This example shows person 6 marking local text number 241 in conference 7 as read. In the first @req{query-read-texts-old} call the person has read local text 240, but nothing higher. The @req{mark-as-read} call is reflected in the second @req{query-read-texts-old} call, where the user is seen to have read text 241 in conference 7. To mark a global text number as read it is necessary to translate it into local text numbers by looking at the misc-info list in the @type{Text-Stat} and calling @req{mark-as-read} once for each recipient. There is no need to call @req{mark-as-read} on deleted texts. The server will automatically mark them as read, sooner or later. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference The conference @rarg{conference} does not exist or is secret. @item conference-zero @rarg{conference} is zero. @item not-member The person logged on is not a member of conference @rarg{conference}. @item no-such-local-text One of the numbers in @rarg{text} is not a local text number in @rarg{conference}. The error argument indicates the index of the invalid number. @item local-text-zero One of the numbers in @rarg{text} is zero. @end table @node create-text-old @section create-text-old [28] (1) Obsolete (10) @findex create-text-old @example create-text-old [28] (( text : @lt{HOLLERITH}; misc-info : @lt{ARRAY} @lt{Misc-Info} )) -> ( @lt{Text-No} ); @end example Creates a new text with contents from @rarg{text} and recipients etc. defined by @rarg{misc-info} (@pxref{The Misc-Info List}). In addition to the result, the server will send an asynchronous message to all members of any of the recipients of the new text. It is not defined whether this messages comes before or after the reply to the create-text message. Clients should be prepared for either situation. The text up to the first linefeed is considered to be the subject line. The remaining text is the message body. Although messages with only a subject are valid, clients should avoid letting users create such messages. The only Misc-Info items valid for this call are @misc{recpt}, @misc{cc-recpt}, @misc{bcc-recpt} (protocol version 10), @misc{comm-to} and @misc{footn-to}. @reqexample @example 1 28 @holl{20,Example@bullet{}Message body} 3 @{ 0 5 1 112 2 33467 @} @t{:16 0 33502 13 16 15 16 6 97 3 196 1 119 1 20 0} @t{ 5 @{ 0 5 6 148 1 112 6 3438 2 33467 @} } @t{=1 33502} @end example In the example, @code{@bullet{}} represents a linefeed. In this example, person 119 creates a text containing a subject and a one-line body. The recipient of the text is conference five, conference 112 is a CC recipient and the text is a comment to text 33467. The server reply indicates that the new text has been given number 33502. Finally there is an asynchronous message sent to all members of recipient conferences. Note how the message was sent before the reply to the client. The misc-info list in this message has two additional fields, the local numbers of the text in each of its recipient conferences. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item string-too-long The string @rarg{text} is longer than the maximum length of a message. @item temporary-failure The text could not be created at the moment. @item no-such-text Attempt to comment or footnote a non-existent or secret text. @item not-author Attempt to footnote a text authored by someone else. @item footnote-limit Attempt to footnote a text with the maximum number of footnotes already set. @item comment-limit Attempt to comment a text with the maximum number of comments already set. @item index-out-of-range Attempt to create a text failed because we reached the maximum number of texts permitted. The @field{error-status} indicates the text number that should have been created if the limit hadn't been reached. @item access-denied Attempt to send a text to a conference failed because no access to the conference or any super conference that will accept a text. @item anonymous-rejected Attempt to send an anonymous text to a conference that does not accept anonymous texts. @item illegal-misc Invalid misc-info list. A recipient is listed more than once or there is an unknown misc item in the misc-info list. @end table @node delete-text @section delete-text [29] (1) Recommended @findex delete-text @example delete-text [29] ( text : @lt{Text-No} ) -> ( ); @end example Deletes the text @rarg{text} from the LysKOM database, if the person issuing the command may do so. @reqexample @example 1 29 33467 @t{=1} @end example This simple example shows the deletion of text number 33467. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item no-such-text The text @rarg{text} does not exist or no read access. @item not-author The person logged in is not the text author or supervisor of the text author. @end table @node add-recipient @section add-recipient [30] (1) Recommended @findex add-recipient @example add-recipient [30] (( text-no : @lt{Text-No}; conf-no : @lt{Conf-No}; recpt-type : @lt{Info-Type} )) -> ( ); @end example Adds @rarg{conf-no} as recipient to text @rarg{text-no}. If @rarg{recpt-type} is 1, then a @misc{cc-recpt} (@pxref{The Misc-Info List}) is created; otherwise a @misc{recpt} is created. Since protocol version 8 this call can also be used to change a @misc{cc-recpt} into a @misc{recpt} and vice versa by simply adding a recipient that already exists. Since protocol version 10 the @rarg{recpt-type} parameter is a @type{Misc-Info}. Only infos @misc{recpt}, @misc{cc-recpt} and @misc{bcc-recpt} are accepted. In protocol version 9 and earlier this argument was a @type{BOOL}, that indicated if the recipient should be a @misc{cc-recpt} (when true) or @misc{recpt} (when false). @reqexample @example 1 26 1 @t{=1 2 22 12 17 6 97 4 197 1 5 4 256 1 0 *} 1 30 1 5 0 @t{=1} 1 26 1 @t{=1 2 22 12 17 6 97 4 197 1 5 4 256 1} @t{ 3 @{ 0 5 6 1 9 34 34 17 17 6 97 4 197 1 @}} 1 30 1 5 1 @t{=1} 1 26 1 @t{=1 2 22 12 17 6 97 4 197 1 5 4 256 1} @t{ 3 @{ 1 5 6 1 9 34 34 17 17 6 97 4 197 1 @}} @end example This example show how conference 5 is added first as a recipient of text 1, then changed to a carbon-copy recipient. The misc-info list reflects these changes. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference The conference @rarg{conf-no} does not exist. @item conference-zero @rarg{conf-no} is zero. @item no-such-text The text @rarg{text-no} does not exist. @item already-recipient The conference @rarg{conf-no} is already a recipient of the same type as @rarg{recpt-type}. @item illegal-info-type @rarg{recpt-type} is not @misc{recpt}, @misc{cc-recpt} or @misc{bcc-recpt}. @item recipient-limit The text already has the maximum number of recipients. @item permission-denied Attempt to change recipient types of a recipient without being the supervisor of either the author, recipient, or sender of the recipient. @item access-denied Attempt to add a conference as recipient that the person logged on does not have permission to add texts to. The client may have to chase the super conf chain. @end table @node sub-recipient @section sub-recipient [31] (1) Recommended @findex sub-recipient @example sub-recipient [31] (( text-no : @lt{Text-No}; conf-no : @lt{Conf-No} )) -> ( ); @end example Removes @rarg{conf-no} from the list of recipients of text @rarg{text-no}. Recipients may be removed by the author of the text or by the supervisor of the recipients of the text or by the supervisor of the author. @reqexample @example 1 26 1 @t{=1 2 22 12 17 6 97 4 197 1 5 4 256 1} @t{ 3 @{ 1 5 6 1 9 34 34 17 17 6 97 4 197 1 @}} 1 31 1 5 @t{=1} 1 26 1 @t{=1 2 22 12 17 6 97 4 197 1 5 4 256 1 0 *} 1 31 1 5 @t{%1 30 0} @end example In this example, conference 5 is removed from the recipient list of text number 5. When the call is repeated, the server simply returns an error since conference 5 is not a recipient of the text. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item no-such-text The text @rarg{text-no} does not exist or is secret. @item not-recipient The conference @rarg{conf-no} is not a recipient of text @rarg{text-no}. @item undefined-conference The conference @rarg{conf-no} does not exist or is secret. @item conference-zero @rarg{conf-no} is zero. @item permission-denied Not supervisor of text author or conference, and not sender of text to @rarg{conf-no} and not enough privileges set and enabled. @end table @node add-comment @section add-comment [32] (1) Recommended @findex add-comment @example add-comment [32] (( text-no : @lt{Text-No}; comment-to : @lt{Text-No} )) -> ( ); @end example Add a comment link between the text @rarg{comment-to} and the text @rarg{text-no} (@rarg{text-no} becomes a comment to the text @rarg{comment-to}). This call is used to add comment links after a text has been created. The normal procedure for creating comments is to add a @misc{comm-to} element to the text's misc-info list when the text is created (@pxref{The Misc-Info List}). @reqexample @example 1 26 1 @t{=1 2 22 12 17 6 97 4 197 1 5 4 256 1 0 *} 1 26 2 @t{=1 49 49 18 17 6 97 4 197 1 5 1 52 1 2 @{ 0 2 6 1 @}} 1 32 2 1 @t{=1} 1 26 1 @t{=1 2 22 12 17 6 97 4 197 1 5 4 256 1 1 @{ 3 2 @}} 1 26 2 @t{=1 49 49 18 17 6 97 4 197 1 5 1 52 1} @t{ 4 @{ 0 2 6 1 2 1 9 19 52 18 17 6 97 4 197 1 @}} @end example In this example, text number two is added as a comment to text number one. The change is reflected in the Misc-Info List of the texts. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item index-out-of-range The texts @rarg{text-no} and @rarg{comment-to} are identical. The @field{error-status} is @rarg{text-no}. @item no-such-text The text @rarg{text-no} of @rarg{comment-to} are undefined. @item comment-limit The text @rarg{comment-to} already has the maximum number of comments. @item already-comment The text @rarg{text-no} is already a comment of @rarg{comment-to}. @item already-footnote The text @rarg{text-no} is already a footnote of @rarg{comment-to}, and a text cannot be both a comment and a footnote to the same text. @end table @node sub-comment @section sub-comment [33] (1) Recommended @findex sub-comment @example sub-comment [33] (( text-no : @lt{Text-No}; comment-to : @lt{Text-No} )) -> ( ); @end example This call removes the text @rarg{text-no} from @rarg{comment-to}'s list of comments. @reqexample @example 1 26 1 @t{=1 2 22 12 17 6 97 4 197 1 5 4 256 1 1 @{ 3 2 @}} 1 26 2 @t{=1 49 49 18 17 6 97 4 197 1 5 1 52 1} @t{ 4 @{ 0 2 6 1 2 1 9 19 52 18 17 6 97 4 197 1 @}} 1 33 2 1 @t{=1} 1 26 1 @t{=1 2 22 12 17 6 97 4 197 1 5 4 256 1 0 *} 1 26 2 @t{=1 49 49 18 17 6 97 4 197 1 5 1 52 1 2 @{ 0 2 6 1 @}} @end example In this example text 2 is a comment to text 1, as shown by the misc-info lists of the two texts. The @req{sub-comment} is called. The misc-info lists are changed to reflect the change. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item no-such-text One of the texts @rarg{text-no} or @rarg{comment-to} does not exist. @item not-comment The text @rarg{text-no} is not a comment to @rarg{comment-to}. @item permission-denied Not supervisor of author of @rarg{text-no} or not sender of the comment and not enough privileges set and enable to complete the call anyway. @end table @node get-map @section get-map [34] (1) Obsolete (10) @findex get-map @example get-map [34] (( conf-no : @lt{Conf-No}; first-local-no : @lt{Local-Text-No}; no-of-texts : @lt{INT32} )) -> ( @lt{Text-List} ); @end example This call has been superseded by @reqlink{local-to-global}. This call retrieves an array mapping local text numbers to global numbers. It is most often used to get a list of unread texts in a conference. Clients will usually use the @reqlink{query-read-texts} or @reqlink{get-membership} calls to find the last local number a user has read in a particular conference, then use the @req{get-map} call to retrieve the global numbers of all unread texts in the conference. The @rarg{conf-no} parameter specifies which conference to get the map of. @rarg{first-local-no} is the local number of the first text returned by the call. @rarg{no-of-texts} is the maximum number of text the client wants. The result is a list of global text numbers. The first element of the list is the global number of local number @rarg{first-local-no}, specified by the call; the second element is the global number of local number @rarg{first-local-no} plus one; and so forth. The list returned by the server is at most @rarg{no-of-texts} long, but may be shorter if the call specifies more texts that there are in the conference. If @rarg{first-local-no} is higher than the highest local text number, the server will return an error. If @rarg{first-local-no} is lower than the lowest number that still exists, the server will set @rarg{first-local-no} in the returned @type{Text-List} to the first text that still exists. The size of the returned array will be decreased by the same amount as @rarg{first-local-no} is increased. This may result in an empty array being returned. (This paragraph applies even when @rarg{first-local-no} is 0.) If no texts at all exists in @rarg{conf-no} the resulting array will be empty, and @rarg{first-local-no} will be set to the number the next text to be created will receive. @reqexample @example 1 34 119 10 5 @t{=1 10 5 @{ 0 0 466 478 391 @}} 2 34 119 16 5 @t{=2 16 3 @{ 481 0 491 @}} 3 34 119 19 5 @t{%3 16 0} 4 34 120 1 5 @t{=4 4 2 @{ 480 485 @}} 5 34 120 1 2 @t{=5 4 0 *} @end example This example shows five @req{get-map} calls. The first retrieves the mappings of local numbers 10 to 15; the second call returns local numbers 16 to 18. As this example shows the maps are not necessarily sorted in ascending order, since texts may be added after their creation, and the maps may contain zeroes anywhere. These represent texts that have been removed for some reason. Since the first example returned two leading zeroes we can be certain that at least one text with a local text number lower than 10 still exists. Otherwise the result would have been truncated in the front as it is in examples 4 and 5. The third exchange in the example shows what happens when @rarg{first-local-no} is too large. The forth and fifth examples shows what happens when an attempt to retrieve a mapping from a conference where the first local text numbers have been deleted. In the example local text numbers 1, 2 and 3 no longer exist, and 4 corresponds to 480, and 5 to 485. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference Conference @rarg{conf-no} does not exist or is secret. @item conference-zero @rarg{conf-no} is zero. @item access-denied Conference @rarg{conf-no} is read protected. @item no-such-local-text @rarg{first-local-no} is higher than the highest local text number that ever has existed in this conference. @end table @node get-time @section get-time [35] (1) Recommended @findex get-time @example get-time [35] ( ) -> ( @lt{Time} ); @end example This call simply returns the local time according to the server. @reqexample @example 1 35 @t{=1 23 47 19 17 6 97 4 197 1} @end example This example demonstrates the call. According to the server the time is 19:47:23, Thursday July 17, 1997. The result also shows that it is the 197th day of the year, and that daylight savings time is in effect. @subheading Error codes This call always succeeds @node get-info-old @section get-info-old [36] (1) Obsolete (10) @findex get-info-old @example get-info-old [36] ( ) -> ( @lt{Info-Old} ); @end example This call returns the @type{Info-Old} structure for the server (@pxref{Info-Old}). Clients should call this in order to find out which conferences are used for presentations and such. This call has been superseded by @reqlink{get-info}. This call can be issued without logging in. @reqexample @example 1 36 @t{=1 10900 1 2 3 4 1} @end example In this example, the server version is 1.9, the conference for presentation of new conferences is conference 1, the conference for presentation of new persons is conference 2, the conference for door messages is conference 3, the LysKOM news conference is conference 4 and the login message is text number 1. @subheading Error codes This call always succeeds. @node add-footnote @section add-footnote [37] (1) Recommended @findex add-footnote @example add-footnote [37] (( text-no : @lt{Text-No}; footnote-to: @lt{Text-No} )) -> ( ); @end example Add a footnote link between the text @rarg{footnote-to} and the text @rarg{text-no} (@rarg{text-no} becomes a footnote to the text @rarg{footnote-to}). This call is used to add footnote links after a text has been created. Only the author of both texts is allowed to add the footnote link. @reqexample @example 1 26 1 @t{=1 2 22 12 17 6 97 4 197 1 5 4 256 1 0 *} 1 26 2 @t{=1 49 49 18 17 6 97 4 197 1 5 1 52 1 2 @{ 0 2 6 1 @}} 1 37 2 1 @t{=1} 1 26 1 @t{=1 2 22 12 17 6 97 4 197 1 5 4 256 1 1 @{ 5 2 @}} 1 26 2 @t{=1 49 49 18 17 6 97 4 197 1 5 1 52 1} @t{ 4 @{ 0 2 6 1 4 1 9 19 52 18 17 6 97 4 197 1 @}} @end example In this example, text number two is added as a footnote to text number one. The change is reflected in the Misc-Info List of the texts. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item no-such-text The text @rarg{text-no} or @rarg{footnote-to} does not exist or is secret. @item index-out-of-range The @rarg{text-no} and @rarg{footnote-to} arguments are equal, and the server does not support texts that are footnotes to themselves. @item not-author Not author of @rarg{footnote-to}. @item footnote-limit Text @rarg{footnote-to} already has the maximum number of footnotes. @item already-footnote Text @rarg{text-no} is already a footnote to @rarg{footnote-to}. @item already-comment Text @rarg{text-no} is already a comment to @rarg{footnote-to}, and a text cannot be both a comment and a footnote to the same text. @end table @node sub-footnote @section sub-footnote [38] (1) Recommended @findex sub-footnote @example sub-footnote [38] (( text-no : @lt{Text-No}; footnote-to : @lt{Text-No} )) -> ( ); @end example This call removes the text @rarg{text-no} from @rarg{footnote-to}'s list of footnotes. Only the author of a footnote may remove it. @reqexample @example 1 26 1 @t{=1 2 22 12 17 6 97 4 197 1 5 4 256 1 1 @{ 5 2 @}} 1 26 2 @t{=1 49 49 18 17 6 97 4 197 1 5 1 52 1} @t{ 4 @{ 0 2 6 1 4 1 9 19 52 18 17 6 97 4 197 1 @}} 1 38 2 1 @t{=1} 1 26 1 @t{=1 2 22 12 17 6 97 4 197 1 5 4 256 1 0 *} 1 26 2 @t{=1 49 49 18 17 6 97 4 197 1 5 1 52 1 2 @{ 0 2 6 1 @}} @end example In this example text 2 is a footnote to text 1, as shown by the misc-info lists of the two texts. The @req{sub-footnote} is called. The misc-info lists are changed to reflect the change. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item no-such-text The text @rarg{text-no} or @rarg{footnote-to} does not exist or is secret. @item not-footnote The text @rarg{text-no} is not a footnote to @rarg{footnote-to}. @item permission-denied Not supervisor of the author of @rarg{text-no} and not enough privileges set and enabled to complete call anyway. @end table @node who-is-on-old @section who-is-on-old [39] (1) Obsolete (1) @findex who-is-on-old @example who-is-on-old [39] ( ) -> ( @lt{ARRAY} @lt{Who-Info-Old} ); @end example This call is obsolete. Use @reqlink{get-static-session-info} and @reqlink{who-is-on-dynamic} instead. If the server does not support these calls, use @reqlink{who-is-on} instead. The returned list contains all sessions where a person is logged in and the invisible flag of the session is unset. @subheading Error codes This call always succeeds. @node set-unread @section set-unread [40] (1) Recommended @findex set-unread @example set-unread [40] (( conf-no : @lt{Conf-No}; no-of-unread : @lt{INT32} )) -> ( ); @end example Only read the last @rarg{no-of-unread} in the conference @rarg{conf-no}. This call modifies the @field{last-text-read} of current person's membership for the conference. This call is sometimes used to implement the ``only read last N texts'' command found in many clients. Due to possible race conditions@footnote{Another client might create a new text immediately before the server processes this @req{set-unread} call, so you might end up setting @field{last-text-read} to something unexpected.}, this call is usually better implemented using the @reqdlink{set-last-read} call@linkhere{} which explicitly sets the @field{last-text-read} field of the membership. @reqexample @example 1 9 5 6 @t{=1 1 34 21 17 6 97 4 197 1 6 100 0 0 *} 1 40 6 0 @t{=1} 1 9 5 6 @t{=1 1 34 21 17 6 97 4 197 1 6 100 4 0 *} @end example This example shows that person 5 last read text 0 in conference 6 (and since 0 is an illegal local text number, that implies that the person has not read anything in the conference.) After calling @req{set-unread} and asking to have zero unread texts in conference 6, this is reflected by the call to @req{query-read-texts-old}. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference The conference @rarg{conf-no} does not exist or is secret. @item not-member Not a member of conference @rarg{conf-no}. @end table @node set-motd-of-lyskom @section set-motd-of-lyskom [41] (1) Recommended @findex set-motd-of-lyskom @example set-motd-of-lyskom [41] ( text-no : @lt{Text-No} ) -> ( ); @end example This call sets the login message of LysKOM. It can only be executed by a privileged person, with the proper privileges enabled. A somewhat less convenient way of doing this is to use the @reqdlink{set-info} call@linkhere{}. @reqexample @example 1 36 @t{=1 10900 1 2 3 4 0} 1 41 435 @t{=1} 1 36 @t{=1 10900 1 2 3 4 435} @end example This example shows how the login message of LysKOM is set using the set-motd-of-lyskom call. The results of the @req{get-info} calls demonstrate the effect. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item permission-denied Administrator bit not set or privilege level not enabled. @item no-such-text The text @rarg{text-no} does not exist. @item mark-limit The text @rarg{text-no} already has the maximum number of marks. @end table @node enable @section enable [42] (1) Recommended @findex enable @example enable [42] ( level : @lt{INT8} ) -> ( ); @end example Sets the security level for the current session to @rarg{level}. @xref{Security}, for details about security levels. The only levels that make any sense right now are 0 and 255. This call may be issued by any person, but without the right privilege bits set, it has no effect. @reqexample @example 1 41 1 @t{%1 12 0} 1 42 255 @t{=1} 1 41 1 @t{=1} @end example This example shows how @req{enable} makes a privileged call possible, in this case a call to @reqlink{set-motd-of-lyskom}. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @end table @node sync-kom @section sync-kom [43] (1) Recommended @findex sync-kom @example sync-kom [43] ( ) -> ( ); @end example This call instructs the LysKOM server to make sure the permanent copy of its database is current. Processing of requests is normally blocked until this call has completed, but the exact details depend on the server implementation. This call is privileged in most implementations. @reqexample @example 1 42 255 @t{=1} 1 43 @t{:0 7} @t{:0 7} @t{=1} @end example This example shows how the @reqdlink{enable} call is used to enable all privileges@linkhere{}, then the @req{sync-kom} call is used to save the database. The server responds with two asynchronous messages signaling that the database is being saved. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item permission-denied Administrator bit not set or privileges not enabled. @end table @node shutdown-kom @section shutdown-kom [44] (1) Recommended @findex shutdown-kom @example shutdown-kom [44] ( exit-val : @lt{INT8} ) -> ( ); @end example This call instructs the server to save all data and shut down. @rarg{exit-val} is currently not used. This call is privileged. @reqexample @example 1 42 255 @t{=1} 1 44 0 @t{=1} @t{:2 13 5 3} @end example This example shows the shutdown of a server. The asynchronous message sent after the call returns is the result of a session being forced to log out. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item permission-denied Administrator bit not set or privileges not enabled. @end table @node broadcast @section broadcast [45] (1) Obsolete (1) @findex broadcast @example broadcast [45] ( message : @lt{HOLLERITH} ) -> ( ); @end example This call can been replaced by @reqlink{send-message}. It is a privileged call. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item string-too-long The string @rarg{message} is too long. @item feature-disabled Messages have been disabled. @end table @node get-membership-old @section get-membership-old [46] (1) Obsolete (10) @findex get-membership-old @example get-membership-old [46] (( person : @lt{Pers-No}; first : @lt{INT16}; no-of-confs : @lt{INT16}; want-read-texts : @lt{BOOL} )) -> ( @lt{ARRAY} @lt{Membership-Old} ); @end example This call retrieves the membership record for a list of conferences for a single person. @rarg{person} is the person whose memberships are to be retrieved. @rarg{first} is the first position in the membership list to retrieve, numbered from 0 and up. @rarg{no-of-confs} is the number of membership records to retrieve. If @rarg{want-read-texts} is @samp{0} the server will not send the contents of the @field{read-texts} array of the memberships. (The size will be transmitted, but a single asterisk (@samp{*}) will be sent instead of the array itself.) The server will return a membership list that is shorter than @rarg{no-of-confs} if @rarg{no-of-confs} + @rarg{first} is larger than the number of conferences the person is a member of. Servers that support protocol version 10 will return a priority of zero if the passive bit in the membership record has been set (either by a set-membership-type or by setting the priority of the conference to zero.) @reqexample @example 1 46 5 0 3 1 @t{=1 2 @{ 49 14 17 13 8 91 5 255 1 5 255 0 0 * } @t{ 20 14 22 17 6 97 4 197 1 6 100 2 0 * @}} 1 46 5 0 1 1 @t{=1 1 @{ 49 14 17 13 8 91 5 255 1 5 255 0 0 * @}} 1 46 5 1 4 1 @t{=1 1 @{ 20 14 22 17 6 97 4 197 1 6 100 2 0 * @}} @end example In this example we retrieve the memberships of person 5. The first call asks for three memberships, starting with number 0. Since this person is only a member of two conferences, the list returned only contains two memberships. (An extra newline has been inserted in the result of the first call to make the result more readable.) The next two calls retrieve a single membership each, the first by asking for only one, and the second by asking for four memberships, starting with number 1. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-person The person @rarg{person} does not exist. @item undefined-conference The conference @rarg{person} does not exist or is secret. @item index-out-of-range @rarg{first} is higher than the index of the last conference in the person's membership list. @item bad-bool @rarg{want-read-texts} must be either @samp{0} or @samp{1}. @end table @node get-created-texts @section get-created-texts [47] (1) Obsolete (10) @findex get-created-texts @example get-created-texts [47] (( person : @lt{Pers-No}; first : @lt{Local-Text-No}; no-of-texts : @lt{INT32} )) -> ( @lt{Text-List} ); @end example This call is obsolete; instead you should use @reqlink{map-created-texts}. This call returns a list of the texts written by a person. @rarg{person} is the person whose created texts are to be retrieved. @rarg{first} is the first text to retrieve. @rarg{no-of-texts} is the number of texts to retrieve. This call is essentially the same as @reqlink{get-map}, but instead of returning the texts sent to a single conference, it returns the texts written by a single person to any conference. The number of texts written by any one person is contained in the Person record for that person. If @rarg{first} is lower than the first text written by @rarg{person} that still exists, it will be automatically increased to the first still existing text written by @rarg{person}. The @req{get-created-texts} will still attempt to return information about @rarg{no-of-texts} texts. (In this regard @req{get-map} and @req{get-created-texts} differ, since @req{get-map} will never ever return information about a later text than specified in the arguments to the call.@footnote{This difference was not intentional, but it is now too late to change the semantics of either @req{get-map} or @req{get-created-texts}. Besides, they are both obsolete calls.}) @reqexample @example 1 47 5 0 100 @t{=1 1 8 @{ 1 2 3 4 5 6 7 8 @}} 2 47 5 4 2 @t{=2 4 2 @{ 4 5 @}} 3 47 10 8 8 @t{=3 12 8 @{ 309 312 324 327 329 339 0 387 @}} @end example In this example we have retrieved all texts written by person five. The first call asked for 100 texts, but only 8 were returned, which implies that person number 5 only created a total of 8 texts. We can also see that person 5 wrote all the first 8 texts in the conference system. The second call shows how a part of the map can be retrieved. The third call asks for eight texts written by person 10, starting with the eighth number. Since the first eleven texts written by that person no longer exists the server instead returns information about eight texts staring from the twelfth text person 10 created. One of the eight texts has been deleted. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-person The person @rarg{person} does not exist or is secret. @item undefined-conference The conference @rarg{person} does not exist or is secret. @item no-such-local-text @rarg{first} is higher than the local text number of the last created text. @end table @node get-members-old @section get-members-old [48] (1) Obsolete (10) @findex get-members-old @example get-members-old [48] (( conf : @lt{Conf-No}; first : @lt{INT16}; no-of-members : @lt{INT16} )) -> ( @lt{ARRAY} @lt{Pers-No} ); @end example This call returns a list of members of the conference @rarg{conf}. @rarg{first} is the first index in the membership to return, numbered from zero and up. @rarg{no-of-members} is the maximum number of members to return. @reqexample @example 1 48 1 0 100 @t{=1 4 @{ 7 8 9 10 @}} 1 48 6 0 100 @t{=1 4 @{ 5 7 9 10 @}} 1 48 6 2 2 @t{=1 2 @{ 9 10 @}} @end example In this example the client first requests the first 100 members in conference 1. The second request is for the first 100 members of conference 6. The last request is for members 2 and 3 in conference 6. As can be seen from the examples, the returned list is truncated if there are fewer members than requested. @subheading Error codes @table @errorcode @item undefined-conference The conference @rarg{conf} does not exist or is secret. @item index-out-of-range @rarg{first} is higher than the number of members in @rarg{conf}. @end table @node get-person-stat @section get-person-stat [49] (1) Recommended @findex get-person-stat @example get-person-stat [49] ( pers-no : @lt{Pers-No} ) -> ( @lt{Person} ); @end example This call returns the person @rarg{pers-no}. This call does not return all the information a client usually needs since the name is not included in the Person data structure. Use @reqlink{get-conf-stat} on the same number to get additional information about the person. @reqexample @example 1 49 8 @t{=1 @holl{44,byers@@lage.lysator.liu.se} 0000010000000000 00000000} @t{ 44 21 19 18 6 97 5 198 1 0 2 3 0 0 0 0 0 0 1 0 0 2} 1 50 8 @t{=1 @holl{11,Paul Dekker} 1001 8 6 19 18 6 97 5 198 1} @t{ 8 6 19 18 6 97 5 198 1 8 0 8 0 0 0 77 1 1 0} @end example This simple example shows how person number 8 is retrieved from the server. The second call shows the @req{get-conf-stat-old} call on the same ID number. @subheading Error codes @table @errorcode @item undefined-person The person @rarg{pers-no} does not exist. @item undefined-conference The conference @rarg{pers-no} does not exist or is secret. @end table @node get-conf-stat-old @section get-conf-stat-old [50] (1) Obsolete (10) @findex get-conf-stat-old @example get-conf-stat-old [50] ( conf-no : @lt{Conf-No} ) -> ( @lt{Conference-Old} ); @end example This call retrieves the conference data structure for conference number @rarg{conf-no}. Important note: This call does not return the extra flag bits that were introduced in protocol version 8. To get this information, use the @req{get-uconf-stat} call instead. However, clients should be able to handle @type{Conference-Old} structures with an arbitrary number of flag bits since we may decide to change the behavior of this call in the future. @reqexample @example 1 50 1 @t{=1 @value{presconf} 0000 48 11 17 13 8 91 5 255} @t{ 1 18 34 21 17 6 97 4 197 1 0 0 0 0 0 0 77 0 1 1} 1 50 8 @t{=1 @holl{11,Paul Dekker} 1001 8 6 19 18 6 97 5 198 1} @t{ 8 6 19 18 6 97 5 198 1 8 0 8 0 0 0 77 1 1 0} @end example This simple example retrieves conferences 1 and 8 from the server. Conference 1 is a regular conference, and conference 8 is a mailbox. @subheading Error codes @table @errorcode @item undefined-conference The conference @rarg{conf-no} does not exist or is secret. @end table @node who-is-on @section who-is-on [51] (1) Obsolete (9) @findex who-is-on @example who-is-on [51] ( ) -> ( @lt{ARRAY} @lt{Who-Info} ); @end example This call is obsolete. Please use @reqlink{who-is-on-dynamic} and @reqdlink{get-static-session-info} calls instead@linkhere{}. Nonetheless, servers should support this call since many clients still use it. This call should simply return a list of visible sessions (sessions where a person is logged in and the invisible flag is unset). The data structure is described elsewhere (@pxref{Who-Info}). @subheading Error codes This call always succeeds. @node get-unread-confs @section get-unread-confs [52] (1) Recommended @findex get-unread-confs @example get-unread-confs [52] ( pers-no : @lt{Pers-No} ) -> ( @lt{ARRAY} @lt{Conf-No} ); @end example This call returns a list of conferences in which the person @rarg{pers-no} may have unread texts. This call will return a result for any valid @rarg{pers-no}. To retrieve information about secret persons, or to get information about unread texts in secret conference, the session must log on as a person with access to that information. The result is guaranteed to include all conferences where @rarg{pers-no} has unread texts. It may also return some extra conferences. Passive memberships are never returned. The returned conference numbers will be returned in the same order as they appear on the persons list of memberships. @reqexample @example 1 52 7 @t{=1 2 @{ 1 6 @}} 1 52 1 @t{%1 10 0} 1 52 1000 @t{%1 10 0} @end example This example shows how a session first retrieves the list of conferences in which person 7 has unread texts. The next request is for the unread conferences of person 1, but that happens to be a conference. The last request is for the unread conferences of person 1000, but that person didn't exist in the test database. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-person Person @rarg{pers-no} does not exist or is secret. @end table @node send-message @section send-message [53] (1) Recommended @findex send-message @example send-message [53] (( recipient : @lt{Conf-No}; message : @lt{HOLLERITH} )) -> ( ); @end example This call sends the message @rarg{message} to all members of @rarg{recipient} using @asynclink{async-send-message}. If @rarg{recipient} is 0, the message is sent to all sessions that are logged in. The message is sent to all members of @rarg{recipient} that are currently logged in, and where the @field{passive} and @field{passive-message-invert} bits of the @type{Membership-Type} (@pxref{Membership-Type}) don't prevent the message from being delivered. @reqexample @example 1 53 4 @holl{14,This is a test} @t{=1} 1 53 1 @holl{14,This is a test} @t{:3 12 1 8 @holl{14,This is a test}} @t{=1} 1 53 0 @holl{14,This is a test} @t{:3 12 0 8 @holl{14,This is a test}} @t{=1} 1 53 5 @holl{14,This is a test} @t{%1 16 0} 1 53 3 @holl{14,This is a test} @t{%1 42 0} @end example @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item string-too-long The string @rarg{message} is too long. @item undefined-conference Conference @rarg{recipient} does not exist or is secret. @item feature-disabled The message feature has been disabled in the server. @item message-not-sent The message was not sent for some other reason. Perhaps the recipient is not accepting messages or no member of the recipient was logged on. @end table @node get-session-info @section get-session-info [54] (1) Obsolete (4) @findex get-session-info @example get-session-info [54] ( session-no : @lt{Session-No} ) -> ( @lt{Session-Info} ); @end example This call is obsolete. It has been replaced by @reqlink{get-session-info-ident}, which in turn is also obsolete. See @req{get-session-info-ident} for more information. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-session The session @rarg{session-no} does not exist. @end table @node disconnect @section disconnect [55] (1) Recommended @findex disconnect @example disconnect [55] ( session-no : @lt{Session-No} ) -> ( ); @end example This call disconnects the session @rarg{session-no} from the LysKOM server. A session can always disconnect itself, even without logging in. If the session is logged in as user @i{foo} it can also disconnect any session logged in as a person for which @i{foo} is the supervisor. Session number zero is always interpreted as the session making the call, so the easiest way to disconnect the current session is to disconnect session zero. @reqexample @example 1 56 @t{=1 7} 1 55 7 @t{=1} @t{:2 13 8 7} @t{Connection closed by foreign host.} @end example In this example the client asks for its own session number, then disconnects itself (disconnection session 0 would have had the same effect.) The asynchronous message sent just before the session is disconnected is the logout message for the user that was logged on in the session. The ``Connection closed by foreign host.'' is not part of the server output. This message was generated by telnet. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call if @rarg{session-no} is not the session issuing the call. @item permission-denied Attempt to disconnect another session and not supervisor of person logged in and not enough privileges set and enabled to complete the call anyway. @item undefined-session The session @rarg{session-no} does not exist. @end table @node who-am-i @section who-am-i [56] (1) Recommended @findex who-am-i @example who-am-i [56] ( ) -> ( @lt{Session-No} ); @end example This call simply returns the session number of the session issuing the call. @reqexample @example 1 56 @t{=1 7} @end example In this example the session number of the session issuing the call is seven. @subheading Error codes This call always succeeds. @node set-user-area @section set-user-area [57] (2) Recommended @findex set-user-area @example set-user-area [57] (( pers-no : @lt{Pers-No}; user-area : @lt{Text-No} )) -> ( ); @end example This call sets the user-area field for the person @rarg{pers-no} in the database to the text @rarg{user-area}. The user area is used to store client data for a particular person. @xref{The User Area}, for more details. @reqexample @example 1 49 7 @t{=1 @holl{25,davby@@lage.lysator.liu.se} 0000010000000000 00000000} @t{ 6 58 21 19 6 97 6 199 1 0 458 7 3 12 7 12 0 0 3 0 0 4} 1 57 7 11 @t{=1} 1 49 7 @t{=1 @holl{25,davby@@lage.lysator.liu.se} 0000010000000000 00000000} @t{ 6 58 21 19 6 97 6 199 1 11 458 7 71 2592 7 13 0 0 3 1 0 4} @end example In this example the user area of person 7 is set to text number 11. The original user area was text numbers zero, which means that the person had no user area. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-person The person @rarg{pers-no} does not exist or is secret. @item permission-denied Not enough access to person @rarg{pers-no} to complete the call. @end table @node get-last-text @section get-last-text [58] (3) Recommended @findex get-last-text @example get-last-text [58] ( before : @lt{Time} ) -> ( @lt{Text-No} ); @end example This call returns the number of the last text created before @rarg{before}. There is no guarantee that the text is readable by the person making the request, or that the text even exists. This call assumes that all texts are written in chronological order, when the time is expressed in the local time zone of the server. That may not always be the case in real life. When daylight savings time reverts to standard time the same time span will occur twice. The clock of the server may also have been adjusted manually from time to time. This protocol specification does not mandate what the server should do in such cases. If @reqlink{set-connection-time-format} has been used with @code{use-utc} set to 1, the @rarg{before} time should be expressed in UTC. Daylight savings time will not be an issue in that case. @reqexample @example 1 58 49 6 22 19 6 97 6 199 1 @t{=1 11} 1 58 49 6 22 18 6 97 6 199 1 @t{=1 8} 1 58 49 6 22 1 6 97 6 199 1 @t{=1 0} @end example In this example the text created most recently before 22:06 on July 19, 1997 was text number 11; the text created most recently before 22:06 on July 18 was text number 8; and the text created most recently before 22:06 on July 1st was text number 0, which means that there is no text that old in the database. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @end table @node create-anonymous-text-old @section create-anonymous-text-old [59] (3) Obsolete (10) @findex create-anonymous-text-old @example create-anonymous-text-old [59] (( text : @lt{HOLLERITH}; misc-info : @lt{ARRAY} @lt{Misc-Info} )) -> ( @lt{Text-No} ); @end example Similar to @reqlink{create-text-old}, but the text is created with the @field{author} field set to zero. Not even the server has a record of who created the text. The original intended use for this call was for importing texts from other sources, such as WWW, FTP or Gopher, but some clients include explicit support for sending anonymous texts to a server. It is only possible to send anonymous texts to a conference with the right flag bit set. The only Misc-Info items valid for this call in the @rarg{misc-info} array are @misc{recpt}, @misc{cc-recpt}, @misc{bcc-recpt} (introduced in protocol version 10), @misc{comm-to} and @misc{footn-to}. @reqexample @example 1 28 @holl{20,Example@bullet{}Message body} 3 @{ 0 5 1 112 2 33467 @} @t{:16 0 33502 13 16 15 16 6 97 3 196 1 0 1 20 0} @t{ 5 @{ 0 5 6 148 1 112 6 3438 2 33467 @} } @t{=1 33502} @end example In the example, @code{@bullet{}} represents a linefeed. In this example, person 119 creates a text containing a subject and a one-line body. The recipient of the text is conference five, conference 112 is a CC recipient and the text is a comment to text 33467. The server reply indicates that the new text has been given number 33502. Finally there is an asynchronous message sent to all members of recipient conferences. Note how the message was sent before the reply to the client. The misc-info list in this message has two additional fields, the local numbers of the text in each of its recipient conferences. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item string-too-long The string @rarg{text} is longer than the maximum length of a message. @item temporary-failure The text could not be created at the moment. @item no-such-text Attempt to comment or footnote a non-existent or secret text. @item not-author Attempt to footnote a text authored by someone else. @item footnote-limit Attempt to footnote a text with the maximum number of footnotes already set. @item comment-limit Attempt to comment a text with the maximum number of comments already set. @item access-denied Attempt to send a text to a conference failed because no access to the conference or any super conference that will accept a text. @item anonymous-rejected Attempt to send an anonymous text to a conference that does not accept anonymous texts. @item illegal-misc Invalid misc-info list. A recipient is listed more than once or there is an unknown misc item in the misc-info list. @end table @node find-next-text-no @section find-next-text-no [60] (3) Recommended @findex find-next-text-no @example find-next-text-no [60] ( start : @lt{Text-No} ) -> ( @lt{Text-No} ); @end example This call returns the next readable text in the database created after text @rarg{start}. @rarg{start} does not have to be a valid or readable text number, as shown in the examples. @reqexample @example 1 60 0 @t{=1 2} 1 60 2 @t{=1 4} @end example This example shows how to retrieve the first readable text in the LysKOM database by calling @req{find-next-text-no} with @rarg{start} set to zero. In the example, the first text is number 2. The second example gets the text following number 2, which happens to be text number 4. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item no-such-text There is no text following text @rarg{start}. @end table @node find-previous-text-no @section find-previous-text-no [61] (3) Recommended @findex find-previous-text-no @example find-previous-text-no [61] ( start : @lt{Text-No} ) -> ( @lt{Text-No} ); @end example This call returns the first readable text in the database created most recently before @rarg{start}. @rarg{start} does not have to be a valid or readable text number, as shown in the examples. @reqexample @example 1 61 134217727 @t{=1 11} 1 61 4 @t{=1 2} @end example This example shows that the last readable text in the database is number 11 (unless by some odd coincidence all text from 11 to text number 134217727 have been deleted.) It also shows that the most recent text before number 4 is text number 2. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item no-such-text There is no text preceding text @rarg{start}. @end table @node login @section login [62] (4) Recommended @findex login @example login [62] (( person : @lt{Pers-No}; passwd : @lt{HOLLERITH}; invisible : @lt{BOOL} )) -> ( ); @end example This call is used to log in. The session is logged in as person number @rarg{person} if @rarg{passwd} is the correct password for that person. If @rarg{invisible} is true, the session is invisible: it will not be returned by @reqlink{who-is-on} and @reqlink{who-is-on-ident}, and the dynamic session info (@pxref{Dynamic-Session-Info}) will have the invisible flag set. Invisible sessions are primarily used by software agents that do not act on the behalf of real users. @reqexample @example 1 62 7 @holl{6,gazonk} 1 @t{=1} 1 62 7 @holl{6,gazonk} 0 @t{:2 9 7 1} 1 62 7 @holl{6,gazonk} 0 @t{:2 13 7 1} @t{:2 9 7 1} @t{=1} @end example This example first shows a session log in as person seven with the invisible flag set. Because of this the asynchronous login message is not sent. The second call logs in as person seven again. This time a login message is sent, but not a logout message since the login was invisible. The third example shows a third login as person 7, but this time both the logout and login messages are sent. @subheading Error codes @table @errorcode @item undefined-person The person @rarg{person} does not exist. @item login-disallowed Logins have been disabled and person @rarg{person} does not have enough privileges to override. @item invalid-password The password @rarg{passwd} is not the password of @rarg{person} and the currently logged in person is not the supervisor of @rarg{person} and does not have enough privileges set and enabled to log in anyway. @item conference-zero Attempt to log in as person number 0. @item bad-bool @rarg{invisible} must be either @samp{0} or @samp{1}. @end table @node who-is-on-ident @section who-is-on-ident [63] (4) Obsolete (9) @findex who-is-on-ident @example who-is-on-ident [63] ( ) -> ( @lt{ARRAY} @lt{Who-Info-Ident} ); @end example This call is obsolete. It has been replaced by @reqlink{who-is-on-dynamic} and @reqlink{get-static-session-info}. It returns a list of all visible sessions. @subheading Error codes This call always succeeds. @node get-session-info-ident @section get-session-info-ident [64] (4) Obsolete (9) @findex get-session-info-ident @example get-session-info-ident [64] ( session-no : @lt{Session-No} ) -> ( @lt{Session-Info-Ident} ); @end example This call is obsolete. Use @reqlink{who-is-on-dynamic} combined with @reqlink{get-static-session-info} instead. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-session The session @rarg{session-no} does not exist. @end table @node re-lookup-person @section re-lookup-person [65] (5) Obsolete (7) @findex re-lookup-person @example re-lookup-person [65] ( regexp : @lt{HOLLERITH} ) -> ( @lt{ARRAY} @lt{Pers-No} ); @end example This call is obsolete. It has been replaced by @reqlink{re-z-lookup}. It returns a list of persons matching the regular expression @rarg{regexp}. The regexp syntax used is that of the @command{ed}(1) Unix utility. @subheading Error codes @table @errorcode @item regexp-error Error compiling the regexp @rarg{regexp}. Perhaps the pattern is not a correct regexp. @end table @node re-lookup-conf @section re-lookup-conf [66] (5) Obsolete (7) @findex re-lookup-conf @example re-lookup-conf [66] ( regexp : @lt{HOLLERITH} ) -> ( @lt{ARRAY} @lt{Conf-No} ); @end example This call is obsolete. It has been replaced by @reqlink{re-z-lookup}. It returns a list of conferences matching the regular expression @rarg{regexp}. The regexp syntax used is that of the @command{ed}(1) Unix utility. @subheading Error codes @table @errorcode @item regexp-error Error compiling the regexp @rarg{regexp}. Perhaps the pattern is not a correct regexp. @end table @node lookup-person @section lookup-person [67] (6) Obsolete (7) @findex lookup-person @example lookup-person [67] ( name : @lt{HOLLERITH} ) -> ( @lt{ARRAY} @lt{Pers-No} ); @end example This call is obsolete. It has been replaced by @reqlink{lookup-z-name}. This call returns a list of persons with names matching the contracted name in @rarg{name}. @xref{Name Expansion}, for a description of the matching process. @subheading Error codes This call always succeeds. @node lookup-conf @section lookup-conf [68] (6) Obsolete (7) @findex lookup-conf @example lookup-conf [68] ( name : @lt{HOLLERITH} ) -> ( @lt{ARRAY} @lt{Conf-No} ); @end example This call is obsolete. It has been replaced by @reqlink{lookup-z-name}. This call returns a list of conferences with names matching the contracted name in @rarg{name}. @xref{Name Expansion}, for a description of the matching process. @subheading Error codes This call always succeeds. @node set-client-version @section set-client-version [69] (6) Recommended @findex set-client-version @example set-client-version [69] (( client-name : @lt{HOLLERITH}; client-version : @lt{HOLLERITH} )) -> ( ); @end example This call is used to tell the server which client and which version of that client is being used. The name of the client is passed in @rarg{client-name} and the version in @rarg{client-version}. The information sent in this call is made available to other sessions through the @reqlink{get-client-name} and @reqdlink{get-client-version} calls@linkhere{}. This call should be used exactly once per session. The following names are currently registered: @multitable @columnfractions .3 .7 @item elisp-client @tab The famous CPU hog. @item nilkom @tab C++ experiment @item tkom @tab C++ experiment @item getmail @tab Postmaster @item ttykom @tab The one and second tty client by Linus @item WinKOM @tab Windows client @item JySKom @tab JSK Web Client @end multitable @reqexample @example 1 56 @t{=1 7} 2 69 @holl{11,elisp-client} @holl{4,0.45} @t{=2} 3 70 7 @t{=3 @holl{11,elisp-client}} 4 71 7 @t{=4 @holl{4,0.45}} @end example In this example the @reqdlink{who-am-i} call is used to find the ID of the current session@linkhere{}. Next, @req{set-client-version} is used to set the name of the client to ``elisp-client'' and the version to ``0.45''. The third call is to @reqdlink{get-client-name}, which returns the string just sent to the server@linkhere{}. Finally @reqlink{get-client-version} is used to retrieve the client version of session number 7, which is, as expected, the string ``0.45''. @subheading Error codes @table @errorcode @item string-too-long The string @rarg{client-name} or @rarg{client-version} is too long. @item client-is-crazy The client attempted to use this call more than once. The @field{error-status} is undefined. @end table @node get-client-name @section get-client-name [70] (6) Recommended @findex get-client-name @example get-client-name [70] ( session : @lt{Session-No} ) -> ( @lt{HOLLERITH} ); @end example This call returns the name of the client that owns session number @rarg{session}. This client name string returned is the one set by the client using @reqlink{set-client-version}. If @req{set-client-version} has not been issued in session number @rarg{session}, the empty string is returned. @xref{set-client-version}, for an example of this call. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-session The session @rarg{session} does not exist. @end table @node get-client-version @section get-client-version [71] (6) Recommended @findex get-client-version @example get-client-version [71] ( session : @lt{Session-No} ) -> ( @lt{HOLLERITH} ); @end example This call returns the version of the client that owns session number @rarg{session}. This client version string returned is the one set by the client using @reqlink{set-client-version}. If @req{set-client-version} has not been issued in session number @rarg{session}, the empty string is returned. @xref{set-client-version}, for an example of this call. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-session The session @rarg{session} does not exist. @end table @node mark-text @section mark-text [72] (4) Recommended @findex mark-text @example mark-text [72] (( text : @lt{Text-No}; mark-type : @lt{INT8} )) -> ( ); @end example This call associates the mark @rarg{mark-type} with the text @rarg{text}. The list of marks set by a person can be retrieved using the @reqdlink{get-marks} call@linkhere{}. Currently, servers do not associate any particular meaning to the different types of marks, but that may change in the future. Currently, servers should not delete texts that have marks, except by user request. @reqexample @example 1 23 @t{=1 0 *} 2 72 110 230 @t{=2} 3 23 @t{=3 1 @{ 110 230 @}} @end example This example shows how a person with no marks set sets mark 230 on text number 110. The calls to @reqlink{get-marks} show the effect of the call. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item no-such-text The text @rarg{text} does not exists or is secret. @item permission-denied No read access to text @rarg{text}. @item undefined-person The person currently logged in does not exist (can't happen error.) @item mark-limit Already the maximum number of marks on text @rarg{text}. @end table @node unmark-text @section unmark-text [73] (6) Recommended @findex unmark-text @example unmark-text [73] ( text-no : @lt{Text-No} ) -> ( ); @end example This call removes any marks the logged-in person has set on the text @rarg{text-no}. @reqexample @example 1 23 @t{=1 1 @{ 110 230 @}} 2 73 110 @t{=2} 3 23 @t{=3 0 *} @end example This example shows how a user with a mark set on text number 110 removes it using the @req{unmark-text} call. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-person The person currently logged in does not exist (can't happen error.) @item not-marked The text @rarg{text-no} was not marked. @end table @node re-z-lookup @section re-z-lookup [74] (7) Recommended @findex re-z-lookup @example re-z-lookup [74] (( regexp : @lt{HOLLERITH}; want-persons : @lt{BOOL}; want-confs : @lt{BOOL} )) -> ( @lt{ARRAY} @lt{Conf-Z-Info} ); @end example This call returns a list of those conferences and/or persons matching the regular expression @rarg{regexp}. If @rarg{want-confs} is true, then the result will include non-mailbox conferences. If @rarg{want-persons} is true, then the result will include mailbox conferences. See also @ref{lookup-z-name}, for an alternative way to look up names. Refer to @ref{Name Expansion}, for more details on how name lookup works. @reqexample @example 1 74 @holl{2,.*} 1 1 @t{=1 4 @{ @holl{15,Test Conference} 0000 10 @holl{11,David Byers} 1001 6} @t{ @holl{21,Trains (-) Discussion} 0000 11 @holl{4,John} 1001 9 @}} 2 74 @holl{2,.*} 0 1 @t{=2 2 @{ @holl{15,Test Conference} 0000 10} @t{ @holl{21,Trains (-) Discussion} 0000 11 @}} 3 74 @holl{7,@badspell{T.*[cC]}} 1 1 @t{=3 2 @{ @holl{15,Test Conference} 0000 10} @t{ @holl{21,Trains (-) Discussion} 0000 11 @}} @end example This example shows three calls to @req{re-z-lookup}. The first call returns all conferences and persons in the entire database, in this case two conferences and two persons. The second example uses the same regular expression, but in this case, the call specifies that the result is only to contain conferences, so the two persons are not returned. The third example simply returns all names matching the pattern ``@badspell{T.*[cC]}''. @subheading Error codes @table @errorcode @item regexp-error Error compiling the regexp @rarg{regexp}. Perhaps the pattern is not a correct regexp. @item bad-bool @rarg{want-persons} and @rarg{want-confs} must be either @samp{0} or @samp{1}. @end table @node get-version-info @section get-version-info [75] (7) Recommended @findex get-version-info @example get-version-info [75] ( ) -> ( @lt{Version-Info} ); @end example This call returns information about the server version. The data returned by this call are primarily useful for presenting to the user. A client should not use this call to determine what the server's capabilities are. @reqexample @example 1 75 @t{=1 9 @holl{7,lyskomd} @holl{5,1.9.0}} @end example This example lets us know that the server is lyskomd, version 1.9.0, which at the time of writing this is the only really usable server. @subheading Error codes This call always succeeds. @node lookup-z-name @section lookup-z-name [76] (7) Recommended @findex lookup-z-name @example lookup-z-name [76] (( name : @lt{HOLLERITH}; want-pers : @lt{BOOL}; want-confs : @lt{BOOL} )) -> ( @lt{ARRAY} @lt{Conf-Z-Info} ); @end example This call looks up the name @rarg{name} in the server, and returns a list of all matching conferences and/or persons. If @rarg{want-confs} is true, then the result will include conferences that are not mailboxes. If @rarg{want-pers} is true, then the result will include conferences that are mailboxes. See also @ref{re-z-lookup}, for an alternative way to look up names. Refer to @ref{Name Expansion}, for details on the matching process. @reqexample @example 1 76 @holl{0,} 1 1 @t{=1 4 @{ @holl{15,Test Conference} 0000 10 @holl{11,David Byers} 1001 6} @t{ @holl{21,Trains (-) Discussion} 0000 11 @holl{4,John} 1001 9 @}} 2 76 @holl{0,} 0 1 @t{=1 2 @{ @holl{15,Test Conference} 0000 10} @t{ @holl{21,Trains (-) Discussion} 0000 11 @}} 3 76 @holl{3,T C} 1 1 @t{=3 1 @{ @holl{15,Test Conference} 0000 10 @}} @end example This example shows three calls to @req{lookup-z-name}. The first call retrieves all conferences and persons in the server. The second request looks up the same name as the first, but this time the result is restricted to conferences. The final request requests all conferences and persons matching the pattern ``T C''. @subheading Error codes @table @errorcode @item bad-bool @rarg{want-pers} and @rarg{want-confs} must be either @samp{0} or @samp{1}. @end table @node set-last-read @section set-last-read [77] (8) Recommended @findex set-last-read @example set-last-read [77] (( conference : @lt{Conf-No}; last-read : @lt{Local-Text-No} )) -> ( ); @end example This call tells the server that the last local text number the person issuing the call has read in conference @rarg{conference} is @rarg{last-read}. This call is typically used when a user wants to have a specific number of unread texts in a particular conference. @reqexample @example 1 9 7 6 @t{=1 2 4 22 18 6 97 5 198 1 6 100 6 0 *} 2 77 6 3 @t{=2} 3 9 7 6 @t{=3 2 4 22 18 6 97 5 198 1 6 100 3 0 *} @end example This example shows how person 7 originally had read everything up to and including local text number 6 in conference 6. After the call to @req{set-last-read}, the @reqlink{query-read-texts-old} call reports that person 7 has read everything up to and including local text number 3. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference The conference @rarg{conference} does not exist or is secret. @item not-member Not a member of conference @rarg{conference}. @end table @node get-uconf-stat @section get-uconf-stat [78] (8) Recommended @findex get-uconf-stat @example get-uconf-stat [78] ( conference : @lt{Conf-No} ) -> ( @lt{UConference} ); @end example This call returns some information about conference @rarg{conference}. The information it returns is sufficient for most uses of conference information, and this call should be used instead of @reqdlink{get-conf-stat} wherever possible@linkhere{}. It uses less bandwidth and the lyskomd server always keeps all @type{UConference} objects in memory, so this call is significantly faster than @req{get-conf-stat}. This is also currently the only way to get all the flag bits of the conference. @reqexample @example 1 50 6 @t{=1 @holl{8,Testconf} 0000 1 34 21 17 6 97 4 197 1} @t{ 37 3 22 18 6 97 5 198 1 5 4 5 0 5 0 77 4 1 6} 2 78 6 @t{=2 @holl{8,Testconf} 00001000 6 77} 3 50 7 @t{=3 @holl{11,David Byers} 1111 13 4 19 18 6 97 5 198 1} @t{ 13 4 19 18 6 97 5 198 1 7 0 7 0 0 0 77 1 1 0} 4 78 7 @t{=4 @holl{11,David Byers} 11111000 0 77} @end example This example shows the difference between @reqlink{get-conf-stat-old} and @req{get-uconf-stat}. In the first two examples conference 6 is retrieved, and in the second two, conference 7, which happens to be a person, is retrieved. Note the difference in length of the flag field. @subheading Error codes @table @errorcode @item undefined-conference The conference @rarg{conference} does not exist or is secret. @item conference-zero @rarg{conference} is zero. @end table @node set-info @section set-info [79] (9) Recommended @findex set-info @example set-info [79] ( info : @lt{Info-Old} ) -> ( ); @end example This call sets the server information retrieved by @reqlink{get-info-old}. The version number in the info structure is ignored (but must be present); all other fields are stored permanently in the LysKOM database. This is a privileged call. @reqexample @example 1 79 10901 1 2 3 4 1080 @t{=1} @end example This example sets the conference presentation conference to one, the user presentation conference to two, the motd conference to three and the news conference to four. It also sets the login message to text 1080. It also attempts to set the version number to 1.9.1, but that number is silently ignored by the server. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item permission-denied Administrator bit not set or privileges not enabled. @item undefined-conference One of the conferences in @rarg{info} does not exist. @item no-such-text The MOTD text in @rarg{info} does not exist. @item mark-limit The MOTD text in @rarg{info} already has the maximum number of marks. @item text-zero This error message should never be returned, but lyskomd 1.9.0 erroneously returned this error message if the MOTD text in @rarg{info} was set to 0. That should mean that there should be no message of the day, and the current implementation of the server does accept MOTD to be 0. @end table @node accept-async @section accept-async [80] (9) Recommended @findex accept-async @example accept-async [80] ( request-list : @lt{ARRAY} @lt{INT32} ) -> ( ); @end example This call advises the server that the client wants to receive the asynchronous messages listed in @rarg{request-list}. The server must send these messages to the client when applicable, but may also send other types of messages if it so desires. The list of currently requested asynchronous messages may be retrieved using the @reqdlink{query-async} call@linkhere{}. Don't forget that message type 12 is personal, group and global text messages. Most users will not want these turned off. @reqexample @example 1 80 2 @{ 7 9 @} @t{=1} @end example This example tells the server that the client wants to receive asynchronous messages when the database is being synched (message 7) and when someone logs in (message 9). @subheading Error codes If the client requests a message that the server does not send, the server will reply with an error message saying which message number it does not support. The call will succeed anyway. This mechanism is useful for clients that want new versions of some messages, but need to be compatible with older servers. @table @errorcode @item unknown-async At least one of the numbers in @rarg{request-list} is not the number of an async message the server knows about. The @field{error-status} indicates the first offending number. Please note that a bug in lyskomd 1.9.0 prevented the server from sending this error message (frankly, we simply forgot about it.) @item long-array The @rarg{request-list} was too long. Servers should always accept a @rarg{request-list} that contains a lot more asynchronous messages than the server sends, so that it can deal with newer clients. This error message should only be returned if the client tries to trigger a buffer overrun. @end table @node query-async @section query-async [81] (9) Recommended @findex query-async @example query-async [81] ( ) -> ( @lt{ARRAY} @lt{INT32} ); @end example This call queries the server for which asynchronous messages the client is receiving. Note that the client may not be able to turn off all messages returned in this list since the server may consider some messages to be mandatory. Also note that the client may still receive messages that are not listed in the result of this call. Even though those messages are turned off, the server may decide to send them under certain circumstances. @reqexample @example 1 81 @t{=1 7 @{ 0 5 7 9 11 12 13 @}} @end example In this example the client is receiving seven types of asynchronous messages: messages about new articles, changed names, database synching, new logins, rejected connections, personal messages and logouts. This particular set was the default for new connections to lyskomd 1.9 servers. @xref{Asynchronous Messages}, for the currently recommended list of asynchronous messages that servers should preselect. @subheading Error codes This call always succeeds. @node user-active @section user-active [82] (9) Recommended @findex user-active @example user-active [82] ( ) -> ( ); @end example This call simply notifies the server that the user is active. The server uses the time of the last user-active call to calculate how long a user has been idle. The client should send this to the server every time the user actively does something LysKOM-related, such as reads a texts, writes on a comment, gives a command, de-iconifies the LysKOM window, et c. However, the call should not be issued more than twice per minute, to avoid excessive network and server load. @subheading Error codes This call always succeeds. @node who-is-on-dynamic @section who-is-on-dynamic [83] (9) Recommended @findex who-is-on-dynamic @example who-is-on-dynamic [83] (( want-visible : @lt{BOOL}; want-invisible : @lt{BOOL}; active-last : @lt{INT32} )) -> ( @lt{ARRAY} @lt{Dynamic-Session-Info} ); @end example This call returns a list of information about sessions. Only sessions with the desired visibility and activeness are returned. If @rarg{want-visible} is true then information about visible sessions is returned. If @rarg{want-invisible} is true then information about invisible sessions is returned. If they are both true sessions will be included in the answer regardless of their visibility status. Sessions where no-one is logged in are considered invisible, and the @field{invisible} flag is set in the corresponding @type{Dynamic-Session-Info} that is returned. If @rarg{active-last} is zero then the result is a list of all sessions with the proper visibility. If @rarg{active-last} is nonzero then only sessions that have issued an @req{user-active} call within the last @rarg{active-last} seconds are included in the list. Sessions that have never issued an @req{user-active} call are always included (if they have the proper visibility). @subheading Error codes @table @errorcode @item bad-bool @rarg{want-visible} and @rarg{want-invisible} must be either @samp{0} or @samp{1}. @end table @node get-static-session-info @section get-static-session-info [84] (9) Recommended @findex get-static-session-info @example get-static-session-info [84] ( session-no : @lt{Session-No} ) -> ( @lt{Static-Session-Info} ); @end example This call returns information about session number @rarg{session-no}. The returned information cannot change until the session number is reused (and that cannot happen until the server is shut down), so clients are encouraged to cache the information. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-session The session @rarg{session-no} does not exist. @end table @node get-collate-table @section get-collate-table [85] (10) Recommended @findex get-collate-table @example get-collate-table [85] ( ) -> ( @lt{HOLLERITH} ); @end example This call returns the collate table being used by the server to match names. If index A and index B in the string are the same character, characters A and B are considered equivalent. An empty collate table indicates that the server considers all characters different. Currently, the lyskomd server only deals with 8-bit characters. Clients should be prepared for collate tables of any length. Characters whose code are greater than the length of the collate table should be considered to be unique. @subheading Error codes This call always succeeds. @node create-text @section create-text [86] (10) Recommended @findex create-text @example create-text [86] (( text : @lt{HOLLERITH}; misc-info : @lt{ARRAY} @lt{Misc-Info}; aux-items : @lt{ARRAY} @lt{Aux-Item-Input} )) -> ( @lt{Text-No} ); @end example Creates a new text with contents from @rarg{text} and recipients etc. defined by @rarg{misc-info} (@pxref{The Misc-Info List}). In addition to the result, the server will send an asynchronous message to all members of any of the recipients of the new text. It is not defined whether this messages comes before or after the reply to the create-text message. Clients should be prepared for either situation. The text up to the first linefeed is considered to be the subject line. The remaining text is the message body. Although messages with only a subject are valid, clients should avoid letting users create such messages. The items in @rarg{aux-items} are attached to the new text. The only Misc-Info items valid for this call are @misc{recpt}, @misc{cc-recpt}, @misc{bcc-recpt} (introduced in protocol version 10), @misc{comm-to} and @misc{footn-to}. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item string-too-long The string @rarg{text} is longer than the maximum length of a message. @item temporary-failure The text could not be created at the moment. @item no-such-text Attempt to comment or footnote a non-existent or secret text. @item not-author Attempt to footnote a text authored by someone else. @item footnote-limit Attempt to footnote a text with the maximum number of footnotes already set. @item comment-limit Attempt to comment a text with the maximum number of comments already set. @item index-out-of-range Attempt to create a text failed because we reached the maximum number of texts permitted. The @field{error-status} indicates the text number that should have been created if the limit hadn't been reached. @item access-denied Attempt to send a text to a conference failed because no access to the conference or any super conference that will accept a text. @item anonymous-rejected Attempt to send an anonymous text to a conference that does not accept anonymous texts. @item illegal-misc Invalid misc-info list. A recipient is listed more than once or there is an unknown misc item in the misc-info list. @item illegal-aux-item One of the aux-items in @rarg{aux-items} is illegal. The tag might be out of range, the item not applicable to texts or whatever @item aux-item-permission One of the items looks valid but could not be created anyway. @item long-array Too many Misc-Info items or aux-items were specified. @end table @node create-anonymous-text @section create-anonymous-text [87] (10) Recommended @findex create-anonymous-text @example create-anonymous-text [87] (( text : @lt{HOLLERITH}; misc-info : @lt{ARRAY} @lt{Misc-Info}; aux-items : @lt{ARRAY} @lt{Aux-Item-Input} )) -> ( @lt{Text-No} ); @end example Similar to @reqlink{create-text}, but the text is created the author field set to zero. Not even the server has a record of who created the text. The original intended use for this call was for importing texts from other sources, such as WWW, FTP or Gopher, but some clients include explicit support for sending anonymous texts to a server. It is only possible to send anonymous texts to a conference with the right flag bit set. The only Misc-Info items valid for this call in the @rarg{misc-info} array are @misc{recpt}, @misc{cc-recpt}, @misc{bcc-recpt} (introduced in protocol version 10), @misc{comm-to} and @misc{footn-to}. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item string-too-long The string @rarg{text} is longer than the maximum length of a message. @item temporary-failure The text could not be created at the moment. @item no-such-text Attempt to comment or footnote a non-existent or secret text. @item not-author Attempt to footnote a text authored by someone else. @item footnote-limit Attempt to footnote a text with the maximum number of footnotes already set. @item comment-limit Attempt to comment a text with the maximum number of comments already set. @item access-denied Attempt to send a text to a conference failed because no access to the conference or any super conference that will accept a text. @item anonymous-rejected Attempt to send an anonymous text to a conference that does not accept anonymous texts. @item illegal-misc Invalid misc-info list. A recipient is listed more than once or there is an unknown misc item in the misc-info list. @item illegal-aux-item One of the aux-items in @rarg{aux-items} is illegal. The tag might be out of range, the item not applicable to texts or whatever @item aux-item-permission One of the items looks valid but could not be created anyway. @end table @node create-conf @section create-conf [88] (10) Recommended @findex create-conf @example create-conf [88] (( name : @lt{HOLLERITH}; type : @lt{Any-Conf-Type}; aux-items : @lt{ARRAY} @lt{Aux-Item-Input} )) -> ( @lt{Conf-No} ); @end example This call is used to create new conferences. @rarg{name} is the name of the new conference and @rarg{type} is its type. If successful, the call returns the conference number of the newly created conference. The list @rarg{aux-items} contains the aux items to attach to the conference. To use this call the session must have logged in as a user with privileges to create conferences (@pxref{Security}). @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item permission-denied The server does not allow everyone to create a conference and user does not have the @req{create-conf} bit set. May also be an attempt to create a conference with the @conftype{letterbox} bit set. @item conference-exists A conference named @rarg{name} already exists. @item bad-name @rarg{name} contains invalid characters. @item string-to-long @rarg{name} is too long to be used as a conference name. @item secret-public The conference type has the @conftype{secret} bit set, but the @conftype{rd-prot} bit is cleared. @item illegal-aux-item One of the aux-items in @rarg{aux-items} is illegal. The tag might be out of range, the item not applicable to conferences or whatever @item aux-item-permission One of the items looks valid but could not be created anyway. @item index-out-of-range Attempt to create a conference failed because we reached the maximum number of conferences permitted. The @field{error-status} indicates the conference number that should have been created if the limit hadn't been reached. @end table @node create-person @section create-person [89] (10) Recommended @findex create-person @example create-person [89] (( name : @lt{HOLLERITH}; passwd : @lt{HOLLERITH}; flags : @lt{Personal-Flags}; aux-items : @lt{ARRAY} @lt{Aux-Item-Input} )) -> ( @lt{Pers-No} ); @end example This call requests that the server create a new person with the name and password given as arguments. To create a person the session must be logged in as a person with sufficient privileges. The list @rarg{aux-items} contains the aux items that are to be attached to the new person's mailbox conference. The person flags are set to @rarg{flags}. The new person will be a member of exactly one conference: the associated mailbox. That membership will have priority 255 and (of course) position 0. All flags of the membership will be 0. Unlike call number 5, this call does not do an automatic login. @subheading Error codes @table @errorcode @item login-first The session is not logged in and the server does not allow person creation before logging in. @item permission-denied The server does not allow everyone to create person and the person currently logged on does not have the @priv{create-pers} bit set. @item person-exists There is already a person named @rarg{name}. @item invalid-password The string @rarg{passwd} is not a valid password. @item illegal-aux-item One of the aux-items in @rarg{aux-items} is illegal. The tag might be out of range, the item not applicable to conferences or mailboxes or whatever. @item aux-item-permission One of the items looks valid but could not be created anyway. @item index-out-of-range Attempt to create a person failed because we reached the maximum number of conferences permitted. The @field{error-status} indicates the person number that should have been created if the limit hadn't been reached. @end table @node get-text-stat @section get-text-stat [90] (10) Recommended @findex get-text-stat @example get-text-stat [90] ( text-no : @lt{Text-No} ) -> ( @lt{Text-Stat} ); @end example Get information about text number @rarg{text-no}. The text-stat contains information about the size of the text, its recipients, comments, author and more. @subheading Error codes @table @errorcode @item no-such-text The text @rarg{text-no} does not exist, or no read access. This error code will also be used when attempting to fetch texts without logging in first. (There are some texts that are readable without logging in: the motd-of-lyskom (@pxref{set-motd-of-lyskom}), and texts with the @aux{world-readable} aux item set on them.) @item text-zero Attempt to retrieve text number 0. @end table @node get-conf-stat @section get-conf-stat [91] (10) Recommended @findex get-conf-stat @example get-conf-stat [91] ( conf-no : @lt{Conf-No} ) -> ( @lt{Conference} ); @end example This call retrieves the conference data structure for conference number @rarg{conf-no}. @subheading Error codes @table @errorcode @item undefined-conference The conference @rarg{conf-no} does not exist or is secret. @end table @node modify-text-info @section modify-text-info [92] (10) Recommended @findex modify-text-info @example modify-text-info [92] (( text : @lt{Text-No}; delete : @lt{ARRAY} @lt{Aux-No}; add : @lt{ARRAY} @lt{Aux-Item-Input} )) -> ( ); @end example This call deletes the aux-items listed in @rarg{delete} from the text @rarg{text} and then adds the ones listed in @rarg{add} to the text. Either list may be empty, and the call is guaranteed to either completely fail or completely succeed. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item no-such-text The text @rarg{text} does not exist or is secret. @item aux-item-permission No permission to delete one or more of the items in @rarg{delete}, or not enough permissions to add one or more of the items in @rarg{add}. @item illegal-aux-item One of the items in @rarg{add} is illegal for some reason. @end table @node modify-conf-info @section modify-conf-info [93] (10) Recommended @findex modify-conf-info @example modify-conf-info [93] (( conf : @lt{Conf-No}; delete : @lt{ARRAY} @lt{Aux-No}; add : @lt{ARRAY} @lt{Aux-Item-Input} )) -> ( ); @end example This call deleted the aux-items listed in @rarg{delete} from the conference @rarg{conf} and then adds the ones listed in @rarg{add} to the conference. Either list may be empty, and the call is guaranteed to either completely fail or completely succeed. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference The conference @rarg{conf} does not exist or is secret. @item aux-item-permission No permission to delete one or more of the items in @rarg{delete}, or not enough permissions to add one or more of the items in @rarg{add}. @item illegal-aux-item One of the items in @rarg{add} is illegal for some reason. @end table @node get-info @section get-info [94] (10) Recommended @findex get-info @example get-info [94] ( ) -> ( @lt{Info} ); @end example This call returns the @type{Info} structure for the server (@pxref{Info}). Clients should call this in order to find out which conferences are used for presentations and such. It can be issued without logging in. @subheading Error codes This call always succeeds. @node modify-system-info @section modify-system-info [95] (10) Recommended @findex modify-system-info @example modify-system-info [95] (( items-to-delete : @lt{ARRAY} @lt{Aux-No}; items-to-add : @lt{ARRAY} @lt{Aux-Item-Input} )) -> ( ); @end example This call modifies the aux-item list of the server information (which can be retrieved using @reqlink{get-info}.) It only succeeds when issued by a person with the admin bit set and privileges enabled. The items in @rarg{items-to-delete} are removed, and the items in @rarg{items-to-add} are added. This call is atomic; either all deletions or additions succeeded, or none of them is made. @subheading Error codes @table @errorcode @item login-first Login requires before issuing this call. @item permission-denied Admin bit not set or privileges not enabled. @item illegal-aux-item Attempt to create an invalid aux item. @item aux-item-permission Attempt to delete an undeletable item or create an uncreateable item. @end table @node query-predefined-aux-items @section query-predefined-aux-items [96] (10) Recommended @findex query-predefined-aux-items @example query-predefined-aux-items [96] ( ) -> ( @lt{ARRAY} @lt{INT32} ); @end example Returns the list of aux-items that have specific definitions in the server. These items are the only items within the restricted tag ranges that can be created. The meanings of the various item types are defined in this document; see @ref{Aux-Item Types}. @subheading Error codes This call always succeeds. @node set-expire @section set-expire [97] (10) Experimental @findex set-expire @example set-expire [97] (( conf-no : @lt{Conf-No}; expire : @lt{Garb-Nice} )) -> ( ); @end example This call sets the @rarg{expire} field of the conference @rarg{conf-no} to @rarg{expire}. This call can only be issued by the conference's supervisor or a privileged user. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference The conference @rarg{conf-no} does not exist or is secret. @item permission-denied Not supervisor of conference @rarg{conf-no} and not privileged enough to complete the call anyway. @end table @node query-read-texts-10 @section query-read-texts-10 [98] (10) Obsolete (11) @findex query-read-texts-10 @example query-read-texts-10 [98] (( person : @lt{Pers-No}; conference : @lt{Conf-No} )) -> ( @lt{Membership-10} ); @end example This call is obsolete. Use @reqlink{query-read-texts}. This call is used to find the number of unread texts in a conference. The data it returns is actually a membership structure which specifies which texts have been read. It is up to the client to transform the data to a more usable form. @rarg{person} is the person being queried and @rarg{conference} is the conference in question. Calling @req{query-read-texts-10} does not require the session to be logged in. @reqexample @example 1 98 6 1 @t{=1 4 32 5 11 12 7 93 1 193 1 1 20 133} @t{ 3 @{ 135 136 137 @} 5 43 8 3 12 7 93 1 193 1 01000000} @end example This example finds the read texts for user 6 in conference 1. The returned data indicates that conference 1 is the fifth conference on the users' membership list (@samp{4}; remember that the @field{position} starts its count at 0), user last read the conference on Monday July 12th, 1993 at 11:05:32 (@samp{32 5 11 12 7 93 1 193 1}), that it is the membership in conference number 1 (@samp{1}), that the person has assigned priority 20 to the conference (@samp{20}) and that all articles up to and including local number 133 (@samp{133}) plus articles 135, 136 and 137 (@samp{3 @{ 135 136 137 @}}) have been read. The membership was added by person 5 (@samp{5}) at Monday July 12th, 1993 at 03:08:43 (@samp{43 8 3 12 7 93 1 193 1}) and it is passive (@samp{01000000}). @subheading Error codes @table @errorcode @item undefined-person @rarg{person} does not exist, or no access to person. @item undefined-conference Conference @rarg{conference} does not exist, or is secret. @item conference-zero @rarg{conference} is zero. @item not-member @rarg{person} is not a member of @rarg{conference} or insufficient privileges to find out if @rarg{person} is a member. @end table @node get-membership-10 @section get-membership-10 [99] (10) Obsolete (11) @findex get-membership-10 @example get-membership-10 [99] (( person : @lt{Pers-No}; first : @lt{INT16}; no-of-confs : @lt{INT16}; want-read-texts : @lt{BOOL} )) -> ( @lt{ARRAY} @lt{Membership-10} ); @end example This call is obsolete. Use @reqlink{get-membership}. This call retrieves the membership record for a list of conferences for a single person. @rarg{person} is the person whose memberships are to be retrieved. @rarg{first} is the first position in the membership list to retrieve, numbered from 0 and up. @rarg{no-of-confs} is the number of membership records to retrieve. If @rarg{want-read-texts} is @samp{0}, the server will not send the contents of the @field{read-texts} array of the memberships. (The size will be transmitted, but a single asterisk (@samp{*}) will be sent instead of the array itself.) The server will return a membership list that is shorter than @rarg{no-of-confs} if @rarg{no-of-confs} + @rarg{first} is larger than the number of conferences the person is a member of. Elements of the member list that the person requesting the list does not have sufficient privileges to see may be cleared. Cleared elements simply have all fields set to zero. @reqexample @example 1 99 5 0 3 1 @t{=1 2 @{ 0 49 14 17 13 8 91 5 255 1 5 255 0 0 * 5 } @t{ 49 14 17 13 8 91 5 255 1 00000000 } @t{ 1 20 14 22 17 6 97 4 197 1 6 100 2 0 * 5 } @t{ 49 14 17 13 8 91 5 255 1 00000000 @}} 2 99 5 0 1 1 @t{=2 1 @{ 0 49 14 17 13 8 91 5 255 1 5 255 0 0 * 5 } @t{ 49 14 17 13 8 91 5 255 1 00000000 @}} 3 99 5 1 4 1 @t{=3 1 @{ 1 20 14 22 17 6 97 4 197 1 6 100 2 0 * 5 } @t{ 49 14 17 13 8 91 5 255 1 00000000 @}} @end example In this example we retrieve the memberships of person 5. The first call asks for three memberships, starting with number 0. Since this person is only a member of two conferences, the list returned only contains two memberships. The next two calls retrieve a single membership each. The first by asking for only one, and the second by asking for four memberships, starting with number 1. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-person The person @rarg{person} does not exist. @item undefined-conference The conference @rarg{person} does not exist or is secret. @item index-out-of-range @rarg{first} is higher than the index of the last conference in the person's membership list. @item bad-bool @rarg{want-read-texts} must be either @samp{0} or @samp{1}. @end table @node add-member @section add-member [100] (10) Recommended @findex add-member @example add-member [100] (( conf-no : @lt{Conf-No}; pers-no : @lt{Pers-No}; priority : @lt{INT8}; where : @lt{INT16}; type : @lt{Membership-Type} )) -> ( ); @end example Make the person @rarg{pers-no} a member of conference @rarg{conf-no}. The membership priority is set to @rarg{priority} and its position in the membership list is set to @rarg{where}. The membership flags are set to @rarg{type}. If the current user is adding a user he isn't supervisor of, the @field{invitation} bit of @rarg{type} is automatically set by the server. This call can be used to change the priority, position and flags of a conference in the person's membership list if the person is already a member of the conference. The person doing this must either be a supervisor of the affected person, or have sufficient privileges enabled. @reqexample @example 1 99 119 0 10 0 @t{=1 1 @{ 49 14 17 13 8 91 5 255 1 119 255 0 0 * 119 00001111 @}} 1 100 1 119 250 0 10000000 @t{=1} 1 100 119 119 251 1 00000000 @t{=1} 1 99 119 0 10 0 @t{=1 2 @{ 52 30 14 11 5 96 2 162 1 1 250 0 0 * 119 00000000 49 14 17 13 8 91 5 251 1 119 255 0 0 * 10000000 @}} @end example This example makes person 119 (me) a member of conference number 1 and changes the priority and some flags of the preexisting membership in conference 119. The priority is set to 250 and the conference is placed first in the membership list. The first and last calls of the example show the membership list for person 119 before and after the calls. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference Conference @rarg{conf-no} does not exist or is secret. @item conference-zero @rarg{conf-no} is zero. @item undefined-person Person @rarg{pers-no} does not exist @item access-denied @c FIXME (bug 199): the "or to change" part is bogus, right? Aren't those @c circumstances covered by permission-denied? Not enough permissions or privileges to add members to @rarg{conf-no} or to change privileges, position or type of a preexisting membership. @item permission-denied Person @rarg{pers-no} is already a member of conference @rarg{conf-no}, but the person logged on is not a supervisor and does not have enough privileges to change the priorities of person @rarg{pers-no}. @end table @node get-members @section get-members [101] (10) Recommended @findex get-members @example get-members [101] (( conf : @lt{Conf-No}; first : @lt{INT16}; no-of-members : @lt{INT16} )) -> ( @lt{ARRAY} @lt{Member} ); @end example This call returns a list of members of the conference @rarg{conf}. @rarg{first} is the first index in the membership to return, numbered from zero and up. @rarg{no-of-members} is the maximum number of members to return. Some of the elements of the result may be cleared if the person requesting the information does not have sufficient privileges to see the contents. Cleared elements simply have all fields set to zero. @reqexample @example 1 101 1 0 100 @t{=1 4 @{ 7 7 00000000 8 8 00000000 9 8 00000000 } @t{ 10 10 00000000 @}} 1 101 6 0 100 @t{=1 4 @{ 5 5 01000000 7 7 01000000 9 8 10000000 } @t{ 10 10 00000000 @}} 1 101 6 2 2 @t{=1 2 @{ 9 8 10000000 10 10 00000000 @}} @end example In this example the client first requests the first 100 members in conference 1. The second request is for the first 100 members of conference 6. The last request is for members 2 and 3 in conference 6. @subheading Error codes @table @errorcode @item undefined-conference The conference @rarg{conf} does not exist or is secret. @item index-out-of-range @rarg{first} is higher than the number of members in @rarg{conf}. @end table @node set-membership-type @section set-membership-type [102] (10) Recommended @findex set-membership-type @example set-membership-type [102] (( pers : @lt{Pers-No}; conf : @lt{Conf-No}; type : @lt{Membership-Type} )) -> ( ); @end example This call modifies the type of a membership. The person @rarg{pers} membership in conference @rarg{conf} is affected. The server may impose arbitrary restrictions on how the membership type may be changed. Typically it will only be possible to clear the @field{invitation} bit. It is possible that the server will not permit the @field{secret} bit to be set. Attempting to set a membership type that does not agree with the server's restrictions will result in an error. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item conference-zero @rarg{conf} is zero. @item undefined-conference The conference @rarg{conf} does not exist or is secret or the person @rarg{pers} does not exist or is secret. @item permission-denied Insufficient permissions to change the membership of @rarg{pers}. @item not-member Person @rarg{pers} is not a member of conference @rarg{conf}. @item invalid-membership-type The requested membership type @rarg{type} was not compatible with restrictions set on the server or on the conference @rarg{conf} @end table @node local-to-global @section local-to-global [103] (10) Recommended @findex local-to-global @example local-to-global [103] (( conf-no : @lt{Conf-No}; first-local-no : @lt{Local-Text-No}; no-of-existing-texts : @lt{INT32} )) -> ( @lt{Text-Mapping} ); @end example This call retrieves information that makes it possible to convert @rarg{no-of-existing-texts} existing local text numbers starting at @rarg{first-local-no} to global text numbers, provided that there are that many local texts. The @rarg{conf-no} parameter specifies which conference to look up local numbers in. @rarg{first-local-no} is the first number that the client is interested in. @rarg{no-of-existing-texts} is the maximum number of texts the client wants information about. Legal values for @rarg{no-of-existing-texts} are 1-255 (inclusive). The server will return a sparse or dense Text-Mapping depending on the how many deleted texts there are after @rarg{first-local-no}. The @reqlink{local-to-global-reverse} request can be useful if you want to traverse the mapping from higher to lower numbers. @reqexample @example 1 103 93 1 5 @t{=1 1 7 1 1 1 6 @{ 1003 1005 1009 1029 0 1034 @}} 2 103 93 1 6 @t{=2 1 63 1 0 6 @{ 1 1003 2 1005 3 1009 4 1029 6 1034 62 1302 @}} 3 103 93 50 10 @t{=3 50 70 0 0 2 @{ 62 1302 69 1006 @}} @end example The above example shows three calls to @req{local-to-global}. (Extra newlines have been inserted in the result of the two final calls to make the result more readable.) The first call requests information about the first five existing texts in conference 93. The result contains information about texts in the range 1-7 (including the lower limit, but not the upper), and there are more texts. The server uses the dense form of the @type{Text-Mapping}. As can be seen from the result, they have local text numbers 1, 2, 3, 4 and 6. The global text number corresponding to local text number 5 is sent as 0, indicating that it doesn't exist. In the second call, the client requests the same information, but one additional text. The result looks dramatically different, since the next existing text in this example has local text number 62. The result contains information about texts in the range 1-63 (including the lower limit, and excluding the upper), and there are more texts. The server of course uses the sparse form of the @type{Text-Mapping}. The final call shows what happens when @rarg{first-local-no} doesn't exist. The result contains information about texts in the range 50-70 (including the lower limit and excluding the upper); only local text number 62 and 69 actually exists in that range. 69 is the highest local text number. (Note that local text number 69 corresponds to global text number 1006, which is lower than 1302. Situations like this often occurs when @req{add-recipient} is used.) @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item long-array @rarg{no-of-existing-texts} was larger than 255. @item conf-zero @rarg{conf-no} was set to 0. @item local-text-zero @rarg{first-local-no} was set to 0. @item undef-conf The conference does not exist, or the client is not allowed to know that it exists. @item access-denied The conference exists, but the client is not allowed to retrieve information about the texts in the conference. @item no-such-local-text @rarg{first-local-no} is greater than the highest local text number that ever existed in the conference. @end table @node map-created-texts @section map-created-texts [104] (10) Recommended @findex map-created-texts @example map-created-texts [104] (( author : @lt{Pers-No}; first-local-no : @lt{Local-Text-No}; no-of-existing-texts : @lt{INT32} )) -> ( @lt{Text-Mapping} ); @end example Return text numbers for existing texts that @rarg{author} has written. Just as each conference has a mapping from local text numbers to global text numbers, each person has a mapping from the N:th text written by him to the global text number. This function can be used to retrieve part of that mapping. More information and examples may be found in @ref{local-to-global}. The @reqlink{map-created-texts-reverse} request can be useful if you want to traverse the mapping from higher to lower numbers. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item long-array @rarg{no-of-existing-texts} was larger than 255. @item conf-zero @rarg{author} was set to 0. @item local-text-zero @rarg{first-local-no} was set to 0. @item undef-pers The conference does not exist, or the client is not allowed to know that it exists. @item no-such-local-text @rarg{first-local-no} is greater than the highest local text number that ever existed in the conference. @item access-denied The conference exists, but the client is not allowed to retrieve information about the texts in the conference. @end table @node set-keep-commented @section set-keep-commented [105] (10) Recommended @findex set-keep-commented @example set-keep-commented [105] (( conf-no : @lt{Conf-No}; keep-commented : @lt{Garb-Nice} )) -> ( ); @end example Sets the @rarg{keep-commented} field of the conference @rarg{conf-no} to @rarg{keep-commented}. This call can only be issued by a conference's supervisor or a privileged user. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference The conference @rarg{conf-no} does not exist or is secret. @item permission-denied Not supervisor of conference @rarg{conf-no} and not privileged enough to complete the call anyway. @end table @node set-pers-flags @section set-pers-flags [106] (10) Recommended @findex set-pers-flags @example set-pers-flags [106] (( pers-no : @lt{Pers-No}; flags : @lt{Personal-Flags} )) -> ( ); @end example Set the flags field of person @rarg{pers-no} to @rarg{flags}. This call can only be issued by the person supervisor or a privileged user. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item conference-zero The @rarg{pers-no} parameter is zero. @item undefined-person The person does not exist, or the session does not have permission to know about the person. @item permission-denied Person exists, but the session does not have permission to change the flags. @end table @node query-read-texts @section query-read-texts [107] (11) Recommended @findex query-read-texts @example query-read-texts [107] (( person : @lt{Pers-No}; conference : @lt{Conf-No}; want-read-ranges : @lt{BOOL}; max-ranges : @lt{INT32} )) -> ( @lt{Membership} ); @end example This call is used to find the number of unread texts in a conference. The data it returns is actually a membership structure which specifies which texts have been read. It is up to the client to transform the data to a more usable form. @rarg{person} is the person being queried and @rarg{conference} is the conference in question. If @rarg{want-read-ranges} is @samp{0}, the server will not send the contents of the @field{read-ranges} array of the memberships. (The size will be transmitted, but a single asterisk (@samp{*}) will be sent instead of the array itself.) The @rarg{max-ranges} argument is ignored in this case. If @rarg{want-read-ranges} is @samp{1}, the @field{read-ranges} array will be returned. If @rarg{max-ranges} is non-zero, the array will be truncated to @rarg{max-ranges} ranges. (It isn't possible to determine if the array has been truncated, or if the array actually contained exactly that many ranges.) Setting @rarg{max-ranges} to @samp{1} gives you enough information to find out the first unread text. When you call this request with @rarg{want-read-ranges} set to @samp{1}, the ranges will expand to include any adjacent texts that are now deleted. This may not happen if @reqlink{get-membership} is used to retrieve the information. Calling @req{query-read-texts} does not require the session to be logged in. @reqexample @example 1 107 6 1 1 0 @t{=1 4 32 5 11 12 7 93 1 193 1 1 20} @t{ 2 @{ 1 133 135 137 @} 5 43 8 3 12 7 93 1 193 1 01000000} @end example This example finds the read texts for user 6 in conference 1. The returned data indicates that conference 1 is the fifth conference on the users' membership list (@samp{4}; remember that the @field{position} starts its count at 0), user last read the conference on Monday July 12th, 1993 at 11:05:32 (@samp{32 5 11 12 7 93 1 193 1}), that it is the membership in conference number 1 (@samp{1}), that the person has assigned priority 20 to the conference (@samp{20}) and that all texts 1-133 and 135-137 have been read (@samp{2 @{ 1 133 135 137 @}}). The membership was added by person 5 (@samp{5}) at Monday July 12th, 1993 at 03:08:43 (@samp{43 8 3 12 7 93 1 193 1}) and it is passive (@samp{01000000}). @subheading Error codes @table @errorcode @item undefined-person @rarg{person} does not exist, or no access to person. @item undefined-conference Conference @rarg{conference} does not exist, or is secret. @item conference-zero @rarg{conference} is zero. @item not-member @rarg{person} is not a member of @rarg{conference} or insufficient privileges to find out if @rarg{person} is a member. @item bad-bool @rarg{want-read-ranges} must be either @samp{0} or @samp{1}. @end table @node get-membership @section get-membership [108] (11) Recommended @findex get-membership @example get-membership [108] (( person : @lt{Pers-No}; first : @lt{INT16}; no-of-confs : @lt{INT16}; want-read-ranges : @lt{BOOL}; max-ranges : @lt{INT32} )) -> ( @lt{ARRAY} @lt{Membership} ); @end example This call retrieves the membership record for a list of conferences for a single person. @rarg{person} is the person whose memberships are to be retrieved. @rarg{first} is the first position in the membership list to retrieve, numbered from 0 and up. @rarg{no-of-confs} is the number of membership records to retrieve. If @rarg{want-read-ranges} is @samp{0}, the server will not send the contents of the @field{read-texts} array of the memberships. (The sizes will be transmitted, but a single asterisk (@samp{*}) will be sent instead of the array itself.) The @rarg{max-ranges} argument is ignored in this case. If @rarg{want-read-ranges} is @samp{1}, the @field{read-ranges} arrays of the memberships will be returned. If @rarg{max-ranges} is non-zero, each array will be truncated to @rarg{max-ranges} ranges. (It isn't possible to determine if an array has been truncated, or if that array actually contained exactly that many ranges.) Unlike @reqlink{query-read-texts}, the ranges may not expand to include deleted texts, so it isn't certain that you get enough information to find the first unread text if you specify a non-zero @rarg{max-ranges} argument. The server will return a membership list that is shorter than @rarg{no-of-confs} if @rarg{no-of-confs} + @rarg{first} is larger than the number of conferences the person is a member of. Elements of the member list that the person requesting the list does not have sufficient privileges to see may be cleared. Cleared elements simply have all fields set to zero. @reqexample @example 1 108 5 0 3 1 0 @t{=1 2 @{ 0 49 14 17 13 8 91 5 255 1 5 255 0 * 5 } @t{ 49 14 17 13 8 91 5 255 1 00000000 } @t{ 1 20 14 22 17 6 97 4 197 1 6 100 1 @{ 1 2 @} 5 } @t{ 49 14 17 13 8 91 5 255 1 00000000 @}} 2 108 5 0 1 1 0 @t{=2 1 @{ 0 49 14 17 13 8 91 5 255 1 5 255 0 * 5 } @t{ 49 14 17 13 8 91 5 255 1 00000000 @}} 3 108 5 1 4 1 0 @t{=3 1 @{ 1 20 14 22 17 6 97 4 197 1 6 100 1 @{ 1 2 @} 5 } @t{ 49 14 17 13 8 91 5 255 1 00000000 @}} @end example In this example we retrieve the memberships of person 5. The first call asks for three memberships, starting with number 0. Since this person is only a member of two conferences, the list returned only contains two memberships. The next two calls retrieve a single membership each. The first by asking for only one, and the second by asking for four memberships, starting with number 1. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-person The person @rarg{person} does not exist. @item undefined-conference The conference @rarg{person} does not exist or is secret. @item index-out-of-range @rarg{first} is higher than the index of the last conference in the person's membership list. @item bad-bool @rarg{want-read-ranges} must be either @samp{0} or @samp{1}. @end table @node mark-as-unread @section mark-as-unread [109] (11) Recommended @findex mark-as-unread @example mark-as-unread [109] (( conference : @lt{Conf-No}; text : @lt{Local-Text-No} )) -> ( ); @end example Marks text @rarg{text} in conference number @rarg{conference} as not read for the current user. This call updates the membership record for the user. It can be used to undo the effect of @reqlink{mark-as-read}. @reqexample @example 1 9 6 7 @t{=1 20 32 11 17 6 96 3 198 1 7 1 241 0 *} 1 78 7 @t{=1 @holl{13,@value{IAM}} 00001000 241 1} 1 27 7 241 @t{=1} 1 9 6 7 @t{=1 20 32 11 17 6 96 3 198 1 7 1 240 0 *} @end example This example shows person 6 marking local text number 241 in conference 7 as not read. In the first @req{query-read-texts-old} call the person has read local text 241, and nothing higher. The @req{mark-as-read} call is reflected in the second @req{query-read-texts-old} call, where the user is seen to have read text 240 in conference 7, but nothing higher. To mark a global text number as not read it is necessary to translate it into local text numbers by looking at the misc-info list in the @type{Text-Stat} and calling @req{mark-as-read} once for each recipient. Attempts to mark a deleted text as unread will appear to succeed, but might have no effect, since the server will automatically mark them as read, sooner or later. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference The conference @rarg{conference} does not exist or is secret. @item conference-zero @rarg{conference} is zero. @item not-member The person logged on is not a member of conference @rarg{conference}. @item no-such-local-text @rarg{text} is not, and has never been, a local text number in @rarg{conference}. The error argument contains the invalid number. @item local-text-zero @rarg{text} is zero. @end table @node set-read-ranges @section set-read-ranges [110] (11) Recommended @findex set-read-ranges @example set-read-ranges [110] (( conference : @lt{Conf-No}; read-ranges : @lt{ARRAY} @lt{Read-Range} )) -> ( ); @end example This call tells the server that the person issuing the call has read exactly those texts specified by @rarg{read-ranges} in conference @rarg{conference}. This call is typically used to migrate a membership from one person to another. It can also be used instead of @reqlink{set-unread} or @reqlink{set-last-read}. The server may automatically extend the ranges with adjacent local text numbers that are deleted. @reqexample @example 1 9 7 6 @t{=1 2 4 22 18 6 97 5 198 1 6 100 6 0 *} 2 110 6 3 @{ 1 20 23 23 25 28 @} @t{=2} 3 9 7 6 @t{=3 2 4 22 18 6 97 5 198 1 6 100 20 5 @{ 23 25 26 27 28 @}} @end example This example shows how person 7 originally had read everything up to and including local text number 6 in conference 6. After the call to @req{set-read-ranges}, the @reqlink{query-read-texts-old} call reports that person 7 has read the local text numbers 1-20, 23 and 25-28. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference The conference @rarg{conference} does not exist or is secret. @item conference-zero @rarg{conference} is zero. @item not-member Not a member of conference @rarg{conference}. @item local-text-zero @rarg{read-ranges} contains the number 0. @item no-such-local-text @rarg{read-ranges} contains a local text number that never has existed. @item long-array The @rarg{read-ranges} array is too long. @field{error-status} indicates the maximum range allowed. @item invalid-range The @field{first-read} field in one of the ranges in @rarg{read-ranges} is greater than @field{last-read}. The @field{error-status} indicates the interval (0 for the first interval, 1 for the second, and so on). @item invalid-range-list The @field{first-read} field in one of the ranges in @rarg{read-ranges} is not greater than the @field{last-read} field of the previous range. The @field{error-status} indicates the interval (0 for the first interval, 1 for the second, and so on). @end table @node get-stats-description @section get-stats-description [111] (11) Recommended @findex get-stats-description @example get-stats-description [111] ( ) -> ( @lt{Stats-Description} ); @end example Return a list of the supported statistical measurements. This request always succeeds, and always returns the same value for the duration of a session, so a client doesn't need to use it more than once per session. @xref{Stats-Description}, for more info about the data type. @xref{Measured Properties}, for more info on what the returned values means. @reqexample @example 1 111 @t{=1 2 @{ @holl{3,X-a} @holl{3,X-b} @} 4 @{ 0 60 300 900 @}} @end example @subheading Error codes This call always succeeds. @node get-stats @section get-stats [112] (11) Recommended @findex get-stats @example get-stats [112] ( what : @lt{HOLLERITH} ) -> ( @lt{ARRAY} @lt{Stats} ); @end example Return a list of the statistical measurements of @rarg{what}. The number of elements in the result corresponds to the @code{when} field of the @type{Stats-Description} returned by @reqlink{get-stats-description}. @xref{Measured Properties}, for more info on the @rarg{what} argument. See also @ref{Stats-Description}. @reqexample @example 1 112 @holl{7,clients} @t{=1 4 @{ 20 0 0 19.80 1.2 1.1 18.33 1.2 1.1 16.11 1.2 1.2e-02 @}} @end example Assuming that the @code{when} field of @req{get-stats-description} contains the time periods 0, 60, 300 and 900, the above result indicates that there is currently 20 connected clients. The past averages for 1, 5 and 15 minutes are 19.8, 18.33 and 16.11 connected clients. You can use this call even if you are not logged in. @subheading Error codes @table @errorcode @item feature-disabled The measurement that was requested has been disabled. @item undefined-measurement The server doesn't measure the value requested by @rarg{what}. @item access-denied The client isn't allowed to retrieve the requested value. The client might be granted the privilege by logging in as a privileged user, using the @reqlink{enable} request, by a receiving a privilege bit, or in an implementation-defined way. @end table @node get-boottime-info @section get-boottime-info [113] (11) Recommended @findex get-boottime-info @example get-boottime-info [113] ( ) -> ( @lt{Static-Server-Info} ); @end example Return status information that was current when the server started. This include the time of the last restart. Clients are encouraged to cache the return value of this request, as it will never change while a client is connected. @subheading Error codes This call always succeeds @node first-unused-conf-no @section first-unused-conf-no [114] (11) Recommended @findex first-unused-conf-no @example first-unused-conf-no [114] ( ) -> ( @lt{Conf-No} ); @end example Return first conference number that is not yet used. @subheading Error codes This call always succeeds @node first-unused-text-no @section first-unused-text-no [115] (11) Recommended @findex first-unused-text-no @example first-unused-text-no [115] ( ) -> ( @lt{Text-No} ); @end example Return first text number that is not yet used. @subheading Error codes This call always succeeds @node find-next-conf-no @section find-next-conf-no [116] (11) Recommended @findex find-next-conf-no @example find-next-conf-no [116] ( start : @lt{Conf-No} ) -> ( @lt{Conf-No} ); @end example This call returns the next conference that you are allowed to see in the database created after conference @rarg{start}. @rarg{start} does not have to be a valid or readable conference number, as shown in the examples. @reqexample @example 1 116 0 @t{=1 2} 1 116 2 @t{=1 4} @end example This example shows how to retrieve the first readable conference in the LysKOM database by calling @req{find-next-conf-no} with @rarg{start} set to zero. In the example, the first conference is number 2. The second example gets the conference following number 2, which happens to be conference number 4. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference There is no conference following conf @rarg{start}. @end table @node find-previous-conf-no @section find-previous-conf-no [117] (11) Recommended @findex find-previous-conf-no @example find-previous-conf-no [117] ( start : @lt{Conf-No} ) -> ( @lt{Conf-No} ); @end example This call returns the last accessible conference in the database created before @rarg{start}. @rarg{start} does not have to be a valid or readable conference number, as shown in the examples. @reqexample @example 1 114 @t{=1 12345} 2 117 12345 @t{=2 12330} 1 117 12330 @t{=1 12329} @end example This example uses @reqlink{first-unused-conf-no} to find the largest number that can meaningfully be sent to @req{find-previous-conf-no}. It then uses the request twice to find that the two conferences with highest conference numbers that are accessible to the user logged in is 12329 and 12330. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item undefined-conference There is no conf preceding conf @rarg{start}. @end table @node get-scheduling @section get-scheduling [118] (11) Experimental @findex get-scheduling @example get-scheduling [118] ( session-no : @lt{Session-No} ) -> ( @lt{Scheduling-Info} ); @end example Get the current scheduling information for a session. You can use 0 as @rarg{session-no} to get information about the current session. @reqlink{set-scheduling} contains an example. @subheading Error codes The first error code in the list below that is applicable will be returned. @table @errorcode @item login-first Login required before issuing this call, unless @rarg{session-no} is 0 or the number of the current session. @item undefined-session That session does not exist. @end table @node set-scheduling @section set-scheduling [119] (11) Experimental @findex set-scheduling @example set-scheduling [119] (( session-no : @lt{Session-No}; priority : @lt{INT16}; weight : @lt{INT16} )) -> ( ); @end example This call sets the scheduling priority and weight of the connection. @ref{Scheduling-Info}, for more information. You can use 0 as @rarg{session-no} to set the info for the current session. @reqexample @example 1 118 0 @t{=1 1 1000} 2 119 0 0 1000 @t{%2 58 1} 3 119 0 1 2500 @t{%2 59 1500} 3 119 0 1 1500 @t{=3} @end example This example uses @reqlink{get-scheduling} to find out the current scheduling setting (priority 1 and weight 1000). The client then attempts to get a better priority (0), but is informed that priority 1 is the best priority available to this user (or before logging in). At request 3 the client attempts to increase the weight to 2500, but is informed that 1500 is the best weight available. It finally sets the weight to 1500. This will result in a 50% speedup compared to the default setting. The @req{set-scheduling} request makes it possible to implement a quite complex scheduling machinery in the server. Please note, however, that a server that only implements priority 0 and weight 1 (and thus treats all sessions equally) is fully compliant with this specification. The number of priorities and weights that are available is implementation-defined. They can vary depending on the privileges of the user that is logged in, and may be affected by the @reqlink{enable} call. @subheading Error codes The first error code in the list below that is applicable will be returned. @table @errorcode @item weight-zero You must specify a non-zero @rarg{weight}. @item login-first Login required before issuing this call, unless @rarg{session-no} is 0 or the number of the current session. @item undefined-session That session does not exist. @item access-denied You don't have enough privileges to modify the priority of the specified session. You can only modify your own session and sessions logged in as a person you are supervisor of. @item index-out-of-range The @rarg{priority} argument is numerically too large. @field{error-status} indicates the numerically largest priority that the server supports. @item priority-denied You don't have enough privileges to lower your priority. @field{error-status} indicates the lowest priority that you have access to. @item weight-denied You don't have enough privileges to set the specified weight at the specified priority. @field{error-status} indicates the highest weight you have access to at the specified priority. The limit may differ at different priorities. @end table @node set-connection-time-format @section set-connection-time-format [120] (11) Recommended @findex set-connection-time-format @example set-connection-time-format [120] ( use-utc : @lt{BOOL} ) -> ( ); @end example This call specifies how @type{Time} values are sent over the protocol. By default, they are sent in the local time zone of the server. If @rarg{use-utc} is 1, they will instead be sent using UTC. This affects both times sent from the server to the client, and from the client to the server. Please note that there is a race condition. The time contained in any asynchronous message received after sending a @req{set-connection-time-format} request and before getting the reply may have been sent using either the old or the new setting. You should not trust them. @subheading Error codes @table @errorcode @item bad-bool @rarg{use-utc} must be either @samp{0} or @samp{1}. @end table @node local-to-global-reverse @section local-to-global-reverse [121] (11) Recommended @findex local-to-global-reverse @example local-to-global-reverse [121] (( conf-no : @lt{Conf-No}; local-no-ceiling : @lt{Local-Text-No}; no-of-existing-texts : @lt{INT32} )) -> ( @lt{Text-Mapping} ); @end example This call retrieves information that makes it possible to convert @rarg{no-of-existing-texts} existing local text numbers smaller than @rarg{local-no-ceiling} to global text numbers, provided that there are that many local texts smaller than @rarg{local-no-ceiling}. In other words, this request is just link @reqlink{local-to-global}, but it searches backwards in the mapping. The @rarg{conf-no} parameter specifies which conference to look up local numbers in. @rarg{local-no-ceiling} is the first number that the client is not interested in. @rarg{no-of-existing-texts} is the maximum number of texts the client wants information about. Legal values for @rarg{no-of-existing-texts} are 1-255 (inclusive). The server will return a sparse or dense Text-Mapping depending on the how many deleted texts there are before @rarg{local-no-ceiling}. As a special case, if @rarg{local-no-ceiling} is 0, information will be returned about the @rarg{no-of-existing-texts} highest-numbered texts. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item long-array @rarg{no-of-existing-texts} was larger than 255. @item conf-zero @rarg{conf-no} was set to 0. @item undef-conf The conference does not exist, or the client is not allowed to know that it exists. @item access-denied The conference exists, but the client is not allowed to retrieve information about the texts in the conference. @end table @node map-created-texts-reverse @section map-created-texts-reverse [122] (11) Recommended @findex map-created-texts-reverse @example map-created-texts-reverse [122] (( author : @lt{Pers-No}; local-no-ceiling : @lt{Local-Text-No}; no-of-existing-texts : @lt{INT32} )) -> ( @lt{Text-Mapping} ); @end example Return text numbers for existing texts that @rarg{author} has written. This is just like @reqlink{map-created-texts}, but searches in the other direction. (Compare with @reqlink{local-to-global-reverse}.) As a special case, if @rarg{local-no-ceiling} is 0, information will be returned about the last @rarg{no-of-existing-texts} texts. @subheading Error codes @table @errorcode @item login-first Login required before issuing this call. @item long-array @rarg{no-of-existing-texts} was larger than 255. @item conf-zero @rarg{author} was set to 0. @item undef-pers The conference does not exist, or the client is not allowed to know that it exists. @item access-denied The conference exists, but the client is not allowed to retrieve information about the texts in the conference. @end table @node Asynchronous Messages @chapter Asynchronous Messages Asynchronous messages are information messages sent from the server to the client. Most of them are used to inform the client about changes to the database (such as when a new text is created), so that the clients don't have to poll the server for new information. Some have other uses. The messages with status "O" are included here for historical purposes only. Servers are not required to handle them, and are encouraged to reject them if a client uses it as an argument to @reqlink{accept-async}. @menu * About Asynchronous Messages:: Introductory information about asynchronous messages. * async-new-text-old:: O A text has been created (0) * async-i-am-off:: O Logged off (obsolete) (1) * async-i-am-on-obsolete:: O Client changed i-am-on string (obsolete) (2) * async-new-name:: r Conference or person changed name (5) * async-i-am-on:: r Client changed i-am-doing string (6) * async-sync-db:: r Server is saving the database (7) * async-leave-conf:: r Person has been removed from a conference (8) * async-login:: r Someone has logged in (9) * async-broadcast:: O Broadcast message (obsolete) (10) * async-rejected-connection:: r LysKOM is full. Log out to make room. (11) * async-send-message:: r Text message to group or person (12) * async-logout:: r A person has logged out (13) * async-deleted-text:: r A text was deleted (14) * async-new-text:: r A text has been created (15) * async-new-recipient:: r A new recipient has been added to a text (16) * async-sub-recipient:: r A recipient has been removed from a text (17) * async-new-membership:: r A user has been added to a conference (18) * async-new-user-area:: r A user-area was changed (19) * async-new-presentation:: r A presentation was changed (20) * async-new-motd:: r A motd was changed (21) * async-text-aux-changed:: r The aux-item list of a text was changed (22) @end menu @ifnottex @node About Asynchronous Messages @section About Asynchronous Messages @end ifnottex Clients can select which messages to receive by issuing an @reqdlink{accept-async} call@linkhere{}. They can find out which messages are being sent by issuing the @reqdlink{query-async} call@linkhere{}. Note that the server can send other messages as well. For example, a broadcast message from a person with admin bits set may get through even if the client has not requested broadcast messages. When a connection is opened some messages are selected by default. Clients should use the @req{accept-async} call to select which messages they want. Servers are encouraged to preselect the @async{async-new-text-old}, @async{async-new-name}, @async{async-sync-db}, @async{async-leave-conf}, @async{async-login}, @async{async-rejected-connection}, @async{async-send-message} and @async{async-logout} messages. These correspond to the useful messages that were sent prior to the introduction of @reqlink{accept-async}. An asynchronous message is sent as a colon immediately followed by the number of message parameters, the message number and the message parameters. For example, message number 5 could be sent as @example :3 5 119 @holl{11,David Byers} @holl{13,David C Byers} @end example The parameters of each message are listed in the same format as server calls. @node async-new-text-old @section async-new-text-old [0] (1) Obsolete (10) @amindex async-new-text-old @example async-new-text-old [0] (( text-no : @lt{Text-No}; text-stat : @lt{Text-Stat-Old} )); @end example This message is sent when a text is created. The text number of the text is sent in @aarg{text-no} and the text stat in @aarg{text-stat}. This message is sent to all logged-in members of any recipient of the text, any text it is a comment of, and any text it is a footnote of. In protocol version 10 this call has been superseded by @ref{async-new-text}. @node async-i-am-off @section async-i-am-off [1] (1) Obsolete (1) @amindex async-i-am-off @c obsolete @example async-i-am-off [1] ( person : @lt{Pers-No} ); @end example This message was sent when @aarg{person} logged off. It has been replaced by @asynclink{async-logout}, since this asynchronous message could not differentiate between sessions if the same person was logged in more than once. @node async-i-am-on-obsolete @section async-i-am-on-obsolete [2] (1) Obsolete (1) @amindex async-i-am-on-obsolete @c obsolete @example async-i-am-on-obsolete [2] (( person : @lt{Pers-No}; conference : @lt{Conf-No}; what-am-i-doing : @lt{HOLLERITH} )); @end example This message was sent when @aarg{person} changed his @code{what-i-am-doing} string to @aarg{what-am-i-doing} or his working conference to @aarg{conference}. It has been replaced by call number 6, @asynclink{async-i-am-on}, since this asynchronous message could not differentiate between sessions if the same person was logged in more than once. @node async-new-name @section async-new-name [5] (1) Recommended @amindex async-new-name @example async-new-name [5] (( conf-no : @lt{Conf-No}; old-name : @lt{HOLLERITH}; new-name : @lt{HOLLERITH} )); @end example This message is sent when a person or conference changes names. The conference whose name is being changed is sent in @aarg{conf-no}, the old name in @aarg{old-name} and the new name in @aarg{new-name}. @node async-i-am-on @section async-i-am-on [6] (1) Recommended @amindex async-i-am-on @example async-i-am-on [6] ( info : @lt{Who-Info} ); @end example This message is sent when a session's working conference, @code{what-i-am-doing} string (@pxref{change-what-i-am-doing}) or username changes. The new information is sent in @aarg{info}. @c FIXME (bug 200): can the username change? @node async-sync-db @section async-sync-db [7] (1) Recommended @amindex async-sync-db @example async-sync-db [7] ( ); @end example This message is sent once just before the server blocks to save its database and once just after it blocks. There is no good way to tell the difference between the two cases. @node async-leave-conf @section async-leave-conf [8] (1) Recommended @amindex async-leave-conf @example async-leave-conf [8] ( conf-no : @lt{Conf-No} ); @end example This message is sent to a user when the user's membership in the working conference is removed for any reason. The conference the user is being removed from is sent in @aarg{conf-no}. Earlier versions of the LysKOM Protocol A specifications stated that this message was only sent if the membership was "revoked forcefully". The exact meaning of that phrasing was never specified. The lyskomd implementation has probably always followed the current version of the specification, which means that this message is sent whatever the reason for the removal is. Possible reasons include: @itemize @bullet @item The session issued a @reqdlink{sub-member} call@linkhere{}. @item Some other session issued a @reqdlink{sub-member} call@linkhere{}. @item The conference was deleted. @end itemize This message is not sent if a membership is transformed from an active to a passive membership. @node async-login @section async-login [9] (1) Recommended @amindex async-login @example async-login [9] (( pers-no : @lt{Pers-No}; session-no : @lt{Session-No} )); @end example This message is sent when someone logs in. The identity of the person logging in is sent in @aarg{pers-no}, and the session number in @aarg{session-no}. @node async-broadcast @section async-broadcast [10] (1) Obsolete (1) @amindex async-broadcast @c obsolete @example async-broadcast [10] (( sender : @lt{Pers-No}; message : @lt{HOLLERITH} )); @end example This message has been superseded by @asyncdlink{async-send-message} which is more flexible@linkhere{}. It used to be sent when the administrator (@aarg{sender}) broadcasted a string (@aarg{message}) to all LysKOM users, but is no longer used. @node async-rejected-connection @section async-rejected-connection [11] (1) Recommended @amindex async-rejected-connection @example async-rejected-connection [11] ( ); @end example This message is sent when someone fails to log in because the maximum number of allowed connections has been reached. Some clients may take this as a signal to log out. Administrators should take it as a signal to allow more connections. @node async-send-message @section async-send-message [12] (1) Recommended @amindex async-send-message @example async-send-message [12] (( recipient : @lt{Conf-No}; sender : @lt{Pers-No}; message : @lt{HOLLERITH} )); @end example This message is sent when someone (the @aarg{sender}) sends a message string (the @aarg{message}). The recipient of the message is sent in @aarg{recipient}. If it is zero, then the message was sent to all connections. If it is a conference, then the message is being sent to all logged-in members of that conference. If it is a mailbox then the message is personal and is only sent to members of the mailbox conference. The @field{passive} and @field{passive-message-invert} bits of the membership influence if this message is sent. @xref{Membership-Type}. @node async-logout @section async-logout [13] (1) Recommended @amindex async-logout @example async-logout [13] (( pers-no : @lt{Pers-No}; session-no : @lt{Session-No} )); @end example This message is sent when someone logs out. @aarg{pers-no} is the person logging out and @aarg{session-no} is the session in which the person is logging out. This message might also be sent when a session disconnects, even if there is nobody logged on in the session. @node async-deleted-text @section async-deleted-text [14] (10) Recommended @amindex async-deleted-text @example async-deleted-text [14] (( text-no : @lt{Text-No}; text-stat : @lt{Text-Stat} )); @end example This message is sent when a text is deleted and the currently logged-in person is a member of one of the recipients, or a recipient of any text that is linked to this text via a comment or footnote link. The text number being deleted is sent in @aarg{text-no} and the text stat in @aarg{text-stat}. @node async-new-text @section async-new-text [15] (10) Recommended @amindex async-new-text @example async-new-text [15] (( text-no : @lt{Text-No}; text-stat : @lt{Text-Stat} )); @end example This message indicates that a new text has been created. The text has number @aarg{text-no}, and the text stat is @aarg{text-stat}. The message is sent to all logged-in members of any recipient of the text, any text it is a comment of, and any text it is a footnote of. @node async-new-recipient @section async-new-recipient [16] (10) Recommended @amindex async-new-recipient @example async-new-recipient [16] (( text-no : @lt{Text-No}; conf-no : @lt{Conf-No}; type : @lt{Info-Type} )); @end example This message indicates that a new recipient has been added to text @aarg{text-no}. The recipient added is @aarg{conf-no} and the type of recipient is indicated by @aarg{type}. This message is sent to all recipients of the text (of any text that is linked to this text via a comment or footnote link) that are permitted to know about the new recipient. @node async-sub-recipient @section async-sub-recipient [17] (10) Recommended @amindex async-sub-recipient @example async-sub-recipient [17] (( text-no : @lt{Text-No}; conf-no : @lt{Conf-No}; type : @lt{Info-Type} )); @end example This message indicates that a recipient has been removed from text @aarg{text-no}. The recipient removed is @aarg{conf-no} and the type of recipient is indicated by @aarg{type}. This message is sent to everybody that were recipients of the text (or any text that is linked to this text via a comment or footnote link) and that were permitted to know about the recipient. @node async-new-membership @section async-new-membership [18] (10) Recommended @amindex async-new-membership @example async-new-membership [18] (( pers-no : @lt{Pers-No}; conf-no : @lt{Conf-No} )); @end example This message indicates that the membership for @aarg{pers-no} in conference @aarg{conf-no} has been added. This message is currently sent only to @aarg{pers-no}, but that may change in the future. See also @ref{async-leave-conf}. @node async-new-user-area @section async-new-user-area [19] (11) Recommended @amindex async-new-user-area @example async-new-user-area [19] (( pers-no : @lt{Pers-No}; old-user-area : @lt{Text-No}; new-user-area : @lt{Text-No} )); @end example This message indicates that the user-area of @aarg{pers-no} has changed from @aarg{old-user-area} to @aarg{new-user-area}. This message is sent to all supervisors of @aarg{pers-no} (which of course includes @aarg{pers-no} himself). @node async-new-presentation @section async-new-presentation [20] (11) Recommended @amindex async-new-presentation @example async-new-presentation [20] (( conf-no : @lt{Conf-No}; old-presentation : @lt{Text-No}; new-presentation : @lt{Text-No} )); @end example This message indicates that the presentation of @aarg{conf-no} has changed from @aarg{old-presentation} to @aarg{new-presentation}. This message is sent to everybody who is allowed to see @aarg{conf-no}. If the conference had no presentation, @aarg{old-presentation} will be 0. Likewise, if the presentation of the conference was removed, @aarg{new-presentation} will be 0. @node async-new-motd @section async-new-motd [21] (11) Recommended @amindex async-new-motd @example async-new-motd [21] (( conf-no : @lt{Conf-No}; old-motd : @lt{Text-No}; new-motd : @lt{Text-No} )); @end example This message indicates that the @field{msg-of-day} of @aarg{conf-no} has changed from @aarg{old-motd} to @aarg{new-motd}. This message is sent to everybody who is allowed to see @aarg{conf-no}. If the conference had no message-of-the-day, @aarg{old-motd} will be 0. Likewise, if the motd of the conference was removed, @aarg{new-motd} will be 0. @node async-text-aux-changed @section async-text-aux-changed [22] (11) Recommended @amindex async-text-aux-changed @example async-text-aux-changed [22] (( text-no : @lt{Text-No}; deleted : @lt{ARRAY} @lt{Aux-Item}; added : @lt{ARRAY} @lt{Aux-Item} )); @end example This message indicates that the aux-items of text @aarg{text-no} have been changed. (This message is not sent when the text is created or deleted.) @aarg{deleted} is a list of the deleted items, and @aarg{added} is a list of the added items. At least one of the arrays will be non-empty. Please note that all items in @aarg{deleted} will have the @field{deleted} bit of the @field{flags} field set. @node Error Codes @chapter Error Codes Normal errors are sent in reply to syntactically correct calls to the server. The client should accept any error code in response to any call, even if the error code in question is not listed in the description of the call, and even if the error code in question is not defined in the protocol specification yet. This table lists the currently defined error codes together with a short explanation. The explanation given below is the default semantics for the error code. It can be updated by the descriptions found for a specific call. @xref{Client-Server Dialog}, for more information about error responses, including the syntax of the error response. @table @code @item no-error (0) No error has occurred. @field{error-status} is undefined. This should never happen, but it might. @item not-implemented (2) The call has not been implemented yet. @field{error-status} is undefined. @item obsolete-call (3) The call is obsolete and no longer implemented. @field{error-status} is undefined. @item invalid-password (4) Attempt to set a password containing illegal characters, or to use an incorrect password. @item string-too-long (5) A string was too long (see descriptions of each call.) @field{error-status} indicates the maximum string length. @item login-first (6) Login is required before issuing the call. @field{error-status} is undefined. @item login-disallowed (7) The system is in single-user mode. You need to be privileged to log in despite this. @field{error-status} is undefined. @item conference-zero (8) Attempt to use conference number 0. @field{error-status} is undefined. @item undefined-conference (9) Attempt to access a non-existent or secret conference. @field{error-status} contains the conference number in question. @item undefined-person (10) Attempt to access a non-existent or secret person. @field{error-status} contains the person number in question. @item access-denied (11) No read/write access to something. This might be returned in response to an attempt to create a text, when the recipient conference and its super conferences are read-only, or when attempting to add a member to a conference without enough permission to do so. @field{error-status} indicates the object to which we didn't have enough permissions to. @item permission-denied (12) Not enough permissions to do something. The exact meaning of this response depends on the call. @field{error-status} indicated the object for which permission was lacking, or zero. @item not-member (13) The call requires the caller to be a member of some conference that the caller is not a member of. @field{error-status} indicates the conference in question. @item no-such-text (14) Attempt to access a text that either does not exist or is secret in some way. @field{error-status} indicates the text number in question. @item text-zero (15) Attempt to use text number 0. @field{error-status} is undefined. @item no-such-local-text (16) Attempt to access a text using a local text number that does not represent an existing text. @field{error-status} indicates the offending number. @item local-text-zero (17) Attempt to use local text number zero. @field{error-status} is undefined. @item bad-name (18) Attempt to use a name that's too long, too short or contains invalid characters. @field{error-status} is undefined. @item index-out-of-range (19) Attempt to use a number that's out of range. The range and meaning of the numbers depends on the call issued. @field{error-status} is undefined unless stated otherwise in the call documentation. @item conference-exists (20) Attempt to create a conference or person with a name that's already occupied. @field{error-status} is undefined. @item person-exists (21) Attempt to create a person with a name that's already occupied. @field{error-status} is undefined. This error code is probably not used, but you never know for sure. @item secret-public (22) Attempt to give a conference a type with @conftype{secret} bit set and the @conftype{rd-prot} bit unset. This is an error since such a conference type is inconsistent. @field{error-status} is undefined. @item letterbox (23) Attempt to change the @conftype{letterbox} flag of a conference. @field{error-status} indicates the conference number. @item ldb-error (24) Database is corrupted. @field{error-status} is an internal code. @item illegal-misc (25) Attempt to create an illegal misc item. @field{error-status} contains the index of the illegal item. @item illegal-info-type (26) Attempt to use a Misc-Info type (or Info-Type value) that the server knows nothing about. @field{error-status} is the type. @item already-recipient (27) Attempt to add a recipient that is already a recipient of the same type. @field{error-status} contains the recipient that already is. @item already-comment (28) Attempt to add a comment to a text twice over. @field{error-status} contains the text number of the text that already is a comment. @item already-footnote (29) Attempt to add a footnote to a text twice over. @field{error-status} contains the text number of the text that already is a footnote. @item not-recipient (30) Attempt to remove a recipient that isn't really a recipient. @field{error-status} contains the conference number in question. @item not-comment (31) Attempt to remove a comment link that does not exist. @field{error-status} contains the text number that isn't a comment. @item not-footnote (32) Attempt to remove a footnote link that does not exist. @field{error-status} contains the text number that isn't a footnote. @item recipient-limit (33) Attempt to add a recipient to a text that already has the maximum number of recipients. @field{error-status} is the text that has the maximum number of recipients. @item comment-limit (34) Attempt to add a comment to a text that already has the maximum number of comments. @field{error-status} is the text with the maximum number of comments. @item footnote-limit (35) Attempt to add a footnote to a text that already has the maximum number of footnote. @field{error-status} is the text with the maximum number of footnotes. @item mark-limit (36) Attempt to add a mark to a text that already has the maximum number of marks. @field{error-status} is the text with the maximum number of marks. @item not-author (37) Attempt to manipulate a text in a way that required the user to be the author of the text, when not in fact the author. @field{error-status} contains the text number in question. @item no-connect (38) Currently unused. @item out-of-memory (39) The server ran out of memory. @item server-is-crazy (40) Currently unused. @item client-is-crazy (41) The client used an illegal call sequence, such as calling @req{set-client-version} more than once. @item undefined-session (42) Attempt to access a session that does not exist. @field{error-status} contains the offending session number. @item regexp-error (43) Error using a regexp. The regexp may be invalid or the server unable to compile it for other reasons. @field{error-status} is undefined. @item not-marked (44) Attempt to manipulate a text in a way that requires the text to be marked, when in fact it is not marked. @field{error-status} indicates the text in question. @item temporary-failure (45) Temporary failure. Try again later. @field{error-status} is undefined. @item long-array (46) An array sent to the server was too long. @field{error-status} is undefined. @item anonymous-rejected (47) Attempt to send an anonymous text to a conference that does not accept anonymous texts. @field{error-status} is undefined. @item illegal-aux-item (48) Attempt to create an invalid aux-item. Probably the tag or data are invalid. @field{error-status} contains the index in the aux-item list where the invalid item appears. @item aux-item-permission (49) Attempt to manipulate an aux-item without enough permissions. This response is sent when attempting to delete an item set by someone else or an item that can't be deleted, and when attempting to create an item without permissions to do so. @field{error-status} contains the index at which the item appears in the aux-item list sent to the server. @item unknown-async (50) Sent in response to a request for an asynchronous message the server does not send. The call succeeds, but this is sent as a warning to the client. @field{error-status} contains the message type the server did not understand. @item internal-error (51) The server has encountered a possibly recoverable internal error. @field{error-status} is undefined. @item feature-disabled (52) Attempt to use a feature that has been explicitly disabled in the server. @field{error-status} is undefined. @item message-not-sent (53) Attempt to send an asynchronous message failed for some reason. Perhaps the recipient is not accepting messages at the moment or there are no viable members in the recipient of the message. @field{error-status} is undefined. @item invalid-membership-type (54) A requested membership type was not compatible with restrictions set on the server or on a specific conference. @field{error-status} is undefined unless specifically mentioned in the documentation for a specific call. @item invalid-range (55) The lower limit of a supplied range is greater than the upper limit. @field{error-status} is undefined. @item invalid-range-list (56) The lower limit of a supplied range is not greater than the upper limit of the previous range in the list. @field{error-status} is undefined. @item undefined-measurement (57) A request for a measurement that the server doesn't make has been made. @field{error-status} is undefined. @item priority-denied (58) You don't have enough privileges to lower your priority. @field{error-status} indicates the lowest priority that you have access to. @item weight-denied (59) You don't have enough privileges to set the specified weight. @item weight-zero (60) The scheduling weight must be non-zero. @field{error-status} is undefined. @item bad-bool (61) An argument of type @type{BOOL} was given a value that is neither @samp{0} nor @samp{1}. @field{error-status} is undefined. @end table @node Aux-Item Types @chapter Aux-Item Types Some of the aux-items below (mostly the ones that begin with "mx-") are used by mail importers. @table @samp @item content-type [1] (text) Specifies the content type of a text. Data is a valid MIME type or one of the special LysKOM types (@pxref{LysKOM Content Types}). This item may only be set by the author of a text. The inherit, secret and hide-owner bits are cleared. Only one content-type item can be created per creator. @item fast-reply [2] (text) Data is a string that constitutes a brief comment to the text. This comment should be displayed immediately after the text body. An item of this type will never be inherited, can always be deleted, is never anonymous and is never secret. @item cross-reference [3] (text, conference, letterbox) Data is a cross-reference to something else. The contents consist of a letter, a number, and optionally a space and a descriptive text. The letter must be one of T, C or P. T specifies that the cross-reference points to a text; C that it points to a conference; and P that it points to a person. The number is the id of the target of the cross reference. The descriptive text is simply that, a text that describes the cross-reference. For example, "T15 Check this out!" is a cross reference to text 15 with a description that reads "Check this out!", and "T17" is a cross reference without a description. The inherit bit is automatically cleared and the item can always be deleted. @item no-comments [4] (text) When this item is set, the author requests that nobody comments the text. This is advisory only; it is still possible to write comments, but clients should advise the user that this is contrary to the author's wishes. Data should be empty. This item may only be set by the author. The secret, hide-creator and inherit bits are automatically cleared. @item personal-comment [5] (text) When this item is set, the author requests only personal comments. This is advisory only; it is still possible to create regular comments, but clients should advise the user that the author prefers a personal comment. Data should be empty. This item may only be set by the author. The secret, hide-creator and inherit bits are automatically cleared. @item request-confirmation [6] (text) The author requests that everyone who reads the text confirms having done so by creating read-confirmation items on the text. Clients should ask users if they wish to confirm having read the text when it is displayed. Data should be empty. The hide-creator, secret and inherit bits are automatically cleared. @item read-confirm [7] (text) This item can be taken as confirmation that the item creator has read the text to which the item is attached. Clients should never ever create this item without an explicit confirmation from the user that the text has indeed been read. The hide-creator, secret and inherit bits are automatically cleared. Once created an item of this type cannot be deleted. @item redirect [8] (conference, letterbox) This item indicates that texts should not be sent to the conference, but be directed to some other target instead. Clients should notify users that attempt to send texts to the conference of the redirect and offer to send the text to the target of the redirect instead. A typical use of this item would be a user that does not read LysKOM very often and would like to advise other users to send e-mail instead. Data is PROTOCOL:ADDRESS where PROTOCOL is either "E-mail" or "LysKOM", and ADDRESS is either an e-mail address or a LysKOM conference number. Hopefully we'll be able to replace this with a forwarding mechanism later. This item can only be set by the conference supervisor or in the case of a mailbox, the person attached to the mailbox. The hide-creator and secret bits are cleared automatically. Only one redirect can be specified. @item x-face [9] (conference, letterbox, server) Data is the face of the person in compface format. Cool, @badspell{innit}? This item can only be set by the conference supervisor or in the case of a mailbox, the person attached to the mailbox. The hide-creator and secret bits are cleared automatically. @item alternate-name [10] (text, conference, letterbox) Data is a string that the client may use as an alternate to the name of a conference or the subject of a text. Note that the server does not match against this name when performing name lookups. Clients should only display alternate names created by the user currently logged on. The inherit flag is automatically cleared. @item pgp-signature [11] (text) Data is a PGP signature of the text. The signature should be the equivalent of what @samp{pgp -sba} in PGP 2.6.2 generates. The secret, hide-creator and inherit bits are automatically cleared. Signatures cannot be deleted once they have been created. @item pgp-public-key [12] (letterbox) Data is the public key of the person. It is desirable that the public key contains a userid of the format "LysKOM +", where @var{n} is the number of the person in the LysKOM server specified in @var{server}. This rule is currently not enforced. This item can only be set by the person himself. The hide-creator, secret and inherit bits are automatically cleared. @item e-mail-address [13] (conference, letterbox, server) Data is an RFC 822-style email address. When set on a mailbox, it should be the email address of the person. If the person has multiple email addresses he may set several e-mail-address aux-items. The meaning of this aux-item when set on a conference that isn't a mailbox is vague. For a conference that is used as to import a mailing list this should be the email address of the list. For other conferences we haven't really defined a sensible use. When this aux-item is set on the server it should contain the email address of the administrator (or administrators.) This aux-item can only be set by the supervisor of a conference or the server administrator. The creator cannot be hidden. @item faq-text [14] (conference, letterbox, server) Data is a decimal text number, which is a FAQ for the conference, letterbox or server. Creating an item of this type automatically causes creation of a faq-for-conf item. This item can only be set by the supervisor or server administrator. The hide-creator, secret, and inherit bits are automatically cleared. @item creating-software [15] (text) Data is the name and version number of the client that created the text. This aux-item can only be set by the author of the text. Once set, it cannot be removed or changed. A typical value would be @samp{elisp-client 0.47.3}. Setting the creating-software aux-item is optional. The data should be the client name, a space, and the client version used in the @reqlink{set-client-version} call. The server may enforce this restriction. @item mx-author [16] (text) Data is a string containing the name of the author of an imported e-mail, extracted from the @code{From} header. This aux-item may be missing, if the mail address in the @code{From} header consists of just the @code{addr-spec} (see the next aux-item). Clients should display this instead of the actual author of the text (which will be an importer ID) even if an mx-from aux-item is not present. Sample contents: @code{Joe Q. Public} which may come from a @code{From} header containing @code{"Joe Q. Public" }. @item mx-from [17] (text) Data is the proper e-mail address (called @code{addr-spec} in the mail standards) extracted from the @code{From} header of an imported e-mail. Clients should display this address together with the @aux{mx-author}, preferably inside angles. If @aux{mx-author} is not present, this address should be shown anyway. It can also be used by clients to construct an address for personal (e-mail) replies to an imported message. Sample contents: @code{john.q.public@@example.com} which may come from a @code{From} header containing @code{john.q.public@@example.com} or something like @code{"Joe Q. Public" }. @item mx-reply-to [18] (text) Data is the proper e-mail address (called @code{addr-spec} in the mail standards) extracted from the @code{Reply-To} header of an imported e-mail. Clients should use this for constructing replies to imported messages. @item mx-to [19] (text) Data is a single e-mail address from an email @code{To} header. Multiple @aux{mx-to} items may be present when multiple recipients are specified in the header. Clients should display these items along with the normal LysKOM recipient headers. Sample contents: Both @code{john.q.public@@example.com} and @code{"Joe Q. Public" } are valid. @item mx-cc [20] (text) Same as @aux{mx-to}, but applies to the @code{CC} header rather than the @code{To} header. @item mx-date [21] (text) Data is the date and time from the @code{Date} header of an imported email. Its format is @badspell{"YYYY-MM-DD hh:mm:ss TZ"}. @badspell{YYYY} is the year the message was sent, @badspell{MM} is the month, @badspell{DD} is the day, @badspell{hh} is the hour, @badspell{mm} is the minute and @badspell{ss} is the second. This date and time are given in the timezone where the message was sent. TZ is the timezone the date is valid for. It must be of the form "@badspell{+hhmm}" or "@badspell{-hhmm}", where @badspell{hh} is the number of hours offset from UTC and @badspell{mm} is the number of minutes offset. Symbolic timezones are not permitted. The timezone specification is recommended but optional, since it is not always available. Clients should display this information as the date and time a text was written, since the imported text will have been created at a later time. The date and time when the message was imported would then be displayed elsewhere or not at all. @item mx-message-id [22] (text) Data is the @code{Message-ID} header of an imported e-mail, with whitespace and comments removed. The Message-ID should contain the surrounding angles. @item mx-in-reply-to [23] (text) Data is a string containing one item of the same form as the mx-message-id item described above. This is the Message-ID of another mail the current text is a comment to. Hopefully, this information comes from the @code{In-Reply-To} header of the imported e-mail, but it could also have been picked from the end of the @code{References} header line. If the text really comments more than one other text directly, it is allowed to attach more than one @aux{mx-in-reply-to} items to it. @item mx-misc [24] (text) Data is a string that contains all of the headers of an imported email, including @code{Subject}, and including those that are redundantly stored in other aux-items. The headers are concatenated with "\n". In other words, this item contains all headers of an imported e-mail as they appear in the message. Clients are encouraged to provide a command to display this information. @item mx-allow-filter [25] (conference, letterbox) This aux-item has been declared obsolete. It was intended to supply the importer with information on how to filter incoming messages based on regular expressions matching header lines. @item mx-reject-forward [26] (conference, letterbox) This aux-item has been declared obsolete. It was intended to supplement mx-allow-filter by telling where rejected mails should be sent. @item notify-comments [27] (letterbox) Data is a decimal text number that the user is interested in. Clients should monitor this text for unread comments and present these to the user in some convenient manner. This is typically used by users that want to read comments to some text of theirs as soon as they arrive, rather than in the normal reading order. This item can only be set by the owner of the letterbox. No flags are forced or cleared. @item faq-for-conf [28] (text) Data is a decimal number specifying the conference a certain text is a FAQ for. The special number zero denotes that the text is a FAQ for the entire system. Items of this kind can only be created by the LysKOM server itself. Texts with this item are protected from garbage collection. @item recommended-conf [29] (server) Data is a decimal number specifying a conference that new members should automatically be added to, optionally followed by a space and a recommended priority, optionally followed by a space and a membership type. In the future, additional data may be defined; clients should be prepared to accept and ignore a space and any trailing data that may follow the membership type. A few examples might clarify what the data may look like: @table @code @item 1 Conference number 1. @item 2 32 Conference number 2, with priority 32. @item 3 250 11100000 Conference number 3, with priority 250. The membership should be secret, passive and have the invitation bit set. @item 4 253 01000000 garbage Conference number 4, with priority 253. The membership should be passive. The client should ignore the trailing garbage; it is reserved for future extensions. Note that clients are not allowed to create aux-items of this format, but they should be prepared to handle them correctly. @end table This is a recommendation only; it is up to the client that creates a new person to also add him to the conferences that are specified via @aux{recommended-conf}. @item allowed-content-type [30] (conference, letterbox, server) Data is a non-negative decimal priority number, followed by a space, followed by a LysKOM content type glob pattern. Clients should send texts to a conference only if the content-type matches any of the @aux{allowed-content-type} glob patterns of that conference. If the conference doesn't have any @aux{allowed-content-type}, the @aux{allowed-content-type} items of the server should be used. If the server also has no @aux{allowed-content-type} aux-items, it should be interpreted as if a single @aux{allowed-content-type} aux-item with the value @samp{1 text/plain} exists. If there are @aux{allowed-content-type} aux-items with different priority numbers, it is a hint to the client about which content-type is most desirable. Content-types that matches a lower priority number are preferred. As an example, consider a conference with the following four @aux{allowed-content-type} aux-items: @example 1 text/plain 2 text/x-kom-basic 2 text/enriched 3 text/* @end example These aux-items taken together means that @samp{text/plain} is preferred, that @samp{text/x-kom-basic} and @samp{text/enriched} can be used if there is a reason why @samp{text/plain} is inadequate, and that any text type (such as @samp{text/html}) is acceptable. Other content types, such as @samp{x-kom/user-area}, should not be used. The server does not currently enforce the above restriction on the content type of new texts. This mechanism is currently a hint to the client (or to the author of a new text). This may change in the future, if experience shows that it is desirable to have the server enforce the content type. @item canonical-name [31] (server) This should be set to the official domain name of the server, optionally followed by a colon and the port number. The port number should only be used if a non-standard port is used. Examples: @samp{kom.lysator.liu.se:8300}, @samp{kom.lysator.liu.se}. The intent is that the @aux{canonical-name} should be globally unique among all LysKOM servers. Only a single aux-item of this type can be set on the server. This aux-item can be used by clients that wish to do certain things only when connected to a specific server. @item mx-list-name [32] (conference) This item should only be used if the main purpose of the conference is to import a single external mailing list. The data should be the email address that is used to post to the list, such as @samp{bug-lyskom@@lysator.liu.se}. @item send-comments-to [33] (letterbox) Normally, when a comment is created, the LysKOM client adds the author of the commented text to the recipient list if he isn't a member of any of the recipients of the comment. By setting this aux-item on the letterbox, a person can request different treatment. Data is a decimal integer (a conference number) optionally followed by a space character and a decimal number (a recipient type). In the future, additional data may be defined; clients must be prepared to accept and ignore a space and any trailing data that may follow the recipient type. Clients must be prepared to accept items of this type that contain only the conference number. Comments should be sent to the specified conference number instead of to the author. The value @samp{0} is special and means that the comment should not be sent to any special conference, even though that means that the author of the commented text will never see the comment. (The value @samp{0} is useful for mail importers and other similar robots.) The recipient type is the type of recipient to add. If the recipient type is missing, clients should either assume recipient type zero (@misc{recpt}) or ask the user. Legal recipient types are @samp{0} for @misc{recpt}, @samp{1} for @misc{cc-recpt} and @samp{15} for @misc{bcc-recpt} (these are the values used in @type{Info-Type}). Additional recipient types may be added in the future. Clients should treat unknown or invalid recipient types as if they were missing (i.e. treat them as zero or ask the user). @xref{Recipients of comments}, for more information about how the client should select the conferences that a comment should be sent to. This aux-item can only be set by the supervisor of the person. @item world-readable [34] (text) Texts that has this aux-item set on them can be read by everybody. It is not even necessary to log in. Only the author of the text can set this item. The data must be the empty string. The hide-creator, secret, dont-garb and inherit bits are automatically cleared. @item mx-refuse-import [35] (conference, letterbox) This item tells the importer under what circumstances mail should be imported to the conference or letterbox. If no aux-item of this type is present, there are no limitations on import to this conference or letterbox. If the data is the string @code{all}, the importer will never add this conference or letterbox as a recipient. If the data is the string @code{spam}, the importer will not add this conference or letterbox as a recipient if the mail is considered to be spam according to some importer specific criteria (such as the presence of SpamAssassin flags). If the data is the string @code{html}, the importer will not add this conference or letterbox as a recipient if the mail is considered to be in HTML format. In the future, other alternatives in addition to the above may be defined for this aux-item. An importer should silently ignore unrecognized ones. If more than one aux-item of this type is present, they will be combined in the most restrictive way, i.e. the recipient will not be added if any of the aux-items forbids import. Clients are encouraged to provide commands to manage aux-items of this type for conferences and letterboxes. @item mx-mime-belongs-to [10100] (text) Data is a decimal text number that this text is an attachment to. Most likely, the current text is also a comment (or perhaps a footnote) to the text mentioned in the aux-item. A client can use this aux-item to alter the display format of the text (stating that this is an attachment, not a normal comment). @item mx-mime-part-in [10101] (text) Data is a decimal text number of a text that is an attachment to the current one. In other words: this is the converse of mx-mime-belongs-to. A client can use this aux-item to know which comments to mark as attachments; the remaining comments are assumed to be normal. @item mx-mime-misc [10102] (text) Data is a string that contains all of the MIME headers for the current text. It is set by the importer. The fields are concatenated with "\n". Clients are encouraged to provide a command to display this. @item mx-envelope-sender [10103] (text) Data is the envelope sender of an imported text. The mail server is supposed to pass this information to the importer, for inclusion here. @item mx-mime-file-name [10104] (text) Data is the file name of an attachment. Most likely, the importer gets this information from a @code{name} parameter on a @code{Content-Type} MIME header line. Clients are encouraged to use this file name as the default file name when the user chooses to save the text. @end table See also @ref{Some Client-specific Aux-Item Types}, for information about some non-standardized aux-item types. @node Name Expansion @chapter Name Expansion Names in LysKOM can be expanded according to two rules, regexp matching or KOM conventions. @section Regexp Matching This type of expansion, used by the @reqdlink{re-z-lookup} call and its predecessors@linkhere{} simply matches @command{ed}(1) style regular expressions to names in the database to find the list of matching names. The matching is case sensitive. @section KOM Conventions This type of matching is a little more complicated. Patterns consist of words and parenthesized expressions, and contain implicit wildcards. The @command{lyskomd} program implements an approximation of theses conventions. Since @command{lyskomd} is the trendsetter, these semantics are good enough. The rules are simple. Any parenthesized expressions are removed from the pattern and the names being checked for matches. Then the words of the pattern are examined from beginning to end, and if every pattern word matches the prefix of the corresponding word in the name, the name matches the pattern. For example ``L D'' matches ``LysKOM (client, server and protocol) Discussion (and) Ideas'', but not ``LysKOM Protocol Discussion''. The matching is case insensitive. Character case is converted according to a collate table in the server. The collate table can be retrieved from the server with the @reqdlink{get-collate-table} call@linkhere{}. The current collate table simply maps ISO 8859-1 uppercase and lowercase letters to equivalents, and also considered braces and suchlike equivalent according to swascii rules. @node LysKOM Content Types @chapter LysKOM Content Types LysKOM defines a few special content types for texts. They are all described in this chapter. In addition to these, clients must support @samp{text/plain}, should support @samp{text/enriched} and are encouraged to support @samp{text/html}. Lines are separated by a single linefeed (ASCII 10) character. The linefeed character is used as a line separator, not as a line terminator. In other words, there should be no linefeed after the last line. @menu * Reformattable Text (text/x-kom-basic):: * The User Area (x-kom/user-area):: @end menu @node Reformattable Text (text/x-kom-basic) @section Reformattable Text This type of content corresponds to the mime type @samp{text/x-kom-basic}. It is raw text that can be reformatted by the client without ill effects, but that can be legibly displayed on a text terminal without formatting. @itemize @bullet @item Lines must be no longer than 70 characters. @item Each line, except the last, is terminated by a single linefeed character. @item Two linefeed characters in succession signal the end of the paragraph. @item There must be no whitespace or linefeeds after the last character. @item The end of the last line also signals the end of the paragraph. @end itemize The following rules apply when reformatting: @itemize @bullet @item The indentation of the first line of a paragraph is to be applied to all lines in the paragraph. @item If the first line of a paragraph matches ">+ *" then the string that matched that regexp is to be prefixed to all lines of the paragraph. @end itemize This content type was previously erroneously called @samp{x-kom/basic}, but as far as we know no client ever created texts that were labeled with that name. Please use the new name @samp{text/x-kom-basic} instead. Historical note: version 0.46.1 and earlier of the elisp client created texts labeled with @samp{x-kom/text}. Clients may treat that content type as @samp{text/x-kom-basic} for improved interoperability. @node The User Area (x-kom/user-area) @section The User Area This content type indicates that the article contains a user area. @xref{The User Area}. @node The User Area @chapter The User Area The user area is a regular text that is used to store client-specific information in the server. Most clients use this to store settings a user has made that are specific to a particular server. There are also provisions to store settings that are shared between clients. The user-area is divided into several sub-blocks. The @code{common} block is shared by all clients, and its formats and contents are dictated by this protocol specification. Clients may also create one or more other blocks. In normal texts, everything up to the first linefeed is considered to be the subject line. The user area is an exception: it does not contain any subject line. Each block is encoded as a @type{HOLLERITH} string. A table of contents is also encoded as a @type{HOLLERITH} string and added first in the user area. There must be at last one space between each string, and there might be spaces at the beginning and/or end of the user-area. Thus, a user-area made up of three blocks will contain four @type{HOLLERITH}-encoded strings, each separated by at least one space, and maybe with extra spaces at the beginning or end of the text. The table of contents consists of one @type{HOLLERITH}-encoded string for each block in the user-area. Each string contains the name of the corresponding block. There is at least one space between each string, and there may be spaces before the first string and after the last string. Clients must never create two or more blocks with the same name. This format ensures that clients can copy or read past other clients' blocks without knowing their structure. @need 2000 @i{Example:} @example 13H7Hblock-a 1Hb 4Hasdf 5H hjkl @end example In the above example, there are two blocks: @code{block-a} and @code{b}. @code{block-a} contains four bytes, @code{asdf}, while @code{b} contains five bytes: @w{@code{ hjkl}} (note the leading space). Below are a few other ways to encode the same user-area: @example 14H 7Hblock-a 1Hb 4Hasdf 5H hjkl 16H 7Hblock-a 1Hb 4Hasdf 5H hjkl 13H1Hb 7Hblock-a 5H hjkl 4Hasdf @end example The first two examples embed extra (redundant) spaces, and the last swaps the order of the two blocks. The following block names have been defined: @table @code @item common The common block shared by all clients. The format of the common block is described below. @item elisp The block created by the Emacs lisp client. The format is completely undocumented, but you'll need a lisp reader to parse it. @item WWW-kom The block created by the web gateway WWW-kom. It has the same syntax as the common block, but the keys and values are not documented. @item rkom Used by Anders Magnusson . @end table If you're writing a client that uses the user-area, please let us know what you name your client's block. @section The Common Block This defines the structure of the common block. The common block contains a list of variable settings. Each variable setting consists of a name, some whitespace, and a value. Settings are separated by a linefeed character. The values can be of several different types (such as integers, strings, booleans, lists of stuff) but they are all encoded as HOLLERITHs. The reason for this is to simplify for clients that need to ignore the value, and so it is possible to add new value types without confusing old clients. The grammar below defines the syntax of the common block. @c ispell-ignore @example common-block : settings settings : settings setting | /* empty */ setting : variable ' ' value '\n' variable : [A-Za-z-_0-9]+ value : HOLLERITH @end example @c ispell-end-ignore The values contain structure within the HOLLERITH. The following grammar defines the data types that are currently used. Clients must be prepared to ignore values that have other data types. @c ispell-ignore @example boolean : 1 | 0 integer : -?[0-9]+ string-list : string-list ' ' HOLLERITH | HOLLERITH @end example @c ispell-end-ignore Currently the following variables are used, but more may be added, and clients must cope with variables they know nothing of in the common block. (Doing so is easy, as all values are encoded as HOLLERITHs.) @table @code @item created-texts-are-read True if the user wants texts s/he creates to be marked as read automatically. @code{boolean}. @item dashed-lines True if the user wants dashed lines around the text body when it's displayed. @code{boolean}. @item presence-messages True if the user wants messages about people logging in and logging out of LysKOM. @code{boolean}. @item print-number-of-unread-on-entrance True if the user wants to see the number of unread texts when entering a conference. @code{boolean}. @item read-depth-first True if the user wants to read text in depth-first order. @code{boolean}. @item reading-puts-comments-in-pointers-last True if the user wants the client to display comment links after the text body. @code{boolean}. @item confirm-multiple-recipients True if the user wants the client to ask for confirmation before sending a text to many conferences. @code{boolean}. @item default-mark The default mark to set on marked texts. @code{integer}. @item language Preferred languages, in priority order. @code{string-list}. This contains a list of ISO 639 language codes. ISO 639-2 should be used for languages that have a 2-character language code. For other languages, ISO 639-1 should be used. @uref{http://lcweb.loc.gov/standards/iso639-2/langcodes.html} contains a list of the current language codes. The client should configure its user interface to use the first language in the list that it supports. Example: a client that supports English and Swedish would use: @itemize @bullet @item Swedish if the list is @samp{2Hfr 2Hsv 2Hen} @item English if the list is @samp{2Hen 2Hsv 2Hfr} @item either if the list is @samp{2Hes 2Hfr} @end itemize @end table @node Membership visibility @chapter Membership visibility The details of the security model isn't properly documented. Much information can be extracted from various parts of the protocol specification, but there is no complete overview. In time, this chapter may become such an overview. For now, it only defines when a membership is visible. The various requests that return information about a membership can be grouped into three categories: @itemize @bullet @item Category 1: given a conference, list (some of) the members. @itemize @bullet @item @reqlink{get-members} @item @reqlink{get-members-old} @end itemize These requests fail if the conference is secret and you don't have access to it, even if a membership should be visible to you according to the rules below. @item Category 2: given a person, list (some of) the conferences that the person is a member of. @itemize @bullet @item @reqlink{get-membership} @item @reqlink{get-membership-10} @item @reqlink{get-membership-old} @item @reqlink{get-unread-confs} @end itemize @c FIXME (Bug 70): Should secret persons be allowed? These requests fail if the person is secret and you don't have access to it, even if a membership should be visible to you according to the rules below. @item Category 3: given a person and a conference, return the membership. @itemize @bullet @item @reqlink{query-read-texts} @item @reqlink{query-read-texts-10} @item @reqlink{query-read-texts-old} @end itemize These requests follows the rules below exactly. @end itemize The rules for membership visibility are given below. In the explanation, the variables @var{C}, @var{P} and @var{V} are used like this: @itemize @bullet @item a conference @var{C} @item a person @var{P} who is a member of the conference @var{C} @item a viewer @var{V} who wants to find out about @var{P}:s membership in @var{C}. @end itemize The following flags also influences how much @var{V} can see: @itemize @bullet @item the @field{unread-is-secret} flag of @var{P} @item the @field{secret} flag of @var{P}:s membership in @var{C} @end itemize The following rules determines if a membership is visible to @var{V}. The first rule that matches is used. @itemize @bullet @item If @var{V} is supervisor of @var{P}, then the membership is visible. Both the @field{unread-is-secret} and @field{secret} flags are ignored. @item If @var{V} is supervisor of @var{C}, then the membership is visible. The @field{secret} flag is ignored. The @field{unread-is-secret} flag is honored. @item If @var{V} is allowed to see both @var{P} and @var{C}, and if @field{secret} is unset, then the membership is visible. The @field{unread-is-secret} flag is honored. @item Otherwise, @var{V} is not allowed to se the membership. @end itemize @node Garb @chapter Automatic text removal (the garb) Old texts are automatically removed by a process known as @dfn{the garb}. By default, the garb will remove all texts when it looks at them. There are several things that can save a text from removal: @itemize - @item if the server is configured to never remove any texts. @item if text is marked. See @reqlink{mark-text}. @item if the text is presentation of a conference. See @reqlink{set-presentation}. @item if the text is message of the day for a conference. See @reqlink{set-etc-motd}. @item if the text is message of the day for the system. See @reqlink{set-motd-of-lyskom}. @item if the text is message of the user area of a person. See @reqlink{set-user-area}. @item if the text is less than 24 hours old. @item if the text has an aux-item with the @field{dont-garb} bit set. See @xref{Aux-Item-Flags}. @item if the text is less than @field{nice} days old, for any of the recipients. @field{nice} is part of the @type{Conference} status. @reqlink{set-garb-nice}. All recipient types, @misc{recpt}, @misc{cc-recpt} and @misc{bcc-recpt}, counts. If the text was added to the conference after its creation, the check is made against the addition time instead of the creation time. See @reqlink{set-garb-nice}. @item if the text was added as a comment or footnote to a text within the last 24 hours. See @reqlink{add-comment} and @reqlink{add-footnote}. @item for each comment and footnote to the text, the time when it became a comment or a footnote of the text is considered. If it is less than 24 hours, the text is saved. If it is less than the @field{keep-commented} field of any of the recipients of the text and the comment/footnote, it is saved. All recipient types, @misc{recpt}, @misc{cc-recpt} and @misc{bcc-recpt}, counts. See @reqlink{set-keep-commented}. @end itemize Other texts will be removed. It is an implementation detail of the server exactly when texts will be removed. @node Measured Properties @chapter Measured Properties The server measures a number of properties, and can return information about them to a client via the @reqdlink{get-stats} request@linkhere{}. A server implementation may include experimental properties, whose name should begin with @samp{X-}. All other properties should be defined in this chapter. Some of the properties that are suggested here might prove to be too hard to measure efficiently, or might prove to expose too much information. In that case, a server may select to not implement them. Clients must be prepared to receive a @errorcode{feature-disabled} or @errorcode{undefined-measurement} error if they call @req{get-stats} with a value that wasn't received from @reqlink{get-stats-description}. For each measured value, both the levels and the ascent and descent rates are returned. @xref{Stats}, for more information. Ascent and descent rates are always normalized to a number of events per 100 seconds. @table @code @item run-queue-length The number of clients that the server is currently refusing to serve since its time for the server to process other clients for a while. @item pending-dns The number of pending DNS requests. @item pending-ident The number of pending IDENT requests. @item clients The number of connected clients. @item reqs The number of Protocol A requests that is being processed. In the current implementation, this will always be a number between 0 and 1, but that might change in the future. @item texts The number of existing texts. @item confs The number of existing conferences (including letterboxes). @item persons The number of existing persons. @item send-queue-bytes @itemx recv-queue-bytes The number of bytes waiting in the send and receive queues. @end table @node Extracted grammar @appendix Extracted grammars (informative) The file @file{Protocol-A.texi} is the authoritative standard for protocol A. However, it has a two problems: @itemize @bullet @item The Texinfo markup makes it hard for a program to extract information--and once a program is written, we might change the Texinfo markup, so that the program has to be updated. @item We often rename requests and data types, in order to have good names for the most recommended functions and types. However, a program that uses a data type might fail if that type suddenly is altered. @end itemize To overcome these problems, and better server client writers that want to generate the protocol-level code automatically from the specification, a few variants of the grammar is available as separate files. In some of these files, the names have been changed to @dfn{stable} names that will not change as the protocol evolves. Currently, these three grammars exists: @table @file @item protocol-a-full.txt The full Protocol A specification, with stable names. @item protocol-a-recommended.txt The recommended requests and asynchronous messages, and all types they need, with stable names. @item protocol-a-current.txt The recommended requests and asynchronous messages, with the names used in this specification. @end table @c FIXME: I still awaiting a go-ahead from some authors of this @c document regarding the license. For now, it is restrictive. @c @c These generated files are in the public domain, so you are free to use @c them any way you like. The files are generated by @file{doc/checkargs.py} in the lyskom-server distribution. Adding more output formats is fairly easy. Let us know, preferably via Bugzilla, if a new output format would be useful for you. It is the intention that the format of the above-mentioned files will not change. The file format should be self-explanatory once you have read the protocol specification. It does contain some comments that should be useful. The stable names are generated by this process: @itemize @bullet @item Don't modify builtin types such as @type{INT32}. @item Remove the suffixes @samp{-old}, @samp{-older} and @samp{-Old}, unless that would introduce an ambiguity. @item Unless the name already has a version suffix, add one. @end itemize All files mentioned above are reachable via @uref{http://www.lysator.liu.se/lyskom/protocol/}. @node Writing Clients @appendix Writing Clients (informative) This appendix is not really part of the protocol specification, but it contains some information that may be useful for client writers. @menu * Common Commands:: Common commands and how they're implemented. * Client Conventions:: Conventions clients should follow. @end menu @node Common Commands @section Common Commands Most clients will implement certain commands. This main purpose of this section is to get client writers started on some of these commands, and to answer some questions that seem to come up over and over again. @menu * What do I have unread:: How to figure out which articles to present. @end menu @node What do I have unread @subsection What do I have unread Each person has a membership list containing the conferences the person is a member of. Each element is an object of type @type{Membership}. Among other things it contains the number of the conference, the priority of the membership, when the person most recently marked a text as read in the conference, and which texts the person has read. The list of read texts consists of two parts: a local text number called @field{last-text-read} and a list of local text numbers called @field{read-texts}. The person has marked all texts up to and including @field{last-text-read} as read, and also the texts listed in @field{read-texts}. All other texts in the conference are unread. Clients can use either the @req{query-read-texts} or @req{get-membership} calls to get membership data. The standard procedure for finding out which texts are unread is the following: @enumerate @item Call @req{get-unread-confs} for the person. This returns a list of conferences in which the person may have unread texts. This call may return conferences that do not contain any unread texts, but it will never forget to return a conference that does contain an unread text. @item Call @req{query-read-texts} for each conference returned in the previous step. This will return the membership data for all the conferences that may contain unread texts. @item Call @req{get-uconf-stat} for each conference returned in the first step. The conference status will be needed shortly. Repeat the following steps for each conference. @item Compare the highest existing local number in the conference (from the conference status) with the @field{last-text-read} field for the corresponding membership. If the highest existing local text is higher than @field{last-text-read}, the conference may contain unread texts. @item Get part of the local to global map from the conference starting at @field{last-text-read} and ending at the highest existing local number. Every local number in the map that is not read according to the membership data and that has a mapping to a global number is an unread text. You might say that you remove the read texts from the map to get the unread texts. @end enumerate Take care not to call get-map or get-membership too much since they tend to be expensive operations. Use @req{get-unread-confs} and @req{query-read-texts} to minimize the work. Another point to remember is that the server will send asynchronous messages with information about new texts. Clients need to listen to these messages. @node Client Conventions @section Client Conventions There are certain conventions that most clients follow, and that users expect. These are not part of the protocol and are subject to change. In particular those conventions that address deficiencies in the protocol will go away when the protocol is updated to correct these deficiencies. @menu * Text formatting:: The format of texts in the database. * Content type specification:: Clients can tag the content type of a text. * Client-side name expansion:: By number, by word, by regexp. * Recipients of comments:: Where comments should be sent. * Order of misc-info groups:: Footnotes, comments, recipients. @end menu @node Text formatting @subsection Text formatting Traditionally the only clients for LysKOM were text-based and only displayed texts exactly as they were stored in the server. Although there are a number of clients now that can wrap lines automatically, texts should still be stored in preformatted style, suitable for display in a monospaced font. If the client accepts texts from the user and then reformats them, such as a client with an editor with a variable-width font, it should ensure that it follows the following simple rules: @itemize @bullet @item Lines should be no longer than 72 characters. @item Lines are terminated with a single linefeed character. @item Paragraphs are separated by two linefeeds in succession. @item There are no empty lines at the end of the text. @end itemize Clients that include editors but do not alter the text before sending it to the server should attempt to ensure that texts confirm to the above conventions. The same conventions apply to messages sent with the @reqdlink{send-message} call@linkhere{}. @node Content type specification @subsection Content type specification This convention is understood by all popular clients. If the first line is one of a few predefined strings, then this string specifies the type of text. Currently only the strings ``html:'' and ``enriched:'' are supported, specifying @samp{text/html} and @samp{text/enriched} respectively. Starting with protocol version 10, this ugly workaround is obsolete. Use aux-items to specify content type instead. @node Client-side name expansion @subsection Client-side name expansion When a client needs to prompt the user for a conference (or person), it could offer the user several ways of specifying the conference: @itemize @bullet @item By conference number @item By name, using the @reqdlink{lookup-z-name} call@linkhere{}. @item By name, using the @reqdlink{re-z-lookup} call@linkhere{}. @item By name, transforming the string to a case insensitive regular expression, and then using the @req{re-z-lookup} call. @end itemize It is beyond the scope of this document to specify how the client interacts with the user. The client should offer the user all the methods of specifying a conference listed above. At the very least, the two first methods should be supported. @node Recipients of comments @subsection Recipients of comments When a user writes a comment, the user should have full control over which conferences and/or letterboxes the comment is sent to. By default, the recipient list should be all @misc{recpt} recipients. @misc{cc-recpt} and @misc{bcc-recpt} recipients should not be included. Conferences in the recipient list that have the @conftype{original} bit set, and a non-zero @field{super-conf}, should be replaced by the @field{super-conf}. If the author of the commented text isn't a member of any of the new recipients, the client should check if the author has a @aux{send-comments-to} aux item. If it is @samp{0}, nothing should be done. Otherwise, @aux{send-comments-to} should be a valid conference number, and that conference should be added as a @misc{recpt} recipient. If there is no @aux{send-comments-to} aux-item, the user should be prompted to add the author of the commented text as a @misc{recpt} or @misc{cc-recpt} recipient. If the author of the new comment is not a member of any of the recipients, the client should check if the author has a @aux{send-comments-to} aux item. If it is @samp{0} nothing should be done. Otherwise, @aux{send-comments-to} should be a valid conference number, and the user should be prompted to add that conference as a @misc{recpt} or @misc{cc-recpt} recipient. If there is no @aux{send-comments-to}, or @aux{send-comments-to} is invalid, the user should be prompted to add his letterbox as a @misc{recpt} or @misc{cc-recpt} recipient. If a recipient is present more than once, all duplicates should be removed. @node Order of misc-info groups @subsection Order of misc-info groups The ordering of the groups of @type{Misc-Info} items are not defined by this protocol. However, when creating a new text, clients are recommended to use this order: @itemize @bullet @item any @misc{footn-to} items @item any @misc{comm-to} items @item any @misc{recpt} items @item any @misc{cc-recpt} items @item any @misc{bcc-recpt} items @end itemize This is the order that the elisp-client normally uses, and users have come to expect that order. @node Importing and Exporting E-Mail @appendix Importing and Exporting E-Mail (informative) E-mail import has been implemented using various programs since the first LysKOM server became operational. Protocol version 10 introduces a lot of aux-items, a large part of which are intended for use by mail importers to enhance the functionality. As of this moment, there is one mail importer (@command{komimportmail}) that is designed to take full advantage of all the new aux-items. E-mail export has never been used seriously. The first person to design and implement an exporter gets to rewrite this appendix based on his or her experiences. @section Importing e-mail The main job of the mail importer is to figure out where to deliver mail, how to handle MIME coding and/or structure and how to deal with threading. During this, it creates one or more texts and a lot of aux-items. @subsection Recipients Although a mail message contains @code{To} and @code{CC} headers, they are not really useful when importing as it is the envelope recipients, not the header recipients, that should be used. To understand this, consider a mail where the @code{To} header contains a personal mail address. The mail is received using a tool like @command{procmail} and forwarded to the LysKOM importer. The envelope address will be correct, but the @code{To} header will still contain the personal address. The @command{komimportmail} importer uses addresses like ``@var{number}@@@var{server}'', where @var{number} is the number of the recipient and @var{server} is the mail domain reserved for the LysKOM importer. For backwards compatibility with earlier importers, it is allowed to prepend a ``p'' before the number. Instead of the number, @command{komimportmail} can accept a name, as long as the name can be resolved to exactly one conference or letterbox. Before looking up the name, any underscore or period is translated into a space. Care should be taken when a mail is received more than once. This can happen if a mail is addressed to more than one address. For example, assume that a mail is sent to @code{john.q.public@@example.com} and @code{sven.svensson@@exempel.se}. Two different mail servers handle the two recipients, but both eventually decide to forward the mail to the LysKOM importer (but for different conferences). The LysKOM importer will receive the mail twice, with different envelope recipients. A solution is to keep a database containing a mapping from @code{Message-ID} to LysKOM text number for imported messages. If a message is seen more than once, the message is not imported. Instead, recipients are added to the existing text. On the other hand, that will introduce a security hole, where a person who knows the @code{Message-ID} of an interesting imported mail can add himself or some open conference as a recipient. Perhaps the importer should check for matching contents before adding recipients. The importer needs to be careful not to deliver messages to conferences that do not allow messages, even though the server might not complain. @c FIXME (bug 201): Please elaborate on that... For mail delivery to work for any conference, the importer has to use a privileged person, or it will be unable to deliver mail to secret conferences. A potential problem is that this leaks secret information from the server. For the time being, the @command{komimportmail} importer avoids this problem by using an unprivileged person and requiring the members of secret conferences to invite the importer if they want e-mail import to work. @subsection Threading The importer should do its best to thread messages. When the importer sees a new message it needs to look at the @code{In-Reply-To} header to see what the message is a reply to. If the @code{In-Reply-To} header does not exist, or if it exists but does not contain a valid Message-ID, the last valid Message-ID of a @code{References} header may be used instead. If the Message-ID of a previously imported e-mail is found, the new text should be made a comment of the replied-to text. If the Message-ID is of the form defined below (@pxref{Message-ID}), and it refers to a text exported from this server, the new text should be made a comment of the replied-to text. This means that the importer will probably have to maintain its own database of imported texts that maps the message ID to the text number in the LysKOM database. There is no other way to find the text number for a particular imported text. Fortunately, this is exactly the same database we need to solve the multiple reception problem described above. It has been noted that messages on some mailing lists arrive in peculiar order, with replies before the original messages. Perhaps this is due to moderation. A smart importer should be prepared to handle this, by adding a comment link when the original message eventually arrives. One possible solution is to add a new kind of entry to the Message-ID database, mapping a Message-ID to a list of text numbers that should become comments to the message when it is imported. @subsection MIME issues An importer should try to handle e-mail messages containing MIME appendices as smart as possible. As the current LysKOM model lacks hierarchical structuring inside articles, appendices should probably be imported as comments or footnotes to the main message. One would think that it is easy to convert the hierarchical MIME structure to a corresponding LysKOM comment tree. However, this would require creating empty interior nodes to attach some comments to. Therefore, the @command{komimportmail} importer currently uses a rather naive algorithm: All leaf parts are found. The first one gets to be the main text, and the rest are included as comments to it. Appendices encoded with Base64 or Quoted-Printable should be decoded. When creating aux-items like @aux{mx-author}, text coded using the method in RFC 2047 should be decoded. @section Exporting e-mail As of this writing, an experimental e-mail exporter exists, but it is a fairly recent creation. The author of this document knows very little about how it works, so this section contains very little information. @anchor{Message-ID} @subsection Message-ID A standard for Message-ID creation has been established. The general format is: @example @var{text-no}.@var{port}.@var{exporter}.@var{randomness}@@@var{server} @end example The different parts are explained below: @table @var @item text-no The text number of the text that was exported. @item port @itemx server The @aux{canonical-name} aux item defines a unique name for the LysKOM system that the text was exported from. The @var{server} and @var{port} fields are set from it. If no port is specified in the @aux{canonical-name}, the @var{port} part is set to the empty string. @item exporter The name of the software that exported the text. @item randomness A string that ensures that the Message-ID is unique even if the same text is exported several times. This could contain a random string, a sequence number, or something else that makes the Message-ID unique. @end table @node Some Client-specific Aux-Item Types @appendix Some Client-specific Aux-Item Types (informative) This appendix contains some contributed information from client writers about some of the aux-item types that they use. This information may be updated at any time by the client writers. How much the client writer cares about backward compatibility when they make changes to these aux-item types may be beyond the control of the authors of the Protocol A specification. If any of the aux-item types defined here becomes widely used by different clients, they should probably be standardized and moved to the @ref{Aux-Item Types} chapter. @c This marker is used by "make check". See Makefile.am. @c BEGIN-EXTRA-AUX @table @samp @item elisp-client-read-faq [10000] (letterbox) This item indicates FAQs that the user has read. Data is a decimal number indicating the conference for which a FAQ has been read, followed by a space character and a second decimal number indicating the text number of the FAQ. In the future, additional data may be defined; clients should be prepared to accept and ignore a space and any trailing data that may follow the second number. Note that aux-items of this type should always be secret since they may contain information about texts of conferences that are not publicly visible. A few examples might clarify what the data may look like: @table @code @item 459 11215 FAQ in text 11215 for conference 459 has been read. @item 459 11215 garbage FAQ in text 11215 has been read. Clients must ignore the trailing garbage. Note that clients are not allowed to create aux-items of this format, but they should be prepared to handle them correctly. @end table This aux-item is specific to the elisp client. Other clients are not required to use or understand this item type. @item elisp-client-rejected-recommendation [10001] (letterbox) This item indicates a rejected membership recommendation. Data is a decimal number indicating the conference for which the recommendation was rejected. In the future, additional data may be defined; clients should be prepared to accept and ignore a space and any trailing data that may follow the second number. Note that aux-items of this type should always be secret since future extensions may contain sensitive data. A few examples might clarify what the data may look like: @table @code @item 459 A recommendation for conference 459 has been rejected. @item 459 garbage A recommendation for conference 459 has been rejected. Clients must ignore the trailing garbage. Note that clients are not allowed to create aux-items of this format, but they should be prepared to handle them correctly. @end table This aux-item is specific to the elisp client. Other clients are not required to use or understand this item type. @end table @c END-EXTRA-AUX @node Future changes @appendix Future changes (speculative) While useful and stable, this protocol is far from perfect. Here is a short list of things the current developers would like to change in future versions of the protocol. The list is not sorted. All changes will be made in a backwards compatible way. Clients will still be able to use the old requests. @itemize @bullet @item Cryptography! LysKOM is sometimes used for sensitive information. It is unacceptable that everything is sent in the clear. Should we use TLS? This area needs further study. (This is @uref{http://bugzilla.lysator.liu.se/show_bug.cgi?id=133, bug 133}.) @item The information contained in the @type{Misc-Info} array should be integrated into the @type{Text-Stat}. There should be one array of recipients, one of texts that comments this text, and so on. This would make the @type{Misc-Info} type obsolete. (This is @uref{http://bugzilla.lysator.liu.se/show_bug.cgi?id=134, bug 134}.) @item The aux-items can be very large. It was a mistake to include them in the @type{Text-Stat}. They should probably be separated from the @type{Text-Stat}; retrieving the @type{Text-Stat} should only indicate which aux-items that exists. (This is @uref{http://bugzilla.lysator.liu.se/show_bug.cgi?id=135, bug 135}.) @item The super conference is used for two purposes: to indicate where followups of original conferences should be sent, and to indicate where articles created by persons that are not permitted submitters should be sent. Occasionally one wants to send followups to one conference and unauthorized original articles to another conference. One way to fix this is to remove the @conftype{original} bit and introduce a @code{followups-to} field in the @type{Conference}. Doing this in a backwards-compatible way requires some thought@dots{} (This is @uref{http://bugzilla.lysator.liu.se/show_bug.cgi?id=136, bug 136}.) @item The security system is too complex, yet unable to do many useful things, and should be rethought. (This is @uref{http://bugzilla.lysator.liu.se/show_bug.cgi?id=137, bug 137}.) @item If the client issues several request without waiting for a reply, the replies will nevertheless always arrive in the same order as the requests were sent in. If a threaded version of the LysKOM server is ever made, it could possibly process two requests from the same client at the same time, and the answers could be returned in any order. However, the current clients are probably not written so that they can handle such reordering. In the future, a new call might be added, so that a client can give the server explicit permission to reorder the replies. The client would then have to rely on the @field{ref-no} to match each reply to the corresponding call. (This is @uref{http://bugzilla.lysator.liu.se/show_bug.cgi?id=138, bug 138}.) @end itemize For more information about potential future changes, see @uref{http://bugzilla.lysator.liu.se/, Bugzilla @@ Lysator}. The above list is in no way complete. @node Protocol Version History @appendix Protocol Version History (informative) @section Protocol version 11 (first implemented in lyskomd 2.1.0) @table @asis @item New Server Calls These new calls have status Recommended. @itemize @bullet @item 107=query-read-texts @item 108=get-membership @item 109=mark-as-unread @item 110=set-read-ranges @item 111=get-stats-description @item 112=get-stats @item 113=get-boottime-info @item 114=first-unused-conf-no @item 115=first-unused-text-no @item 116=find-next-conf-no @item 117=find-previous-conf-no @item 120=set-connection-time-format @item 121=local-to-global-reverse @item 122=map-created-texts-reverse @end itemize These new calls have status Experimental. @itemize @bullet @item 118=get-scheduling @item 119=set-scheduling @end itemize @item Status change The following calls have change status from Experimental to Recommended. @itemize @bullet @item 105=set-keep-commented @end itemize The following calls have changed status from Recommended or Experimental to Obsolete. @itemize @bullet @item 98=query-read-texts-10 @item 99=get-membership-10 @end itemize @item New and Modified Types @itemize @bullet @item Read-Range @item Membership @item Membership-Type @item Stats @item Stats-Description @item Static-Server-Info @item FLOAT @end itemize @item New Asynchronous Messages @itemize @bullet @item 19=async-new-user-area @item 20=async-new-presentation @item 21=async-new-motd @item 22=async-text-aux-changed @end itemize @item New aux-items @xref{Document Edition History}, as new aux-items are added between protocol versions. @item New error codes @xref{Document Edition History}. @item Notes @itemize @bullet @item The @code{reserved1} bit of @type{Membership-Type} has been renamed to @field{passive-message-invert}. @xref{Membership Information}. This affects @asynclink{async-send-message} and @reqlink{send-message}. @item The following requests can no longer be used until you have logged in: @reqlink{get-last-text}, @reqlink{find-next-text-no} and @reqlink{find-previous-text-no}. @item You can now modify the type of a recipient with the @reqlink{add-recipient} call if you are the supervisor of either the author, recipient or sender. The check used to be more restrictive. @item The following asynchronous messages are also sent to recipients of texts linked to the relevant text via comment or footnote links: @asynclink{async-new-text-old}, @asynclink{async-deleted-text}, @asynclink{async-new-text}, @asynclink{async-new-recipient} and @asynclink{async-sub-recipient}. @item All requests that take a @type{BOOL} argument now return the error @errorcode{bad-bool} if the argument is anything but @samp{0} or @samp{1}. @end itemize @end table @section Protocol version 10 (first implemented in lyskomd 2.0.0) @table @asis @item Error codes The error codes are now documented. Several error codes were changed to more sane values while documenting the new behavior. @item New Server Calls These new calls have status Recommended. @itemize @bullet @item 85=get-collate-table @item 86=create-text @item 87=create-anonymous-text @item 88=create-conf @item 89=create-person @item 90=get-text-stat @item 91=get-conf-stat @item 92=modify-text-info @item 93=modify-conf-info @item 94=get-info @item 95=modify-system-info @item 96=query-predefined-aux-items @item 98=query-read-texts @item 99=get-membership @item 100=add-member @item 101=get-members @item 102=set-membership-type @item 103=local-to-global @item 104=map-created-texts @item 106=set-pers-flags @end itemize These new calls have status Experimental. @itemize @bullet @item 97=set-expire @item 105=set-keep-commented @end itemize @item Name changes @multitable {59=create-anonymous-text} {59=create-anonymous-text-old} @item Old name @tab New name @item 5=create-person @tab 5=create-person-old @item 9=query-read-texts @tab 9=query-read-texts-old @item 10=create-conf @tab 10=create-conf-old @item 13=get-conf-stat-old @tab 13=get-conf-stat-older @item 14=add-member @tab 14=add-member-old @item 26=get-text-stat @tab 26=get-text-stat-old @item 28=create-text @tab 28=create-text-old @item 36=get-info @tab 36=get-info-old @item 46=get-membership @tab 46=get-membership-old @item 48=get-members @tab 48=get-members-old @item 50=get-conf-stat @tab 50=get-conf-stat-old @item 59=create-anonymous-text @tab 59=create-anonymous-text-old @end multitable @item Status change The following calls have change status from Experimental to Recommended. @itemize @bullet @item 58=get-last-text @item 77=set-last-read @item 78=get-uconf-stat @end itemize The following calls have changed status from Recommended or Experimental to Obsolete. @itemize @bullet @item 5=create-person-old @item 9=query-read-texts-old @item 10=create-conf-old @item 14=add-member-old @item 26=get-text-stat-old @item 28=create-text-old @item 36=get-info-old @item 46=get-membership-old @item 47=get-created-texts @item 48=get-members-old @item 50=get-conf-stat-old @item 59=create-anonymous-text-old @end itemize @item New and Modified Structures @itemize @bullet @item Aux-Item @item Aux-Item-Input @item Conference @item Info @item Member @item Membership @item Membership-Type @item Misc-Info @item Text-Stat @end itemize @item Renamed Asynchronous Messages A @samp{async-} prefix has been added to the name of all asynchronous messages. In addition, 0=new-text has been renamed to 0=async-new-text-old, and it is now considered obsolete. Clients should use 80=accept-async to listen to 15=async-new-text instead. @item New Asynchronous Messages @itemize @bullet @item 14=async-deleted-text @item 15=async-new-text @item 16=async-new-recipient @item 17=async-sub-recipient @item 18=async-new-membership @end itemize @item Notes @itemize @bullet @item Since protocol version 9 setting a priority of zero for a conference was supposed to indicate passive membership in a conference. It was largely up to the client to implement this. True passive memberships have been introduced in this protocol version through the Membership-type extension to the Membership type. In order to maintain compatibility with clients that interpret priority 0 as passive membership, the old calls @reqlink{add-member-old} and @reqlink{get-membership-old} perform magic, translating between priorities and membership types. The magic is documented with each call. @end itemize @end table @section Protocol version 9 (first implemented in lyskomd 1.9.0) @table @asis @item New functionality @itemize @bullet @item The server shall now reply with error @errorcode{not-implemented} when a client attempts to use an unimplemented call. This feature requires that the client uses linefeed as call terminator. @end itemize @item Added Commands @itemize @bullet @item 79=set-info: Can change server information. @item 80=accept-async: Can select asynchronous messages to receive. @item 81=query-async: Can query which messages are being send. @item 82=user-active @item 83=who-is-on-dynamic @item 84=get-static-session-info @end itemize @item Changed names @itemize @bullet @item @req{change-conference} was previously called @code{pepsi}. The name was changed, but not the functionality. @end itemize @item Status change @itemize @bullet @item 63=@req{who-is-on-ident} is now considered obsolete. @item 64=@req{get-session-info-ident} is now considered obsolete. @end itemize @end table @section Protocol version 8 (first implemented in lyskomd 1.8.0) @table @asis @item Added Functionality @itemize @bullet @item 30=add-recipient: Can change @misc{recpt} to @misc{cc-recpt} and vice versa. @item 21=set-conf-type: Accepts @type{Conf-Type} and @type{Extended-Conf-Type}. @item 10=create-conf: Accepts @type{Conf-Type} and @type{Extended-Conf-Type}. @end itemize @item New Commands @itemize @bullet @item 77=set-last-read @item 78=get-uconf-stat @end itemize @end table @section Protocol version 7 (first implemented in lyskomd 1.7.0) @table @asis @item Added Functionality @itemize @bullet @item 53=send-message: Recipient can be a conference or a person. @end itemize @item New Commands @itemize @bullet @item 74=re-z-lookup @item 75=get-version-info @item 76=lookup-z-name @end itemize @item Other @itemize @bullet @item The asynchronous message 1=i-am-off has been removed @end itemize @end table @section Protocol Version 6 (first implemented in lyskomd 1.4.0) @table @asis @item New Calls @itemize @bullet @item 67=lookup-person @item 68=lookup-conf @item 69=set-client-version @item 70=get-client-name @item 71=get-client-version @item 72=mark-text @item 73=unmark-text @end itemize @end table @section Protocol Version 5 (first implemented in lyskomd 1.3.0) @table @asis @item New Calls @itemize @bullet @item 65=re-lookup-person @item 66=re-lookup-conf @end itemize @end table @section Protocol Version 4 (first implemented in lyskomd 1.1.1) @table @asis @item New Calls @itemize @bullet @item 62=login @item 63=who-is-on-ident @item 64=get-session-info-ident @end itemize @end table @section Protocol Version 3 (first implemented in lyskomd 1.1.0) @table @asis @item New Calls @itemize @bullet @item 61=find-previous-text-no @item 60=find-next-text-no @item 59=create-anonymous-text @item 58=get-last-text @end itemize @end table @section Protocol Version 2 (first implemented in lyskomd 0.30.0) @table @asis @item New Calls @itemize @bullet @item 57=set-user-area @end itemize @end table @section Protocol Version 1 (first implemented in lyskomd 0.29.2) @table @asis @item New Calls All calls from 0--56. @end table @node Document Edition History @appendix Document Edition History (informative) @table @asis @item 11.1: 2003-08-30 @emph{Modified aux-item:} @aux{mx-refuse-import} [35] now supports the value @code{html}. @xref{Aux-Item Types}. @emph{Previously undocumented stuff:} @xref{Garb}, for information about how the garb works. @emph{New appendix:} @xref{Extracted grammar}, for information about machine-readable grammars extracted from this specification. @emph{Typographic improvements:} The section heading of all asynchronous messages now contains the async number. @emph{Fixed errors:} In the info manual, the status codes in the menus of request and asynchronous messages were set to @samp{r} instead of @samp{O} for @req{who-is-on-ident}, @req{get-session-info-ident} and @async{async-new-text-old}. Several section headings for obsolete requests was missing information about when the request became obsolete. Distributed with lyskomd 2.1.2. @item 11.0: 2003-08-24 @emph{New aux-items:} @aux{mx-refuse-import} [35]. @xref{Aux-Item Types}. @emph{New types:} @type{Read-Range} and @type{Membership} (the old @type{Membership} was renamed to @type{Membership-10}). @xref{Membership Information}. @type{Stats} and @type{Stats-Description}. @xref{Statistics}. @type{Static-Server-Info}. @xref{Server Information}. @type{FLOAT}. @xref{Simple Data Types}. @emph{Status change:} The @reqlink{query-read-texts-10} and @reqlink{get-membership-10} requests are now obsolete. The @reqlink{set-keep-commented} request is now recommended. @emph{New calls:} @itemize @bullet @item @reqlink{query-read-texts} @item @reqlink{get-membership} @item @reqlink{mark-as-unread} @item @reqlink{set-read-ranges} @item @reqlink{get-stats-description} @item @reqlink{get-stats} @item @reqlink{get-boottime-info} @item @reqlink{first-unused-conf-no} @item @reqlink{first-unused-text-no} @item @reqlink{find-next-conf-no} @item @reqlink{find-previous-conf-no} @item @reqlink{get-scheduling} @item @reqlink{set-scheduling} @item @reqlink{set-connection-time-format} @item @reqlink{local-to-global-reverse} @item @reqlink{map-created-texts-reverse} @end itemize @emph{New error codes:} @errorcode{invalid-range}, @errorcode{invalid-range-list}, @errorcode{priority-denied}, @errorcode{weight-denied}, @errorcode{weight-zero}, @errorcode{undefined-measurement} and @errorcode{bad-bool}. @emph{New async messages:} @itemize @bullet @item @asynclink{async-new-user-area} @item @asynclink{async-new-presentation} @item @asynclink{async-new-motd} @item @asynclink{async-text-aux-changed} @end itemize @emph{Protocol change:} Renamed the @code{reserved1} bit of @type{Membership-Type} to @field{passive-message-invert}. @xref{Membership Information}. This affects @asynclink{async-send-message} and @reqlink{send-message}. The following requests can no longer be used until you have logged in: @reqlink{get-last-text}, @reqlink{find-next-text-no} and @reqlink{find-previous-text-no}. You can now modify the type of a recipient with the @reqlink{add-recipient} call if you are the supervisor of either the author, recipient or sender. The check used to be more restrictive. Aux-item tags 10200-10299 are now reserved for private test use. @xref{Client-Specific Aux-Item Types}. The following asynchronous messages are also sent to recipients of texts linked to the relevant text via comment or footnote links: @asynclink{async-new-text-old}, @asynclink{async-deleted-text}, @asynclink{async-new-text}, @asynclink{async-new-recipient} and @asynclink{async-sub-recipient}. Two requests can now return more error codes than they used to: @table @asis @item @reqlink{add-comment} @errorcode{already-comment} and @errorcode{already-footnote}. @item @reqlink{add-footnote} @errorcode{already-comment}. @end table The field @code{later-texts-exists} in @type{Text-Mapping} has been renamed to @field{more-texts-exists}, as this name is more meaningful for the new requests @reqlink{local-to-global-reverse} and @reqlink{map-created-texts-reverse}. @emph{Fixed errors:} The description of the error @errorcode{index-out-of-range} was wrong for @reqlink{add-footnote},missing for @reqlink{create-person-old}, @reqlink{create-person}, @reqlink{create-conf-old}, @reqlink{create-conf} and @reqlink{create-text-old}, and incomplete for @reqlink{create-text}. @asynclink{async-leave-conf} is not sent when the person is deleted, so don't say that it is. Distributed with lyskomd 2.1.0. @item 10.7: 2002-11-03 @emph{Fixed errors:} The description of common block of the user area was just plain wrong. @xref{The User Area}, for the updated specification. The documentation for no-of-created-texts in the @type{Person} structure was wrong. @xref{Person}. The documentation for the privilege bits @priv{create-conf} and @priv{create-pers} stated that they are by default on. In fact, they are by default ignored, but off. @xref{Security}. The example for @reqlink{re-z-lookup} was wrong. An example for @reqlink{lookup-z-name} was wrong. @emph{Protocol change:} Added a new "language" value to the common block of the user area. @xref{The User Area}. @emph{New aux-items:} @aux{world-readable} [34]. @xref{Aux-Item Types}. @aux{elisp-client-read-faq} [10000] and @aux{elisp-client-rejected-recommendation} [10001]. @xref{Some Client-specific Aux-Item Types}. @emph{Modified aux-item:} @aux{send-comments-to} [33] may now also contain an optional recipient type. @xref{Aux-Item Types}. @emph{Previously undocumented stuff:} The rules for when a membership is visible are now documented. @xref{Membership visibility}. Documented the @field{unread-is-secret} flag of @type{Person}. @xref{Personal-Flags}. The documentation for @reqdlink{get-person-stat-old} was improved@linkhere{}. The Message-ID of exported texts is now documented. @xref{Message-ID}. A client should offer to add the author as a recipient of a text he is creating if he isn't a member of any of the recipients. @xref{Recipients of comments}. There should be no linefeed after the last line of a text. @xref{LysKOM Content Types}. @xref{Reformattable Text (text/x-kom-basic)}. Added a recommendation for how groups of @type{Misc-Info} items should be sorted. @xref{Order of misc-info groups}. @emph{Editorial changes:} Several spelling errors, typos, et c were fixed. Distributed with lyskomd 2.0.7. @item 10.6: 2002-03-29 @emph{Fixed errors:} The format of the user area was plain wrong. The examples for @req{query-read-texts-10} and @req{get-membership-10} were wrong. The @field{idle-time} field is only affected by the @req{user-active} request, not by all activity (@pxref{Session Information}). @emph{Protocol change:} Expanded the documentation of @field{super-conf}. @xref{Conference Status Types}. Simplified the rules for @field{super-conf}; a setting of 0 no longer means anything. A new section contains a summary of how a client should decide where to send a comment, and it contains the new rules. @ref{Recipients of comments}. Most clients already implemented the new rules; the old rules were overly complex. @emph{New aux-item:} @aux{send-comments-to} [33]. @emph{Modified aux-item:} @aux{faq-text} [14] may now be set on a letterbox. @emph{Previously undocumented stuff:} Expanded the documentation of @field{permitted-submitters}. @xref{set-permitted-submitters}. Clarify that a person is a supervisor of himself, except for the @req{set-supervisor} call; see @ref{Conferences}. Document the @priv{change-name} privilege bit; see @ref{Security}. Document that @field{last-login} is also updated on logout; see @ref{Person Status Types}. Clarify that the address part of @aux{redirect} [8] is a conference number. @emph{Compatibility info:} Mention that the elisp client used to enter texts as @samp{x-kom/text} instead of @samp{text/x-kom-basic}. @emph{Administrativia:} Updated ``Future changes'' (@pxref{Future changes}), and mention that we now use Bugzilla to keep track of bugs and feature requests. @emph{Editorial changes:} Added some of Texinfo markup and cross references. Several spelling errors, typos, et c were fixed. Distributed with lyskomd 2.0.6. @item 10.5: 2001-09-30 A new section (@pxref{Client-side name expansion}) in the informative Client Conventions appendix was written. Distributed with lyskomd 2.0.5. @item 10.4: 2001-05-24 @emph{Fixed errors:} Fixed the description of the @code{old-pwd} argument to @reqlink{set-passwd}. The content-type @samp{x-kom/basic} was renamed to @samp{text/x-kom-basic}. @emph{Previously undocumented stuff:} Documented several previously undocumented aspects of the protocol: the hello string used during connection establishment, the @code{items-to-delete} and @code{items-to-add} arguments of @req{modify-system-info}, the @code{type} argument of @req{add-member} (including the fact that the invitation membership flag is automatically set in some circumstances), that a client can issue many requests at once (and that the replies are sent back in order). @emph{New stuff:} Registered the "rkom" user-area block. @emph{New aux-items:} The following predefined aux-items were added: @aux{canonical-name} [31], @aux{mx-list-name} [32] @aux{mx-mime-belongs-to} [10100], @aux{mx-mime-part-in} [10101], @aux{mx-mime-misc} [10102], @aux{mx-envelope-sender} [10103] and @aux{mx-mime-file-name} [10104]. Those aux-items with a number higher than 10000 were previously documented in this document, but they now have the status of predefined aux-items. @emph{Editorial changes:} Lots of editorial changes needed to publish an online version on the web at @uref{http://www.lysator.liu.se/lyskom/protocol/}. Many minor syntax errors corrected, and much missing Texinfo markup added. The document now makes heavy use of Texinfo macros. Due to bugs in the current version of @file{texinfo.tex} this file cannot currently be typeset using @TeX{}. (All bugs are reported to the Texinfo maintainers.) @req{get-membership-old}, @req{get-membership-10} and @req{login} used to take an argument of type @code{BITSTRING(@var{a-single-field})}. The type has now been changed to @type{BOOL} instead, to simplify the description. The encoding of the protocol is unchanged. The indices are now joined into a single index. More terms have been added to it. Many sections of text were moved around to make it easier to find information. Some non-normative information was moved to appendices. Removed a few non-normative empty sections. This edition was published on the web; no lyskomd release was imminent when the edition was finished. Future editions will also be published on the web; most of them will likely be published at the same time as a lyskomd release is made. They will continue to be included in the lyskomd releases. @item 10.3: 2000-09-09 Several aux-items can be set on letterboxes and not only conferences. A few can now be set on the server. The @aux{allowed-content-type} and @aux{recommended-conf} aux-items were added. The @aux{mx-allow-filter} and @aux{mx-reject-forward} aux-items are marked obsolete. Text regarding mail import was improved, based on actual experience in writing an email importer. Reserved a range of aux-items for komimportmail. Several minor corrections and clarifications made. Distributed with lyskomd 2.0.4. @item 10.2: 1999-07-23 Some typos and other minor errors were fixed. Distributed with lyskomd 2.0.2. @item 10.1: 1999-07-12 Call @req{sub-comment} was incorrectly marked obsolete. This has been corrected. Regexps are case sensitive. The Info-Type enumeration was introduced in the description of the protocol. (Previous versions of the protocol had broken definitions of @req{add-recipient}, @async{async-new-recipient} and @async{async-sub-recipient}.) Distributed with lyskomd 2.0.1. @item 10.0: 1999-06-27 The specification was translated to English and converted to Texinfo by David Byers. Protocol version 10. Distributed with lyskomd 2.0.0. Note: this edition incorrectly marked the @req{sub-comment} call as obsolete, and stated that regexp lookup was case insensitive. Both statements were wrong, and has since been fixed. @item 9.0: 1996-08-04 Protocol version 9. Distributed with lyskomd 1.9.0. @item 8.0: 1995-11-10 Protocol version 8. Distributed with lyskomd 1.8.0. @item 7.1: 1995-01-08. Protocol and document revision history were added by Per Cederqvist. Outline mode was used to make the document more manageable. This version was distributed with lyskomd 1.7.1. @item 7.0: 1994-12-31. The first specification with a version number. All calls that had been added since 1991-06-25 were documented. Pell and Per Cederqvist did the deed. This version was distributed with lyskomd 1.7.0. @item 1993-05-19. Linus Tolke wrote comments for some calls that were without comments. @item 1992-07-06. Linus Tolke converted the document to ISO 8859-1. @item 1991-08-12. Per Cederqvist started using version control for documentation. @item 1991-06-25. Lars Aronsson documented the protocol that was in use at the time. @end table @node Index @unnumbered Index @printindex fn @bye Local Variables: sentence-end: "[.?!][]\"')}]*\\($\\| $\\|\t\\| \\)[ \t\n]*" sentence-end-double-space: t ispell-local-dictionary: "american" ispell-skip-region-alist: ((ispell-words-keyword forward-line) ("^@\\(end\\|syncodeindex\\|\\(un\\)?macro\\) .*$") ("^@\\(printindex\\|set\\) .*$") ("@\\(uref\\|value\\|badspell\\)\ {[^{}]*\\({[^{}]*}\\)?[^{}]*}") ("@[a-z]+[{ ]") ("@[a-z]+$") ("\input texinfo.*$") ("ispell-ignore" . "ispell-end-ignore") ("^Local Variables:$" . "^End:$")) End: @c LocalWords: ACS BITSTRING BNF BOOL BortaKOM CC CSCW Cederqvist Dekker liu @c LocalWords: Elisp HOLLERITHs INT JSK JySKom KOM LysKOM lysator Magnusson @c LocalWords: Padrone's PortaCOM PottaKOM QZ RFC RPC Stat TLS TZ Tolke FIXME @c LocalWords: UConference UTC WinKOM abbrev'd addr admin aronsson async aux @c LocalWords: bcc cc ciokwe comm compface conf confs dst elisp se IANA Stats @c LocalWords: exempel faq flg foo footn gazonk getmail guwal hakka hopi pell @c LocalWords: hostname html iconifies ident infos kajsa kom komimportmail om @c LocalWords: lage ldb letterbox letterboxes linefeed linus loc ludd luth db @c LocalWords: lyskom lyskomd markup misc motd msg mx nMessage nilkom nos ok @c LocalWords: passwd pepsi perm pers pgp pres priv procmail prot pwd ragge @c LocalWords: rec recpt ref regexp regexps rkom sans stat struct submitters @c LocalWords: sven svensson swascii sync synched synching texinfo tkom kent @c LocalWords: ttykom uconf undef unmark userid username val varg yoruba dont @c LocalWords: Nyheter davby Testconf com Unicode roadmap interoperability @c LocalWords: Bugzilla stats spam SpamAssassin DNS boottime fprintf IEC libc @c LocalWords: SRV bool utc txt lyskom-server-2.1.2/doc/lyskomd.texi0000664000015100472110000033344507723626576013177 \input texinfo @c $Id: lyskomd.texi,v 1.77 2003/08/29 10:39:23 ceder Exp $ @c %**start of header @setfilename lyskomd.info @include version.texi @settitle lyskomd @value{VERSION} Reference Manual @setchapternewpage odd @c %**end of header @iftex @parindent 0pt @begin tex \global\def\BB#1{\b{#1}} \global\def\II#1{\i{#1}} @end tex @end iftex @ifinfo @macro BB {text} '\text\' @end macro @macro II {text} /\text\/ @end macro @end ifinfo @ifinfo This is the reference manual for the lyskomd LysKOM server version @value{VERSION}. Copyright @copyright{} 1995-2003 Lysator ACS. Permission is granted to make and distribute verbatim copies of this specification provided the copyright notice and this permission notice are preserved on all copies. @end ifinfo @dircategory LysKOM @direntry * lyskomd: (lyskomd). lyskomd reference manual. @end direntry @titlepage @sp 10 @title lyskomd Reference Manual @sp 2 @subtitle Server version @value{VERSION} @sp 2 @author by the lyskomd developers @page @vskip 0pt plus 1filll Copyright @copyright{} 1995-2003 Lysator ACS Permission is granted to make and distribute verbatim copies of this document provided the copyright notice and this permission notice are preserved on all copies. Modified versions of this document may be redistributed with the added condition that all modifications not cleared with the LysKOM development group are clearly marked and that the entire modified work be redistributed under the same conditions as the original. Permission is granted to copy and distribute translations of this manual into another language under the same conditions as for modified versions. @end titlepage @ifinfo @node Top @top lyskomd lyskomd is a server for the LysKOM conferencing system. This info file documents version @value{VERSION} of lyskomd. @menu * Copying:: lyskomd is free software. * Overview:: Overview of LysKOM. * Installation:: How to install lyskomd. * Configuration:: How to configure lyskomd. * Running lyskomd:: How to run lyskomd. * Invoking updateLysKOM:: How to run updateLysKOM. * Invoking komrunning:: How to run komrunning. * Administration:: Administering a LysKOM server. * Bugs:: Known bugs in lyskomd. * DBCK Reference:: Checking and repairing the database. * splitkomdb:: How to backup the database. * Hacking:: Notes for server developers. * lyskomd Database Specification:: @end menu @end ifinfo @node Copying @chapter Copying lyskomd is free software. It is distributed under the Gnu General Public License version 2. The file COPYING in the top level of the distribution contains the text of the license. @node Overview @chapter Overview LysKOM is a conferencing system@footnote{Or in modern terms, enabling technology for Computer-Supported Cooperative Work (CSCW).}. Similar systems were QZ-KOM and PortaCOM@footnote{Also known as ``PottaKOM'' and ``BortaKOM''.}. The LysKOM system is copyrighted by Lysator Academic Computing Society and distributed under conditions of the GNU General Public License version 2. LysKOM and its documentation is provided ``as is'' without warranty of any kind. This reference manual documents version @value{VERSION} of the lyskomd LysKOM server. The lyskomd server is the work of several people. The main contributors have been Per Cederqvist @email{ceder@@lysator.liu.se}, Inge Wallin @email{inge@@lysator.liu.se}, Thomas Bellman @email{bellman@@lysator.liu.se}, David Byers @email{byers@@lysator.liu.se} and Peter Eriksson @email{pen@@lysator.liu.se}. @section History In 1990, Per Cederqvist @email{ceder@@lysator.liu.se} and Peter Eriksson @email{pen@@lysator.liu.se} and a few other persons started to write the server. It was operational in the summer of 1990, even though the members of Lysator discovered a thing called MUD. We started using RCS on 20 May 1991. The first release was made on 16 Sept 1991. Around that time we switched from RCS to CVS to handle our source code. @node Installation @chapter Installation Instructions for compiling and installing lyskomd are in the files @file{README} and @file{INSTALL}, located in the top level of the lyskomd distribution. Installation should be straightforward on most platforms. @node Configuration @chapter Configuration There are two configuration files for lyskomd. One defines the server options and the other defines aux-item types @ref{(protocol-a)The Aux-Item List,The Aux-Item List}. @menu * Server Configuration File:: The server configuration file. * Aux-Item Definition File:: The aux-item definition file. @end menu @node Server Configuration File @section Server Configuration File The server reads its configuration from a configuration file. The default configuration file is @file{/usr/lyskom/etc/config}. The location of the configuration file can be changed at run-time by supplying an argument to lyskomd. The configuration file is line oriented. Each line consists of a parameter name followed by a colon, and the value of the parameter. Empty lines and lines whose first non-blank character is a @samp{#} are ignored. @menu * Parameter Types:: Types of configuration parameters. * Parameters:: Valid configuration parameters. @end menu @node Parameter Types @subsection Parameter Types Every parameter has a type. The standard types are: @table @code @item bool The parameter can be true or false. Legal values are @code{on}, @code{true}, @code{yes} and @code{1} for true and @code{off}, @code{false}, @code{no} and @code{0} for false. @item locale-name The parameter is a locale name. The value must be a legal locale name of the system where lyskomd is running. @item path The parameter is a path name. The value must be a legal path on the system where lyskomd is running. Most paths you can specify can be either absolute paths (if they begin with a @samp{/}) or paths relative to the installation prefix which is specified at compile time and can be overridden by the @code{Prefix:} parameter in the configuration file. @item portname The parameter is a TCP/IP port. It can be a symbolic port name (traditionally looked up in @file{/etc/services}) or a port number. @item int The parameter is a number of some sort. It can be a conference number, text number or perhaps something else. @item double The parameter is a floating point number. Any syntax that the C function @code{strtod} accepts is OK. Examples of truly portable values: @samp{1} or @samp{1.3}. @item timeval The parameter is a time period. It consists of a floating point number (in the same format as for parameters of type @code{double}), optionally followed by optional whitespace and a suffix. If no suffix is specified, it defaults to the suffix mentioned in the description of the parameter. Valid suffixes includes: @itemize @item seconds @item second @item sec @item s @item minutes @item minute @item min @item hours @item hour @item h @item days @item day @item d @item milliseconds @item millisecond @item m @item microseconds @item microsecond @item u @end itemize @end table A few parameters have ad-hoc types, that are used for a single parameter. They are documented in the description of that parameter. @node Parameters @subsection Parameters @table @code @item Max conferences: @var{int} The maximum number of conferences possible in the server. This number must be larger than the number of conferences in the database. This parameter is required. There is no default. @item Max texts: @var{int} The maximum number of texts possible in the server. This number must be larger than the number of texts in the database. This parameter is required. There is no default. @item Locale: @var{string} Use @var{string} as the locale to run in. This parameter is only available om systems which support the @code{setlocale} call. If this parameter is not set, no call to @code{setlocale} will be made. The default is unset. @item Force ISO 8859-1: @var{bool} This option is provided for those with dysfunctional computers that cannot handle @code{setlocale} properly. If this is set, lyskomd will handle texts according to the ISO 8859-1 (latin1) alphabet. Default is off. @item Prefix: @var{path} Specify the installation prefix. All relative filenames that the server uses are interpreted relative to this directory. The default value of this parameter is set at compile time. The default is @file{/usr/lyskom}, but it can be changed by the @samp{--prefix} argument of @samp{configure} at compile time. @item Send async: @var{bool} Do not send any non-requested messages. This disables the sending of messages about events in the server to all connections. Use of this parameter is not recommended. Default is on. @item Client host: @var{hostname} Specify which IP number the server should use when listening for new clients. @var{hostname} may be a FQDN (such as @samp{kom.lysator.liu.se}) or an IP number (such as @samp{10.0.0.1}). Default is to bind @code{INADDR_ANY}, which means that the server will listen to all IP numbers of the computer it is running on. @item Client port: @var{portname} Listen for new clients on port @var{portname}. The default is 4894, which is what all clients expect. Do not change this parameter without really good reason. @item Presentation of conferences: @var{int} The number of the conference where presentations should be sent. Defaults to 1. This option is ignored in lyskomd 1.9 and later. Set this using dbck or the @ref{(protocol-a)set-info,set-info}. @item Presentation of persons: @var{int} The number of the conference where presentations should be sent. Defaults to 2. This option is ignored in lyskomd 1.9 and later. Set this using dbck or the @ref{(protocol-a)set-info,set-info}. @item Motd-conference: @var{int} The number of the conference where "message-of-the-day" messages should be sent. Defaults to 3. This option is ignored in lyskomd 1.9 and later. Set this using dbck or the @ref{(protocol-a)set-info,set-info}. @item News-conference: @var{int} The number of the conference where news of interest to the readers of this LysKOM server should be written. This is typically a conference with very low traffic which everyone shoule be a member of. Clients should offer new users to join it. Defaults to 4. This option is ignored in lyskomd 1.9 and later. Set this using dbck or the @ref{(protocol-a)set-info,set-info}. @item Message of the day: @var{int} Default message-of-the-day of this server. The text will be shown automatically by conforming LysKOM clients when a user logs on. This option is ignored in lyskomd 1.9 and later. Set this using dbck or the @ref{(protocol-a)set-info,set-info}. @item Garb: @var{bool} Should the database be automatically purged of old texts? The default is on. @item Never save: @var{bool} Completely disables saving the database. Do not set this to @code{true} unless you really know what you're doing. The default is @code{false}. @item Log accesses: @var{path} This parameter can only be set if the server has been compiled with @code{LOGACCESSES} defined. It will save a trace of all activity in the database to a file, for later use in simulations et c. Compiling with @code{LOGACCESSES} slows the server down quite a lot, so it is normally not defined. @item Data file: @var{path} The path relative to the installation prefix@footnote{The installation prefix can be specified at compile time, and overridden by the @code{Prefix:} parameter.} where part of the database is kept. The default is @file{var/lyskomd/db/lyskomd-data}. @item Backup file: @var{path} The path relative to the installation prefix where a backup of the database is kept. This file will always contain a complete database, but it may be a little out-of-date. Default is @file{var/lyskomd/db/lyskomd-backup}. @item Backup file 2: @var{path} The path relative to the installation prefix where a previous generation of the backup of the database is kept. This file may be needed if an error in the backup file is detected during the creation of the data file. Default is @file{var/lyskomd/db/lyskomd-backup-prev}. @item Lock file: @var{path} Name of the lock file that ensures that @code{dbck} and @code{lyskomd} never attempt to modify the database at the same time. It should always reside in the same directory as the @samp{Data file}. Default is @file{var/lyskomd/db/lyskomd-lock}. @item Text file: @var{path} The path relative to the installation prefix where the actual texts in the database are kept. Default is @file{var/lyskomd/db/lyskomd-texts}. @item Text backup file: @var{path} When @code{dbck} is run with the @samp{-g} option (@ref{Invoking dbck}, it will store the previous contents of the text file in the file specified by this option. The path is relative to the installation prefix. This file is never used by @code{lyskomd} itself. Default is @file{var/lyskomd/db/lyskomd-texts-backup}. @item Backup export directory: @var{path} When @code{splitkomdb} is run, it will create a copy of the database in this directory. The copy will be split in a way that helps to keep incremental backups of that directory small. @xref{splitkomdb}. The path is relative to the directory specified by @code{Prefix:}. This directory is never used by @code{lyskomd} itself. Default is @file{var/lyskomd/exportdb}. @item Number file: @var{path} @itemx Number temp file: @var{path} Name of the file where the first unused conference and text numbers are stored. This file contains a single line. It is rewritten each time a new conference or text is created, to ensure that numbers are never reused even if the server later crashes before it has time to save the database. The information is first written to @code{Number temp file:}, and then renamed to @code{Number file:}. The path is relative to the installation prefix. Default is @file{var/lyskomd/db/number.txt} and @file{var/lyskomd/db/number.tmp}, respectively. Both files must reside on the same partition. @item Log file: @var{path} The path relative to the installation prefix where log messages from lyskomd are written. Default is @file{var/lyskomd.log}. @item Log statistics: @var{path} Whenever lyskomd receives a SIGUSR1 it will append a timestamp and a count of how many different atomic calls have been made in this file. The path is relative to the installation prefix. Default is @file{var/lyskomd.stats}. @item Pid file: @var{path} When lyskomd is up and running it will write its pid in this file. The path is relative to the installation prefix. This file is used so the @code{updateLysKOM} script can easily find out what pid the LysKOM server has. Default is @file{var/run/lyskomd.pid}. This file should be removed when the computer reboots, before @code{komrunning} or @code{updateLysKOM} is run. @item Memory usage file: @var{path} When lyskomd exits normally it appends some info on its usage of memory to this file. The path is relative to the installation prefix. Almost any memory leak bugs should be detectable by looking in this file. Default is @file{var/lyskomd.memory}. @item Aux-item definition file: @var{path} This file defines which aux-items the server should support and how it should handle them. You will find the details in @xref{Aux-Item Definition File}. The path is relative to the installation prefix. Default is @file{etc/aux-items.conf}. This file is re-read if a @samp{SIGWINCH} singal is sent to the server. @c FIXME (bug 1095): Remove the following warning when bug 1095 is @c fixed. @b{Warning:} If the aux-item definition file contains an error so that it cannot be parsed, the server will call @code{restart_kom()}, which will cause the server to abort without saving the database. Always test the file on a standby system first! @item Core directory: @var{path} The Directory where core dumps are written. This path is relative to the installation prefix. Default is @file{var/lyskomd.cores}. @item Connection status file: @var{path} @itemx Connection status temp file: @var{path} Where to store a status file that contains information about all connections. The status is written to the temp file and atomically renamed to the status file. The path is relative to the installation prefix. Defaults are @file{var/lyskomd.clients} and @file{var/lyskomd.clnt.tmp}. Both files must reside on the same file system. @xref{Files}, for information about the file format. @item Status file: @var{path} This file is created by @code{komrunning} to indicate that lyskomd should currently not be running. When this file exists @code{updateLysKOM} will send it a @samp{SIGTERM} signal, so that it saves the database and dies. Default is @file{var/lyskomd/db/status}. @item Nologin file: @var{path} If this file exists, the server will not allow any connections at all. Default is @file{/etc/nologin}. @item Garb busy postponement: @var{timeval} How often should the garb run when the server is busy serving clients? Default is once every @code{50 milliseconds}. @item Garb timeout: @var{timeval} How long to sleep when the server is garbage-collecting texts, and has nothing else important to do. Default is @code{0 milliseconds}. @item Sync timeout: @var{timeval} How long to sleep when lyskomd is saving its database. Defaults to @code{0 milliseconds}. @item Permissive sync: @var{bool} Turning this option on lets any session sync the LysKOM database. Turning it off restricts the operation to LysKOM administrators. Default is off. @item Garb interval: @var{timeval} How long to wait between each garb sweep. Defaults to @code{1440 minutes}, which means that 24 hours will pass between each garb sweep. @item Sync interval: @var{timeval} How long to wait between syncs. The current version of lyskomd keeps changes to the database in memory until they are synced to disk. This parameter specifies how long the server waits before attempting to dump the database. The default is @code{5 minutes}. @item Sync retry interval: @var{timeval} If anything goes wrong while trying to dump the data base (such as if the disk is full), lyskomd will wait for this long before trying again. Default is @code{1 minute}. @item Saved items per call: @var{int} When the server is saving the database, it does so in the background. It serves one call from a client, saves a few items to the new database file, serves another call, et c. This parameter sets the number of items (texts, conferences, persons) that are saved after each call. Default is @code{5}. @item Penalty per call: @var{int} Penalty points given to a client once a call is completed. This affects the scheduling. Default is @code{10}. @item Penalty per read: @var{int} Penalty points given to a client each time a @code{read(2)} is performed on the socket connected to the client. This affects the scheduling. Default is @code{1}. @item Max penalty: @var{int} Once a client receives this many penalty points, the server will stop reading from the socket connected to the client. (Once the server becomes idle, all penalty points will be aged, so the server will soon start reading from it again.) Default is @code{100}. @item Low penalty: @var{int} Once the penalty points for a client is reduced below this setting, the server will start reading from the client again. This should be lower than @code{Max penalty}. Default is @code{20}. @item Default priority: @var{int} @itemx Max priority: @var{int} The default and max scheduling priority of a client. Both values must currently be set to @code{0}, which is the default. @item Default weight: @var{int} @itemx Max weight: @var{int} The default and max scheduling weight for a client. Defaults to @code{20} and @code{100}. @item Connect timeout: @var{timeval} If the client doesn't send the initial handshake (such as @samp{A27Hceder@@stanly.lysator.liu.se}) within this time period, the client will be disconnected. Default is @code{30 seconds}. @item Login timeout: @var{timeval} @itemx Active timeout: @var{timeval} If nothing is sent to the client for this long, the client will be disconnected. Both asynchronous messages and replies to requests from the clients will reset the timer. The @samp{Login timout:} value is used while nobody is logged in on the session. Default is @code{30 minutes} and @code{11.5 days}, respectively. @item Max client data length: @var{int} The maxiumum allowed length for client name and version data. The default is @code{60}. @item Max conference name length: @var{int} The maximum length of conference names. The default is @code{60}. @item Max password length: @var{int} Only the first eight characters of the password are currently significant, even if this number is much larger. The default is @code{128}. @item Max what am I doing length: @var{int} The maximum length of the string permitted in the protocol A call @ref{(protocol-a)change-what-i-am-doing, change-what-i-am-doing}. The default is 60. @item Max username length: @var{int} The maximum length permitted for user names. Default is 128. @item Max text length: @var{int} The maximum length allowed for a text. The default is 131072 characters. @item Max aux_item length: @var{int} The maximum length allowed for a single aux-item. The default is 16384 characters. @item Max broadcast length: @var{int} The maximum length allowed for broadcast messges. The default is 1024 characters. @item Max regexp length: @var{int} The maximum length allowed for regexps in various calls. The default is 1024 characters. @item Statistic name length: @var{int} The maximum lenght allowed for the name of a measured statistics. The default is 64 characters. @item Max marks per person: @var{int} The maximum number of marks a person is allowed to have. The default is 2048. @item Max marks per text: @var{int} The maximum number of marks a text can have. The default is 1024. @item Max recipients per text: @var{int} The maximum number of recipients of a text. The default is 512. @item Max comments per text: @var{int} The maximum number of comments a text can have. The default is 128. @item Max footnotes per text: @var{int} The maximum number of footnotes a text can have. The default is 32. @item Max links per text: @var{int} The maximum number of misc info items that can be added to a text. @item Max mark_as_read chunks: @var{int} @c FIXME: What is this? @item Max super_conf loop: @var{int} @c FIXME: What is this? @item Max accept_async len: @var{int} Maximum length of list accepted in the accept_async call. Default is 128. @item Max aux_items deleted per call: @var{int} Maximum number of aux_items that can be deleted in one call. Default is 128. @item Max aux_items added per call: @var{int} Maximum number of aux_items that can be added at once. Default is 128. @item Max read_ranges per call: @var{int} Maximum number of read_ranges that can sent in a single request. Default is 512. @item Default garb nice: @var{int} Each conference has a lifetime for texts written in it. The lifetime is counted in days, and can be set for each conference by the administrator of the conference. This is the default value assigned to new conferences. Default is 77 days. @item Default keep commented nice: @var{int} A text will not be removed if it has comments newer than a certain number of days. This number can be set for each conference. This parameter specifies the default value for that number of days. The default is 77. @item Max client message size The maximum number of bytes that is read or written in a single system call. Defaults to 8176. (Attempts to set it to a larger value will currently only affect the input.) @item Max client transmit queue messages: @var{int} @itemx Max client transmit queue bytes: @var{int} Max number of pending data blocks (or total number of bytes) in the reply queue to a client. If there is ever more than this many data blocks in the queue the client will be disconnected. Each atomic question typically generates two data blocks. Default is 50 and 100000, respectively. @item Stale timeout: @var{timeval} If the transmit queue of a client is full for this long, without the server being able to send anything to the client, the client will be disconnected. Default is 60 minutes. @item Max simultaneous client replies: @var{int} This is a performance tuning parameter of little real interest. Default is 10. @item Open files: @var{int} Try to persuade the operating system to allow lyskomd to have this many open file descriptors simultaneously. Each client that is connected to the server occupies one file descriptor, and lyskomd needs several file descriptors for internal purposes. Default is to not use this parameter. @item Use DNS: @var{bool} The IP address of a client is looked up using DNS when it connects. Unfortunately, this lookup blocks the entire server, and it can take several minutes. You can disable DNS lookup with this parameter. Default is on. @item DNS log threshold: @var{double} If the @samp{Use DNS:} parameter is true, the server will measure the time each DNS lookup takes. If the time exceeds the specified threshold, an entry will be made in the log. The value is specified in seconds. The default value is 1.5 seconds. If your libc supports it, you can enter @code{+inf} to disable logging. @item Anyone can create new persons: @var{bool} If this is set, anyone can create a new person, even if he lacks special bits for doing so. Default is on. @item Anyone can create new conferences: @var{bool} If this is set, anyone can create a new conferences, even if he lacks special bits for doing so. Default is on. @item Allow creation of persons before login: @var{bool} If this is set, persons can connect the the server and create a new person without logging in. This is how new users register in open environments. If this option is off, then new persons can only be created by existing users. The default is on. @item Default change name capability: @var{bool} If this is set, new users are created with the ability to change their own name. Default is on. @item Ident-authentication: @var{policy} Decide how strictly the server should use the IDENT protocol. The policy can take any of three values: @table @asis @item @code{off} or @code{never} Do not use the IDENT protocol. @item @code{on} or @code{try} Use it, but allow logins even if the lookup fails. @item @code{require} or @code{required} Disallow connections if the server cannot find a IDENT login name. @end table @item Log login: @var{bool} Should logins be logged to the log file? Default value is off. @item Cache conference limit: @var{int} How many conference statuses the server cache should hold in main memory. Default is 20. This parameter should be set to at least the number of expected simultaneous logins. @item Cache person limit: @var{int} How many person statuses the server cache should hold in main memory. Default is 20. This parameter should be set to at least the number of expected simultaneous logins. @item Cache text_stat limit: @var{int} How many text statuses the server cache should hold in main memory. The default is 20. This parameter should be increased on busy servers. @item Echo: @var{string} Write @var{string} in the log when the config file is read. @item Jubel: @var{pers_no} @var{text_no} @itemx Jubel: public @var{pers_no} @var{text_no} States that @var{pers_no} is not allowed to create text number @var{text_no}. Default is unset. This parameter may be used multiple times. The form with the string @code{public} means that the text must have a public conference as recipient. @item Jubel: @var{pers_no} @var{dividend} @var{remainder} @item Jubel: public @var{pers_no} @var{dividend} @var{remainder} States that @var{pers_no} is not allowed to create any text number @var{T} which meets the condition @var{T} % @var{dividend} == @var{remainder}. Default is unset. This parameter may be used multiple times. The form with the string @code{public} means that the text must have a public conference as recipient. @item Add members by invitation: @var{bool} If this is set, then adding others as members to a conference sets the invitation bit of the membership. If this is off, the membership bit is set to whatever the caller specifies. The default is on. @item Allow secret memberships: @var{bool} If this is set, then memberships may be secret. Otherwise any attempt to create a secret membership or change an existing membership to a secret membership will fail. The default is on. @item Allow reinvitations: @var{bool} If this is set, then it is possible to set the invitation bit of a membership even after it has been cleared. If it is not set, then the invitation bit of a conference type can only be set when the membership is created. It can be cleared at any time. The default is off. @item lyskomd path: @var{path} Path to the @code{lyskomd} binary. This is used by @code{updateLysKOM} to find the right program to run. Defaults to @file{sbin/lyskomd}. @item savecore path: @var{path} Path to the @code{savecore-lyskom} program. If a file named @file{core} exists in the directory specified with @code{Core directory} when @code{updateLysKOM} is about to start @code{lyskomd}, this program will be called first. It could, for instance, move the core file so that it is available for later debugging. The script supplied by the distribution does nothing. Defaults to @file{sbin/savecore-lyskom}. @item Normal shutdown time: @var{int} In a normal setup, @code{updateLysKOM} will be run from @code{cron} once every ten minutes or so. If it detects that it has taken @code{lyskomd} more than @var{int} minutes to shut down it will print a warning message. @item Mail after downtime: @var{int} @itemx Mail until downtime: @var{int} If @code{lyskomd} has been down for X minutes, where @code{Mail after downtime} <= X < @code{Mail until downtime}, @code{updateLysKOM} will send a mail message to the mail address found on the first line of the status file. Actually, it is the age of the status file (named with @code{Status file}) that is measured. The defaults are 60 and 120, respectively. @item sendmail path: @var{path} Path to the @code{sendmail}-compatible program that @code{updateLysKOM} should use to send mail. This program will be invoked with a @samp{-t} option via a @samp{popen()} call. It should accept an email header, a blank line, an email body, and a terminating line consisting of a single @samp{.} on standard input. The default is found at configure time. The special value @samp{:} means that no mail will ever be sent. @end table @node Aux-Item Definition File @section Aux-Item Definition File The default aux-item definition file should not be changed unless it is really necessary. The need to change the definitions will probably only arise at installations used for client or server development. The location of the aux-item definition file is specified by the @code{Aux-item definition file} option in the server configuration file. The default location is @file{/usr/lyskom/etc/aux-items.conf}. @subsection Syntax of the Aux-Item Definition File The aux-item definition file contains a sequence of aux-item definitions. Each definition specifies one type of predefined aux-item: its number, name, and properties. Empty lines and all characters from a # character to the end of the line are ignored. Each entry has the following format: @example tag : name (target, target, ... ) @{ field = value; field = value; ... @} @end example @var{tag} is an integer, the aux-item's tag. If a tag is defined more than once, the last definition is used. The @var{target}s specify what kind of objects aux-items with tag @var{tag} can be added to. Valid targets are: @table @code @item any Aux-items with the specified tag can be added to any object in the database. This is shorthand for @code{text,conference,letterbox,server}. @item text Aux-items with the specified tag can be added to texts. @item conference Aux-items with the specified tag can be added to conferences that are @emph{not} letterboxes. @item letterbox Aux-items with the specified tag can be added to conferences that are letterboxes. @item server Aux-items with the specified tag can be added to the server itself. @end table It is legal to add one of the keywords @code{create} or @code{modify} before any target except @code{server}. If @code{create} is specified, aux-items with the specified tag can only be added when an object is being created. They cannot be added later. If @code{modify} is specified, aux-items with the specified tag can only be added after an object has been created. They cannot be added when the object is being created. Each @var{field}/@var{value} pair specifies a property of aux-items with the specified tag. Most values are boolean or trillian. Legal values for either type are @code{true} and @code{false}. Boolean values have reasonable defaults; trillian values can be unset. @table @code @item author-only Boolean, default false. When true, only the author of a text or supervisor of a conference can create items with this tag. This has no effect on items placed on the system. @item supervisor-only Boolean, default false. When true, only the supervisors of the author or letterbox can create items with this tag. In all likelihood, the implementation of this flag is screwed up in version 2.0 of lyskomd. This has no effect on items placed on the system. @item system-only Boolean, default false. When true, only the server can initiate creation of items with this tag. This is normally used for items that are created automatically in response to events in the system. @item permanent Boolean, default false. When true, aux-items with this tag cannot be deleted once they have been created. (They will be deleted automatically when the object they are assigned to is deleted.) @item unique Boolean, default false. When true, there can only be one non-deleted item with this tag per creator. @item unique-data Boolean, default false. When true, there can only be one non-deleted item with this tag that contains the same data (regardless of who creates the item). @item owner-delete Boolean, default false. When true, the owner of the object that this aux-item is attached to can always delete the aux-item. For a text, the owner is defined as the supervisor(s) of the author of the text. For a conference, the owner is defined as the supervisor(s) of the conference. @item inherit-limit Integer, default 0. The maximum number of times items with this tag can be inherited, plus one. Zero means an unlimited number of times, one means no times, 2 means once and so forth. This number overrides the inherit-limit set by the client only if that number is higher than this one. @item inherit Trillian. When set, the inherit bit on new items with this tag is forced to the specified value. @item secret Trillian. When set, the secret bit on new items with this tag is forced to the specified value. @item hide-creator Trillian. When set, the hide-creator bit on new items with this tag is forced to the specified value. @item dont-garb Trillian. When set, the dont-garb bit on new items will be forced to the specified value. @item reserved-2 @item reserved-3 @item reserved-4 Trillian. When set, these flags force the values of the three reserved bits in the aux-item flags field. These should only be used by lyskomd developers, and then only very carefully. @item validate String or function, default none. When set to a string, this specifies a regexp that must match the data field in newly created items with this tag. If the regexp fails to match, then the item will not be created. The syntax for strings is essentially the same as the syntax used in C files. When set to a function, this specified a built-in validation function to call. The following validator functions are currently implemented: @table @code @item existing-readable-text Creation is only allowed if the item contains the number of an existing text that the item creator has permission to read. @end table @end table There are a few fields which specify actions the server is to take when something happens to aux-items with the specified tag. Each of these values is a function specification, the name of a trigger function defined in lyskomd. The syntax for functions is the name followed by an empty pair of parens. It is not possible to pass arguments to the functions yet. @table @code @item add-trigger Function to call when an item with the specified tag is added to an object. @item delete-trigger Function to call when an item with the specified tag is scheduled for deletion. @item undelete-trigger Function to call when an item with the specified tag scheduled for deletion is unscheduled. It should undo the effects of the delete trigger. @end table The following trigger functions are currently defined: @table @code @item mark-text Increase the mark count for the text the item refers to. The item must contain the number of a text. This trigger should be combined with the existing-readable-text validation function. @item unmark-text Decrease the mark count for the text the item refers to. The item must contain the number of a text. This trigger should be combined with the existing-readable-text validation function. @item link-faq Create a faq-for-conf item linked to a faq-text item. This trigger is used exclusively for faq-text items. The item must contain the number of a text. This trigger must be combined with the existing-readable-text validation function. @end table @node Running lyskomd @chapter Running lyskomd This section explains how to run lyskomd, the files it uses and how it can be controlled while running. @menu * Invoking lyskomd:: How to run lyskomd. * Signals:: How to control lyskomd with Unix signals. * Files:: Files used by lyskomd. @end menu @node Invoking lyskomd @section Invoking lyskomd @example lyskomd [-f] [-d] [@var{config-file}] @end example The option @samp{-d} adds one to the debug level. The amount of output on stderr/to the log file is increased for each time the option is specified on the command line. Using one @samp{-d} makes the process print a `>' for every timeout, a message for every person that is connecting or disconnecting and a message for every successful or unsuccessful communication to the process. The option @samp{-f} tells lyskomd to stay in forground mode, and not run in the background as a daemon. The output that is normally written to the log file is instead sent to stderr. The optional @var{config-file} argument can be used to specify the server configuration file. @xref{Server Configuration File}. @node Signals @section Signals It is possible to control some aspects of lyskomd using Unix signals. The following signals have special meaning to the server: @table @samp @item SIGTERM @itemx SIGHUP @itemx SIGINT Logs out all sessions, saves the database and exits normally. Use @samp{SIGTERM}; the other signals currently have the same functionality, but that may be changed in the future. @item SIGQUIT Saves the database and dump core. (This should only be used for debugging purposes.) @item SIGUSR1 Print statistics about how often different commands have been used since the process started. @item SIGUSR2 Forks a child that immediately dumps core. The main process just waits until the child is done and then continues. @item SIGWINCH Re-read the aux-item definition file. @c FIXME (bug 1095): Remove the following warning when bug 1095 is @c fixed. @b{Warning:} If the aux-item definition file contains an error so that it cannot be parsed, the server will call @code{restart_kom()}, which will cause the server to abort without saving the database. Always test the file on a standby system first! @end table @node Files @section Files Used by lyskomd All file names can be changed in the server configuration file. @xref{Parameters}. @table @file @item /usr/lyskom Default value of the @code{Prefix} parameter. The default of this value is set at compile time, but it can be changed in the server configuration file. @xref{Parameters}. @item @var{prefix}/var/lyskomd/db/lyskomd-data Half of the database: all status information. @item @var{prefix}/var/lyskomd/db/lyskomd-texts The other half of the database: the actual texts. @item @var{prefix}/var/lyskomd/db/lyskomd-backup A backup copy of @file{lyskomd-data}. Never, ever delete this file unless you know what you are doing, or you may lose the entire data base. Most of the time this is the only complete database file! @item @var{prefix}/var/lyskomd/db/number.txt Information about the highest used text- and conference numbers. In case of a crash, some objects may be lost. This file ensures that even if that happens, their numbers will not be reused. @item @var{prefix}/var/run/lyskomd.pid File with the pid of the lyskom-process. @item @var{prefix}/var/lyskomd.memory On normal exit, @code{lyskomd} will append some statistics to this file. It can be used for detecting memory leaks. @item @var{prefix}/etc/aux-items.conf This file contains definitions of the aux-items that the server should support. It is read by @code{lyskomd} at startup. @item @var{prefix}/var/lyskomd.clients A list of all currently connected clients, maintained by the server. The data about each client is collected on a single line: @itemize @bullet @item The file descriptor @item The session number @item @samp{1} if the handshake is OK, the reverse DNS has completed, and the IDENT lookup has completed. @samp{0} otherwise. @item The IP address of the client @item The port number of the client @end itemize In the following example, we see that file descriptor 437 is used by session 330978, and the connection is from 130.236.254.83:3156. @example 437 330978 130.236.254.83 3156 @end example @item /etc/nologin If this file exists, lyskomd will not allow anyone to connect to the server. This path can be set with the @code{Nologin file} parameter in the server configuration file. @end table @node Invoking updateLysKOM @chapter Invoking updateLysKOM @example updateLysKOM [-c @var{config-file}] [ -v ] [ -V ] @end example @code{updateLysKOM} determines if @code{lyskomd} should be running. It can start or stop @code{lyskomd} if needed. It uses the same configuration file as @code{lyskomd} (@pxref{Server Configuration File}). You can use @samp{-c @var{config-file}} to override the compiled-in default. Note, however, that this option is not passed along to @code{lyskomd} if @code{updateLysKOM} starts it, so the option should be used with extreme caution. @samp{-v} and @samp{-V} causes @code{updateLysKOM} to report its version number and exit. @code{updateLysKOM} is normally run from @code{cron}; @pxref{Administration}. @node Invoking komrunning @chapter Invoking komrunning @example komrunning [-c config-file] [start | stop] komrunning -v | -V @end example @code{komrunning}, when invoked with no arguments, reports whether @code{lyskomd} is currently running or not, and whether it should be running or not. @samp{komrunning start} attempts to start @code{lyskomd}. @samp{komrunning stop} attempts to stop @code{lyskomd}, and it will not return until the server has saved its database and exited. @code{komrunning} uses the same configuration file as @code{lyskomd} (@pxref{Server Configuration File}). You can use @samp{-c @var{config-file}} to override the compiled-in default. Note, however, that this option is not passed along to @code{updateLysKOM} if @code{komrunning} invokes it, so the option should be used with extreme caution. The @code{komrunning} can be installed in @file{/etc/init.d/}. Be careful, however, to ensure that the pid file is removed earlier during the boot sequence. @samp{-v} and @samp{-V} causes @code{komrunning} to report its version number and exit. @node Administration @chapter Administration The first thing you will have to do is to follow the instructions in the files @file{INSTALL} and @file{README}. This will set up the LysKOM system with a database containing a few necessary conferences and one person - the administrator. Once the LysKOM system is running, there is not much you will have to do to keep it that way. One thing to remember is that the current release of the server has an incomplete handling of garbage collection of the database. The database is split into two files, the information file and the text file. Newly written texts are concatenated to the text file and old texts are never removed. The information file contains information about conferences, users and where in the text file the texts are. This file is properly garbage collected, but not the text file. There is a program called @code{dbck} (Data Base Check) which is used to check the consistency of the LysKOM database. This program can also be used to shrink the text file. To do this, just type @samp{dbck -g}. @xref{DBCK Reference}. When @code{dbck} is to be run on the database, the LysKOM server @emph{must} be stopped, or unrepairable damage may result. See below for a description on how to stop the server. There is a program called @code{updateLysKOM} which is used to ensure continuous operation. This program should be run with certain intervals, for instance from @code{cron}. If the LysKOM server has died for some reason, @code{updateLysKOM} restarts it. If the server is still running properly, @code{updateLysKOM} sends a signal (@samp{SIGUSR1}) to it, which causes the server to write some statistics to a file named @file{var/lyskomd.stats} in the lyskom directory. Taking the server down cleanly can be done in two ways: through the use of the LysKOM protocol on a socket, preferably through the use of a suitable client, or by sending the signal @samp{SIGTERM} to it. This will cause the server to save the database and close all client connections. It will also create a file named @file{var/lyskomd.memory} in which the memory usage of the server is reported. To prevent @code{updateLysKOM} from restarting a server, create a file named @file{/usr/lyskom/var/lyskomd/db/status}. The file should contain a valid mail address on the first line. @code{updateLysKOM} will not restart the server as long as that file exists. In addition, if the file is between 1 and 2 hours old (configurable) an email will be sent to the mail address found in the file. If the file is older than that, an error message will be printed on stderr and @code{updateLysKOM} will exit with a non-zero exit status. cron is expected to deliver the error message to an operator. The shell script @code{komrunning} can be used to start and stop the LysKOM server. With no arguments, it will report the status. @example komrunning stop @end example will (attempt to) shut down the server, creating the file @file{/usr/lyskom/var/lyskomd/db/status}. If the user running @code{komrunning} doesn't have permission to send signals to @code{lyskomd} the actual shutdown will be delayed until the next time that @code{updateLysKOM} is run. @example komrunning start @end example will restart the server. The actual starting of the server will be done by @code{updateLysKOM} the next time it is run. @code{komrunning} only removes the @file{/usr/lyskom/var/lyskomd/db/status} file. @node Bugs @chapter Known Bugs @itemize @bullet @item lyskomd should re-read the config file when a @samp{SIGHUP} is received. @item The security policy is vague and the implementation is frayed at the edges. @item The choice of asynchronous messages is not very good. @item The server uses too much memory. @end itemize @c ====================================================================== @c ====================================================================== @c == == @c == DBCK REFERENCE == @c == == @c ====================================================================== @c ====================================================================== @node DBCK Reference @chapter DBCK Reference dbck is a program that can is used for minor database maintenance tasks and for repairing a corrupt lyskomd database. @menu * DBCK Overview:: Overview of dbck. * Invoking dbck:: How to run dbck. * DBCK Notes:: Notes about running dbck. * DBCK Files:: Files used by dbck. * DBCK Bugs:: Known bugs in dbck. @end menu @node DBCK Overview @section Overview The dbck program is used for minor maintenance of the LysKOM database and for repairing corrupt databases. In brief it performs the following functions: @itemize @bullet @item Compact the text file to remove deleted texts. @item Repair inconsistent membership information. @item Repair invalid recipients @item Repair inconsistent comment links @item Correct invalid local text numbers @item Correct invalid text maps @item Set special conferences @item Convert between database formats @end itemize @node Invoking dbck @section Invoking dbck The functionality of dbck is controlled through command-line switches. These are documented below. If @code{dbck} is invoked without any options it will read the database and report on its integrity. No files will be modified. @menu * General Options:: Controlling the overall behavior of dbck. * Database Repair Options:: Repairing errors in the LysKOM database. * Format Conversion Options:: Converting the database file to a new format. * Database Maintenance Options:: Options for database maintenance. * Reporting Options:: Options controlling status reports. @end menu @node General Options @subsection General Options These options control the general behavior of lyskomd. @table @asis @item @samp{-h} or @samp{--help} Give a usage message (which includes the version number and the compiled-in default location of the config file) and exit immediately. @item @samp{-v} or @samp{--verbose} Verbose mode. Report not only errors but the status of the database. @item @samp{-F} or @samp{--force-output} This option forces dbck to write the database file. Normally @code{dbck} will only write a new database file if changes have been made for some other reason. If you want to simply convert a database from one version to another, you will probably have to give this option. @end table @node Database Repair Options @subsection Database Repair Options The following options control database repair. @table @asis @item @samp{-i} or @samp{--interactive} Run interactively. If any inconsistency is found, a remedial cure will be suggested and the user must confirm the correction. @item @samp{-r} or @samp{--auto-repair} Repair simple errors without asking. @item @samp{-c} or @samp{--set-change-name} Consider it an error if the @code{change-name} capability of a person is not set. Due to a bug that capability was never set for newly created persons in release 1.6.1 of lyskomd. This option can be used to repair the damage. @end table @node Format Conversion Options @subsection Format Conversion Options dbck can be used to conver the LysKOM database from one storage format to another. This is necessary only when moving the database to a new server version. @table @asis @item @samp{-F} or @samp{--force-output} This option forces dbck to write the database file. Normally @code{dbck} will only write a new database file if changes have been made for some other reason. If you want to simply convert a database from one version to another, you will probably have to give this option. @item @samp{-o} or @samp{--output-version} This option is used to set the output version of the database. This option will normally be used in conjunction with the @samp{-F} option. Version 1.9 of @code{lyskomd} requires database version 1; version 2.0 requires database version 2. Versions of @code{lyskomd} prior to 1.9 requires database version 0. Note that information is irrevocably lost when converting from a higher to a lower database version. This options requires an argument: the output format version. @end table @node Database Maintenance Options @subsection Database Update Options dbck can be used to update certain aspects of the database that either were impossible to update in early versions of protocol A or that are inconvenient in all protocol versions. @table @asis @item @samp{-g} or @samp{--compact-text-mass} Do garbage collection on the texts part of the database. This removes all unreferenced texts from the database. @item @samp{-P} or @samp{--clear-password} Clear the password of a specified user. This option is silently ignored if the user does not exist. This option requires an argument: the ID of the person whose password is to be cleared. @item @samp{-G} or @samp{--grant-all} Grant all privileges to the specified user. This option is silently ignored if the user does not exist. This option requires an argument: the ID of the person who is to be granted all privileges. @item @samp{--pers-pres-conf} Set the person presentation conference of the server to the specified conference. Since version 1.9 of lyskomd the @code{set-info} call can be used to do this. @item @samp{--conf-pres-conf} Set the conference presentation conference of the server to the specified conference. Since version 1.9 of lyskomd the @code{set-info} call can be used to do this. @item @samp{--motd-conf} Set the message-of-the-day conference of the server to the specified conference. Since version 1.9 of lyskomd the @code{set-info} call can be used to do this. @item @samp{--kom-news-conf} Set the news-about-lyskom conference of the server to the specified conference. Since version 1.9 of lyskomd the @code{set-info} call can be used to do this. @item @samp{--motd-of-kom} Set the message of the day of the server to the specified text. Since version 1.9 of lyskomd the @code{set-info} call can be used to do this. @end table @node Reporting Options @subsection Reporting Options These options control reporting of information about the database. @table @asis @item @samp{-s} or @samp{--print-statistics} Gather statistics about the lengths of texts. A table containing the frequence of all lengths that are currently present is printed. @item @samp{-t} or @samp{--list-text-no} Print ``Checking @var{text-no}'' for every text that examined. @b{Warning:} This produces lots of output. @end table @node DBCK Notes @section Notes for DBCK The messages ``Conference @var{conf-no} has a bad Text-list. Starts with 0'' and ``Person @var{pers-no} has created @var{num} conferences, not @var{num} (as said in person-stat).'' are normal. If you get them when you specify the @samp{-g} option, let @code{dbck} repair them and run @samp{dbck -g} again. @node DBCK Files @section Files Used by dbck dbck uses the same files as @code{lyskomd} (@xref{(lyskomd)}.) All file names can be changed in the server configuration file. @xref{(lyskomd)Parameters}. @table @file @item /usr/lyskom Default value of @code{Prefix:}. The default of this value is set at compile time, but it can be changed in the server configuration file. @xref{(lyskomd)Parameters}. @item @var{prefix}/var/lyskomd/db/lyskomd-data Half of the database: all status information. @item @var{prefix}/var/lyskomd/db/lyskomd-texts The other half of the database: the actual texts. @item @var{prefix}/var/lyskomd/db/lyskomd-backup A backup copy of @file{lyskomd-data}. Never, ever delete this file unless you know what you are doing, or you may lose the entire data base. Most of the time this is the only complete database file! @end table @node DBCK Bugs @section Known Bugs @itemize @bullet @item Should have an unlock database option. @item Does not check that the data file and text file are consistent. @end itemize @c ====================================================================== @c ====================================================================== @c == == @c == SPLITKOMDB REFERENCE == @c == == @c ====================================================================== @c ====================================================================== @node splitkomdb @chapter Backups with splitkomdb The files created by @code{lyskomd} can become huge. They are more or less constantly modified, so if you do incremental backups the entire @code{lyskomd} database will be saved each time you perform a backup. The @code{splitkomdb} program improves the situation. @menu * splitkomdb basics:: How splitkomdb works. * Invoking splitkomdb:: splitkomdb reference. * splitkomdb example:: A typical setup of splitkomdb. * splitkomdb restore:: How to restore the database. @end menu @ifnottex @node splitkomdb basics @section splitkomdb theory of operation @end ifnottex The @code{splitkomdb} program attempts to split the current database in several files, some of which will not be modified the next time you run @code{splitkomdb}. An incremental backup will thus only have to save some of the files created by @code{splitkomdb}. @code{splitkomdb} can be run while @code{lyskomd} is running. It will use the last completely saved snapshot, and make a copy of it in the directory specified by the @code{Backup export directory:} parameter (default: @file{/usr/lyskom/var/lyskomd/exportdb/}). There are two recommended ways to make backups of a @code{lyskomd} database: @itemize @bullet @item Run @code{splitkomdb} before each backup, and instruct the backup program to backup @file{/usr/lyskom/var/lyskomd/exportdb}, but ignore @file{/usr/lyskom/db}. Run @samp{splitkomdb -f} before each full backup. @item Backup all the files in @file{/usr/lyskom/db}. @end itemize The first alternative needs more disk for the copy in @file{/usr/lyskom/var/lyskomd/exportdb} and is slightly more complex to set up; the second alternative saves the entire database each time you make a backup. @node Invoking splitkomdb @section Invoking splitkomdb @example splitkomdb [-c config-file] [-f] splitkomdb -v | -V @end example @code{splitkomdb} creates a splitted copy of the most recent database snapshot in the directory specified by the @code{Backup export directory:} parameter. If @samp{-v} or @samp{-V} is specified, @code{splitkomdb} prints its version number and exits. The @samp{-f} option is a hint to @code{splitkomdb} that the next backup will be a full backup. When this option is used, @code{splitkomdb} might rewrite all the output files in a way so that future invocations of @code{splitkomdb} will create a little incremental data as possible. The optional @var{config-file} argument can be used to specify the server configuration file. @xref{Server Configuration File}. @node splitkomdb example @section Typical splitkomdb setup A typical way to run @code{splitkomdb} is from @code{cron}. A @file{crontab} entry might look like this: @example 50 2 26 * * /sw/lyskom/bin/splitkomdb -f 10 3 * * * /sw/lyskom/bin/splitkomdb @end example This entry assumes that backups are started at 03:30. It gives @code{splitkomdb} 20 minutes to run. (That should be enough for most sites, but please check what is appropriate for your site.) Full backups are run on the 26th of each month. On those days, at 02:50, @samp{splitkomdb -f} is run. @node splitkomdb restore @section Restoring the database from splitkomdb The splitted format of the database is currently very simple: @table @file @item var/lyskomd/exportdb/lyskomd-texts-base.backup This file contains the first part of @code{Text file:} (default: @file{var/lyskomd/db/lyskomd-texts}). This file is created when the @samp{-f} option is given to @code{splitkomdb}. @item lyskomd-texts-tail.backup This file contains the rest of @code{Text file:}. It is always recreated when @code{splitkomdb} is run. @item lyskomd-data.backup This file contains a copy of @code{Data file:} (default: @file{var/lyskomd/db/lyskomd-data}). If @code{Data file:} file wasn't clean when @code{splitkomdb} was run, @code{Backup file:} (default: @file{var/lyskomd/db/lyskomd-backup}) will be copied instead. @end table This means that it is easy to restore the database from the splitted database. If you use the default paths, all you have to do is run these commands: @example $ cd /usr/lyskom/var/lyskomd/exportdb $ cat lyskomd-texts-base.backup \ > lyskomd-texts-tail.backup \ > > ../db/lyskomd-texts $ cp lyskomd-data.backup ../db/lyskomd-data @end example Future versions of @code{splitkomdb} may use a different format. It may even evolve into something so complex that you need a program to recreate the database. Always check the current documentation for information on how to restore the database. @c ====================================================================== @c ====================================================================== @c == == @c == LYSKOMD HACKING GUIDE == @c == == @c ====================================================================== @c ====================================================================== @node Hacking @chapter Hacking lyskomd @menu * The Database:: * Adding Configuration Parameters:: How to add configuration options. * Adding Asynchronous Messages:: Adding protocol A messages. * Adding a New Protocol Request:: Adding protocol A calls. * Adding New Input Types:: * Adding New Result Types:: * Modifying Output Types:: * Adding Aux-Item Types:: Adding predefined aux item types. * Modifying Stored Types:: Modifying types stored in the DB. * Notes:: Mixed notes. * Debugging and Testing:: How to test and debug the server. * local-to-global:: The Local_to_global structure. * Coding conventions:: Indentation style et c. @end menu @node The Database @section The Database This section is not translated to English yet. See a comment in the @file{lyskomd.texi} for the raw Swedish text. @c FIXME: ramkomd är död! Länge leve LysKOM! @c FIXME: @c FIXME: Jag har tillsammans med Inge kommit på ett sätt att dels få ner @c FIXME: väntetiden i samband med syncningar till <1 sekund, dels få ner @c FIXME: storleken på serverprocessen till mer rimliga nivåer. Denna lösning @c FIXME: lider dock av det stora problemet att den kräver dubbelt så mycket @c FIXME: diskutrymme som den egentligen behöver. Det gör även ramkomd, så det @c FIXME: är ingen försämring i det avseendet. Dock är detta bara en temporär @c FIXME: lösning i väntan på ldb. @c FIXME: @c FIXME: Varför spara allt på en gång? Varför inte spara en liten del av filen @c FIXME: i taget, och utföra några atomiska anrop mellan varje liten @c FIXME: delsynkning? Ungefär så tänkte jag när jag kom på följande schema för @c FIXME: hur man kan göra det hela bättre än det är nu. @c FIXME: @c FIXME: Den databas som ligger på fil är en ögonblickbild (snapshot) av det @c FIXME: som finns i LysKOM. Så är det i ramkomd; så blir det i diskomd. @c FIXME: (Bättre namn, någon? lyskomd tycker jag är reserverat för den version @c FIXME: som har en riktig cache&ldb.) I ramkomd skrivs allt ut på disk @c FIXME: samtidigt. I diskomd minns man bara vad som skall sparas, och sparar @c FIXME: bara en bit i taget. @c FIXME: @c FIXME: I ramkomd finns allt inne i ram-minnet (i teorin. I praktiken är det @c FIXME: mesta utswappat - något som märks varje gång det är dags att synca!). @c FIXME: I diskomd ligger det mesta på disk. I minnet finns dels det som har @c FIXME: använts nyligen, dels det som är ändrat och ännu ej syncat. Diskomd @c FIXME: har alltid minst en, ofta två, databasfiler öppna: @c FIXME: @c FIXME: Fil A Senaste kompletta fil. @c FIXME: Fil B Fil under uppbyggnad. @c FIXME FIXME: Fil Z Näst senast kompletta fil @c FIXME FIXME: (den här gick att kopiera en gång i @c FIXME FIXME: tiden, även om A inte går att kopiera @c FIXME FIXME: just nu.) @c FIXME: @c FIXME: (Dessutom textmassefilen, precis som ramkomd nuförtiden.) @c FIXME: @c FIXME: Så till detaljerna: @c FIXME: @c FIXME: Det finns tre typer av objekt som berörs av den här ändringen: @c FIXME: Text_stat, Person och Conference. Jag använder Person som ett exempel @c FIXME: nedan. @c FIXME: @c FIXME: I ram-cache.c finns en array @c FIXME: @c FIXME: Person *pers_arr[ MAX_CONF ]; @c FIXME: @c FIXME: Den byts mot @c FIXME: @c FIXME: Cache_node *pers_arr[ MAX_CONF ]; @c FIXME: @c FIXME: typedef struct cache_node @{ @c FIXME: Bool exists; @c FIXME: Bool exists_b; @c FIXME: Bool dirty; /* Är *ptr modifierad? */ @c FIXME: void *snap_shot; @c FIXME: void *ptr; @c FIXME: off_t pos; @c FIXME: off_t pos_b; @c FIXME: struct cache_node *lru_link; @c FIXME: int lock_cnt; @c FIXME: @} Cache_node; @c FIXME: @c FIXME: @c FIXME: @c FIXME: UPPSTART @c FIXME: @c FIXME: När servern startas scannar den igenom datafilen (fil A) och fyller i @c FIXME: fältet exists till TRUE/FALSE och pos till att peka på början av det @c FIXME: ställe i filen där data ligger. Övriga fält sätts till FALSE/NULL/0. @c FIXME: @c FIXME: @c FIXME: @c FIXME: CACHE_GET_PERSON @c FIXME: @c FIXME: När ovanliggande rutiner vill läsa en person händer följande: @c FIXME: @c FIXME: !exists Returnera NULL @c FIXME: ptr != NULL Lägg noden först i lru_link. Returnera ptr. @c FIXME: snap_shot != NULL Kopiera snap_shot till ptr. Lägg noden först i @c FIXME: lru_link. Returnera ptr. @c FIXME: annars Läs in från fil A, sätt ptr till den inlästa @c FIXME: structen, lägg noden först i lru_link, @c FIXME: returnera ptr. @c FIXME: @c FIXME: @c FIXME: MARK_PERSON_AS_CHANGED @c FIXME: @c FIXME: När något har ändrats sätts dirty-flaggan till TRUE. @c FIXME: @c FIXME: @c FIXME: CREATE_PERSON @c FIXME: @c FIXME: Sätt exists=TRUE, dirty=TRUE, ptr och lru. @c FIXME: @c FIXME: @c FIXME: DELETE_PERSON @c FIXME: @c FIXME: Sätt exists=FALSE. ptr=NULL. Troligtvis error om lock_cnt != 0. @c FIXME: @c FIXME: @c FIXME: @c FIXME: THROW-OUT @c FIXME: @c FIXME: För att inte diskomd ska bli för stor slängs saker ut ur cachen. @c FIXME: Algoritm: tag första elementet i lru_list. Om dirty==FALSE och @c FIXME: ptr!=NULL och lock_cnt==0 så frigör ptr. Upprepa tills antalet noder @c FIXME: med ptr!=NULL och dirty==FALSE är mindre än antalet "rena" @c FIXME: element man vill ha inne i minnet. (Smutsiga element slängs @c FIXME: aldrig ut.) @c FIXME: @c FIXME: @c FIXME: LOCK_PERSON @c FIXME: @c FIXME: Öka lock_cnt. @c FIXME: @c FIXME: @c FIXME: UNLOCK_PERSON @c FIXME: @c FIXME: Minska lock_cnt. @c FIXME: @c FIXME: @c FIXME: PRE-SYNC @c FIXME: @c FIXME: Utsparningen till fil sker i tre steg. Först sveper man över alla @c FIXME: Cache_noder. För alla som har dirty=TRUE gör man följande: @c FIXME: @c FIXME: if ( lock_cnt == 0 ) @{ @c FIXME: snap_shot = ptr; (Pekartilldelning, ej kopiering.) @c FIXME: ptr = NULL; @c FIXME: Ta bort ptr ur lru-kedjan. @c FIXME: @} else @{ @c FIXME: snap_shot = copy(ptr); @c FIXME: @} @c FIXME: @c FIXME: dirty = FALSE; @c FIXME: @c FIXME: För _alla_ noder görs dessutom följande: @c FIXME: @c FIXME: b_exists==exists; @c FIXME: @c FIXME: @c FIXME: SYNC @c FIXME: @c FIXME: Steg två utförs en liten bit i taget. Till exempel så skulle @c FIXME: man kunna spara en person efter varje atomiskt anrop, eller så. @c FIXME: @c FIXME: b_exists==FALSE? Sätt pos_b. Skriv "@@\n" till fil B. @c FIXME: Är snap_shot != NULL? Sätt pos_b. Skriv ut innehållet i snap_shot @c FIXME: till fil B. @c FIXME: dirty==FALSE && ptr!=NULL Skriv ut innehållet i ptr till fil B. @c FIXME: annars: Kopiera från fil A till fil B. (Eftersom man @c FIXME: vet både var blocket börjar och slutar kan @c FIXME: man kopiera blocket utan att bry sig om vad @c FIXME: som står i det -> väldigt lite CPU går åt). @c FIXME: @c FIXME: @c FIXME: @c FIXME: @c FIXME: POST-SYNC @c FIXME: @c FIXME: När alla Person:er har hanterats som i SYNC ovan är det dags för det @c FIXME: tredje steget. Då går man igenom alla Cache_node:er och gör följande: @c FIXME: @c FIXME: pos = pos_b; @c FIXME: file_b = FALSE; @c FIXME: free(snap_shot); @c FIXME: snap_shot = NULL; @c FIXME: @c FIXME: Fil B som man förut hade öppen för skrivning öppnar man i stället för @c FIXME: läsning som fil A. @c FIXME: @c FIXME: @c FIXME: @c FIXME: @c FIXME: ANMÄRKNINGAR @c FIXME: @c FIXME: Innehållet i snap_shot är alltid "smutsigt" jämfört med innehållet i @c FIXME: fil A. Det som snap_shot pekar på finns aldrig med i lru-kedjan. @c FIXME: @node Adding Configuration Parameters @section Adding Configuration Parameters Make sure that you really understand what you want to configure. Think it over again. Find a good, descriptive name for it. Decide what values the parameter can be set to. Integers? Booleans? Document the parameter in @file{lyskomd.texi}. Add a field to @code{struct kom_par} in @file{param.h}. Add it to @code{parameters[]} in @file{server-config.c}. See @file{conf-file.h} and maybe @file{conf-file.c} for information on this structure. Make sure that the parameter is used instead of any previous hard-coded value. Make sure that @code{dbck} can cope with it. @node Adding Asynchronous Messages @section Adding Asynchronous Messages @table @asis @item @file{async.h} Add the message in @code{enum async @{ @}}. Make sure that @code{ay_dummy_last} is one more than any other message. If the message is to be sent by default, which is @emph{not} recommended, place its number into @code{ASYNC_DEFAULT_MESSAGES}. @item @file{prot-a-send-async.c} @itemx @file{prot-a-send-async.h} Write a function that sends the message. This function is responsible for writing the message to a particular connection and for ensuring that the message is not sent to clients who do not want it. Make sure that the second argument to @code{async_header} really is the number of elements being sent. Arrays count as two elements: the item count and the elements. @item @file{send-async.c} @itemx @file{send-async.h} Write a function that sends the message to appropriate clients. This function is responsible for checking that async messages should be sent at all, for each client check if it allowed to see the message and ensure that the protocol specified by the connection is appropriate. The send function should either take a @code{struct connection *} as an argument and send the message to that connection, or loop over all connections. Most send functions take a connection pointer; the looping is dealt with elsewhere. @item @file{session.c} Add a case label for the @code{enum} in the large @code{switch} statement. @item Make sure that the message is sent in appropriate places. @item @file{testsuite/lyskomd.0/03.exp} A few tests will fail. Fix them. @item Document the message type in @file{Protocol-A.texi}. @item Write test cases for the new async message. @end table @menu * Function Templates for prot-a-send-async.c:: * Function Templates for send-async.c:: @end menu @node Function Templates for prot-a-send-async.c @subsection Function Templates for prot-a-send-async.c This is what a typical function in @file{prot-a-send-async.c} should look like. This function is responsible for checking that the client is accepting the message and writing the message itself to the connection. @example void prot_a_async_@var{something}(Connection *cptr, @var{parameters}) @{ ASYNC_CHECK_ACCEPT(cptr, ay_@var{something}); async_header(cptr, @var{num_tokens}, ay_@var{something}); /* Output the body of the message */ async_trailer(cptr); @} @end example @node Function Templates for send-async.c @subsection Function Templates for send-async.h This is what a typical function in @file{send-async.c} should look like. This function is responsible for sending the message to all connections that are appropriate, not sending it if the server is not supposed to send messages at all, and for checking that the protocol specified by the client is one the server knows. @example void async_@var{something}( @var{parameters} ) @{ Connection *cptr; Session_no i = 0; if (!param.send_async_messages) return; while ((i = traverse_connections(i)) != 0) @{ cptr = get_conn_by_number(i); switch(cptr->protocol) @{ case 0: /* No protocol specified yet */ break; case 'A': /* Check that connection is logged on. We might want to check other things here too, such as if the connection is allowed to see the message */ if (handshake_ok(cptr, 0)) prot_a_async_@var{something}(cptr, @var{parameters}); break; default: restart_kom("async_@var{something}(): bad protocol.\n"); break; @} @} @} @end example Template for a function that sends to a single connection: @example void async_@var{something}(struct connection *cptr, @var{parameters}) @{ if (!param.send_async_messages) return; switch(cptr->protocol) @{ case 0: /* No protocol specified yet */ break; case 'A': /* Check that connection is logged on. We might want to check other things here too, such as if the connection is allowed to see the message */ if (handshake_ok(cptr)) prot_a_async_@var{something}(cptr, @var{parameters}); break; default: restart_kom("async_@var{something}(): bad protocol.\n"); break; @} @} @end example @node Adding a New Protocol Request @section Adding a New Protocol Request Before doing anything, think again. Make sure that the protocol request is needed, is in line with the rest of the protocol, behaves the way people want it to, and that everyone involved agrees that it is a good idea. @enumerate @item Document the request in @file{Protocol-A.texi} @item Declare the function in @file{include/services.h} @item Declare the function @emph{last} in @file{server/fncdef.txt}. It should be given a call number one higher than the currently existing highest contiguous call number. @item If the function takes an input parameter of a new type, changes need to be made in several places. @xref{Adding New Input Types}. @item If the function takes too many parameters of type @code{num}, @code{string} or @code{c_string}, the definition of @code{Connection} in @file{server/connection.h} has to be changed. @item If the function has an output parameter of a new type, changes need to be made in several plaves. @xref{Adding New Result Types}. @item Write the function in a suitable place in the server directory. @item Write tests for the new function in @file{server/testsuite/lyskomd.0}. Write one file for testing the functionality. Write tests in @file{01.exp} (behavior when the client is not logged on) and @file{03.exp} (normal behavior.) @item Run the testsuite to make sure nothing old has been broken. @end enumerate Every request handler should call the @code{CHK_CONNECTION} macro before doing anything else. This ensures that the @code{active_connection} variable is non-NULL. The only time when this might not be the case is if the request handler is not called in response to a client request. This should never happen, but might if someone gets careless. If your function should not be available before the user is logged in, call the CHK_LOGIN macro after doing @code{CHK_CONNECTION}. Take care returning errors to the client. Previous versions of @samp{lyskomd} leaked secret information through error returns. For example, the following code leaks information: @example Success service(Conf_no conf_no, Text_no text_no) @{ Conference *conf_stat; Text_stat *text_stat; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_C_STAT(conf_stat, conf_no, FAILURE); GET_T_STAT(text_stat, text_no, FAILURE); if (!has_access(conf_no, active_connection, read_protected)) @{ err_stat = conf_no; kom_errno = KOM_UNDEF_CONF; return FAILURE; @} if (!text_read_access(active_connection, text_no, text_stat)) @{ err_stat = text_no; kom_errno = KOM_NO_SUCH_TEXT; return FAILURE; @} /* Permissions checked. Do the deed. */ return OK; @} @end example This request can be used to gain precise information on which conferences and texts exist in the system. If an unprivileged user makes a request for any conference and readable text, and the user receives a @samp{KOM_NO_SUCH_TEXT} error, the user can deduce that the conference exists, but is secret. If the user makes a request for a conference known to be secret and a text known not to be readable (either secret or deleted), and the user receives a @samp{KOM_UNDEF_CONF} error, the user can deduce that the text does exist. To avoid traps like these, do permission checks for objects immediately after attempting to get them from the database. See also: @itemize @bullet @item @ref{Adding New Input Types} @item @ref{Adding New Result Types} @item @ref{Modifying Output Types} @end itemize @node Adding New Input Types @section Adding New Input Types Changes need to be made in the following files: @table @file @item Protocol-A.texi Document the new type. @item server/call-switch.awk The new type has to be added to the cascaded ifs that translate the type name to code that points to the appropriate field in a @code{Connection} structure. @item server/prot-a-parse-arg-c.awk The new type has to be added to the cascaded ifs that create the argument list parser. @item server/connections.h The definition of @code{Connection} must be extended with a field where the parse value can be stored. Don't even think about trying to reuse an existing field. It's more trouble than it's worth. @item server/connection.c Free the contents of the field in @code{free_parsed}. @item server/prot-a.c Free the contents of the field in @code{prot_a_destruct}. @item server/internal-connections.c Initialize the contents of the field in @code{init_connection}. @item server/testsuite/lyskomd.0/29.exp Add test cases for disconnecting in the middle of the data type. This is important both for singletons and lists. @end table @node Adding New Result Types @section Adding New Result Types Changes need to be made in the following files: @table @file @item Protocol-A.texi Document the new type. @item server/prot-a.c Add a line in the @code{prot_a_reply} switch that calls the correct output function. @item server/connections.h Add the type in @code{enum res_type} and @code{union result_holder}. @item server/prot-a-output.c @itemx server/prot-a-output.h Write a function that outputs the new type to a connection. Use the existing functions as templates. @end table @node Modifying Output Types @section Modifying Output Types When you modify an existing type you have to rename the old version of the type since it will still be used in existing calls. The convention has previously been to rename @var{Something} to @var{Something}@samp{_old}, but the preferred method is to append an underscore and the protocol version in which the current version of the type was introduced. For example, if the type @samp{Gazonk} was introduced in protocol version 11, and a new version is to be introduced in protocol version 15, the current @samp{Gazonk} structure is renamed to @samp{Gazonk_11}. This is to avoid names like @samp{Something_older}, @samp{Something_oldest} and @samp{Something_Truly_Ancient}. Changes need to be made to the following files: @table @file @item Protocol-A.texi Document the new type in the appropriate section. Rename the existing type in the type documentation and in all calls that return it. Be thorough! @item fncdef.txt Rewrite all calls that use the modified type so they use the old version of the type. @item prot-a.c Modify the current line in @code{prot_a_reply} for the existing version of the type, and add a new line for the new version of the type. @item connections.h Modify the existing entry in @code{enum res_type} and @code{union result_holder}, if necessary. This should only be necessary if the server uses both a new and old type internally, which is not recommended. Add new entries for the new version of the type. @item prot-a-output.h @itemx prot-a-output.c Rename the existing output routing according to the new name of the type. Write a new output routine for the new version of the type. @item memory.c If there are functions for the type in @code{memory.c}, make sure that your new type is initialized, cleared and copied in an appropriate manner. @end table If the type you modify is stored in the database, make sure it gets saved properly. @xref{Modifying Stored Types}. @node Adding Aux-Item Types @section Adding Aux-Item Types @enumerate @item Document the new type in Protocol-A.texi @item Write a definition of the new type in @file{run-support/aux-items.conf}. @item Some tests in at least @file{server/testsuite/lyskomd.0/01.exp}, @file{server/testsuite/lyskomd.0/03.exp} and @file{server/testsuite/lyskomd.0/18.exp} will fail when new predefined aux-items are added. Fix the tests. @item Write test cases for the new aux-item. If the aux item can be set on a letterbox, do so in @file{server/testsuite/lyskomd.0/03.exp} where the comment containing @samp{AUXITEM} says to do so. More complex aux-items should have more tests written for them. @file{server/testsuite/lyskomd.0/20.exp} might provide some inspiration. @item If the new type requires add, delete or undelete triggers that do not already exist, declare the trigger functions in @file{aux-items.c} and add them to the @code{aux_item_triggers} array in the same file. @item If the new type is so complex that is cannot be fully defined in @file{aux-items.conf}, then add it to the @code{compiled_aux_items} array in @file{aux-items.c}. Note that this functionality has not been tested until someone actually adds one of these beasts, so watch your step. @end enumerate @node Modifying Stored Types @section Modifying Stored Types If you want to modify an existing type that is stored in the database, think again. Can the job be done with aux-items instead? Is it really necessary? Be very, very careful when doing this. You have to make sure that the type as sent in old calls and async messages is not changed in any way. You have to make sure that the type can be stored to and read from the database. @enumerate @item Document the changes in Protocol-A.texi if the change is visible in the protocol. @item Bump the database version number by one for the next release of the server. @item Write a function in @file{ram-output.c} to output the new format. Update all old functions in @file{ram-output.c} that are database version dependent so that they can deal with the new database format. @item Write a function in @file{ram-parse.c} to read the new format. Update all old functions in @file{ram-parse.c} that are database version dependent so that they can deal with the new database format. @item Set the default database format in @file{ram-parse.c} and @file{ram-output.c}. The variables to change are @code{input_format} and @file{output_format}, respectively. @item Don't forget to update the functions in @file{memory.c} @item Update dbck so that it can convert to the new format. @item Add as many test cases as are needed for the dbck conversion. @end enumerate @menu * Template for ram-output.c:: * Template for ram-parse.c:: @end menu @node Template for ram-output.c @subsection Template for ram-output.c For types that can be output in several different formats, use the following templates for them. You have to be able to output in all formats, or @code{dbck} will be unable to convert between formats. @example static void foutput_@var{something}_0(FILE *fp, @var{something} *o) @{ /* Output version 0 of @var{something} */ @} static void foutput_@var{something}_1(FILE *fp, @var{something} *o) @{ /* Output version 1 of @var{something} */ @} static void foutput_@var{something}_2(FILE *fp, @var{something} *o) @{ /* Output version 2 of @var{something} */ @} void foutput_@var{something}(FILE *fp, @var{something} *o) @{ switch(output_format) @{ case 0: foutput_@var{something}_0(fp, info); break; case 1: foutput_@var{something}_1(fp, info); break; case 2: foutput_@var{something}_2(fp, info); break; default: restart_kom("unknown database format: %d", output_format); break; @} @} @end example Note that if two versions are the same, only write one function. For example, if version 0 and version 1 are the same, only write an @code{foutput_@var{something}_0} function and call it from both case 0 and case 1. @node Template for ram-parse.c @subsection Template for ram-parse.c @example static Success fparse_@var{something}_0(FILE *fp, @var{something} *o) @{ /* Parse version 0 */ return OK; @} static Success fparse_@var{something}_1(FILE *fp, @var{something} *o) @{ /* Parse verson 1 */ return OK; @} static Success fparse_@var{something}_2(FILE *fp, @var{something} *o) @{ /* Parse verson 2 */ return OK; @} extern Success fparse_@var{something}(FILE *fp, @var{something} *o) @{ if ( fparse_long_errors != 0 ) @{ log("fparse_@var{something}(): fparse_long_errors == %d on entry." " Reset.\n", fparse_long_errors); fparse_long_errors = 0; @} switch (input_format) @{ case 0: return fparse_@var{something}_0(fp, o); break; case 1: return fparse_@var{something}_1(fp, o); break; case 2: return fparse_@var{something}_2(fp, o); break; default: restart_kom("unknown input format: %d\n", input_format); return FAILURE; break; @} @} @end example Note that if two versions are the same, only write one function. For example, if version 0 and version 1 are the same, only write an @code{fparse_@var{something}_0} function and call it from both case 0 and case 1. @node Notes @section Hacking Notes @menu * Parsing Bit Fields:: How to parse bit fields properly. * Membership Notes:: How members and memberships are handled. * Linking Pairs of Aux Items:: How to link pairs of aux items. * Notes for fncdef.txt:: Format of the fncdef.txt file. * Traversing Connections:: How to traverse connections in lyskomd. @end menu @node Parsing Bit Fields @subsection Parsing Bit Fields The parser for a bit field parameter type should be very tolerant of the length of the token. Anything from a single bit and up should be permitted. The parser should use default values for bits that are not provided and ignore extra bits. Here is a model function: @example void prot_a_parse_bitfield(Connection *client, Bitfield *res) @{ String token; String_size len; token = prot_a_get_token(client); len = s_strlen(token); if (len <= 0) longjmp(parse_env, ISC_PROTOCOL_ERR); init_bitfield(res); switch (len = s_strlen(token)) @{ default: case 8: res->bit_8 = token.string[7]; case 7: res->bit_7 = token.string[6]; case 6: res->bit_6 = token.string[5]; case 5: res->bit_5 = token.string[4]; case 4: res->bit_4 = token.string[3]; case 3: res->bit_3 = token.string[2]; case 2: res->bit_2 = token.string[1]; case 1: res->bit_1 = token.string[0]; @} @} @end example The function gets the token, checks the sanity of the length, then initialized the result to its default values. Then it does a switch on all token lengths that are equal to or smaller than the number of bits the server knows about. The fall-through ensures that all bits in the token are read. @node Membership Notes @subsection Membership Notes The @code{position} field in the membership is @emph{not} stored. It has to be set every time a membership is requested for transmission to the client. @node Linking Pairs of Aux Items @subsection Linking Pairs of Aux Items Sometimes two aux items need to work in tandem. The first instance of this was the FAQ and FAQ-for-conference items. The FAQ item contains the text number of a text that is a FAQ for a conference. The FAQ-for-conference item contains the conference for which a text is a FAQ. This is needed so that deletion of the text properly removes the aux-item on the conf (plus, it's nice to be able to see that a text is a FAQ.) The @code{linked_item} field in the Aux_item structure is for linking items. The linking must be managed through the use of triggers. This field is not visible in the protocol. It is saved in the database. It is not possible to have more than one link per item. Please remember the following points. @itemize @bullet @item The target of a link should have a link back. All links need to go both ways. @item In the add trigger for one end, create the other end of the link and set the @code{linked_item} field in both items. Don't forget to mark the objects at both ends as changed. @item Deletion and undeletion of the other side of the link will be managed automatically. You don't need delete and undelete triggers simply to destroy the other side of a link. @item Don't kill the server because one end is missing. It is possible for the administrator to remove an item manually. Log a message and continue working. @end itemize @node Notes for fncdef.txt @subsection Notes for fncdef.txt The fncdef.txt file is used to define the RPC functions. Each line consists of the call number, the return type of the call, the parameters and the output types of the call. Some examples: @example 10 number create_conf_old c_string (param.conf_name_len) conf_type 12 success lookup_name c_string (param.conf_name_len) : conf_list @end example The first line defines a call named @code{create_conf_old} that takes two arguments, a string that can only be as long as @code{param.conf_name_len} and a @code{conf_type}. It returns a number to the client. If the service call returns -1, the server will return an error. The @code{create_conf_old} call has RPC number 10. The second line defines a call named @code{lookup_name} that takes a string argument that can be no longer than @code{param.conf_name_len}, and returns a @code{conf_list}. The service call returns a @code{Success}. If it does not return @code{OK}, the server will return an error. The @code{lookup_name} call has RPC number 12. @subsubsection Scripts That Use fncdef.txt The following scripts operate on @file{fncdef.txt}. If you make modifications to the format of @file{fncdef.txt}, you have to update these scripts. @table @file @item call-switch.awk Generates @file{call-switch.incl}, which is included by @file{connections.c} @item com-h.awk Generates @file{com.h}, which is included by several files. @item fnc-def-init.awk Generates @file{fnc-def-init.incl}, which is included by @file{connections.c}. @item prot-a-is-legal-fnc.awk Generates @file{prot-a-is-legal-fnc.incl}, which is included by @file{prot-a.c} @item prot-a-parse-arg-c.awk @itemx prot-a-parse-arg-h.awk Generates @file{prot-a-parse-arg.c} and @file{prot-a-parse-arg.h}. @end table @node Traversing Connections @subsection Traversing Connections Since session 0 is interpreted as the currently active session by get_conn_by_number it is important to be careful when traversing sessions. Code like this does not work since it will do one iteration through the loop with @code{sess} set to zero. This formerly caused @code{get_conn_by_number} to return @code{NULL}, but now causes it to return the session pointer for the current session. @example for (sess = 0; (sess = traverse_connections(sess)) != 0; ) @{ cptr = get_conn_by_number(sess); ... @} @end example The canonical traversal code looks like this: @example Session_no session = 0; while ((session = traverse_connections(session)) != 0) @{ cptr = get_conn_by_number(session); if (handshake_ok(cptr, 0)) /* can sometimes be skipped */ @{ ... @} @} @end example This code has @code{session} set to a session number before ever entering the loop. @node Debugging and Testing @section Debugging and Testing We're slowly adding support for debugging and testing lyskomd properly. @menu * The Test Suite:: The lyskomd regression test suite. * Configuration Options:: Debugging options for the configure script. * Coverage Testing:: How to do coverage testing with gcov. * Debug Calls:: Special protocol A calls for testing. @end menu @node The Test Suite @subsection The Test Suite The lyskomd test suite is in src/server/testsuite. Please extend this with additional test cases every time you make modifications to the server. Run the test suite often to make sure that your changes did not break anything. The file config/prot-a.exp contains some support for protocol A. Don't use these functions in test cases. Use them to set up the inital database and for things that have to be done, such as logins and enabling privileges, but that don't need to be tested. Also, don't count on all the code in prot-a.exp to be fully functional. Add new functions to this file as you see fit. The basic structure of a test case is the following: @example source "config/prot-a.exp" read_versions lyskomd_start client_start 0 talk_to client 0 kom_connect "DejaGnu test suite" @i{The test cases} talk_to client 0 kom_logout kom_login 5 [holl "gazonk"] 0 kom_enable 255 send "9999 44 0\n" simple_expect "=9999" client_death 0 lyskomd_death @end example Use the existing test cases as templates. @node Configuration Options @subsection Configuration Options There are several testing and debugging-related configuration options for lyskomd. Some of them also apply to libisc. @table @samp @item --with-purify Build lyskomd with Purify. This currently does not work. @item --with-efence Build lyskomd with Electric Fence for checking buffer overruns. This option does work. @item --with-checker Build lyskomd with Gnu Checker for checking memory accesses, leaks, file descriptors and all kinds of stuff. As of Checker version 0.99.6, Gnu Checker cannot deal with lyskomd. Once built, and this requires modifications to Checker (at least on Linux) it reports spurious errors. Still, the option is here for those who want to try it out. @item --with-gcov Build lyskomd with instrumentation for @code{gcov}. You have to use this option if you want to run @code{gcov} on lyskomd. For @code{gcov} to be effective, you should turn off optimization as well. @item --with-traced-allocations There is some builtin support for detecting memory leaks in lyskomd. Whenever the server exits normally it reports how much memory it still uses to @file{var/lyskomd.memory}. The count should always be 0. If there is a leak you can use this option to trace it down. See @file{src/server/ram-smalloc.c} for more information. You need gdb and a lot of time to use this option. @item --with-optimization=@var{value} Build lyskomd with the specified level of optimization. Use either numeric values to select the level of optimization, or say @samp{--with-optimization=no} or @samp{--without-optimization} to turn optimization off. @end table @node Coverage Testing @subsection Coverage Testing When you write new code, make sure that it is completely covered by the test suite. Run the lyskomd configure script with the @samp{--with-gcov}, @samp{--with-debug-calls} and @samp{--without-optimization} flags to instrument the server for coverage testing with gcov. If you run configure without the @samp{--without-optimization} option, the server will be compiled with optimizations on. This is fine, but the coverage data from gcov isn't completely reliable since parts of the program may have been optimized out of existance. Recompile everything, then run the test suite. Next do @samp{gcov -f @var{filename}} to compute coverage information for the file @var{filename}. The resulting file @var{filename}@samp{.gcov} shows which lines have been executed, and which haven't been run. Try to get 100% coverage. @node Debug Calls @subsection Debug Calls Run the configure script with @samp{--with-debug-calls} to compile in support for debugging calls in the server. These calls are strictly for making testing easier (or possible.) They are not official, and they may change at any time. @menu * memory-info:: Get information from malloc (1000) * set-marks:: Set the number of marks on a text (1001) * backdate-text:: Change the creation date of a text (1002) @end menu @node memory-info @subsubsection memory-info (DEBUG) Experimential @findex memory-info @example memory-info [1000] ( ) -> (( arena : INT32; ordblks : INT32; smblks : INT32; hblks : INT32; hblkhd : INT32; usmblks : INT32; fsmblks : INT32; uordblks : INT32; fordblks : INT32; keepcost : INT32; )); @end example This call returns the data returned by @code{mallinfo} in the server. See the man page for @code{mallinfo} for explanations of the fields. @node set-marks @subsubsection set-marks (DEBUG) Experimental @findex set-marks @example set-marks [1001] (( text-no : Text_no; no-of-marks : INT32; )) -> ( ); @end example Set the number of marks on text @code{text-no} to @code{no-of-marks}, regardless of how many marks it really has. This call is useful for forcing the database into a state where the number of marks is incorrect in some way. @node backdate-text @subsubsection backdate-text (DEBUG) Experimental @findex backdate-text @example backdate-text [1002] (( text-no : Text_no; seconds : INT32; )) -> ( ); @end example Backdate a text in the server. Change the creation date of text @code{text-no} so it appears to have been created @code{seconds} earlier than it was actually created. This can be used to test the garbage collector. @node local-to-global @section The local-to-global structure The data structure that stores the mapping from local to global text numbers is currently one of the more advanced structures used by lyskomd. This section is not translated to English yet. See a comment in the @file{lyskomd.texi} for the raw Swedish text. @ignore @c FIXME: Translate this @subsection Background The Det sätt som textnummer läggs till har ett antal egenskaper: - Texter läggs hela tiden på bakifrån, aldrig i mitten eller i början. - Numren på de lokala textnumren är konsekutiva, dvs inga hål finns. Sådana hål kan dock uppstå (och uppstår!) när texter tas bort. Lösning ======= Det första man ser när man analyserar innehållet i en mapp, är att det finns långa avsnitt av idel nollor, och långa avsnitt där det inte finns några nollor alls, eller åtminstone väldigt få. Detta antyder alltså att man bör ha en adaptiv datastruktur som anpassar sig till det lokala förhållanden. Vi föreslår alltså följande. Mappen lagras i block (små arrayer). Det finns två sorters block: 1. Glesa block. Glesa block består egentligen av två block. I det ena blocket ligger nycklar (Local_text_no) och i det andra blocket ligger data (Text_no). Inom ett block använder man binärsökning i det ena blocket för att hitta just den Local_text_no man är ute efter. 2. Täta block. Täta block består av ett enda block som innehåller data (Text_no). Man vet vilket lokalt textnummer det första entryt svarar mot. Det kan finnas enstaka lokala nummer i ett tätt block som inte finns -- då innehåller data 0. Blockstorleken är fixerad till t ex 100 entries. (Det verkar som om man tjänar nästan exakt samma antal bytes oavsett om man väljer blockstorlek 50 eller 1000). Ett fullt tätt block innehåller alltid exakt 100 lokala textnummer. Ett fullt glest block innehåller alltid 100 existerande globala textnummer. (Ett glest block tar dubbelt så mycket plats som ett tätt block, eftersom ett glest block ju egentligen består av både ett nyckelblock och ett värdeblock). För att hålla reda på sina block har man en array av block_info: typedef struct block_info { int first_free; int zeroes; Local_text_no start; Local_text_no * key_block; Text_no * value_block; } L2g_block_info; Om key_block == NULL så är det ett tätt block. first_free Fältet first_free visar var i blocket som man kan fylla på med fler värden. Det är 100 för fulla block. För block som inte är fulla pekar det ut det entry i value_block som nästa värde ska hamna i. Det gäller t ex det sista blocket, som fylls på allt eftersom nya inlägg skickas till mötet eller block där texter har tagits bort. zeroes Fältet zeroes används bara för täta block, och räknar antalet nollor i blocket. Om zeroes blir större än 50% av blockstorleken gör man om blocket till ett glest block. Fältet zeroes är en optimering som troligtvis underlättar ihopslagning av block. Det är möjligt att den inte behövs. start Fältet start innehåller numret på det första lokala textnumret i blocket. key_block Fältet key_block är en pekare till blocket med Local_text_no, dvs nycklarna i blocket. Detta fält är NULL om detta är ett tätt block. value_block Fältet value_block är en pekare till blocket med Text_no, dvs värdena i blocket. Förutom detta behövs en struct per möte som håller reda på arrayen med block: typedef struct local_to_global { int num_blocks; int block_size; L2g_block_info * blocks; } Local_to_global; @end ignore @node Coding conventions @section Coding conventions When I write this chapter, lyskomd is over 13 years old. It shows. The code looks differently. Here are a few notes on the coding style that is preferred. When you make a substantial change in a function, please update it to this style as well. @itemize @bullet @item Keep lines to at most 79 characters. (Exception: the DejaGNU test scripts can be as long as you like. Proper TCL quoting is a bigger nuisance than overly long lines.) @item Don't make invisible whitespace changes: don't change tab to space or vice versa, don't add or remove trailing whitespace. It makes the output of @samp{cvs diff} harder to read. @item Document the public API of a function in the @file{.h} file, not the @file{.c} file. @item Don't use @samp{Bool} to return a failure indication. Use @samp{Success} instead. That type has two values: @samp{OK} and @samp{FAILURE}. They cannot be mistaken, but it isn't obvious if @samp{TRUE} means that some operation failed or if it succeeded. @item If a function returns @samp{Bool}, its name should make it clear what @samp{TRUE} means. Don't call the function @samp{validate_existing_text}; call it @samp{validate_text_exists}. (But it might be better to use @samp{Success}.) @item Follow this indentation example: @example int some_fun(int x, int y) @{ if (x > y) return x; else @{ if (y == 0 && x < y) @{ return x; @} @} return 0; @} @end example @item Don't use redundant braces (as in the first @samp{if} statement above), unless they help readability (as they do in the second @samp{if} statement above). @item If you break a line near a @samp{&&} or @samp{||} (or any other operator), put the operator at the beginning of the next line. @item A suitable style for GNU Emacs can be found in @file{doc/kom-style.el}. @end itemize @c ====================================================================== @c ====================================================================== @c == == @c == LYSKOMD DATABASE FORMAT == @c == == @c ====================================================================== @c ====================================================================== @ifinfo @node lyskomd Database Specification @chapter lyskomd Database Specification This document specifies the format of the lyskomd database files. The specification is currently incomplete. Only the structure, not the actual data records are documented. @menu * Version 0:: Database used with early versions of lyskomd. * Version 1:: Database used with lyskomd 1.9.0. * Version 2:: Database used with lyskomd 2.0.0. @end menu @end ifinfo @node Version 0 @section Data File Version 0 Version 0 was used by lyskomd versions up to 1.8. @example database : header @II{NL} next-free-num @II{NL} confs persons next-text-num @II{NL} texts ; header : @BB{CLEAN} | @BB{DIRTY} ; next-free-num : @II{INTEGER} ; confs : confs conf | @II{empty} ; conf : empty-record | @BB{+} conf-record @II{NL} ; persons : persons person | @II{empty} ; person : empty-record | @BB{+} person-record @II{NL} ; next-text-num : @II{INTEGER} ; texts : texts text | @II{empty} ; text : empty-record | @BB{+} text-record @BB{NL} ; empty-record : @BB{@@} @BB{NL} ; @end example The number of person and conference records is exactly one less than @II{next-free-num}. The number of text records is exactly one less than @II{next-text-num}. Records are stored sequentially. Conference number 18 is the 18th conference record in the file. This implies that deleted records must be stored as @II{empty-record} records. @II{next-text-num} is the number of the highest text. There are exactly one less than this number of text records in the database. @II{next-free-num} is the number of the highest conference. There are exactly one less than this number of both person and conference records. This implies that if conference N is not a letterbox, then person record N will be an @II{empty-record}. If the header says ``CLEAN'', the database file is complete. If the header says ``DIRTY'', the server has not finished writing it completely. @node Version 1 @section Data File Version 1 Version 1 was used by lyskomd version 1.9. @example database : header @BB{NL} @BB{records} ; header : @BB{CLEAN:00001} | @BB{DIRTY:00001} ; records : records record | @II{empty} ; record : next-free-num | next-text-num | conference | person | info | text | deleted ; next-free-num : @BB{#C} @II{INTEGER} ; next-text-num : @BB{#P} @II{INTEGER} ; conference : @BB{C} @II{integer} conf-record @BB{NL} | @BB{P} @II{integer} person-record @BB{NL} | @BB{T} @II{integer} text-record @BB{NL} | @BB{I} info-record @BB{NL} ; deleted : @BB{-C} @II{integer} @BB{NL} | @BB{-P} @II{integer} @BB{NL} | @BB{-T} @II{integer} @BB{NL} ; @end example The integer in the conference, text and person records is the ID of the record. This implies that records can be in any order. The @II{next-free-num} record is used to store the next available ID for conferences in the system. There may be several of these records in the database. The @II{next-text-num} record is used to store the next available ID for texts in the system. There may be several of these records in the database. A conference or text must have a number lower than the closest @II{next-free-num} or @II{next-text-num} preceding it. The deletion records are used to indicate that an object found earlier in the database has been deleted. The implementation of these in lyskomd 1.9 does not work, and they are not used. The @II{-C} record indicates deletion of a conference. The @II{-P} record indicates deletion of a person. The @II{-T} record indicates deletion of a text. The integer in the deletion record is the ID of the object being deleted. @node Version 2 @section Data File Version 2 Version 2 is used by lyskomd version 2.0. The structure of the data file is similar to version 1. The header has been extended with a timestamp contaning the time when the database file was saved. This timestamp consists of twenty characters, the number of seconds since 00:00:00 GMT January 1, 1970 (a Unix @code{time_t}.) @example database : header @BB{NL} @BB{records} ; header : @BB{CLEAN:00001} @BB{NL} timestamp @BB{NL} | @BB{DIRTY:00001} @BB{NL} timestamp @BB{NL} ; timestamp : digit digit digit digit digit digit digit digit digit digit digit digit digit digit digit digit digit digit digit digit ; ; digit : @BB{0} | @BB{1} | @BB{2} | @BB{3} | @BB{4} | @BB{5} | @BB{6} | @BB{7} | @BB{8} | @BB{9} ; @end example Furthermore several data types have been changed to accommodate additions introduced in version 10 of protocol A. The @II{server-info}, @II{conf-record} and @II{text-record} include information about aux-items (highest-aux-no and aux-item-list.) The @II{conf-record} contains the expire field added to the conf-stat structure. The @II{conf-record} and @II{person-record} records use the new local-to-global structure for storing maps. @contents @bye lyskom-server-2.1.2/doc/.cvsignore0000664000015100472110000000140207723467770012602 *.tmp Makefile Makefile.in Protocol-A.am Protocol-A.aux Protocol-A.cp Protocol-A.dvi Protocol-A.fn Protocol-A.fns Protocol-A.ky Protocol-A.log Protocol-A.notab Protocol-A.pdf Protocol-A.pg Protocol-A.toc Protocol-A.tp Protocol-A.tps Protocol-A.vr lyskomd.aux lyskomd.cp lyskomd.dvi lyskomd.fn lyskomd.fns lyskomd.info lyskomd.info-* lyskomd.ky lyskomd.log lyskomd.notab lyskomd.pdf lyskomd.pg lyskomd.toc lyskomd.tp lyskomd.vr protocol-a protocol-a-*.txt protocol-a.am protocol-a.aux protocol-a.cp protocol-a.dvi protocol-a.fn protocol-a.fns protocol-a.html protocol-a.info protocol-a.info-* protocol-a.ky protocol-a.log protocol-a.pdf protocol-a.pg protocol-a.texi protocol-a.toc protocol-a.tp protocol-a.vr protocol-a.xml stamp-vti stamp-vti1 texinfo.tex version.texi lyskom-server-2.1.2/doc/IDEAS0000664000015100472110000002400707366573645011362 THIS FILE IS NO LONGER USED THIS FILE IS NO LONGER USED THIS FILE IS NO LONGER USED We now use the Bugzilla installation at Lysator to handle the bugs and feature requests of lyskomd. See the following: http://bugzilla.lysator.liu.se/ The Bugzilla URL:s below point out the relevant entries. The ideas were copied to Bugzilla during October 2001. THIS FILE IS NO LONGER USED THIS FILE IS NO LONGER USED THIS FILE IS NO LONGER USED * Open Secret Conferences (mirar) Bugzilla: It would be nice to be able to set permissions on a conference so that it is considered open to all with write permissions and closed or secret to all others. * Better Text Garbing (nisse@lysator.liu.se) Bugzilla: Keep texts that have comments newer than N days, where N is a parameter of the conference. The parameter N has been implemented (keep_commented). The garb has to be changed (this is also in the TODO file.) It might be desirable to look even deeper into the comment chain so we keep *chains* that have additions newer than N days. * Chop up texts before sending (byers@lysator.liu.se) Bugzilla: We aren't too good at handling large texts. The problem is that we start off by reading the entire thing into memory from disk, then shove it all onto an ISC queue. For big texts that means we sit and wait for I/O of the text, then we sit and wait while we queue it all up, and while we're doing that, we actually wait for the server to write the garbage to the pipe! It would be nice to be able to spread the work around. I think the trick would be to not read everything from disk at once. We want to read a bit, send it, read some more, and send that. We add a function to ISC that lets us push an ISC packet onto the ISC queue that contains no data, just an instruction to call a callback. That callback reads some more data from the disk and queues that in ISC too. When we want to output a text, we start by enqueueing a callback to read the second bit of the text. Then we read the first bit and enqueue that. When we call isc_flush, isc will start by calling the callback. It will enqueue a callback to read the third bit from disk, then read the second bit from disk and enqueue that. Then we return to ISC and let ISC write the first bit to the socket. The result is that the ISC queue will contain block N of the text, then a callback to get N+2, then block N+1. The reason for doing it this way is that if we can get the callback to do the reads asynchronously, we can have ISC writing a bit of data to the socket while we are reading the next bit from disk. If we can do async reads, when ISC gets to the callback, the queue will contain a callback for block N+1, then block N of the text. The callback will enqueue a callback for block N+2, then initiate an async read for block N+1 and return immediately. The server will write block N to the socket concurrently with the read of block N+1. When the async read returns, its handler (callback, signal handler, whatever) enqueues the data in the ISC queue. This should result in the server spending much less time in IO wait. If we can't do async reads, then we might as well just put the callback for block N+1 after the data for block N. Async reads are available under Solaris, but not in Linux 2.0. Regrettably the interface is probably vendor-dependent. A potential problem is that we need to make *sure* that the text file is not cleaned when a text is deleted. That is not a problem in the current server, but could be in the future. If we have a pending request for text N, and someone deletes it before we can send the whole thing, we have to be able to continue sending it. Changes need to be made to ISC (typed queue elements, call the callback); prot_a_output and mux.c (need to output texts in a special way); plus we have to write the callbacks. This should be totally doable. NEWS: The aio_ interface is not supported by Linux, at least not yet. It is, however, a Posix 4 extension, not just a Solaris thing. On Linux we'd have to use poll or select to do asynchronous IO. Is it possible to use ISC for this as well? note: it is impossible to use select to do asynchronous I/O against files. select always considered data from a file to be immediately availabe. /ceder ceder says: adding support for aio_* to ISC is probably a good idea. It should be possible to do it in a way that is useful even on platforms that don't have aio_*. The idea then is to make sure that we never read more than one block from the file until we have written it to the client. Having a 8 KiB buffer where chunks are copied from file to client, from file to client, is a lot better than reading 1 MiB from file, chopping it up in small blocks, and storing them i an ISC queue. * Sync the database without blocking requests (byers@lysator.liu.se) Bugzilla: Currently the database is synced in three phases. Phase one creates a snapshot of all changed objects by traversing the internal arrays and moving the data pointer to the snapshot pointer in the cache nodes. The second phase writes objects to disk. The third phase frees the snapshot data from memory. The first and last phase block the server completely. Rewrite the sync algorithm like this. Assume that all objects in the database can be ordered, regardless of type. The server can be in one of two states: syncing or not syncing. When the server starts syncing, open the target data file and write the database header to the file. Write kom_info to the database. Set next_to_sync to zero. Periodically, sync a few objects. Examine object next_to_sync. If it has been saved to disk, do nothing. If it has a snapshot, write the snapshot to disk. If it is in memory, write it to disk from memory. If it is on disk, copy it from the old data file. Clear the snapshot. Clear the dirty flag. Clear the saved-to-disk flag. Increase next_to_sync and repeat this step until a fixed number of objects have been saved. When all objects are done, set the state of the server to not syncing, set the current data file to the one just synced. While the server is syncing, access to objects needs to be done carefully. If an object is requested that has not been synced, create a snapshot of it before returning it, or write it to disk immediately. If an object that has been synced but is not in memory is requested, then it must be read from the new data file. Tricky stuff: if something is added while we are syncing, it should not be written to disk. If something is deleted while we are syncing is should be written to disk anyway. The basic idea here is to make sure that the database file contains a copy of the database as it was when the sync was started, no matter what happens with it afterwards. We have like an index; everything before the index has been synced and can be treated as if we are not syncing at all. Everything beyond the frontier may be unsynced, and we need to make sure that it is retained unchanged until it gets written to disk. * Hierarchical Conferences (byers@lysator.liu.se) Bugzilla: LysKOM conferences should be organized hierarchically. Give each conference a parent conference pointer and a children conference list. Internally, prepend the parent ID to each conference name, so that we can have two conferences with the same name contained below different parent conferences. The prepending should not be visible to the client. Permissions in a conference are based on the permissions in the conference closest in child-parent order to the requested conference in which the person is a member (whew!) Some examples: conference A is rd_prot and conference B is not. Persons who are members of A can see anything in A and B. Persons who are members in B can see anything in B, but not in A. To persons who are members of neither, B behaves as if it were rd_prot, since its parent conference is. It has to be possible to do name lookup on a subtree of the conference tree. The small_conf_stat structure should probably mirror the tree structure and contain permission information about conferences. Don't forget that we want to be able to do sequential traversal of all elements in a subtree. This should require surprisingly small changes in the server. Mainly small_conf_stat, name lookup and storage, and permissions checks. * Garbage Collecting Conferences (byers@lysator.liu.se) Bugzilla: Conferences have an expire field. Conferences that have not contained texts for that many days should be removed automatically by the garbage collector or by dbck. * Mark Types (byers@lysator.liu.se) Bugzilla: Marks should be fixed. Marks should have flags and stuff. Texts should know who has marked them. There's a text about this somewhere in LysKOM. * Multibyte character compatibility (byers@lysator.liu.se) Bugzilla: The server should be capable of operating in multi-byte environments. We'll have to be able to specify a coding system and charset for conference and person names. We'll have to make sure the regexp engine can deal with multibyte characters. We'll need a new method of separating the subject line from the text body. The name matching will have to be more flexible. For eight-bit characters we'll need a way of specifying a collate table. For multibyte characters, maybe we'll have to be able to specify a procedure to determine equivalence of two characters. Local variables: mode: outline paragraph-separate: "[ \t ]*$" outline-regexp: "[* ]+" end: lyskom-server-2.1.2/doc/checkargs.py0000664000015100472110000023146207723467770013121 # Check Protocol-A.texi. # Copyright (C) 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Check @aarg{} and @rarg{} usage in Protocol-A.texi. # ...and a lot of other stuff... # ...and generate a stable machine-readable protocol specification. import sys import types import string import re import os # A mapping from type names (as strings) to prot_a_* objects. defined_types = {} # A mapping from request names (as strings) to prot_a_request objects. defined_request_names = {} # A mapping from request numbers (as ints) to prot_a_request objects. defined_request_numbers = {} # A mapping from async names (as strings) to prot_a_async objects. defined_async_names = {} # A mapping containing values set with @set. (@ifinfo et c # are not understood; the latest @set found is used.) set_values = {} # Translation tables between the stable names and the names used by # Protocol-A.texi. The first letter is the domain: # t : types # r : requests # a : asyncs # # The second letter is the direction: # t : table (from Protocol-A.texi to stable name) # r : reverse (from stable name to current Protocol-A.texi alias) tt = {} tr = {} rt = {} rr = {} at = {} ar = {} # All fields that have been seen so far. Initialized with some # built-in fields. defined_fields = { 'error-code': None, 'error-status': None, 'ref-no': None, 'reply-data': None, } # Fields seen in @field{} but not yet defined. undefined_fields = {} def number_suffixed(s, base): """Return true if S is BASE followed by a decimal number. """ if s[:len(base)] != base: return 0 s = s[len(base):] if len(s) < 1: return 0 try: int(s) return 1 except: return 0 def has_suffix(s, suffix): """Return true if S has the specified SUFFIX. """ if len(s) < len(suffix): return 0 return s[len(s) - len(suffix):] == suffix def remove_suffix(s, suffix): """Return S, but with SUFFIX removed. Return S unchanged if it doesn't end with SUFFIX. """ if has_suffix(s, suffix): return s[:len(s) - len(suffix)] else: return s # We define our own isalpha et c to avoid dependencies on the current # locale, and to be portable across old Python versions. def isalpha(s): for c in s: if c not in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ": return 0 return 1 def isupper(s): for c in s: if c not in "ABCDEFGHIJKLMNOPQRSTUVWXYZ": return 0 return 1 def islower(s): for c in s: if c not in "abcdefghijklmnopqrstuvwxyz": return 0 return 1 def isdigit(s): for c in s: if c not in "0123456789": return 0 return 1 def isspace(s): for c in s: if c not in " \n": # There should be no \t or \r in this file... return 0 return 1 class reader_eof(Exception): pass class prot_a_type: """Base class used for all Protocol A types. """ __usage_count = 0 def __init__(self, line): """Create a type. LINE should be the line number in Protocol-A.texi where this type was defined. It is used to create error messages. """ self.__line = line self.__protover = None self.__recommended = 0 def line_no(self): """Return the line number that defined this type. """ return self.__line def use(self, protover, recommended): """Mark this type as used by something else. This will increase the usage count (returned by usage()) and call use_recurse(), which in turn will call use() on all types referenced by this type. PROTOVER is the version of the request or async message that uses this type. The type will remember the lowest PROTOVER; this is the protocol version where the type was introduced. RECOMMENDED is true if this is used by a Recommended request or async message. """ self.__usage_count = self.__usage_count + 1 if self.__protover == None or protover < self.__protover: self.__protover = protover if self.__usage_count == 1: self.use_recurse(protover, recommended) if recommended: self.__recommended = 1 def usage(self): """Return the usage count. """ return self.__usage_count def protover(self): """Return the lowest protocol version that used this type. """ return self.__protover def recommended(self): """Return true if this type is used by a recommended request or async. """ return self.__recommended class prot_a_builtin(prot_a_type): """Basic types defined by the protocol, such as INT32. """ def use_recurse(self, protover, recommended): pass class prot_a_simple(prot_a_type): """Simple alias types, such as Conf-No or ARRAY Text-Stat. """ def __init__(self, line, typ, is_array): self.__type = typ self.__array = is_array prot_a_type.__init__(self, line) def use_recurse(self, protover, recommended): defined_types[self.__type].use(protover, recommended) def base_type(self): return self.__type def array(self): return self.__array class prot_a_alternate(prot_a_type): """A type that is an alternative of two other types. The only example of this is currently Any-Conf-Stat. """ def __init__(self, line, type_a, type_b): self.__type_a = type_a self.__type_b = type_b prot_a_type.__init__(self, line) def use_recurse(self, protover, recommended): defined_types[self.__type_a].use(protover, recommended) defined_types[self.__type_b].use(protover, recommended) def type_a(self): return self.__type_a def type_b(self): return self.__type_b class prot_a_struct(prot_a_type): """A structure, such as Conference. """ def __init__(self, line): prot_a_type.__init__(self, line) self.__fields = [] self.__used_names = {} def add_field(self, field_name, type_name, is_array): """Add a field to the structure. """ if self.__used_names.has_key(field_name): return "field name ``%s'' used twice" % field_name o = (field_name, type_name, is_array) self.__used_names[field_name] = o self.__fields.append(o) defined_fields[field_name] = None if undefined_fields.has_key(field_name): del undefined_fields[field_name] return None def use_recurse(self, protover, recommended): for (fn, tn, ar) in self.__fields: defined_types[tn].use(protover, recommended) def fields(self): return self.__fields class prot_a_bitstring(prot_a_type): """A bitstring, such Aux-Item-Flags. """ def __init__(self, line): prot_a_type.__init__(self, line) self.__bits = {} self.__ordered_bits = [] def add_field(self, field_name): if self.__bits.has_key(field_name): return "bit ``%s'' used twice" % field_name self.__bits[field_name] = None defined_fields[field_name] = None if undefined_fields.has_key(field_name): del undefined_fields[field_name] self.__ordered_bits.append(field_name) def check_implemented(self, name, implemented_fields): res = [] i = {} for f in implemented_fields.keys(): if not self.__bits.has_key(f): res.append("%s: bit ``%s'' not documented" % (name, f)) i[f] = None for f in self.__bits.keys(): if not i.has_key(f): res.append("%s: bit ``%s'' not implemented" % (name, f)) return res def use_recurse(self, protover, recommended): pass def bits(self): return self.__ordered_bits class prot_a_selection(prot_a_type): """A selection, such as Misc-Info or Local-To-Global-Block. """ def __init__(self, line): prot_a_type.__init__(self, line) self.__fields = [] self.__used_nums = {} self.__used_names = {} self.__used_tailnames = {} def add_variant(self, number, name, tailname, tail_type, is_array): if self.__used_nums.has_key(number): return "selection number ``%s'' used twice" % number if self.__used_names.has_key(name): return "selection name ``%s'' used twice" % name if self.__used_tailnames.has_key(tailname): return "selection tailname ``%s'' used twice" % tailname o = (number, name, tailname, tail_type, is_array) self.__used_nums[number] = o self.__used_names[name] = o self.__used_tailnames[tailname] = o self.__fields.append(o) def check_implemented(self, imp_nr, imp_name): if not self.__used_names.has_key(imp_name): return "``%s'' implemented but not documented" % imp_name if self.__used_names[imp_name][0] != imp_nr: return "``%s'' implemented as %s but documented as %s" % ( imp_name, repr(imp_nr), repr(self.__used_names[imp_name][0])) return None def all_names(self): return self.__used_names.keys() def use_recurse(self, protover, recommended): for (number, name, tailname, tail_type, is_array) in self.__fields: defined_types[tail_type].use(protover, recommended) def fields(self): return self.__fields class prot_a_enumeration_of(prot_a_type): """An ENUMERATION-OF, such as Info-Type. """ def __init__(self, line, base): prot_a_type.__init__(self, line) self.__base = base def use_recurse(self, protover, recommended): defined_types[self.__base].use(protover, recommended) def base_type(self): return self.__base class prot_a_msg: """Base class for requests and asynchronous messages. """ def __init__(self, line, reqnr, reqname, rec, exp, obs, protover, obsver): """Construct a request. LINE: Line number that defines the message. REQNR: The number of this request. REQNAME: The name, as it appears in Protocol-A.texi. REC: True if recommended. EXP: True if experimental. OBS: True if obsolete. PROTOVER: Protocol version when it was introduced. OBSVER: Protocol version when it became obsolete, or None. """ self.__line_no = line self.__reqnr = reqnr self.__reqname = reqname self.__rec = rec self.__exp = exp self.__obs = obs self.__protover = protover self.__obsver = obsver self.__args = [] self.__retval = None def line_no(self): return self.__line_no def request_nr(self): return self.__reqnr def request_name(self): return self.__reqname def recommended(self): return self.__rec def experimental(self): return self.__exp def obsolete(self): return self.__obs def protover(self): return self.__protover def obsver(self): return self.__obsver def append_arg(self, request_arg): self.__args.append(request_arg) def arguments(self): return self.__args class prot_a_request(prot_a_msg): """Hold all information about a request. """ __retval = None def set_return_type(self, ret_type, is_array): # FIXME: cleanup possible? Use anonymous prot_a_simple? self.__retval = (ret_type, is_array) def return_type(self): if self.__retval == None: return None return self.__retval[0] def array(self): return self.__retval[1] class prot_a_async(prot_a_msg): """Hold all information about an async message. """ pass class menu: def __init__(self, line_no, name, nr, state): self.__line_no = line_no self.__name = name self.__nr = int(nr) self.__state = state def line_no(self): return self.__line_no def name(self): return self.__name def nr(self): return self.__nr def state(self): return self.__state def same_state(self, req): if req.recommended() and self.__state == "r": return 1 if req.experimental() and self.__state == "e": return 1 if req.obsolete() and self.__state == "O": return 1 return 0 class reader: """Read a character at a time. The reader checks that unqoted occurances of (), [] and {} are properly matched, and gives an error message otherwise. The reader also keeps track of the line number. The reader recognizes the info menu lines for the request and async menues, and saves them. """ parens = {'(': ')', '[': ']', '{': '}'} rev_parens = {} for k, v in parens.items(): rev_parens[v] = k del v del k menu_re = re.compile('\\* (?P[-a-z0-9]*):: ' '*(?P[Oer]) .*' '\\((?P[0-9][0-9]*)\\)\n') def __init__(self, file): self.__filename = file self.__file = open(file, "r") self.__line_no = 0 self.__line = [] self.__eof = 0 self.__parenstack = [] self.__errfound = 0 self.__quoted = 0 self.__menu = {} def filename(self): return self.__filename def error(self, line_no, errmsg): sys.stderr.write("%s:%s:%s\n" % (self.filename(), line_no, errmsg)) self.__errfound = 1 def errfound(self): return self.__errfound def ungetc(self, c): if self.rev_parens.has_key(c): self.__parenstack.append((self.rev_parens[c], 0)) if self.parens.has_key(c): assert len(self.__parenstack) > 0 assert self.__parenstack[-1][0] == c del self.__parenstack[-1] if c == '@': self.__quoted = not self.__quoted self.__line.insert(0, c) def getc_eofok(self): if self.__line == []: if self.__eof: return None line = self.__file.readline() if line == '': self.__eof = 1 return None self.__line = list(line) self.__line_no = self.__line_no + 1 if len(line) == 80: m = self.menu_re.match(line) if m != None: self.__menu[m.group("name")] = menu( self.__line_no, m.group("name"), m.group("nr"), m.group("state")) ret = self.__line[0] del self.__line[0] if not self.__quoted: if ret in '([{': self.__parenstack.append((ret, self.line_no())) if ret in '}])': if len(self.__parenstack) == 0: self.error(self.line_no(), "unmatched paren ``%s''" % ret) else: if self.__parenstack[-1][0] != self.rev_parens[ret]: self.error(self.line_no(), "badly matched parens ``%s'' ``%s''" % (self.__parenstack[-1][0], ret)) del self.__parenstack[-1] if ret == '@': self.__quoted = not self.__quoted else: self.__quoted = 0 return ret def getc(self): c = self.getc_eofok() if c == None: raise reader_eof return c def line_no(self): return self.__line_no def check_paren_null(self): for par, line in self.__parenstack: self.error(line, "unclosed ``%s''" % par) self.__parenstack = [] def menu(self, name): """Return the menu line for the request or async named NAME. """ if self.__menu.has_key(name): return self.__menu[name] else: return None class lexer: section_re = re.compile( '(?P[a-z][-a-z0-9]*) ' '\\[(?P[0-9][0-9]*)\\] ' '\\((?P[1-9][0-9]*)\\) ' '(?:(?PRecommended)' '|(?PExperimental)' '|(?PObsolete(?: \\((?P[0-9]*)\\))?))' '$') def __init__(self, file): self.__reader = reader(file) self.__findex = None self.__amindex = None self.__linkhere = None self.__builtin_types = ["BOOL", "INT8", "INT16", "INT32", "FLOAT", "HOLLERITH"] self.__builtin_aggregates = ["BITSTRING", "ENUMERATION", "ENUMERATION-OF", "ARRAY", "SELECTION", "RPC"] self.__builtin_typelike = (self.__builtin_types + self.__builtin_aggregates) self.__tindex_seen = {} for t in self.__builtin_types: defined_types[t] = prot_a_builtin('*builtin*') # A mapping from request name to line number where it is defined. self.__defined_requests = {} # A mapping from async name to line number where it is defined. self.__defined_asyncs = {} # A mapping from request name to request number, extracted # from the lyskomd source code. self.__implemented_reqs = {} f = open("requests-numbered.tmp", "r") for line in f.readlines(): [nr, name] = string.split(line, " ") self.__implemented_reqs[string.strip(name)] = nr f.close() # A mapping from async name to async number, extracted # from the lyskomd source code. self.__implemented_asyncs = {} n = {} f = open("asyncs-numbered.tmp", "r") for line in f.readlines(): [nr, name] = string.split(line, " ") name = string.strip(name) if n.has_key(nr): sys.stderr.write("../src/server/async.h:1:enum async:" " number %s used for both %s and %s\n" % ( nr, n[nr], name)) sys.exit(1) n[nr] = name self.__implemented_asyncs[name] = nr f.close() # A mapping from misc-item name to number, extracted # from the lyskomd source code. self.__implemented_miscs = {} n = {} f = open("miscs-numbered.tmp", "r") for line in f.readlines(): [nr, name] = string.split(line, " ") nr = int(nr) name = string.strip(name) if n.has_key(nr): sys.stderr.write("../src/include/kom-types.h:1:enum info_type:" " number %s used for both %s and %s\n" % ( nr, n[nr], name)) sys.exit(1) n[nr] = name self.__implemented_miscs[name] = nr f.close() # A mapping from conftype bit name to None, extracted # from the lyskomd source code. self.__implemented_conftypes = {} f = open("conftypes.tmp", "r") for line in f.readlines(): name = string.strip(line) self.__implemented_conftypes[name] = None f.close() # A mapping from privilege bit name to None, extracted # from the lyskomd source code. self.__implemented_privbits = {} f = open("privbits.tmp", "r") for line in f.readlines(): name = string.strip(line) self.__implemented_privbits[name] = None f.close() def run(self): while 1: c = self.__reader.getc() if c == '@': ret = self.__toplevel_at() if ret != None: return ret def __toplevel_at(self): line_no = self.__reader.line_no() c = self.__reader.getc() if c in '{}@-"*': return cmd = "" while 1: if isalpha(c) or c in '_"': cmd = cmd + c c = self.__reader.getc() elif c in ' \t\n{@=-': assert cmd != '' if c == '{': arg = self.__read_arg() elif c == ' ' and cmd not in ['tab']: arg = self.__read_line() else: arg = None if c == '@': self.__reader.ungetc(c) if hasattr(self, 'toplevel_' + cmd): return getattr(self, 'toplevel_' + cmd)(arg, line_no) else: self.error(line_no, "unknown command @%s{}" % cmd) return else: self.error(line_no, "bad command ``@%s%s''" % (cmd, c)) return def __read_line(self): line = "" while 1: c = self.__reader.getc() if c == '\n': return line line = line + c def ignore(self, arg, line_no): pass toplevel_setfilename = ignore toplevel_settitle = ignore toplevel_setchapternewpage = ignore toplevel_macro = ignore toplevel_end = ignore toplevel_ifinfo = ignore toplevel_value = ignore toplevel_copyright = ignore toplevel_iftex = ignore toplevel_parindent = ignore toplevel_ifinfo = ignore toplevel_begin = ignore toplevel_titlepage = ignore toplevel_title = ignore toplevel_subtitle = ignore toplevel_author = ignore toplevel_font = ignore toplevel_ignore = ignore toplevel_tensltt = ignore toplevel_page = ignore toplevel_vskip = ignore toplevel_ifnothtml = ignore toplevel_contents = ignore toplevel_dircategory = ignore toplevel_direntry = ignore toplevel_ifhtml = ignore toplevel_html = ignore toplevel_ifnottex = ignore toplevel_top = ignore toplevel_menu = ignore toplevel_chapter = ignore toplevel_penalty = ignore toplevel_table = ignore toplevel_item = ignore toplevel_req = ignore toplevel_reqlink = ignore toplevel_asynclink = ignore toplevel_subsection = ignore toplevel_itemize = ignore toplevel_bullet = ignore toplevel_multitable = ignore toplevel_tab = ignore toplevel_aux = ignore toplevel_errorcode = ignore toplevel_misc = ignore toplevel_type = ignore toplevel_dfn = ignore toplevel_conftype = ignore toplevel_command = ignore toplevel_ref = ignore toplevel_subsubsection = ignore toplevel_priv = ignore toplevel_enumerate = ignore toplevel_itemx = ignore toplevel_ae = ignore toplevel_i = ignore toplevel_subheading = ignore toplevel_c = ignore toplevel_t = ignore toplevel_aa = ignore toplevel_async = ignore toplevel_unnumbered = ignore toplevel_printindex = ignore toplevel_example = ignore toplevel_unmacro = ignore toplevel_dots = ignore toplevel_tex = ignore toplevel_defcodeindex = ignore toplevel_syncodeindex = ignore toplevel_need = ignore toplevel_reqexample = ignore toplevel_anchor = ignore toplevel_appendix = ignore toplevel_display = ignore toplevel_daemon = ignore toplevel_TeX = ignore toplevel_copying = ignore toplevel_quotation = ignore toplevel_insertcopying = ignore def pushback(self, arg, line_no): lst = list(arg) lst.reverse() for char in lst: self.__reader.ungetc(char) toplevel_w = pushback toplevel_code = pushback toplevel_uref = pushback toplevel_footnote = pushback toplevel_email = pushback toplevel_asis = pushback toplevel_samp = pushback toplevel_pxref = pushback toplevel_var = pushback toplevel_emph = pushback toplevel_xref = pushback toplevel_badspell = pushback toplevel_holl = pushback toplevel_file = pushback toplevel_cindex = pushback toplevel_cite = pushback def toplevel_set(self, arg, line_no): [k, v] = string.split(arg, None, 1) set_values[k] = v def toplevel_section(self, arg, line_no): self.__section_name = arg self.__section_start = line_no def toplevel_node(self, arg, line_no): if self.__findex != None: self.__findex = None for (argname, [lineno, usage]) in self.__args.items(): if usage == 0: self.error(lineno, "Undocumented argument ``%s''" % (argname, )) if self.__amindex != None: self.__amindex = None for (argname, [lineno, usage]) in self.__args.items(): if usage == 0: self.error(lineno, "Undocumented argument ``%s''" % (argname, )) self.__node_name = arg self.__node_start = line_no self.__assert_no_linkhere() self.__reader.check_paren_null() def toplevel_findex(self, arg, line_no): if self.__node_name != arg: self.error(line_no, "@node/@findex mismatch: %s..." % arg) self.error(line_no, "...inside node %s" % self.__node_name) return if self.__amindex != None: self.error(line_no, "@findex and @amindex used in the same node") return if self.__findex != None: self.error(line_no, "multiple @findex in single @node") return self.__findex = arg m = self.section_re.match(self.__section_name) if m == None: self.error(self.__section_start, "bad section heading for request") return if m.group("req") != arg: self.error(line_no, "@section/@findex mismatch: %s..." % arg) self.error(self.__section_start, "...inside section %s" % m.group("req")) return reqnr = int(m.group("reqnr")) protover = int(m.group("protover")) if m.group("obsolete") != None and m.group("obsver") == None: self.error(self.__section_start, "when was this obsoleted?") rec = m.group("recommended") != None exp = m.group("experimental") != None obs = m.group("obsolete") != None # self.__args holds a mapping from the argument name # to a list of two elements: # 0: the line number where it is defined # 1: a usage count self.__args = {} if self.__defined_requests.has_key(arg): self.error(line_no, "request ``%s'' redefined" % arg) self.error(self.__defined_requests[arg], "previous definition") self.__defined_requests[arg] = line_no if self.__get_token() != '@example': self.error(self.__reader.line_no(), "missing @example") return req = prot_a_request(line_no, reqnr, arg, rec, exp, obs, protover, m.group("obsver")) self.__parse_request(req) defined_request_names[arg] = req defined_request_numbers[reqnr] = req menu = self.__reader.menu(req.request_name()) if menu == None: self.error(line_no, "no @menu item found") else: if not menu.same_state(req): self.error(menu.line_no(), "state clash for %s" % menu.name()) self.error(line_no, "...clashing") if menu.nr() != req.request_nr(): self.error(menu.line_no(), "number clash for %s" % menu.name()) self.error(line_no, "...clashing") def toplevel_rarg(self, arg, line_no): if self.__findex == None: self.error(line_no, "@rarg outside @findex node") return if not self.__args.has_key(arg): self.error(line_no, "undefined argument ``%s''" % (arg, )) return self.__args[arg][1] = self.__args[arg][1] + 1 def toplevel_amindex(self, arg, line_no): if self.__node_name != arg: self.error(line_no, "@node/@amindex mismatch: %s..." % arg) self.error(line_no, "...inside node %s" % self.__node_name) return if self.__findex != None: self.error(line_no, "@findex and @amindex used in the same node") return if self.__amindex != None: self.error(line_no, "multiple @amindex in single @node") return self.__amindex = arg self.__args = {} if self.__defined_asyncs.has_key(arg): self.error(line_no, "async message ``%s'' redefined" % arg) self.error(self.__defined_asyncs[arg], "previous definition") self.__defined_asyncs[arg] = line_no token = self.__get_token() obsolete = 0 if token == '@c': token = self.__get_token() if token == 'obsolete': obsolete = 1 else: self.error(self.__reader.line_no(), "broken comment within @amindex block") return token = self.__get_token() if token != '@example': self.error(self.__reader.line_no(), "missing @example") return m = self.section_re.match(self.__section_name) if m == None: self.error(self.__section_start, "bad section heading for message") return if m.group("req") != arg: self.error(line_no, "@section/@amindex mismatch: %s..." % arg) self.error(self.__section_start, "...inside section %s" % m.group("req")) return reqnr = int(m.group("reqnr")) protover = int(m.group("protover")) if m.group("obsolete") != None and m.group("obsver") == None: self.error(self.__section_start, "when was this obsoleted?") rec = m.group("recommended") != None exp = m.group("experimental") != None obs = m.group("obsolete") != None req = prot_a_async(line_no, reqnr, arg, rec, exp, obs, protover, m.group("obsver")) self.__parse_async(req) defined_async_names[arg] = req menu = self.__reader.menu(req.request_name()) if menu == None: self.error(line_no, "no @menu item found") else: if not menu.same_state(req): self.error(menu.line_no(), "state clash for %s" % menu.name()) self.error(line_no, "...clashing") if menu.nr() != req.request_nr(): self.error(menu.line_no(), "number clash for %s" % menu.name()) self.error(line_no, "...clashing") def __parse_async(self, req): self.__tokens = [] async = self.__get_token() if async != self.__amindex: self.error(self.__reader.line_no(), "wrong async name ``%s''" % async) return if self.__get_token() != '[': self.error(self.__reader.line_no(), "missing ``[''") return nr = self.__get_token() if type(nr) != types.IntType: self.error(self.__reader.line_no(), "bad async number") if self.__implemented_asyncs.has_key(async): if self.__implemented_asyncs[async] != str(nr): self.error(self.__reader.line_no(), "``%s'' is implemented as asynchronous message %s, " "not %s" % (async, self.__implemented_asyncs[async], nr)) elif not req.obsolete(): self.error(self.__reader.line_no(), "asynchronous message ``%s'' not implemented" % async) if req.request_nr() != nr: self.error(self.__reader.line_no(), "async number mismatch") if self.__get_token() != ']': self.error(self.__reader.line_no(), "missing ``]''") return paren = self.__get_token() if paren == '(': next = self.__get_token() if next != ')': self.__unget_token(next) req.append_arg(self.__parse_request_arg(req)) next = self.__get_token() if next != ')': self.error(self.__reader.line_no(), "missing close parenthesis after arguments") return elif paren == '((': req.append_arg(self.__parse_request_arg(req)) next = self.__get_token() while next == ';': req.append_arg(self.__parse_request_arg(req)) next = self.__get_token() if next != '))': self.error(self.__reader.line_no(), "missing double close parenthesis after arguments") return else: self.error(self.__reader.line_no(), "missing argument list") return if self.__get_token() != ';': self.error(self.__reader.line_no(), "missing final ``;''") return if self.__get_token() != '@end': self.error(self.__reader.line_no(), "extra garbage found") return return def toplevel_aarg(self, arg, line_no): if self.__amindex == None: self.error(line_no, "@aarg outside @amindex node") return if not self.__args.has_key(arg): self.error(line_no, "undefined argument ``%s''" % (arg, )) return self.__args[arg][1] = self.__args[arg][1] + 1 def toplevel_bye(self, arg, line_no): if self.__findex != None: self.error(self.__reader.line_no(), "unterminated @findex node") if self.__amindex != None: self.error(self.__reader.line_no(), "unterminated @amindex node") # Check types. for (n, o) in defined_types.items(): if o.usage() < 1: self.error(o.line_no(), "unused type ``%s''" % n) # Check requests. for req in self.__implemented_reqs.keys(): if not self.__defined_requests.has_key(req): self.error(self.__reader.line_no(), "request ``%s'' not documented" % req) # Check async messages. for req in self.__implemented_asyncs.keys(): if not self.__defined_asyncs.has_key(req): self.error(self.__reader.line_no(), "asynchronous message ``%s'' not documented" % req) # Check misc-info stuff. for name, nr in self.__implemented_miscs.items(): err = defined_types['Misc-Info'].check_implemented(nr, name) if err: self.error(self.__reader.line_no(), "Misc-info " + err) for name in defined_types['Misc-Info'].all_names(): if not self.__implemented_miscs.has_key(name): self.error(self.__reader.line_no(), "Misc-info ``%s'' not implemented." % name) # Check bitfields. for emsg in defined_types['Extended-Conf-Type'].check_implemented( "conference type", self.__implemented_conftypes): self.error(self.__reader.line_no(), emsg) for emsg in defined_types['Priv-Bits'].check_implemented( "conference type", self.__implemented_privbits): self.error(self.__reader.line_no(), emsg) # Check fields. for (field, lines) in undefined_fields.items(): for lin in lines: self.error(lin, "undefined field ``%s'' referenced" % field) self.__reader.check_paren_null() # Some additional checks. self.generate_stable_names() return self.__reader.errfound() def toplevel_reqdlink(self, arg, line_no): self.__assert_no_linkhere() self.__linkhere = ("@reqdlink{%s}" % arg, line_no) def toplevel_asyncdlink(self, arg, line_no): self.__assert_no_linkhere() self.__linkhere = ("@asyncdlink{%s}" % arg, line_no) def __assert_no_linkhere(self): if self.__linkhere != None: self.error(self.__linkhere[1], "@linkhere{} after %s missing" % (self.__linkhere[0])) def toplevel_linkhere(self, arg, line_no): if self.__linkhere == None: self.error(line_no, "spurious @linkhere{}") self.__linkhere = None def __seen_type(self, arg, line_no): if self.__tindex_seen.has_key(arg): self.error(line_no, "multiple @tindex entries for %s" % arg) self.error(self.__tindex_seen[arg], "previous location") else: self.__tindex_seen[arg] = line_no def toplevel_tindex(self, arg, line_no): self.__seen_type(arg, line_no) if arg in self.__builtin_typelike: return self.__bad_type(arg) tindexed_types = [arg] self.__tokens = [] t = self.__get_token() while t == '@tindex': t = self.__get_token() self.__seen_type(t, self.__reader.line_no()) self.__bad_type(t) tindexed_types.append(t) t = self.__get_token() if t != '@example': self.error(self.__reader.line_no(), "missing @example after @tindex for defined type") return self.__parse_userdefined_types(tindexed_types) def __parse_userdefined_types(self, tindexed_types): """Parse type definitions for TINDEXED_TYPES. TINDEXED_TYPES is a list of type names, as strings, that originates from the @tindex statements above this @example section. An error message is given if TINDEXED_TYPES doesn't correspond to the types actually defined in this @example section. """ seen_types = [] while 1: newtype = self.__get_token() line = self.__reader.line_no() if newtype == '@end': token = self.__get_token() if token != 'example': self.error(self.__reader.line_no(), "``@end example'' expected") break if newtype == '@need': self.__get_token() # Skip the argument to @need. newtype = self.__get_token() if newtype == '@anchor': if self.__get_token() != '{': self.error(self.__reader.line_no(), "@anchor must be followed by ``{''") newtype = self.__get_token() if self.__get_token() != '}': self.error(self.__reader.line_no(), "@anchor missing ``}''") token = self.__get_token() if token != newtype: self.error(self.__reader.line_no(), "@anchor mismatch -- ``%s'' or ``%s''?" % ( newtype, token)) token = self.__get_token() if token != '::=': self.error(self.__reader.line_no(), "``::='' expected") return token = self.__get_token() if token == '(': typedef = self.__parse_userdefined_struct(line) elif token == 'SELECTION': typedef = self.__parse_userdefined_selection(line) elif token == 'BITSTRING': typedef = self.__parse_userdefined_bitstring(line) elif token == 'ENUMERATION-OF': typedef = self.__parse_userdefined_enumeration_of(line) else: self.__unget_token(token) token = self.__get_lt_token() if token == 'ARRAY': name = self.__get_lt_token() array = 1 else: array = 0 name = token token = self.__get_token() if token == '|': token = self.__get_lt_token() if array or token == 'ARRAY': self.error(self.__reader.line_no(), "cannot mix ARRAY and ``|''") return typedef = prot_a_alternate(line, name, token) token = self.__get_token() else: typedef = prot_a_simple(line, name, array) if token != ';': # This is not a fatal error; we try to recover # from it. self.error(self.__reader.line_no(), "missing ;") if typedef != None: if newtype not in tindexed_types: self.error(self.__reader.line_no(), "missing @tindex entry for %s" % newtype) seen_types.append(newtype) if defined_types.has_key(newtype): self.error(self.__reader.line_no(), "redefinition of ``%s''" % newtype) else: defined_types[newtype] = typedef # Check that all types in the @tindex were defined. for typename in tindexed_types: if typename not in seen_types: self.error(self.__reader.line_no(), "type %s not defined but @tindex entry exists" % typename) def __parse_userdefined_struct(self, line): res = prot_a_struct(line) while 1: token = self.__get_token() if token == ')': return res name = token token = self.__get_token() if token != ':': self.error(self.__reader.line_no(), "missing ``:'' near %s" % token) token = self.__get_lt_token() if token == 'ARRAY': array = 1 token = self.__get_lt_token() else: array = 0 if not self.__bad_type(token) and not self.__bad_arg(name): ret = res.add_field(name, token, array) if ret: self.error(self.__reader.line_no(), ret) token = self.__get_token() if token != ';': self.error(self.__reader.line_no(), "missing ``;''") def __parse_userdefined_bitstring(self, line): res = prot_a_bitstring(line) token = self.__get_token() if token != '(': self.error(self.__reader.line_no(), "expected ``('' after BITSTRING, not ``%s''" % token) return None while 1: token = self.__get_token() if token == ')': return res name = token if not self.__bad_arg(name): ret = res.add_field(name) if ret: self.error(self.__reader.line_no(), ret) token = self.__get_token() if token != ';': self.error(self.__reader.line_no(), "missing ``;''") def __parse_userdefined_selection(self, line): res = prot_a_selection(line) token = self.__get_token() if token != '(': self.error(self.__reader.line_no(), "expected ``('' after SELECTION, not ``%s''" % token) return None while 1: token = self.__get_token() if token == ')': return res number = token try: int(number) except: self.error(self.__reader.line_no(), "bad number ``%s''" % number) return None token = self.__get_token() if token != '=': self.error(self.__reader.line_no(), "missing ``:'' near %s" % token) name = self.__get_token() tail_name = self.__get_token() token = self.__get_token() if token != ':': self.error(self.__reader.line_no(), "missing ``:'' near %s" % token) token = self.__get_lt_token() if token == 'ARRAY': array = 1 token = self.__get_lt_token() else: array = 0 if (not self.__bad_type(token) and not self.__bad_arg(name) and not self.__bad_arg(tail_name)): ret = res.add_variant(number, name, tail_name, token, array) if ret: self.error(self.__reader.line_no(), ret) token = self.__get_token() if token != ';': self.error(self.__reader.line_no(), "missing ``;''") def __parse_userdefined_enumeration_of(self, line): token = self.__get_token() if token != '(': self.error(self.__reader.line_no(), "expected ``('' after ENUMERATION-OF, not ``%s''" % token) return None name = self.__get_lt_token() token = self.__get_token() if token != ')': self.error(self.__reader.line_no(), "missing close ``)'', got ``%s''" % token) return None if self.__bad_type(name): return None return prot_a_enumeration_of(line, name) def __parse_request(self, req_obj): self.__tokens = [] req = self.__get_token() if req != self.__findex: self.error(self.__reader.line_no(), "wrong request name ``%s''" % req) return if self.__get_token() != '[': self.error(self.__reader.line_no(), "missing ``[''") return nr = self.__get_token() if type(nr) != types.IntType: self.error(self.__reader.line_no(), "bad request number") if self.__implemented_reqs.has_key(req): if self.__implemented_reqs[req] != str(nr): self.error(self.__reader.line_no(), "``%s'' is implemented as request number %s, not %s" % (req, self.__implemented_reqs[req], nr)) else: self.error(self.__reader.line_no(), "request ``%s'' not implemented" % req) if req_obj.request_nr() != nr: self.error(self.__reader.line_no(), "request number mismatch vs. @section") if self.__get_token() != ']': self.error(self.__reader.line_no(), "missing ``]''") return paren = self.__get_token() if paren == '(': next = self.__get_token() if next != ')': self.__unget_token(next) req_obj.append_arg(self.__parse_request_arg(req_obj)) next = self.__get_token() if next != ')': self.error(self.__reader.line_no(), "missing close parenthesis after arguments") return elif paren == '((': req_obj.append_arg(self.__parse_request_arg(req_obj)) next = self.__get_token() while next == ';': req_obj.append_arg(self.__parse_request_arg(req_obj)) next = self.__get_token() if next != '))': self.error(self.__reader.line_no(), "missing double close parenthesis after arguments") return else: self.error(self.__reader.line_no(), "missing argument list") return if self.__get_token() != '->': self.error(self.__reader.line_no(), "missing ``->''") return if self.__get_token() != '(': self.error(self.__reader.line_no(), "missing ``('' for result") return next = self.__get_token() if next != ')': self.__unget_token(next) (ret_type, ret_array) = self.__parse_type(req_obj) req_obj.set_return_type(ret_type, ret_array) next = self.__get_token() if next != ')': self.error(self.__reader.line_no(), "missing ``)'' for result") return if self.__get_token() != ';': self.error(self.__reader.line_no(), "missing final ``;''") return if self.__get_token() != '@end': self.error(self.__reader.line_no(), "extra garbage found") return return def __parse_type(self, req_obj): token = self.__get_lt_token() if token == 'ARRAY': token = self.__get_lt_token() array = 1 else: array = 0 if self.__bad_type(token): return (None, 0) if not defined_types.has_key(token): self.error(self.__reader.line_no(), "undefined type ``%s''" % token) defined_types[token].use(req_obj.protover(), req_obj.recommended()) return (token, array) def __get_lt_token(self): token = self.__get_token() if token != '@lt': self.error(self.__reader.line_no(), 'expected @lt{}-enclosed token') return token token = self.__get_token() if token != '{': self.error(self.__reader.line_no(), "expected ``{'', not ``%s''" % token) return token result = self.__get_token() token = self.__get_token() if token != '}': self.error(self.__reader.line_no(), "expected ``}'', not ``%s''" % token) return result def __bad_type(self, tp): if tp in self.__builtin_types: return 0 # This is an ugly special case, that is a good type name. # More or less. if tp == "UConference": return 0 ok = 1 if len(tp) < 0: ok = 0 if ok and not isupper(tp[0]): ok = 0 upper = 0 num_seen = 0 for c in tp[1:]: if num_seen: if not isdigit(c): ok = 0 elif upper: if isdigit(c): num_seen = 1 elif c == '-' or not isupper(c): ok = 0 upper = 0 else: if c == '-': upper = 1 elif not islower(c): ok = 0 if ok and tp[-1] == '-': ok = 0 if not ok: self.error(self.__reader.line_no(), "bad type name ``%s''" % (tp,)) return not ok def __bad_arg(self, arg): if number_suffixed(arg, 'reserved'): return 0 if number_suffixed(arg, 'flg'): return 0 ok = 1 if len(arg) < 1: ok = 0 if ok and not islower(arg[0]): ok = 0 for c in arg[1:]: if not islower(c) and c != '-': ok = 0 if ok and arg[-1] == '-': ok = 0 if not ok: if arg == '))': self.__unget_token(arg) self.error(self.__reader.line_no(), "extra semicolon after last arg") else: self.error(self.__reader.line_no(), "bad argument ``%s''" % (arg,)) return not ok def __parse_request_arg(self, req_obj): argname = self.__get_token() if self.__bad_arg(argname): return if self.__get_token() != ':': self.error(self.__reader.line_no(), "missing ``:'' after argument") return (tp, array) = self.__parse_type(req_obj) if tp == None: return if self.__args.has_key(argname): self.error(self.__reader.line_no(), "argument name ``%s'' used twice" % (argname, )) return self.__args[argname] = [self.__reader.line_no(), 0] return (argname, tp, array) def toplevel_field(self, arg, line_no): if not defined_fields.has_key(arg): if not undefined_fields.has_key(arg): undefined_fields[arg] = [] undefined_fields[arg].append(line_no) def __unget_token(self, token): self.__tokens.insert(0, token) def __get_token(self): if len(self.__tokens) > 0: res = self.__tokens[0] del self.__tokens[0] return res c = self.__reader.getc() while isspace(c): c = self.__reader.getc() if isalpha(c): res = c while 1: c = self.__reader.getc() if not isalpha(c) and c not in "-" and not isdigit(c): if isdigit(c): self.error(self.__reader.line_no(), "bad token ``%s''" % (res + c)) self.__reader.ungetc(c) return res res = res + c elif c == ':': d = self.__reader.getc() if d != ':': self.__reader.ungetc(d) return c d = self.__reader.getc() if d != '=': self.__reader.ungetc(d) self.__reader.ungetc(':') return c return '::=' elif c in '[];|={}': return c elif c in '()': d = self.__reader.getc() if c != d: self.__reader.ungetc(d) return c else: return c + d elif isdigit(c): res = c while 1: c = self.__reader.getc() if not isdigit(c): if isalpha(c): self.error(self.__reader.line_no(), "bad token ``%s''" % (res + c)) self.__reader.ungetc(c) if res[0] == '0' and len(res) > 1: self.error(self.__reader.line_no(), "bad number ``%s''" % (res,)) return int(res) res = res + c elif c == '-': d = self.__reader.getc() if d == '>': return '->' else: self.error(self.__reader.line_no(), "bad token ``%s%s''" % (c, d)) self.__reader.ungetc(d) return c elif c == '@': res = c while 1: c = self.__reader.getc() if not isalpha(c): self.__reader.ungetc(c) return res res = res + c elif c == '!': # This is a comment. Skip it. We *should* parse it like # toplevel Texinfo code until the next end of line, but # doing so is too hard -- there is only a single comment # in the entire document. while 1: c = self.__reader.getc() if c == '\n': return self.__get_token() else: self.error(self.__reader.line_no(), "bad character ``%s''" % (c,)) return c def __read_arg(self): arg = "" level = 0 while 1: c = self.__reader.getc() if c == '@': # Handle '@{', '@}', and '@@' (and everything else # that starts with `@'). arg = arg + c c = self.__reader.getc() elif c == '{': level = level + 1 elif c == '}': if level == 0: return arg level = level - 1 arg = arg + c def error(self, line_no, errmsg): self.__reader.error(line_no, errmsg) def generate_stable_names(self): number_suffix_re = re.compile("(.*)-([1-9][0-9]*)$") # Create a translation table for type names. for type_name, type_obj in defined_types.items(): if isinstance(type_obj, prot_a_builtin): tt[type_name] = type_name else: pretty = type_name if pretty not in ["Who-Info-Old"]: pretty = remove_suffix(pretty, "-Old") m = number_suffix_re.match(pretty) if m != None: pretty = m.group(1) if type_obj.protover() != int(m.group(2)): self.error(type_obj.line_no(), "protocol version mismatch") stable = "%s-%d" % (pretty, type_obj.protover()) if tr.has_key(stable): self.error(type_obj.line_no(), "stable type name clash: both %s and %s " "becomes %s" % (tr[stable], type_name, stable)) tt[type_name] = stable tr[stable] = type_name tlist = tt.keys() tlist.sort() # Create a translation table for request names. for req_name, req_obj in defined_request_names.items(): pretty = req_name if pretty not in ['who-is-on-old', 'get-person-stat-old', 'get-conf-stat-older']: pretty = remove_suffix(pretty, "-old") pretty = remove_suffix(pretty, "-older") m = number_suffix_re.match(pretty) if m != None: pretty = m.group(1) if req_obj.protover() != int(m.group(2)): self.error(req_obj.line_no(), "protocol version mismatch") stable = "%s-%d" % (pretty, req_obj.protover()) if rr.has_key(stable): self.error(req_obj.line_no(), "stable request name clash: both %s and %s " "becomes %s" % (rr[stable], req_name, stable)) rt[req_name] = stable rr[stable] = req_name # Create a translation table for async names. for async_name, req_obj in defined_async_names.items(): pretty = async_name if pretty not in []: pretty = remove_suffix(pretty, "-old") m = number_suffix_re.match(pretty) if m != None: pretty = m.group(1) if req_obj.protover() != int(m.group(2)): self.error(req_obj.line_no(), "protocol version mismatch") stable = "%s-%d" % (pretty, req_obj.protover()) if ar.has_key(stable): self.error(req_obj.line_no(), "stable async name clash: both %s and %s " "becomes %s" % (ar[stable], async_name, stable)) at[async_name] = stable ar[stable] = async_name def generate_stable_output(filename, only_recommended): fp = open(filename + ".tmp", "w") fp.write("# This protocol-a.txt, generated from Protocol-A.texi\n") fp.write("# by checkargs.py. This file contains the definitions\n") fp.write("# of the types, requests and asynchronous messages in a\n") fp.write("# format that is intended to be machine-readable and\n") fp.write("# stable. All names have a numbered suffix which is\n") fp.write("# the protocol version in which the entity was first\n") fp.write("# introduced.\n") fp.write("\n") fp.write("# This file is Copyright (C) 1995-2003 Lysator ACS.\n") fp.write("# All rights reserved. This file may only be used\n") fp.write("# for testing purposes. Once the file format has\n") fp.write("# stabilized a future version of the file will probably\n") fp.write("# be placed in the public domain.\n") fp.write("\n") if only_recommended: fp.write("# This file only contains the recommended stuff.\n") else: fp.write("# Note: this file does not describe request 12,\n") fp.write("# lookup-name, which returns Conf-List-Archaic.\n") fp.write("# That is because that data type is so irregular.\n") fp.write("\n") fp.write("# Part 1: Define the alias names that Protocol-A.texi\n") fp.write("# uses. These aliases will change from time to time, as\n") fp.write("# new versions which are believed to be better are\n") fp.write("# introduced. It might be best not to use the aliases\n") fp.write("# in generated code.\n") fp.write("\n") fp.write("%%PROTOEDITION %s\n" % set_values["PROTOEDITION"]) fp.write("%%PROTOVER %s\n" % set_values["PROTOVER"]) fp.write("%%LYSKOMDVERSION %s\n\n" % set_values["VERSION"]) fp.write("\n") fp.write("# Types.\n") tlist = tt.keys() tlist.sort() for tn in tlist: if only_recommended and not defined_types[tn].recommended(): continue if tn != tt[tn] and tn not in ["Conf-List-Archaic"]: fp.write("%%type-alias %-30s %s\n" % (tt[tn], tn)) fp.write("\n") fp.write("# Requests.\n") rlist = rt.keys() rlist.sort() for rn in rlist: if (only_recommended and not defined_request_names[rn].recommended()): continue if rn != rt[rn] and rn not in ["lookup-name-1"]: fp.write("%%request-alias %-30s %s\n" % (rt[rn], rn)) fp.write("\n") fp.write("# Asynchronous messages.\n") alist = at.keys() alist.sort() for an in alist: if (only_recommended and not defined_async_names[an].recommended()): continue if an != at[an]: fp.write("%%async-alias %-30s %s\n" % (at[an], an)) fp.write("\n") fp.write("# Part two: all derived types.\n") fp.write("\n") tlist = tr.keys() tlist.sort() for tn in tlist: if tn in ["Conf-List-Archaic-1"]: continue t = defined_types[tr[tn]] if only_recommended and not t.recommended(): continue if isinstance(t, prot_a_builtin): fp.write("%%builtin %s\n" % tn) elif isinstance(t, prot_a_simple): if t.array(): fp.write("%s ::= ARRAY %s\n" % (tn, tt[t.base_type()])) else: fp.write("%s ::= %s\n" % (tn, tt[t.base_type()])) elif isinstance(t, prot_a_alternate): fp.write("%s ::= %s | %s\n" % (tn, tt[t.type_a()], tt[t.type_b()])) elif isinstance(t, prot_a_struct): fp.write("%s ::=\n" % tn) first = 1 for field_name, field_type, is_array in t.fields(): if first: fp.write(" ( ") else: fp.write(" ") first = 0 if is_array: fp.write("%-20s : ARRAY %s;\n" % (field_name, tt[field_type])) else: fp.write("%-20s : %s;\n" % (field_name, tt[field_type])) fp.write(" )\n") elif isinstance(t, prot_a_bitstring): fp.write("%s ::= BITSTRING\n" % tn) first = 1 for bit in t.bits(): if first: fp.write(" ( ") else: fp.write(" ") first = 0 fp.write("%s;\n" % bit) fp.write(" )\n") elif isinstance(t, prot_a_selection): fp.write("%s ::= SELECTION\n" % tn) first = 1 for (nr, name, tailname, tailtype, array) in t.fields(): if first: fp.write(" ( ") else: fp.write(" ") first = 0 fp.write("%2d=%-10s %-20s : " % (nr, name, tailname)) if array: fp.write("ARRAY ") fp.write("%s;\n" % tt[tailtype]) fp.write(" )\n") elif isinstance(t, prot_a_enumeration_of): fp.write("%s ::= ENUMERATION-OF(%s)\n" % ( tn, tt[t.base_type()])) else: sys.stderr.write("bad type %s" % repr(t)) sys.exit(1) fp.write("\n") fp.write("# Part three: all requests types.\n") fp.write("\n") rlist = rr.keys() rlist.sort() for rn in rlist: if rn in ["lookup-name-1"]: continue r = defined_request_names[rr[rn]] if only_recommended and not r.recommended(): continue fp.write("%%Request: %d\n" % r.request_nr()) fp.write(" %%Name: %s\n" % rt[r.request_name()]) fp.write(" %%Protocol version: %s\n" % r.protover()) if r.recommended(): fp.write(" %Status: Recommended\n") elif r.experimental(): fp.write(" %Status: Experimental\n") elif r.obsolete(): fp.write(" %Status: Obsolete\n") fp.write(" %%Obsoleted by: %s\n" % r.obsver()) else: sys.stderr.write("No status found\n") sys.exit(1) fp.write("%End Request\n\n") leader = "%s [%d]" % (rt[r.request_name()], r.request_nr()) if len(r.arguments()) == 0: fp.write("%s ( )" % (leader)) elif len(r.arguments()) == 1 and r.arguments()[0] != None: argname, argtype, array = r.arguments()[0] if array: fp.write("%s ( %s : ARRAY %s )" % (leader, argname, argtype)) else: fp.write("%s ( %s : %s )" % (leader, argname, argtype)) else: leader = "%s (( " % leader fp.write(leader) first = 1 for a in r.arguments(): if a == None: continue argname, argtype, array = a if not first: fp.write(";\n" + " " * len(leader)) if array: fp.write("%-10s : ARRAY %s" % (argname, tt[argtype])) else: fp.write("%-10s : %s" % (argname, tt[argtype])) first = 0 fp.write(" ))") fp.write("\n -> ( ") if r.return_type() != None: if r.array(): fp.write("ARRAY ") fp.write(tt[r.return_type()]) fp.write(" );\n\n") fp.write("\n") fp.write("# Part four: all asynchronous messages.\n") fp.write("\n") alist = ar.keys() alist.sort() for an in alist: r = defined_async_names[ar[an]] if only_recommended and not r.recommended(): continue fp.write("%%Async: %d\n" % r.request_nr()) fp.write(" %%Async-Name: %s\n" % at[r.request_name()]) fp.write(" %%Protocol version: %s\n" % r.protover()) if r.recommended(): fp.write(" %Status: Recommended\n") elif r.experimental(): fp.write(" %Status: Experimental\n") elif r.obsolete(): fp.write(" %Status: Obsolete\n") fp.write(" %%Obsoleted by: %s\n" % r.obsver()) else: sys.stderr.write("No status found\n") sys.exit(1) fp.write("%End Async\n\n") leader = "%s [%d]" % (at[r.request_name()], r.request_nr()) if len(r.arguments()) == 0: fp.write("%s ( )" % (leader)) elif len(r.arguments()) == 1 and r.arguments()[0] != None: argname, argtype, array = r.arguments()[0] if array: fp.write("%s ( %s : ARRAY %s )" % (leader, argname, argtype)) else: fp.write("%s ( %s : %s )" % (leader, argname, argtype)) else: leader = "%s (( " % leader fp.write(leader) first = 1 for a in r.arguments(): if a == None: continue argname, argtype, array = a if not first: fp.write(";\n" + " " * len(leader)) if array: fp.write("%-10s : ARRAY %s" % (argname, tt[argtype])) else: fp.write("%-10s : %s" % (argname, tt[argtype])) first = 0 fp.write(" ))") fp.write("\n\n") fp.close() os.rename(filename + ".tmp", filename) def generate_summary_output(filename): fp = open(filename + ".tmp", "w") fp.write("# This is %s, generated from Protocol-A.texi\n" % filename) fp.write("# by checkargs.py. This file contains the definitions\n") fp.write("# of the types, requests and asynchronous messages in a\n") fp.write("# format that is intended to be both machine-readable and\n") fp.write("# human-readable. The requess may be renamed in the future.\n") fp.write("\n") fp.write("# This file is Copyright (C) 1995-2003 Lysator ACS.\n") fp.write("# All rights reserved. This file may only be used\n") fp.write("# for testing purposes. Once the file format has\n") fp.write("# stabilized a future version of the file will probably\n") fp.write("# be placed in the public domain.\n") fp.write("\n") fp.write("# This file only contains the recommended stuff.\n") fp.write("\n") fp.write("%%PROTOEDITION %s\n" % set_values["PROTOEDITION"]) fp.write("%%PROTOVER %s\n" % set_values["PROTOVER"]) fp.write("%%LYSKOMDVERSION %s\n\n" % set_values["VERSION"]) tlist = tt.keys() tlist.sort() for tn in tlist: t = defined_types[tn] if not t.recommended(): continue if isinstance(t, prot_a_builtin): fp.write("%%builtin %s\n" % tn) elif isinstance(t, prot_a_simple): if t.array(): fp.write("%s ::= ARRAY %s\n" % (tn, t.base_type())) else: fp.write("%s ::= %s\n" % (tn, t.base_type())) elif isinstance(t, prot_a_alternate): fp.write("%s ::= %s | %s\n" % (tn, t.type_a(), t.type_b())) elif isinstance(t, prot_a_struct): fp.write("%s ::=\n" % tn) first = 1 for field_name, field_type, is_array in t.fields(): if first: fp.write(" ( ") else: fp.write(" ") first = 0 if is_array: fp.write("%-20s : ARRAY %s;\n" % (field_name, field_type)) else: fp.write("%-20s : %s;\n" % (field_name, field_type)) fp.write(" )\n") elif isinstance(t, prot_a_bitstring): fp.write("%s ::= BITSTRING\n" % tn) first = 1 for bit in t.bits(): if first: fp.write(" ( ") else: fp.write(" ") first = 0 fp.write("%s;\n" % bit) fp.write(" )\n") elif isinstance(t, prot_a_selection): fp.write("%s ::= SELECTION\n" % tn) first = 1 for (nr, name, tailname, tailtype, array) in t.fields(): if first: fp.write(" ( ") else: fp.write(" ") first = 0 fp.write("%2d=%-10s %-20s : " % (nr, name, tailname)) if array: fp.write("ARRAY ") fp.write("%s;\n" % tailtype) fp.write(" )\n") elif isinstance(t, prot_a_enumeration_of): fp.write("%s ::= ENUMERATION-OF(%s)\n" % ( tn, t.base_type())) else: sys.stderr.write("bad type %s" % repr(t)) sys.exit(1) rlist = rt.keys() rlist.sort() for rn in rlist: r = defined_request_names[rn] if not r.recommended(): continue fp.write("%%Request: %d\n" % r.request_nr()) fp.write(" %%Name: %s\n" % r.request_name()) fp.write(" %%Stable-Name: %s\n" % rt[r.request_name()]) fp.write(" %%Protocol version: %s\n" % r.protover()) if r.recommended(): fp.write(" %Status: Recommended\n") elif r.experimental(): fp.write(" %Status: Experimental\n") elif r.obsolete(): fp.write(" %Status: Obsolete\n") fp.write(" %%Obsoleted by: %s\n" % r.obsver()) else: sys.stderr.write("No status found\n") sys.exit(1) fp.write("%End Request\n\n") leader = "%s [%d]" % (r.request_name(), r.request_nr()) if len(r.arguments()) == 0: fp.write("%s ( )" % (leader)) elif len(r.arguments()) == 1 and r.arguments()[0] != None: argname, argtype, array = r.arguments()[0] if array: fp.write("%s ( %s : ARRAY %s )" % (leader, argname, argtype)) else: fp.write("%s ( %s : %s )" % (leader, argname, argtype)) else: leader = "%s (( " % leader fp.write(leader) first = 1 for a in r.arguments(): if a == None: continue argname, argtype, array = a if not first: fp.write(";\n" + " " * len(leader)) if array: fp.write("%-10s : ARRAY %s" % (argname, argtype)) else: fp.write("%-10s : %s" % (argname, argtype)) first = 0 fp.write(" ))") fp.write("\n -> ( ") if r.return_type() != None: if r.array(): fp.write("ARRAY ") fp.write(r.return_type()) fp.write(" );\n\n") alist = at.keys() alist.sort() for an in alist: r = defined_async_names[an] if not r.recommended(): continue fp.write("%%Async: %d\n" % r.request_nr()) fp.write(" %%Async-Name: %s\n" % r.request_name()) fp.write(" %%Async-Stable-Name: %s\n" % at[r.request_name()]) fp.write(" %%Protocol version: %s\n" % r.protover()) if r.recommended(): fp.write(" %Status: Recommended\n") elif r.experimental(): fp.write(" %Status: Experimental\n") elif r.obsolete(): fp.write(" %Status: Obsolete\n") fp.write(" %%Obsoleted by: %s\n" % r.obsver()) else: sys.stderr.write("No status found\n") sys.exit(1) fp.write("%End Async\n\n") leader = "%s [%d]" % (r.request_name(), r.request_nr()) if len(r.arguments()) == 0: fp.write("%s ( )" % (leader)) elif len(r.arguments()) == 1 and r.arguments()[0] != None: argname, argtype, array = r.arguments()[0] if array: fp.write("%s ( %s : ARRAY %s )" % (leader, argname, argtype)) else: fp.write("%s ( %s : %s )" % (leader, argname, argtype)) else: leader = "%s (( " % leader fp.write(leader) first = 1 for a in r.arguments(): if a == None: continue argname, argtype, array = a if not first: fp.write(";\n" + " " * len(leader)) if array: fp.write("%-10s : ARRAY %s" % (argname, argtype)) else: fp.write("%-10s : %s" % (argname, argtype)) first = 0 fp.write(" ))") fp.write("\n\n") fp.close() os.rename(filename + ".tmp", filename) if __name__ == '__main__': l = lexer(sys.argv[1]) ret = l.run() if ret == 0: generate_stable_output("protocol-a-full.txt", 0) generate_stable_output("protocol-a-recommended.txt", 1) generate_summary_output("protocol-a-current.txt") elif ret == 1: sys.exit(1) else: print "ERROR: bad return from run", `ret` sys.exit(2) lyskom-server-2.1.2/doc/cmsltt12.mf0000664000015100472110000000716106160274530012567 % Computer Modern Slanted Typewriter Text for use with 12 point if unknown cmbase: input cmbase fi font_identifier:="CMSLTT"; font_size 12pt#; u#:=24.7/36pt#; % unit width width_adj#:=0pt#; % width adjustment for certain characters serif_fit#:=0pt#; % extra sidebar near lowercase serifs cap_serif_fit#:=0pt#; % extra sidebar near uppercase serifs letter_fit#:=0pt#; % extra space added to all sidebars body_height#:=300/36pt#; % height of tallest characters asc_height#:=264/36pt#; % height of lowercase ascenders cap_height#:=264/36pt#; % height of caps fig_height#:=264/36pt#; % height of numerals x_height#:=186/36pt#; % height of lowercase without ascenders math_axis#:=132/36pt#; % axis of symmetry for math symbols bar_height#:=95/36pt#; % height of crossbar in lowercase e comma_depth#:=60/36pt#; % depth of comma below baseline desc_depth#:=96/36pt#; % depth of lowercase descenders crisp#:=25/36pt#; % diameter of serif corners tiny#:=25/36pt#; % diameter of rounded corners fine#:=22/36pt#; % diameter of sharply rounded corners thin_join#:=22/36pt#; % width of extrafine details hair#:=28/36pt#; % lowercase hairline breadth stem#:=28/36pt#; % lowercase stem breadth curve#:=28/36pt#; % lowercase curve breadth ess#:=25/36pt#; % breadth in middle of lowercase s flare#:=35/36pt#; % diameter of bulbs or breadth of terminals dot_size#:=39/36pt#; % diameter of dots cap_hair#:=28/36pt#; % uppercase hairline breadth cap_stem#:=28/36pt#; % uppercase stem breadth cap_curve#:=28/36pt#; % uppercase curve breadth cap_ess#:=28/36pt#; % breadth in middle of uppercase s rule_thickness#:=28/36pt#; % thickness of lines in math symbols dish#:=0pt#; % amount erased at top or bottom of serifs bracket#:=0pt#; % vertical distance from serif base to tangent jut#:=39/36pt#; % protrusion of lowercase serifs cap_jut#:=39/36pt#; % protrusion of uppercase serifs beak_jut#:=0pt#; % horizontal protrusion of beak serifs beak#:=39/36pt#; % vertical protrusion of beak serifs vair#:=25/36pt#; % vertical diameter of hairlines notch_cut#:=28/36pt#; % maximum breadth above or below notches bar#:=25/36pt#; % lowercase bar thickness slab#:=25/36pt#; % serif and arm thickness cap_bar#:=25/36pt#; % uppercase bar thickness cap_band#:=25/36pt#; % uppercase thickness above/below lobes cap_notch_cut#:=28/36pt#; % max breadth above/below uppercase notches serif_drop#:=0pt#; % vertical drop of sloped serifs stem_corr#:=0pt#; % for small refinements of stem breadth vair_corr#:=0pt#; % for small refinements of hairline height apex_corr#:=11/36pt#; % extra width at diagonal junctions o#:=5/36pt#; % amount of overshoot for curves apex_o#:=4/36pt#; % amount of overshoot for diagonal junctions slant:=1/6; % tilt ratio $(\Delta x/\Delta y)$ fudge:=0.86; % factor applied to weights of heavy characters math_spread:=-1; % extra openness of math symbols superness:=1/sqrt2; % parameter for superellipses superpull:=0; % extra openness inside bowls beak_darkness:=0; % fraction of triangle inside beak serifs ligs:=0; % level of ligatures to be included square_dots:=false; % should dots be square? hefty:=true; % should we try hard not to be overweight? serifs:=true; % should serifs and bulbs be attached? monospace:=true; % should all characters have the same width? variant_g:=false; % should an italic-style g be used? low_asterisk:=true; % should the asterisk be centered at the axis? math_fitting:=false; % should math-mode spacing be used? generate roman % switch to the driver file lyskom-server-2.1.2/doc/constructs.expected0000664000015100472110000000671707723637625014550 @TeX{} @bullet{} @code{ hjkl} @code{!} @code{0 *} @code{0101} @code{0} @code{10607} @code{1} @code{::=} @code{;} @code{CC} @code{Content-Type} @code{Date} @code{From} @code{In-Reply-To} @code{Joe Q. Public} @code{LysKOM} @code{Message-ID} @code{References} @code{Reply-To} @code{Subject} @code{To} @code{addr-spec} @code{all} @code{asdf} @code{backup} @code{block-a} @code{boolean} @code{b} @code{clean} @code{common} @code{confs} @code{description} @code{error-reply} @code{followups-to} @code{html} @code{integer} @code{items-to-add} @code{items-to-delete} @code{later-texts-exists} @code{name} @code{old-pwd} @code{pepsi} @code{persons} @code{printf("%g", val);} @code{protocol-error} @code{reserved1} @code{shape-of-world} @code{spam} @code{string-list} @code{texts} @code{type} @code{use-utc} @code{what-i-am-doing} @code{what} @code{when} @code{|} @command{ed} @command{komimportmail} @command{lyskomd} @command{procmail} @copyright{} @daemon{} @dfn{creator} @dfn{dense} @dfn{sparse} @dfn{stable} @dfn{supervisor} @dots{} @emph{Administrativia:} @emph{Compatibility info:} @emph{Editorial changes:} @emph{Fixed errors:} @emph{Modified aux-item:} @emph{New appendix:} @emph{New async messages:} @emph{New aux-item:} @emph{New aux-items:} @emph{New calls:} @emph{New error codes:} @emph{New stuff:} @emph{New types:} @emph{Normally assigned} @emph{Normally not assigned} @emph{Please note:} @emph{Previously undocumented stuff:} @emph{Protocol change:} @emph{Status change:} @emph{Typographic improvements:} @emph{must} @emph{one more} @file{Protocol-A.texi} @file{doc/checkargs.py} @file{texinfo.tex} @i{A note about the examples:} @i{Example:} @i{foo} @linkhere{} @multitable {59=create-anonymous-text} @samp{%% No connections left.} @samp{%%LysKOM unsupported protocol.} @samp{(1)} @samp{(10)} @samp{*} @samp{-Old} @samp{-older} @samp{-old} @samp{01000000} @samp{0} @samp{1 text/plain} @samp{133} @samp{15} @samp{1} @samp{2 18} @samp{20} @samp{2Hen 2Hsv 2Hfr} @samp{2Hes 2Hfr} @samp{2Hfr 2Hsv 2Hen} @samp{3 135 136 137 } @samp{43 8 3 12 7 93 1 193 1} @samp{4} @samp{5} @samp{:::} @samp{A} @samp{LysKOM} @samp{Obsolete} @samp{O} @samp{X-} @samp{[5]} @samp{a d} @samp{async-} @samp{create-person-old} @samp{documentation} @samp{elisp-client 0.47.3} @samp{kom.lysator.liu.se:8300} @samp{kom.lysator.liu.se} @samp{lyskomd} @samp{pgp -sba} @samp{r} @samp{sender} @samp{sent-by} @samp{text/enriched} @samp{text/html} @samp{text/plain} @samp{text/x-kom-basic} @samp{x-kom/basic} @samp{x-kom/text} @samp{x-kom/user-area} @title{LysKOM Protocol A} @uref{http://bugzilla.lysator.liu.se/show_bug.cgi?id=133, bug 133} @uref{http://bugzilla.lysator.liu.se/show_bug.cgi?id=134, bug 134} @uref{http://bugzilla.lysator.liu.se/show_bug.cgi?id=135, bug 135} @uref{http://bugzilla.lysator.liu.se/show_bug.cgi?id=136, bug 136} @uref{http://bugzilla.lysator.liu.se/show_bug.cgi?id=137, bug 137} @uref{http://bugzilla.lysator.liu.se/show_bug.cgi?id=138, bug 138} @uref{http://bugzilla.lysator.liu.se/show_bug.cgi?id=99, Bug 99} @uref{http://bugzilla.lysator.liu.se/} @uref{http://lcweb.loc.gov/standards/iso639-2/langcodes.html} @uref{http://www.lysator.liu.se/lyskom/protocol/} @value{IAM} @value{Kent} @value{PROTOEDITION} @value{PROTOVER} @value{Pell} @value{VERSION} @value{presconf} @var{C} @var{P} @var{V} @var{a-single-field} @var{call} @var{element} @var{exporter} @var{hostname} @var{name} @var{number} @var{n} @var{port} @var{randomness} @var{reply} @var{request} @var{server} @var{tail} @var{text-no} @var{text} @var{type} @var{username} lyskom-server-2.1.2/doc/filterlines.py0000664000015100472110000000342107721716114013462 #!/usr/bin/env python # Remove lines matching any line of several input files. # Copyright (C) 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Read and remember each line from all the file names given as arguments. # Then, read stdin, remove any line present in the input files, and # print the rest to stdout. import sys def add_contents(filename, m): f = open(filename, "r") while 1: line = f.readline() if line == "": break if line[-1] == "\n": line = line[:-1] m[intern(line)] = None f.close() def filter_file(f, m): while 1: line = f.readline() if line == "": break if line[-1] == "\n": line = line[:-1] if not m.has_key(line): print line def main(files): m = {} for fn in files: add_contents(fn, m) filter_file(sys.stdin, m) if __name__ == '__main__': main(sys.argv) lyskom-server-2.1.2/doc/kom-style.el0000664000015100472110000000137707720622160013042 ;; Define the indentation style "KOM", for use with GNU Emacs. This ;; file was placed in the public domain by Per Cederqvist on ;; 2003-08-19. Please report bugs or improvements at ;; http://bugzilla.lysator.liu.se/ (c-add-style "KOM" '((c-basic-offset . 4) (c-comment-only-line-offset . 0) (c-offsets-alist . ((statement-block-intro . +) (knr-argdecl-intro . +) (substatement-open . 0) (label . 0) (statement-cont . +))) (c-hanging-braces-alist . ((brace-list-open) (class-open after) (inline-close after) (block-close . c-snug-do-while))) (c-hanging-colons-alist . ((access-label after) (case-label after))) (c-cleanup-list . (defun-close-semi scope-operator)))) lyskom-server-2.1.2/doc/tac.py0000664000015100472110000000232007721716114011706 #!/usr/bin/env python # Reverse the contents of stdin. # Copyright (C) 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. import sys def main(): # Known limitation: we fail if the last line doesn't end with a newline. lines = sys.stdin.readlines() lines.reverse() for line in lines: sys.stdout.write(line) if __name__ == '__main__': main() lyskom-server-2.1.2/doc/man/0000777000015100472110000000000007723710262011425 5lyskom-server-2.1.2/doc/man/Makefile.am0000664000015100472110000000217407717413230013401 # $Id: Makefile.am,v 1.5 2003/08/16 11:29:10 ceder Exp $ # Copyright (C) 1998 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # include $(top_srcdir)/scripts/common.make man_MANS = lyskom.5 dbck.8 lyskomd.8 updateLysKOM.8 \ savecore-lyskom.8 splitkomdb.8 EXTRA_DIST = .cvsignore $(man_MANS) lyskom-server-2.1.2/doc/man/Makefile.in0000664000015100472110000003056107723707422013421 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # $Id: Makefile.am,v 1.5 2003/08/16 11:29:10 ceder Exp $ # Copyright (C) 1998 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEBUG_CALLS = @DEBUG_CALLS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EFENCE = @EFENCE@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FLEX = @FLEX@ HAVE_PYTHON_FALSE = @HAVE_PYTHON_FALSE@ HAVE_PYTHON_TRUE = @HAVE_PYTHON_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSURE = @INSURE@ LANGUAGE_SUFFIX = @LANGUAGE_SUFFIX@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ SED = @SED@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRACED_ALLOCATIONS = @TRACED_ALLOCATIONS@ U = @U@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ YACC = @YACC@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ RM = rm -f dbdir = $(localstatedir)/lyskomd/db exportdir = $(localstatedir)/lyskomd/exportdb man_MANS = lyskom.5 dbck.8 lyskomd.8 updateLysKOM.8 \ savecore-lyskom.8 splitkomdb.8 EXTRA_DIST = .cvsignore $(man_MANS) subdir = doc/man ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = DIST_SOURCES = NROFF = nroff MANS = $(man_MANS) DIST_COMMON = $(top_srcdir)/scripts/common.make Makefile.am Makefile.in all: all-am .SUFFIXES: $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/scripts/common.make $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/man/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) uninstall-info-am: man5dir = $(mandir)/man5 install-man5: $(man5_MANS) $(man_MANS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(man5dir) @list='$(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS)'; \ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ for i in $$l2; do \ case "$$i" in \ *.5*) list="$$list $$i" ;; \ esac; \ done; \ for i in $$list; do \ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ else file=$$i; fi; \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ case "$$ext" in \ 5*) ;; \ *) ext='5' ;; \ esac; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man5dir)/$$inst"; \ $(INSTALL_DATA) $$file $(DESTDIR)$(man5dir)/$$inst; \ done uninstall-man5: @$(NORMAL_UNINSTALL) @list='$(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS)'; \ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ for i in $$l2; do \ case "$$i" in \ *.5*) list="$$list $$i" ;; \ esac; \ done; \ for i in $$list; do \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ case "$$ext" in \ 5*) ;; \ *) ext='5' ;; \ esac; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " rm -f $(DESTDIR)$(man5dir)/$$inst"; \ rm -f $(DESTDIR)$(man5dir)/$$inst; \ done man8dir = $(mandir)/man8 install-man8: $(man8_MANS) $(man_MANS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(man8dir) @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ for i in $$l2; do \ case "$$i" in \ *.8*) list="$$list $$i" ;; \ esac; \ done; \ for i in $$list; do \ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ else file=$$i; fi; \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ case "$$ext" in \ 8*) ;; \ *) ext='8' ;; \ esac; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \ $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \ done uninstall-man8: @$(NORMAL_UNINSTALL) @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ for i in $$l2; do \ case "$$i" in \ *.8*) list="$$list $$i" ;; \ esac; \ done; \ for i in $$list; do \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ case "$$ext" in \ 8*) ;; \ *) ext='8' ;; \ esac; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \ rm -f $(DESTDIR)$(man8dir)/$$inst; \ done tags: TAGS TAGS: ctags: CTAGS CTAGS: DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = ../.. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) $(mkinstalldirs) $(distdir)/../../scripts @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(MANS) installdirs: $(mkinstalldirs) $(DESTDIR)$(man5dir) $(DESTDIR)$(man8dir) install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: info: info-am info-am: install-data-am: install-man install-exec-am: install-info: install-info-am install-man: install-man5 install-man8 installcheck-am: maintainer-clean: maintainer-clean-am maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am uninstall-man uninstall-man: uninstall-man5 uninstall-man8 .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am info info-am install \ install-am install-data install-data-am install-exec \ install-exec-am install-info install-info-am install-man \ install-man5 install-man8 install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am uninstall uninstall-am uninstall-info-am \ uninstall-man uninstall-man5 uninstall-man8 # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/doc/man/.cvsignore0000664000015100472110000000002506551006341013332 Makefile Makefile.in lyskom-server-2.1.2/doc/man/lyskom.50000664000015100472110000000262407721716114012753 .\" $Id: lyskom.5,v 1.10 2003/08/23 16:38:22 ceder Exp $ .\" Copyright (C) 1991, 1996, 1999, 2003 Lysator Academic Computer Association. .\" .\" This file is part of the LysKOM server. .\" .\" LysKOM 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 1, or (at your option) .\" any later version. .\" .\" LysKOM 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 LysKOM; see the file COPYING. If not, write to .\" Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, .\" or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, .\" MA 02139, USA. .\" .\" Please report bugs at http://bugzilla.lysator.liu.se/. .\" .\" $Id: lyskom.5,v 1.10 2003/08/23 16:38:22 ceder Exp $ .\" $Date: 2003/08/23 16:38:22 $ .TH lyskom 5 "April 3, 1999" .SH NAME lyskom - LysKOM .I database format .SH DESCRIPTION The LysKOM database is stored in a couple of files. .SH SEE ALSO Full documentation can be found in the Texinfo manual "lyskomd Database Format Specification" (found in info format as .BR lyskomdb.info ). lyskom-server-2.1.2/doc/man/dbck.80000664000015100472110000000272707721716114012347 .\" $Id: dbck.8,v 1.20 2003/08/23 16:38:22 ceder Exp $ .\" Copyright (C) 1991-1992, 1994-1996, 1999, 2002-2003 Lysator Academic Computer Association. .\" .\" This file is part of the LysKOM server. .\" .\" LysKOM 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 1, or (at your option) .\" any later version. .\" .\" LysKOM 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 LysKOM; see the file COPYING. If not, write to .\" Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, .\" or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, .\" MA 02139, USA. .\" .\" Please report bugs at http://bugzilla.lysator.liu.se/. .\" .\" $Id: dbck.8,v 1.20 2003/08/23 16:38:22 ceder Exp $ .\" $Date: 2003/08/23 16:38:22 $ .TH dbck 8 "April 3, 1999" .SH NAME dbck - LysKOM database maintenance program .SH SYNOPSIS .B /usr/lyskom/bin/dbck [ .B options ] [ .I config_file ] .SH DESCRIPTION dbck is a LysKOM database maintenance program. .SH SEE ALSO Full documentation can be found in the Texinfo manual "dbck Reference Manual" (found in info format as .BR lyskomd.info ). lyskom-server-2.1.2/doc/man/lyskomd.80000664000015100472110000000265107721716115013123 .\" $Id: lyskomd.8,v 1.36 2003/08/23 16:38:22 ceder Exp $ .\" Copyright (C) 1991, 1994-1999, 2003 Lysator Academic Computer Association. .\" .\" This file is part of the LysKOM server. .\" .\" LysKOM 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 1, or (at your option) .\" any later version. .\" .\" LysKOM 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 LysKOM; see the file COPYING. If not, write to .\" Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, .\" or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, .\" MA 02139, USA. .\" .\" Please report bugs at http://bugzilla.lysator.liu.se/. .\" .\" $Id: lyskomd.8,v 1.36 2003/08/23 16:38:22 ceder Exp $ .\" $Date: 2003/08/23 16:38:22 $ .TH lyskomd 8 "April 3, 1999" "Lysator" .SH NAME lyskomd - LysKOM server .SH SYNOPSIS .B lyskomd [ .B -d ... ] [ .B config-file ] .SH DESCRIPTION lyskomd is a LysKOM server. .SH SEE ALSO Full documentation can be found in the Texinfo manual "lyskomd Reference Manual" (found in info format as .BR lyskomd.info ). lyskom-server-2.1.2/doc/man/updateLysKOM.80000664000015100472110000000304307721716115013756 .\" $Id: updateLysKOM.8,v 1.7 2003/08/23 16:38:22 ceder Exp $ .\" Copyright (C) 1991, 1999, 2003 Lysator Academic Computer Association. .\" .\" This file is part of the LysKOM server. .\" .\" LysKOM 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 1, or (at your option) .\" any later version. .\" .\" LysKOM 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 LysKOM; see the file COPYING. If not, write to .\" Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, .\" or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, .\" MA 02139, USA. .\" .\" Please report bugs at http://bugzilla.lysator.liu.se/. .\" .\" $Id: updateLysKOM.8,v 1.7 2003/08/23 16:38:22 ceder Exp $ .\" $Date: 2003/08/23 16:38:22 $ .TH updateLysKOM 8 "April 3, 1999" .SH NAME updateLysKOM - check that lyskomd is running .SH SYNOPSIS .B /usr/lyskom/bin/updateLysKOM .SH DESCRIPTION .B updateLysKOM causes .B lyskomd to save some status information. If .B lyskomd should be running but isn't, .B updateLysKOM will restart it. .SH SEE ALSO Full documentation can be found in the Texinfo manual "lyskomd Reference Manual" (found in info format as .BR lyskomd.info ). lyskom-server-2.1.2/doc/man/savecore-lyskom.80000664000015100472110000000257707717413231014571 .\" Copyright (C) 2003 Lysator Academic Computer Association. .\" .\" This file is part of the LysKOM server. .\" .\" LysKOM 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 1, or (at your option) .\" any later version. .\" .\" LysKOM 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 LysKOM; see the file COPYING. If not, write to .\" Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, .\" or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, .\" MA 02139, USA. .\" .\" Please report bugs at http://bugzilla.lysator.liu.se/. .\" .TH savecore-lyskom 8 "August 16, 2003" "Lysator" .SH NAME savecore-lyskom - Save core files from lyskomd .SH SYNOPSIS .B savecore-lyskom .SH DESCRIPTION The .B savecore-lyskom script is provided as a hook where system administrators can save a core file before a new .B lyskomd process is started. .SH SEE ALSO Full documentation can be found in the Texinfo manual "lyskomd Reference Manual" (found in info format as .BR lyskomd.info ). lyskom-server-2.1.2/doc/man/splitkomdb.80000664000015100472110000000246307717413231013610 .\" Copyright (C) 2003 Lysator Academic Computer Association. .\" .\" This file is part of the LysKOM server. .\" .\" LysKOM 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 1, or (at your option) .\" any later version. .\" .\" LysKOM 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 LysKOM; see the file COPYING. If not, write to .\" Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, .\" or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, .\" MA 02139, USA. .\" .\" Please report bugs at http://bugzilla.lysator.liu.se/. .\" .TH splitkomdb 8 "August 16, 2003" "Lysator" .SH NAME splitkomdb - Split the database for efficient backups .SH SYNOPSIS .B splitkomdb .SH DESCRIPTION The .B splitkomdb program can split the database for efficient backups. .SH SEE ALSO Full documentation can be found in the Texinfo manual "lyskomd Reference Manual" (found in info format as .BR lyskomd.info ). lyskom-server-2.1.2/doc/protocol-a.info0000664000015100472110000002300107723710263013521 This is protocol-a.info, produced by makeinfo version 4.2 from Protocol-A.texi. This is the LysKOM Protocol A specification, edition 11.1. It specifies version 11 of the protocol. It was first distributed with version 2.1.2 of lyskomd. Copyright (C) 1995-2003 Lysator ACS. Permission is granted to make and distribute verbatim copies of this specification provided the copyright notice and this permission notice are preserved on all copies. Modified versions of this document may be redistributed with the added condition that all modifications not cleared with the LysKOM development group are clearly marked and that the entire modified work be redistributed under the same conditions as the original. Permission is granted to copy and distribute translations of this manual into another language under the same conditions as for modified versions. INFO-DIR-SECTION LysKOM START-INFO-DIR-ENTRY * Protocol A: (protocol-a). The LysKOM Protocol A specification. END-INFO-DIR-ENTRY  Indirect: protocol-a.info-1: 1058 protocol-a.info-2: 50894 protocol-a.info-3: 99273 protocol-a.info-4: 148136 protocol-a.info-5: 196409 protocol-a.info-6: 244648 protocol-a.info-7: 294488 protocol-a.info-8: 341378 protocol-a.info-9: 389049  Tag Table: (Indirect) Node: Top1058 Node: About this document3067 Node: Preface3199 Ref: Preface-Footnote-15176 Ref: Preface-Footnote-25272 Node: Concepts5321 Node: Articles6208 Ref: Articles-Footnote-17589 Node: Conferences7670 Node: Persons and Sessions10494 Node: The Misc-Info List11372 Node: The Aux-Item List17249 Node: About Aux-Items18035 Node: Aux-Item Inheritance19447 Node: Predefined Aux-Item Types20896 Node: Client-Specific Aux-Item Types22525 Node: Experimental Aux-Item Types23751 Node: Defining New Aux-Item Types24101 Node: Security25229 Ref: Security-Footnote-127148 Ref: Security-Footnote-227282 Node: Membership and Reading27412 Node: Fundamentals29700 Node: Notation30477 Node: Simple Data Types31388 Ref: INT3231545 Ref: INT1631545 Ref: INT831545 Ref: BOOL31545 Ref: FLOAT31755 Ref: HOLLERITH32112 Ref: BITSTRING33342 Ref: ENUMERATION33977 Ref: ARRAY35365 Ref: SELECTION36038 Ref: RPC36936 Node: Connecting to the Server38061 Ref: Connecting to the Server-Footnote-139971 Ref: Connecting to the Server-Footnote-240073 Node: Client-Server Dialog40544 Ref: Client-Server Dialog-Footnote-145331 Node: Protocol Error Messages45551 Node: LysKOM Data Types46928 Node: Common Types48451 Ref: Time48683 Ref: Conf-No49955 Ref: Text-No50082 Ref: Local-Text-No50082 Ref: Text-List50082 Ref: Pers-No50603 Ref: Session-No50603 Node: Auxiliary Information50894 Ref: Aux-No51064 Ref: Aux-Item51064 Ref: Aux-Item-Input51064 Ref: Aux-Item-Flags51064 Node: Conference Types54360 Ref: Conf-Type54533 Ref: Extended-Conf-Type54533 Ref: Any-Conf-Type54533 Node: Conference Search Results56205 Ref: Conf-Z-Info56398 Node: Conference Status Types56695 Ref: Garb-Nice56899 Ref: Conference-Old56899 Ref: Conference57875 Ref: UConference59014 Ref: Conference Status Types-Footnote-161913 Ref: Conference Status Types-Footnote-262026 Ref: Conference Status Types-Footnote-362192 Node: Archaic way to list conferences62509 Ref: Conf-List-Archaic62740 Node: Mapping Local to Global Text Numbers63247 Ref: Text-Mapping63483 Ref: Local-To-Global-Block63796 Ref: Text-Number-Pair64007 Node: Server Information66190 Ref: Info66378 Ref: Info-Old66815 Ref: Version-Info67196 Ref: Static-Server-Info67423 Node: Person Status Types71082 Ref: Person71258 Ref: Personal-Flags72352 Ref: Priv-Bits72661 Node: Membership Information75576 Ref: Membership-Type75753 Ref: Member77479 Ref: Membership78504 Ref: Read-Range78504 Ref: Membership-Old79171 Ref: Membership-1079518 Node: Article Marks82426 Ref: Mark82585 Node: Article Information83058 Ref: Misc-Info83222 Ref: Info-Type84062 Ref: Text-Stat-Old84127 Ref: Text-Stat84514 Node: Who Information86946 Ref: Who-Info-Old87108 Ref: Who-Info87108 Ref: Who-Info-Ident87108 Node: Session Information89653 Ref: Session-Info89814 Ref: Session-Info-Ident89814 Ref: Static-Session-Info90939 Ref: Session-Flags91257 Ref: Dynamic-Session-Info91596 Ref: Scheduling-Info92048 Ref: Session Information-Footnote-196745 Node: Statistics96843 Ref: Stats96962 Ref: Stats-Description96962 Node: Protocol Requests99273 Node: Protocol Notation109578 Node: login-old111762 Node: logout112440 Node: change-conference113175 Node: change-name113875 Node: change-what-i-am-doing115003 Node: create-person-old115610 Node: get-person-stat-old117459 Node: set-priv-bits118339 Node: set-passwd119374 Node: query-read-texts-old120602 Node: create-conf-old122184 Ref: create-conf-old-Footnote-1124170 Node: delete-conf124255 Node: lookup-name125429 Node: get-conf-stat-older126730 Node: add-member-old127598 Node: sub-member129667 Node: set-presentation131117 Node: set-etc-motd132978 Node: set-supervisor134697 Node: set-permitted-submitters136512 Node: set-super-conf138409 Node: set-conf-type139893 Node: set-garb-nice141671 Node: get-marks142840 Node: mark-text-old143568 Node: get-text144606 Node: get-text-stat-old146419 Node: mark-as-read148136 Node: create-text-old150092 Node: delete-text153320 Node: add-recipient154057 Node: sub-recipient156554 Node: add-comment158111 Node: sub-comment159967 Node: get-map161395 Node: get-time165289 Node: get-info-old165932 Node: add-footnote166919 Node: sub-footnote168787 Node: who-is-on-old170265 Node: set-unread170953 Ref: set-unread-Footnote-1172535 Node: set-motd-of-lyskom172716 Node: enable173844 Node: sync-kom174719 Node: shutdown-kom175762 Node: broadcast176574 Node: get-membership-old177134 Node: get-created-texts179811 Ref: get-created-texts-Footnote-1182579 Node: get-members-old182754 Node: get-person-stat184083 Node: get-conf-stat-old185296 Node: who-is-on186600 Node: get-unread-confs187359 Node: send-message188907 Node: get-session-info190549 Node: disconnect191196 Node: who-am-i192843 Node: set-user-area193350 Node: get-last-text194684 Node: create-anonymous-text-old196409 Node: find-next-text-no199318 Node: find-previous-text-no200320 Node: login201306 Node: who-is-on-ident203328 Node: get-session-info-ident203877 Node: re-lookup-person204531 Node: re-lookup-conf205196 Node: lookup-person205850 Node: lookup-conf206442 Node: set-client-version207036 Node: get-client-name209108 Node: get-client-version209925 Node: mark-text210748 Node: unmark-text212123 Node: re-z-lookup212943 Node: get-version-info214821 Node: lookup-z-name215584 Node: set-last-read217215 Node: get-uconf-stat218550 Node: set-info220199 Node: accept-async221801 Node: query-async223800 Node: user-active225039 Node: who-is-on-dynamic225822 Node: get-static-session-info227317 Node: get-collate-table228065 Node: create-text228919 Node: create-anonymous-text231776 Node: create-conf234130 Node: create-person236074 Node: get-text-stat238119 Node: get-conf-stat238991 Node: modify-text-info239472 Node: modify-conf-info240521 Node: get-info241591 Node: modify-system-info242111 Node: query-predefined-aux-items243210 Node: set-expire243850 Node: query-read-texts-10244648 Node: get-membership-10246751 Node: add-member249576 Node: get-members252098 Node: set-membership-type253650 Node: local-to-global255121 Node: map-created-texts258958 Node: set-keep-commented260583 Node: set-pers-flags261429 Node: query-read-texts262300 Node: get-membership265349 Node: mark-as-unread268761 Node: set-read-ranges270824 Node: get-stats-description273204 Node: get-stats274015 Node: get-boottime-info275554 Node: first-unused-conf-no276139 Node: first-unused-text-no276555 Node: find-next-conf-no276965 Node: find-previous-conf-no278045 Node: get-scheduling279174 Node: set-scheduling279977 Node: set-connection-time-format282959 Node: local-to-global-reverse283942 Node: map-created-texts-reverse285874 Node: Asynchronous Messages287172 Node: About Asynchronous Messages289666 Node: async-new-text-old291066 Node: async-i-am-off291783 Node: async-i-am-on-obsolete292286 Node: async-new-name293074 Node: async-i-am-on293655 Node: async-sync-db294080 Node: async-leave-conf294488 Node: async-login295611 Node: async-broadcast296065 Node: async-rejected-connection296644 Node: async-send-message297171 Node: async-logout298129 Node: async-deleted-text298717 Node: async-new-text299351 Node: async-new-recipient299949 Node: async-sub-recipient300713 Node: async-new-membership301502 Node: async-new-user-area302089 Node: async-new-presentation302735 Node: async-new-motd303520 Node: async-text-aux-changed304222 Node: Error Codes305005 Node: Aux-Item Types315428 Node: Name Expansion337270 Node: LysKOM Content Types338956 Node: Reformattable Text (text/x-kom-basic)339639 Node: The User Area (x-kom/user-area)341117 Node: The User Area341378 Node: Membership visibility347407 Node: Garb350099 Node: Measured Properties352371 Node: Extracted grammar354260 Node: Writing Clients356488 Node: Common Commands356967 Node: What do I have unread357401 Node: Client Conventions360039 Node: Text formatting360816 Node: Content type specification361946 Node: Client-side name expansion362547 Node: Recipients of comments363435 Node: Order of misc-info groups365097 Node: Importing and Exporting E-Mail365663 Ref: Message-ID371919 Node: Some Client-specific Aux-Item Types372764 Node: Future changes375784 Node: Protocol Version History378986 Node: Document Edition History389049 Node: Index403606  End Tag Table lyskom-server-2.1.2/doc/protocol-a.info-10000664000015100472110000014331607723710263013673 This is protocol-a.info, produced by makeinfo version 4.2 from Protocol-A.texi. This is the LysKOM Protocol A specification, edition 11.1. It specifies version 11 of the protocol. It was first distributed with version 2.1.2 of lyskomd. Copyright (C) 1995-2003 Lysator ACS. Permission is granted to make and distribute verbatim copies of this specification provided the copyright notice and this permission notice are preserved on all copies. Modified versions of this document may be redistributed with the added condition that all modifications not cleared with the LysKOM development group are clearly marked and that the entire modified work be redistributed under the same conditions as the original. Permission is granted to copy and distribute translations of this manual into another language under the same conditions as for modified versions. INFO-DIR-SECTION LysKOM START-INFO-DIR-ENTRY * Protocol A: (protocol-a). The LysKOM Protocol A specification. END-INFO-DIR-ENTRY  File: protocol-a.info, Node: Top, Next: About this document, Up: (dir) LysKOM Protocol A ***************** This document specifies version 11 of LysKOM Protocol A. This is edition 11.1 of the specification. It was first distributed with version 2.1.2 of lyskomd. The most up-to-date version if this document can always be found at `http://www.lysator.liu.se/lyskom/protocol/'. * Menu: * About this document:: Copyright information. * Preface:: What is LysKOM? Who wrote this document? * Concepts:: Articles, conferences, aux-items, ... * Fundamentals:: The building blocks of Protocol A. * LysKOM Data Types:: Domain-specific data types used in Protocol A. * Protocol Requests:: Each request explained in depth. * Asynchronous Messages:: Unsolicited information from the server. * Error Codes:: All error codes with explanations. * Aux-Item Types:: All predefined aux-item types. * Name Expansion:: Looking up the name of a conference or person. * LysKOM Content Types:: Predefined content types for articles. * The User Area:: Store client-specific settings in the server. * Membership visibility:: How the security features interacts. * Garb:: Old texts are deleted automatically. * Measured Properties:: Load average, number of processed requests... * Extracted grammar:: If you want to generate code, read this. * Writing Clients:: A few tips for client writers. * Importing and Exporting E-Mail:: A few thoughts on e-mail integration. * Some Client-specific Aux-Item Types:: Informative info about more aux-items. * Future changes:: The protocol is not yet perfect. * Protocol Version History:: The protocol was even less perfect before. * Document Edition History:: Changes in this document. * Index:: Index of protocol elements.  File: protocol-a.info, Node: About this document, Next: Preface, Prev: Top, Up: Top About this document ******************* This is the LysKOM Protocol A specification, edition 11.1. It specifies version 11 of the protocol. It was first distributed with version 2.1.2 of lyskomd. Copyright (C) 1995-2003 Lysator ACS. Permission is granted to make and distribute verbatim copies of this specification provided the copyright notice and this permission notice are preserved on all copies. Modified versions of this document may be redistributed with the added condition that all modifications not cleared with the LysKOM development group are clearly marked and that the entire modified work be redistributed under the same conditions as the original. Permission is granted to copy and distribute translations of this manual into another language under the same conditions as for modified versions.  File: protocol-a.info, Node: Preface, Next: Concepts, Prev: About this document, Up: Top Preface ******* LysKOM is a conferencing system(1). Similar systems were QZ-KOM and PortaCOM(2). The LysKOM system is copyrighted by Lysator Academic Computing Society and distributed under conditions of the GNU Public License. LysKOM and its documentation is provided "as is" without warranty of any kind. Anything described here as "unspecified" is liable to change in future protocol versions. This specification is the work of several people. The main contributors have been Per Cederqvist , David Byers , Pär Emanuelsson , Thomas Bellman , Lars Aronsson , Linus Tolke and Kent Engström . The LysKOM developers can be reached by email to . If you find any errors in this document, please report them at `http://bugzilla.lysator.liu.se/'. Use `lyskomd' as the product, and `documentation' as component. ---------- Footnotes ---------- (1) Or in modern terms, enabling technology for Computer-Supported Cooperative Work (CSCW). (2) Also known as "PottaKOM" and "BortaKOM."  File: protocol-a.info, Node: Concepts, Next: Fundamentals, Prev: Preface, Up: Top Concepts used in LysKOM *********************** This chapter introduces the concepts used in LysKOM, such as articles, conferences and sessions. * Menu: * Articles:: Reading and writing articles is what LysKOM is about. * Conferences:: Articles are organized in conferences. * Persons and Sessions:: Persons log on to the LysKOM system. * The Misc-Info List:: How articles are organized in comment chains and in conferences. * The Aux-Item List:: A generic extension mechanism. * Security:: Some persons have more privileges than others. * Membership and Reading:: You don't have to read anything twice.  File: protocol-a.info, Node: Articles, Next: Conferences, Up: Concepts Articles ======== An article is represented as a value of the type `Text-Stat' and a string containing the article contents. An article will usually have one or more recipients and may be a comment or footnote to other articles. Each article is kept in the database until it is older than the `nice' value of each of its recipients and it is not marked by any user. There is an array of `Misc-Info' included in the `Text-Stat'. This array contains information about recipients, senders, comments and footnotes. Each article is identified by a number, the global(1) article number (the `Text-No'). Global numbers are assigned in ascending order to new articles, and are never reused. If an article has recipients it will also have a local number for each recipient (the `Local-Text-No'). Local numbers are used in some data structures to provide more compact storage and to provide an ordering of articles for a particular recipient. Local numbers are assigned in ascending order and are never reused for a particular recipient, though different recipients will have articles with the same local numbers. Occasionally it is necessary to map between local and global numbers. The server call `local-to-global' does this(*note local-to-global::). ---------- Footnotes ---------- (1) The number is not truly global; it is local to a specific LysKOM server.  File: protocol-a.info, Node: Conferences, Next: Persons and Sessions, Prev: Articles, Up: Concepts Conferences =========== Conferences hold articles. They are represented in the protocol as a data type called `Conference'. Each conference has a "creator", the person who created the conference, and a "supervisor", a conference whose members can modify the conference. If the supervisor is a person, the members of that person's mailbox are supervisors, which in most cases is only that person. Persons are a special case: in addition to those who are supervisors for a certain person because of the `supervisor' field, the person is always a supervisor of himself. There is one exception to this special case: the person cannot use `set-supervisor' (*note set-supervisor::) to change who is his supervisor. We have also introduced a type called `UConference' (pronounced micro-conf-stat) which holds a subset of the information contained in the full `Conference' type. Use the `UConference' type whenever possible since it places a much smaller load on the LysKOM server. Each conference has a type, which is essentially a collection of boolean flags. Currently the flags `rd-prot', `letterbox', `secret', `original', `allow-anonymous' and `forbid-secret' are defined. `rd-prot' The conference is protected from reading by non-members. Persons become members by having one of the existing members or supervisors add him or her to the conference. This restriction is enforced by the server. `original' Conferences of this type are intended for original articles only. Comments are to be redirected to the `super-conf' instead. This restriction is not enforced by the server; clients must implement this functionality. (*Note Recipients of comments::, for a summary of how a client should select the recipients of a comment.) `letterbox' Conferences of this type are connected to persons. Letters to a person are sent to the mailbox and the name of the mailbox is synchronized with the person name. It is currently not possible to explicitly set or clear this flag on a conference. `secret' Conferences of this type are secret. The server will not divulge any information about the existence of the conference to persons who are not members or supervisors of the conference. If a mailbox is made secret, that person cannot log in using the person name, but must specify a person number instead. `allow-anonymous' Conferences of this type accept anonymous articles. Other conferences will reject anonymous articles. `forbid-secret' Conferences of this type do not allow secret members. If a conference is changed to this type, preexisting secret members remain secret.  File: protocol-a.info, Node: Persons and Sessions, Next: The Misc-Info List, Prev: Conferences, Up: Concepts Persons and Sessions ==================== Persons are represented in the protocol by values of the type `Person'. Associated with persons are statistics, a set of personal flags and a set of privileges (*note Security::). Persons are also associated with a conference that has the same number as the person and the `letterbox' bit set. Connections to the server are represented as values of the type `Static-Session-Info', `Session-Info-Ident' or `Session-Info'. Sessions have session number that are unique for each session in the lifetime of the server execution. A single user can have several sessions running at once. The session is not released until the network connection is closed; a user can log in and out repeatedly in a single session.  File: protocol-a.info, Node: The Misc-Info List, Next: The Aux-Item List, Prev: Persons and Sessions, Up: Concepts The Misc-Info List ================== The `Misc-Info' list contains tagged data. The fields are sent in groups pertaining to a particular type of information: information about recipient; carbon copy recipient; blank carbon copy recipient; comment to; footnote to; comment in and footnote in. The information groups may be sent in any order and there may be any number of groups. Within each group the elements are always sent in the order listed below. Recipient --------- `recpt' Starts a recipient group. It contains the conference number of a recipient of the article. `loc-no' Always present within a recipient group. It contains the local text number of the article in the conference specified by the preceding `recpt' field. `rec-time' If the recipient is a person, this element is added by the server when the recipient marks the article as read. It contains the time when the text was read. `sent-by' Present when the recipient was added by a person other than the author (after the article was created.) It contains the person number of the person who added the recipient. `sent-at' Present when the recipient was added after the article was created. It contains the time when the recipient was added. Carbon Copy (CC) Recipient -------------------------- The carbon-copy recipient group is identical to the recipient group above. The difference is how new comments to an article with a recipient or carbon-copy recipient are treated. A comment to an article is sent to all recipients, but not to carbon-copy recipients of the original article. This difference is enforced by the clients. `cc-recpt' Starts a carbon-copy recipient group. It contains the conference number of a carbon-copy recipient of the article. `loc-no' Always present in a CC recipient group. It contains the local text number of the article in the conference specified by the most recent `cc-recpt' field. `rec-time' Present after the CC recipient has read the article. It contains the time when the article was read. Since only persons can read articles this will only be seen if the CC recipient is a person. `sent-by' Present when a CC recipient was added by a person other than the author after the article had been created. It contains the person number of the person who added the CC recipient. `sent-at' Present when a CC recipient was added after the article had been created. It is the time when the CC recipient was added. Blank Carbon Copy (BCC) Recipient --------------------------------- The blank carbon-copy recipient group is identical to the carbon-copy recipient group above. The difference is the visibility of the information. A carbon-copy recipient group is visible to anyone that is allowed to fetch both the text status of the involved text and the conference status of the involved conference. (That is, as long as the conference isn't secret everybody is allowed to see the carbon-copy recipient group.) A BCC recipient group is basically only visible to members and supervisors of the recipient. Persons that have the right to become a member of the recipient can also see it, as can the author of the text (unless the recipient is secret to him). This is enforced by the server. This type of group was introduced in protocol version 10. When old-style calls such as `get-text-stat-old' (*note get-text-stat-old::) are used this will be converted to a CC recipient group by the server for the benefit of clients that don't understand this group. (This conversion will of course only be performed when the user is allowed to se the blank carbon copy.) `bcc-recpt' Starts a blank carbon-copy recipient group. It contains the conference number of a blank carbon-copy recipient of the article. `loc-no' Always present in a BCC recipient group. It contains the local text number of the article in the conference specified by the most recent `bcc-recpt' field. `rec-time' Present after the BCC recipient has read the article. It contains the time when the article was read. Since only persons can read articles this will only be seen if the BCC recipient is a person. `sent-by' Present when a BCC recipient was added by a person other than the author after the article had been created. It contains the person number of the person who added the BCC recipient. `sent-at' Present when a BCC recipient was added after the article had been created. It is the time when the BCC recipient was added. Comment To ---------- `comm-to' Always present when the article is a comment to another article. `sent-by' Present when the article was added as a comment by a person other than the author, after the article had been created. It contains the person number of the person who added the article as a comment. `sent-at' Present when the article was added as a comment after the article had been created. It contains the time when it was added as a comment. Footnote To ----------- `footn-to' Always present when the article is a footnote to another article. `sent-at' Present when the article was added as a footnote after the article had been created. It contains the time when it was added as a footnote. Comment in ---------- `comm-in' Present when there are comments to this article. It contains the article number which is a comment to this article. Footnote in ----------- `footn-in' Present when there are footnotes to this article. It contains the article number which is a footnote to this article.  File: protocol-a.info, Node: The Aux-Item List, Next: Security, Prev: The Misc-Info List, Up: Concepts The Aux-Item List ================= The aux-item list is used as a generic extension mechanism in the LysKOM server and in protocol A. * Menu: * About Aux-Items:: An introduction to aux-items. * Aux-Item Inheritance:: Comments can inherit aux items. * Predefined Aux-Item Types:: Predefined aux-items are part of the protocol. * Client-Specific Aux-Item Types:: Clients can allocate aux-items for their private use. * Experimental Aux-Item Types:: A block of aux-items are reserved for experimental use. * Defining New Aux-Item Types:: Creating new aux-item types is easy.  File: protocol-a.info, Node: About Aux-Items, Next: Aux-Item Inheritance, Up: The Aux-Item List About Aux-Items --------------- Aux-items were introduced in protocol version 10 as a mechanism for extending the conference, text and server information structures without changing the protocol. (There is no need for aux-items on persons - just add an aux-item to the corresponding mailbox.) The exact structure of an aux item is specified elsewhere (*note Auxiliary Information::). The important fields here are the `aux-no', `tag' and `data' fields. The `aux-no' field is used to identify an item. The `aux-no' together with a text or conference number uniquely identifies a particular aux item. Items are numbered from one and up within each item list. Once assigned, the `aux-no' for an item is never changed. New items are guaranteed to be assigned numbers that have never been used before within a particular list. The `tag' field identifies the type of aux item. It is used by the server and by clients to figure out how to interpret the data field, and by the server to decide if the item needs special treatment. The `data' field is a simple string. The meaning of the string is determined by the `tag' field, but since it is a string, clients that have no understanding of the contents can successfully parse the item anyway (in contrast to items in the misc-info list.)  File: protocol-a.info, Node: Aux-Item Inheritance, Next: Predefined Aux-Item Types, Prev: About Aux-Items, Up: The Aux-Item List Aux-Item Inheritance -------------------- An aux item that is placed on a text can be inherited. This means that if a comment or footnote to the text is created, an almost identical item will be created on the new text. The `tag', `creator', `flags' and `data' field will be inherited unchanged. The `aux-no' might be given a different value. A non-zero `inherit-limit' field will be decremented. The `created-at' timestamp will be set to the time when the new comment or footnote is created. Inheritance only happens at text creation time. If a comment or footnote link is added later with `add-comment' (*note add-comment::) or `add-footnote' (*note add-footnote::), no items will be inherited. Also, if the link is removed (via `sub-comment' (*note sub-comment::) or `sub-footnote' (*note sub-footnote::)), the inherited items will still be in place. Inheritance only happens when the `inherit' bit is set, and if `inherit-limit' is 0 or greater than 1. *Note Auxiliary Information::, for more information. Inheritance has no meaning for items placed on the server or on a conference. It is possible for a predefined aux-item to behave in a way that isn't consistent with the description in this section. The documentation for the specific aux-item should document any deviations.  File: protocol-a.info, Node: Predefined Aux-Item Types, Next: Client-Specific Aux-Item Types, Prev: Aux-Item Inheritance, Up: The Aux-Item List Predefined Aux-Item Types ------------------------- Predefined Aux-Item types are part of Protocol A, and clients should support all of them. As with other parts of the protocol, changes to these definitions will be made backwards-compatible, if possible. Creation and deletion of items with a predefined type can cause arbitrarily complex and wondrous behavior in the server. Furthermore, the server may place constraints on the items with regard to content, flags, who can create them, to what objects they can be attached and so forth. The server may also silently enforce specific values for any field of an item, regardless of what the client requests. All items with tags in the range 1-9999 and 30000 and up are considered predefined. If a client attempts to create an item with a tag in this range, but the server has no idea what that tag means, the server will return an error (`illegal-aux-item'). Some items with tags in the range 10000-19999 are also predefined. They are items that initially were reserved for private use for a specific client, but where it was later discovered that the tag was generally useful. They should ideally have been assigned a number in the 1-9999 range from the beginning, but if they already have a widespread use they can be redefined to be predefined. Such redefinition will always be made in cooperation with the client writer. *Note Aux-Item Types::, for the complete list of predefined Aux-Item types.  File: protocol-a.info, Node: Client-Specific Aux-Item Types, Next: Experimental Aux-Item Types, Prev: Predefined Aux-Item Types, Up: The Aux-Item List Client-Specific Aux-Item Types ------------------------------ Client-specific items do not cause the server to perform any magic. All the flags (except the delete flag) are left untouched, the data is not validated in any way, and anyone can create any item. If you need more server support than this, your item should be on the predefined list. All tags in the range 10000-19999 are reserved for clients. Blocks of 100 numbers at a time can be assigned to specific clients. A client should never create items with tags in a range assigned to another client or in an unassigned range. Assigned ranges will never change, except that specific aux-items may be redefined as predefined, as explained in *Note Predefined Aux-Item Types::. Currently, the following ranges are assigned to clients: * 10000-10099: The Elisp Client * 10100-10199: komimportmail * 10200-10299: Private test use (should never be used on a public server) If you want a range of numbers, send e-mail to the LysKOM development group, or request it via Bugzilla.  File: protocol-a.info, Node: Experimental Aux-Item Types, Next: Defining New Aux-Item Types, Prev: Client-Specific Aux-Item Types, Up: The Aux-Item List Experimental Aux-Item Types --------------------------- Experimental numbers are free for all. Use 'em any way you want. All numbers in the range 20000-29999 are for experimental use.  File: protocol-a.info, Node: Defining New Aux-Item Types, Prev: Experimental Aux-Item Types, Up: The Aux-Item List Defining New Aux-Item Types --------------------------- If you want a new predefined item type, just document what it does, what the data format looks like and what the server is to do with the item and send this to the LysKOM development group. We'll assign a number to your item and put the documentation in this document. If you're not sure what you want the data to look like yet, make a note in your documentation that the data format might change. Once you have a data format you're happy with, update the documentation so others may use your item. If you need serious magic in the server (more than can be specified with the lyskomd configuration file), you'll probably have to write the code yourself, or hope that the development group thinks your idea is so cool we do the job for you. The idea is not to reject any type of item, unless there's already an item type that does the job just as well. Adding item types should be a much less painful process than adding new calls.  File: protocol-a.info, Node: Security, Next: Membership and Reading, Prev: The Aux-Item List, Up: Concepts Security ======== Security in LysKOM is based on two components. Each person has a set of privileges and each session has a security level. Rights in the system require both the sufficient privileges and a sufficient security level. The privileges currently available are `wheel', `admin', `statistic', `create-conf', `create-pers' and `change-name'. Security levels range from 0 to 255. `wheel' _Normally not assigned_ Level 0 Person may always log in, even when LysKOM is crowded. Level 6 Person may set Priv-Bits for all persons. Level 7 Person may set password for all persons. Level 8 Person acts as supervisor for everything. Level 10 Person can read all articles. `admin' _Normally not assigned_ Level 1 Shut down the server Set motd-of-kom Read last-login Level 2 Read status of secret conferences and persons Read the protected parts of person and conference statuses Read the entire text status, even when there are secret recipients Level 3 Change everybody's names Level 4 Add/remove members Add/remove recipients to articles Level 5 Set super-conference Remove articles Level 6 Set administrator `statistic' _Normally not assigned_ Level 2 Read the statistics portions of persons, even if protected `create-conf' _Normally not assigned_(1) Level 0 Create conferences `create-pers' _Normally not assigned_(2) Level 0 Create persons `change-name' _Normally assigned_ Level 0 Change names of conferences he is supervisor for ---------- Footnotes ---------- (1) The LysKOM server is normally configured so that anybody can create new conferences, even if they do not have this privilege. (2) The LysKOM server is normally configured so that anybody can create new persons, even if they do not have this privilege.  File: protocol-a.info, Node: Membership and Reading, Prev: Security, Up: Concepts Membership and Reading ====================== Persons' memberships in conferences are represented in the protocol as arrays of `Membership'-typed values. This structure contains information about how and when the membership was created and which texts have been read in the conference. There are two kinds of memberships. An active membership indicates that the person is actively participating in the conference, wants to know if there are unread texts and wants to receive messages send to the conference. A passive membership is similar to no membership at all. The person is still a member but will not receive messages sent to the conference and will not be notified when there are new texts. From the user's perspective, passive membership should be like no membership at all, but the server still remembers what the user has read in the conference while he or she was an active member. Since protocol version 10 a bit in the membership type field of the membership structure indicates the type of membership. Previously the server did not support passive memberships, but there was a convention that clients should treat the priority level zero as a passive membership. The membership record indicates which texts have been read through the `read-ranges' field, which contains a list of ranges of local text numbers that has been read. Finding out which articles a person has read in a particular conference requires a few calls. Normally, a client will retrieve a batch of perhaps 50 articles at a time. The outline of the process is as follows: 1. Fetch the membership to get the `read-ranges'. 2. Use `local-to-global' (*note local-to-global::) to translate a number of local numbers to global numbers. 3. Remove the global numbers corresponding to local numbers contained in `read-texts' from the result. 4. Get and translate more texts as needed. The process is complicated because of the translation between local and global text numbers. If the server does not implement the `local-to-global' call(*note local-to-global::), it is possible to use the less efficient but perfectly serviceable `get-map' call instead(*note get-map::).  File: protocol-a.info, Node: Fundamentals, Next: LysKOM Data Types, Prev: Concepts, Up: Top Fundamentals of Protocol A ************************** The data types in protocol A come in two flavors. The first (vanilla) are the simple data types from which the LysKOM (chocolate) data types are built. Simple data types include things like integers and strings while complex data types include things such as conferences and people. * Menu: * Notation:: The grammar used in this document. * Simple Data Types:: BOOL, INT32, ARRAY, ... * Connecting to the Server:: The initial handshake. * Client-Server Dialog:: Requests, replies, asynchronous messages. * Protocol Error Messages:: How the server reacts to syntax errors.  File: protocol-a.info, Node: Notation, Next: Simple Data Types, Up: Fundamentals Notation ======== This specification uses a BNF-like grammar to describe the protocol and its data elements. Data fields have been given names that start with a lower-case letter. Fundamental data types have names in all-caps (such as `INT32' and `ARRAY'). Derived data types have names that start with an upper-case letter. (If the type contains more than one word, all words start with an upper-case letter, like this: `Text-Stat'.) The operator `::=' defines the name to its left. Comments start with `!' (exclamation mark) and alternatives are separated by a `|' (vertical bar.) A `;' (semicolon) terminates statements in the grammar. In some specifications there are literal strings. There is to be no whitespace before or after literal strings unless there is whitespace in the literal itself.  File: protocol-a.info, Node: Simple Data Types, Next: Connecting to the Server, Prev: Notation, Up: Fundamentals Simple Data Types ================= Integers -------- `INT32', `INT16', `INT8' and `BOOL' are non-negative integers which must fit in 32, 16, 8 and 1 bits, respectively. They are transmitted to the server in ASCII-encoded decimal notation. Floating point numbers ---------------------- `FLOAT' are floating point numbers. They are represented as if printed via `printf("%g", val);' in C. See `7.19.6.1 The fprintf function' in `ISO/IEC 9899:1999 Programming languages - C' for the details. *Note The %g conversion: (libc)Floating-Point Conversions, if you don't have the C standard handy. Strings ------- `HOLLERITH' denotes character strings of arbitrary length. They are transmitted as `NHTEXT' where TEXT is the string and N is the number of characters in TEXT in decimal notation. All byte values are allowed in the string itself, including nulls. Long live FORTRAN! The character set used in the strings is not yet specified by Protocol A. In the future, some Unicode encoding will probably be used, but it is not yet decided which one or how the transition will be handled. Bug 99 (http://bugzilla.lysator.liu.se/show_bug.cgi?id=99) is about the need for a Unicode roadmap; check that bug for the current state of the plans. For now, which character set to use is a local policy of each server installation. There is not yet any way in the protocol to specify the character set that a certain server uses. Most clients currently assume that ISO 8859-1 (Latin-1) is used, and the default collate table of lyskomd also assumes ISO 8859-1. Conference names must currently use an 8-bit character set encoding where whitespace is defined as in ASCII, or conference matching won't work. `get-collate-table' (*note get-collate-table::) contains some more information about character set issues. Bit Strings ----------- `BITSTRING' is a string of bits, commonly used for a set of boolean-valued flags. Bit strings are denoted as BITSTRING ( name-1; name-2; name-3; ... ) in this specification. They are transmitted as a sequence of ASCII ones and zeroes in the order the fields are listed. For instance, given the specification shape-of-world ::= BITSTRING ( is-flat; is-round; is-2d; is-3d; ) most peoples idea of `shape-of-world' would be sent as `0101' (round and three-dimensional.) Enumerations ------------ `ENUMERATION' is an integer constant. It is transmitted as an INT32, but only fixed values are permitted. Clients should be prepared to receive numbers outside the enumeration and either handle this gracefully as an error or use a reasonable default value in place of an invalid enumeration value. An enumeration is specified as ENUMERATION ( name-1=value-1; name-2=value-2; name-3=value-3; ... ) This specification states that name-1 is represented by the integer value-1, name-2 is represented by value-2 and name-3 is represented by value-3. An enumeration can also be inherited from a SELECTION data type: Info-type ::= ENUMERATION-OF(Misc-Info) This means that Info-type is an enumeration, that contains the same keys and values as the SELECTION Misc-Info. For example, in the following specification, the constant guwal will be transmitted as the integer 2, ciokwe as the integer 3, and hopi as the integer 5. language ::= ENUMERATION ( hakka = 1; guwal = 2; ciokwe = 3; yoruba = 4; hopi = 5; ) Arrays ------ `ARRAY' is a list of a fixed number of elements of a single type. The specification for an array is `ARRAY TYPE' where TYPE is the type of the array elements. Arrays are transmitted as an `N { ELEMENT ELEMENT ... }' where N is the number of elements and each ELEMENT is an element of the array. A special case is when the array is empty, in which case the server transmits it as `0 *'. Note that the client must always transmit empty arrays as `0 { }'. In some calls the client can ask the server not to send the array contents, only its length. In these cases the array is transmitted as `N *' where N is the number of elements in the array. Selection --------- `SELECTION' is tagged data. It consists of an INT32 selector followed by a tail of an arbitrary type and is specified as SELECTION ( N=NAME TAIL : TYPE; N=NAME TAIL : TYPE; ... ) where each N is the selector value, NAME the selector name and TAIL the name of the selector tail and TYPE its type. NAME and TAIL are often very similar, such as `sent-by' and `sender'. When transmitted, the selector is transmitted as an INT32 followed by the tail belonging to that selector. For instance, given the specification description ::= SELECTION ( 1=name the_name : HOLLERITH; 2=age years : INT32; ) two legal messages of the type `description' are `1 4HJohn' and `2 18'. RPC --- `RPC' is a notation used to specify calls to the server. An RPC specification has the following form: RPC ( CALL [N] ( REQUEST ) -> ( REPLY ) ; CALL [N] ( REQUEST ) -> ( REPLY ) ; ) where each CALL is the name of a call, N is the call number, REQUEST is a single data element sent as a request and REPLY is a single data element sent in reply from the server. RPC calls are transmitted as N REQUEST where N and REQUEST have the same meaning as above. Note that in the client-server dialog a reference number must also be supplied with each request. This reference number is not part of the RPC itself, but is required for communications; see *Note Client-Server Dialog::. Structure --------- Structures are collections of several data items. In the specification they are written as ( NAME : TYPE ; NAME : TYPE ; ... ) where each NAME is the name of a data field and the corresponding TYPE is its type. Structures are transmitted as a sequence of their fields.  File: protocol-a.info, Node: Connecting to the Server, Next: Client-Server Dialog, Prev: Simple Data Types, Up: Fundamentals Connecting to the Server ======================== The client-server dialog consists of two phases, establishing the connection and the LysKOM session itself. A connection to the server is initiated by connecting to the appropriate network port(1) and sending a single letter which is used to select a protocol version. This letter should always be `A'(2). The protocol version letter should be followed by connection information required by that protocol. In protocol A the connection information is a `HOLLERITH' string saying who the user connecting is followed by a linefeed character. The format of the string should be `USERNAME % HOSTNAME'. When the server has accepted the connection it replies with the string `LysKOM' on a single line. % telnet kom.lysator.liu.se 4894 Trying 130.236.254.151 ... Connected to varg.lysator.liu.se. Escape character is '^]'. A26Hbyers%kajsa.lysator.liu.se LysKOM Besides the string `LysKOM', the server may respond with `%%LysKOM unsupported protocol.' or `%% No connections left.'. The `%%LysKOM unsupported protocol.' reply is sent if the server does not understand the requested protocol, that is, if the first character is anything but an `A'. The connection will be closed by the server as soon as this string has been sent. The `%% No connections left.' reply is sent if the server is not accepting additional connections. This error is transient. The next connection attempt may succeed. Clients should wait a few seconds before attempting to make another connection after receiving this error. The connection will be closed by the server as soon as this string has been sent. ---------- Footnotes ---------- (1) The default port for a LysKOM server is 4894. That port was registered with IANA 2001-06-20. (2) In the early 1990s there was much discussion about the next generation LysKOM protocol, called "Protocol B", and at one point in time it was believed that "Protocol B" would arrive at the same time as "Emacs 19". "Emacs 19" arrived and was obsoleted by new versions. Meanwhile, it was discovered that "Protocol A" was more extensible that first believed. "Protocol A" will continue to evolve, but it is unlikely that it will ever be superseded by "Protocol B".  File: protocol-a.info, Node: Client-Server Dialog, Next: Protocol Error Messages, Prev: Connecting to the Server, Up: Fundamentals Client-Server Dialog ==================== After connecting (*note Connecting to the Server::), calls to the server can be made. Most calls require the user to log in, but some calls can be made without a log-in. Calls to the server are made by sending a reference number followed by the call as specified. The call _must_ be terminated with a linefeed character (ASCII 0x0A). server-call ::= ( ref-no : INT32; request : Protocol-Request; ) The client may send several requests without waiting for the replies. However, the server will only buffer a limited amount of replies, so the client must check for pending replies from the server at least each time it sends requests to the server. At some future point the server will reply with the result of the request or an error code preceded by an indicator and the reference number. The replies will be sent in the same order as the requests(1). server-reply ::= ok-reply | error-reply | protocol-error; ok-reply ::= ( "=" ref-no : INT32; reply-data; ) error-reply ::= ( "%" ref-no : INT32; error-code : INT32; error-status : INT32; ) protocol-error ::= "%% LysKOM protocol error." | "%%Insane token length." | "%%Insane array size." Our notation is not flexible enough to specify the two-way nature of the communication. `ref-no' in the reply is always the same as `ref-no' in the corresponding request. `reply-data' depends on which request was made and is specified together with each request. Note that there is no whitespace after the initial indicator in the reply. Data elements sent from the client to the server are separated by one or more space characters (ASCII 32). An entire call is terminated by a linefeed character (ASCII 10). Earlier versions of the protocol specified that data elements could be separated by any number of linefeed (ASCII 10), return (ASCII 13), tab (ASCII 9) or space (ASCII 32) characters. Servers should be forgiving and understand requests using the older conventions, but clients must conform to the current convention of separating data elements with spaces and terminating all requests with a linefeed character. The `not-implemented' error code will not be returned properly unless the client follows this requirement. The server may return two different types of errors. Normal `error-reply' errors are replies to syntactically correct calls to the server, while `protocol-error' are replies to syntactically incorrect calls. *Note Protocol Error Messages::, for more information about `protocol-error'. If a call cannot complete successfully, LysKOM will respond with an `error-reply'. The meaning of `error-code' and `error-status' varies depending on the request; see *Note Error Codes::, and the documentation for each call, for a list of available `error-code' values and what they mean. A client should be prepared for any error code in response to any call, no matter if the response makes any sense or not. The value returned in `error-status' was more or less undefined before protocol version 10. For protocol version 10 or newer, the meaning of `error-status' is defined in this document. The meaning of `error-status' can be modified by any call. In particular the calls that deal with Misc-Info lists set `error-status' to the index of the misc item that caused the error (if the error was caused by a misc item.) Client should handle the error messages listed with each call in a graceful manner. In addition, the following error types should always be handled gracefully: `temporary-failure', `internal-error', `feature-disabled', `not-implemented', `obsolete-call', `ldb-error', `out-of-memory'. Client should also be able to handle any error in any situation without choking completely since bugs might cause the wrong error message to be sent or new errors might be added later on. The server may send asynchronous messages (*note Asynchronous Messages::) to the client at any time (but not in the middle of a reply). Two important asynchronous messages are `async-new-text' (*note async-new-text::) and `async-send-message' (*note async-send-message::). ---------- Footnotes ---------- (1) Client writers are encouraged to write the clients so that they are prepared for replies that are sent out-of-order. *Note Future changes::, for speculations about how that may benefit the client in the future.  File: protocol-a.info, Node: Protocol Error Messages, Prev: Client-Server Dialog, Up: Fundamentals Protocol Error Messages ======================= Protocol error messages are sent in reply to syntactically incorrect calls to the server. These should never appear in the client-server dialog. If they do, there is probably a bug in the client. "%% LysKOM protocol error." The client has sent a request that does not comply with protocol A. The server will attempt to recover from this error, but additional calls may be silently lost, and the server may send replies that the client does not expect, and in some cases recovery may not be possible. This error is also returned when the client sends an array that is longer than the maximum allowed by the server. "%%Insane token length." The client has sent a single token that is insanely long. Typically this means that the client has sent several kilobytes worth of digits, or something similar. This is never returned for long strings. The server will automatically disconnect a client who sends a token with an insane length. "%%Insane array size." The client has send an array with a negative length. The server is not easily fooled. The server will automatically disconnect a client who sends an array with an insane length.  File: protocol-a.info, Node: LysKOM Data Types, Next: Protocol Requests, Prev: Fundamentals, Up: Top LysKOM Data Types ***************** In this section the data types specific to LysKOM are defined. Most of these will probably make very little sense until you know what calls there are. This section does not include the server calls or asynchronous messages, even though these are also data types. Since the types defined here are all based on the simple types, the definitions are more concise in this section. * Menu: * Common Types:: Simple types used over and over again. * Auxiliary Information:: Aux-items and related types. * Conference Types:: A few flags for conferences. * Conference Search Results:: Name lookup returns these types. * Conference Status Types:: Information about a conference. * Archaic way to list conferences:: Archaic name lookup result type. * Mapping Local to Global Text Numbers:: The Text-Mapping type. * Server Information:: Information about an installation. * Person Status Types:: Information about a person. * Membership Information:: Persons are members of conferences. * Article Marks:: Persons can mark articles. * Article Information:: Information about an article. * Who Information:: Old-style info about logged-on users. * Session Information:: New-style info about logged-on users. * Statistics:: The server measures several things.  File: protocol-a.info, Node: Common Types, Next: Auxiliary Information, Up: LysKOM Data Types Common Types ============ The types defined in this section are fairly simple and used in many of the more complex data types. Time ---- Time ::= ( seconds : INT32; minutes : INT32; hours : INT32; day : INT32; month : INT32; year : INT32; day-of-week : INT32; day-of-year : INT32; is-dst : BOOL; ) `Time' is used to specify times in several data structures. The fields `seconds', `minutes' and `hours' give wall clock time. `day' is the day of month and `month' is the current month, starting with zero for January. `year' is the number of years since 1900. `day-of-week' is the current weekday, with zero used for Sunday. `day-of-year' is how many days of the year have passed starting with zero and `is-dst' is true when the time indicated is daylight savings time. When the server receives a `Time' structure from a client it ignores the `day-of-week' and `day-of-year' fields. All times are expressed in the time zone of the server, unless the `set-connection-time-format' request is used(*note set-connection-time-format::). Conference Numbers ------------------ Conf-No ::= INT16; This type denotes a conference number. Text Numbers ------------ Text-No ::= INT32; Local-Text-No ::= INT32; Text-List ::= ( first-local-no : Local-Text-No; texts : ARRAY Text-No; ) These three types are used to indicate articles in the LysKOM database. `Text-No' is a global text number and `Local-Text-No' a local text number. `Text-List' is used when a mapping from local to global numbers are required. Person and Session Numbers -------------------------- Pers-No ::= Conf-No; Session-No ::= INT32; `Pers-No' is used to indicate a person. `Session-No' is used in a few data structures relating to information about active LysKOM sessions. lyskom-server-2.1.2/doc/protocol-a.info-20000664000015100472110000014043507723710263013673 This is protocol-a.info, produced by makeinfo version 4.2 from Protocol-A.texi. This is the LysKOM Protocol A specification, edition 11.1. It specifies version 11 of the protocol. It was first distributed with version 2.1.2 of lyskomd. Copyright (C) 1995-2003 Lysator ACS. Permission is granted to make and distribute verbatim copies of this specification provided the copyright notice and this permission notice are preserved on all copies. Modified versions of this document may be redistributed with the added condition that all modifications not cleared with the LysKOM development group are clearly marked and that the entire modified work be redistributed under the same conditions as the original. Permission is granted to copy and distribute translations of this manual into another language under the same conditions as for modified versions. INFO-DIR-SECTION LysKOM START-INFO-DIR-ENTRY * Protocol A: (protocol-a). The LysKOM Protocol A specification. END-INFO-DIR-ENTRY  File: protocol-a.info, Node: Auxiliary Information, Next: Conference Types, Prev: Common Types, Up: LysKOM Data Types Auxiliary Information ===================== Aux-No ::= INT32; Aux-Item ::= ( aux-no : Aux-No; tag : INT32; creator : Pers-No; created-at : Time; flags : Aux-Item-Flags; inherit-limit : INT32; data : HOLLERITH; ) Aux-Item-Input ::= ( tag : INT32; flags : Aux-Item-Flags; inherit-limit : INT32; data : HOLLERITH; ) Aux-Item-Flags ::= BITSTRING ( deleted; inherit; secret; hide-creator; dont-garb; reserved2; reserved3; reserved4; ) Aux-Item-Input contains a subset of the fields of an Aux-Item. It is used when the client wants to send an Aux-Item to the server, and it only contains the elements that the client can affect. The fields in Aux-Item and Aux-Item-Input have the following meaning: `aux-no' The number of the item within the list where it is found. This number together with a conference or text number uniquely identifies a particular aux-item. (There is also a global list of Aux-Items for the server. That list is manipulated via the `modify-system-info' request(*note modify-system-info::), and when using that request the `aux-no' is enough to uniquely identify the aux-item.) This field is not present in `Aux-Item-Input'. It is assigned by the server. `tag' The item tag. The tag determines what the data means. *Note Aux-Item Types::. `creator' The person who created the item, or zero if the item was created anonymously or if the owner is being withheld. This field is not present in `Aux-Item-Input'. It is assigned by the server. `created-at' The time when the item was created. This field is not present in `Aux-Item-Input'. It is assigned by the server. `flags' The item flags (see below). `inherit-limit' Determines how many times (how deep) an item may be inherited. If zero, the item is inherited an unlimited number of times. If nonzero it is _one more_ than the number of additional times the item may be inherited. Thus, 1 means that inheritance will be blocked and 2 means that the item will be inherited only to the next level. `data' The item data. The flags that can be set on an aux-item have the following meaning: `deleted' The item has been deleted, and should not be used for anything. `inherit' The item will be inherited (if the inherit-limit field allows it.) `secret' The item will not be revealed to anyone but the item's creator and supervisors of the creator. `hide-creator' The item creator will be withheld from everyone but the item's creator and supervisors of the creator. `dont-garb' The object the item is set on will not be garbage-collected.  File: protocol-a.info, Node: Conference Types, Next: Conference Search Results, Prev: Auxiliary Information, Up: LysKOM Data Types Conference Types ================ Conf-Type ::= BITSTRING ( rd-prot; original; secret; letterbox; ) Extended-Conf-Type ::= BITSTRING ( rd-prot; original; secret; letterbox; allow-anonymous; forbid-secret; reserved2; reserved3; ) Any-Conf-Type ::= Conf-Type | Extended-Conf-Type; These types are used to specify the type of a conference. `Conf-Type' is used in data types and calls that were created before version 8.0 of the protocol and has been augmented in `Extended-Conf-Type'. The type `Any-Conf-Type' is used when either is admissible. The bits have the following meaning (*note Conferences::, for more info.) `rd-prot' If unset anyone can add themselves as members to the conference. `original' If set, comments are not allowed in the conference. `secret' If set the conference is secret. It's existence will only be revealed to members and supervisors. `letterbox' Set if the conference is a person's mailbox. `allow-anonymous' Set if anonymous articles are allowed in the conference. `forbid-secret' If set, secret members cannot be added to the conference. `reserved2' `reserved3' Reserved for future use. The values of these bits should be never be modified or used by clients who do not know their meaning. When a new conference is created these should always be set to zero.  File: protocol-a.info, Node: Conference Search Results, Next: Conference Status Types, Prev: Conference Types, Up: LysKOM Data Types Conference Search Results ========================= Conf-Z-Info ::= ( name : HOLLERITH; type : Conf-Type; conf-no : Conf-No; ) These types are used for the result of some calls that search for conferences based on their names.  File: protocol-a.info, Node: Conference Status Types, Next: Archaic way to list conferences, Prev: Conference Search Results, Up: LysKOM Data Types Conference Status Types ======================= Garb-Nice ::= INT32; Conference-Old ::= ( name : HOLLERITH; type : Conf-Type; creation-time : Time; last-written : Time; creator : Pers-No; presentation : Text-No; supervisor : Conf-No; permitted-submitters : Conf-No; super-conf : Conf-No; msg-of-day : Text-No; nice : Garb-Nice; no-of-members : INT16; first-local-no : Local-Text-No; no-of-texts : INT32; ) Conference ::= ( name : HOLLERITH; type : Extended-Conf-Type; creation-time : Time; last-written : Time; creator : Pers-No; presentation : Text-No; supervisor : Conf-No; permitted-submitters : Conf-No; super-conf : Conf-No; msg-of-day : Text-No; nice : Garb-Nice; keep-commented : Garb-Nice; no-of-members : INT16; first-local-no : Local-Text-No; no-of-texts : INT32; expire : Garb-Nice; aux-items : ARRAY Aux-Item; ) UConference ::= ( name : HOLLERITH; type : Extended-Conf-Type; highest-local-no : Local-Text-No; nice : Garb-Nice; ) These three types are used to specify information about a conference. `Garb-Nice' is a quantity used to specify how long articled are kept in a conference before being removed. `Conference' is the full information about a conference and `UConference' is brief information about a conference. The fields of `Conference' are `name' The name of this conference. `type' The type of the conference. `creation-time' The date and time when the conference was created. `last-written' The date when something was last written in the conference. `creator' The person who created the conference. `presentation' The article containing the conference presentation or zero if the conference has no presentation. `supervisor' The conference(1) who supervises this conference. `permitted-submitters' The conference whose members(2) may submit articles to the conference, or zero if anyone may do so. `super-conf' This field has two unrelated uses. If the `original' bit is set, clients should send comments to this conference (*note Recipients of comments::). If the `permitted-submitters' field rejects a text(3), the server will silently send the text to the `super-conf' conference instead. This redirection mechanism is applied repeatedly until conference that accepts the text is found, or an implementation-defined limit is reached. `msg-of-day' The conference notice, if any. `nice' The number of days an article should be kept before being removed from the conference. `keep-commented' A text that has comments no older than this number of days will not be removed from the conference. `no-of-members' The number of members of this conference. `first-local-no' The local number of the oldest existing article in the conference. `no-of-texts' The number of articles in the conference. `expire' This field will be used to control when a conference expires. It is not used at the moment, and should be set to zero for future compatibility. `aux-items' The conference's aux item list. The fields of `UConference' are `name' The name of this conference. `type' The conference type. Note that this is an extended conference type, unlike the type field of `Conference'. `highest-local-no' The local number of the newest article in the conference. `nice' The number of days an article should be kept before being removed from the conference. ---------- Footnotes ---------- (1) The `supervisor' may be a person, in which case the members of that person's mailbox become supervisors. (2) `permitted-submitters' can be a person, in which case all persons who are members of the associated mailbox are allowed to submit articles to the conference. (3) This is true if the text is created using `create-text' (*note create-text::), `create-anonymous-text' (*note create-anonymous-text::), `create-anonymous-text-old' (*note create-anonymous-text-old::) or `create-text-old' (*note create-text-old::). Future requests that create texts may have other semantics.  File: protocol-a.info, Node: Archaic way to list conferences, Next: Mapping Local to Global Text Numbers, Prev: Conference Status Types, Up: LysKOM Data Types Archaic way to list conferences =============================== The result of request number 12, lookup-name, cannot be expressed in the grammar used in this document. This is as close as it gets: Conf-List-Archaic ::= ( conf-nos : ARRAY Conf-No; conf-types : ARRAY Conf-Type; ! Sans N; see below ) The two arrays `conf-nos' and `conf-types' are always the same size. For some obscure reason the size of the second array is not actually transmitted. See also the example in *Note lookup-name::.  File: protocol-a.info, Node: Mapping Local to Global Text Numbers, Next: Server Information, Prev: Archaic way to list conferences, Up: LysKOM Data Types Mapping Local to Global Text Numbers ==================================== Text-Mapping ::= ( range-begin : Local-Text-No; range-end : Local-Text-No; more-texts-exists : BOOL; block : Local-To-Global-Block; ) Local-To-Global-Block ::= SELECTION ( 0=sparse sparse-block : ARRAY Text-Number-Pair; 1=dense dense-block : Text-List; ) Text-Number-Pair ::= ( local-number : Local-Text-No; global-number : Text-No; ) A `Text-Mapping' is used when the client needs to look up which global `Text-No' that corresponds to a `Local-Text-No'. The client uses `local-to-global' (*note local-to-global::) to ask for information about a few texts starting a a certain local text number, and the server returns the information in a `Text-Mapping'. `range-begin' The first local text number that the `Text-Mapping' says anything about. `range-end' The first local text number that the reply doesn't say anything about. This `Text-Mapping' tells the client about all existing texts from `range-begin' to (but not including) `range-end'. `more-texts-exists' This is true if there are more texts in the conference after this block. If a request such as `local-to-global-reverse' (*note local-to-global-reverse::) which searches backwards, this will instead be true if there are more texts before this block. `block' The block can be sent i two formats. The server is free to choose which format to use as it pleases; clients must be prepared for any of them. * The "sparse" format is useful when many local text number no longer exists. It starts with a `0' that indicates that the sparse format is used, and is followed by an array of `Text-Number-Pair'. The array will always be sorted so that `local-number' always increases. * The "dense" format is good when most of the local text numbers exist. It starts with a `1' that indicates that the dense format is used, and is followed by a `Text-List'. The `Text-List' contains `first-local-no' and an array of `Text-No'. The local text number `first-local-no' corresponds to the first `Text-No' in the array, `first-local-no' + 1 corresponds to the second entry in the array, and so on. The array contains a zero to indicate that a certain local text number doesn't exist.  File: protocol-a.info, Node: Server Information, Next: Person Status Types, Prev: Mapping Local to Global Text Numbers, Up: LysKOM Data Types Server Information ================== Info ::= ( version : INT32; conf-pres-conf : Conf-No; pers-pres-conf : Conf-No; motd-conf : Conf-No; kom-news-conf : Conf-No; motd-of-lyskom : Text-No; aux-item-list : ARRAY Aux-Item; ) Info-Old ::= ( version : INT32; conf-pres-conf : Conf-No; pers-pres-conf : Conf-No; motd-conf : Conf-No; kom-news-conf : Conf-No; motd-of-lyskom : Text-No; ) Version-Info ::= ( protocol-version : INT32; server-software : HOLLERITH; software-version : HOLLERITH; ) Static-Server-Info ::= ( boot-time : Time; save-time : Time; db-status : HOLLERITH; existing-texts : INT32; highest-text-no : Text-No; existing-confs : INT32; existing-persons : INT32; highest-conf-no : Conf-No; ) These data types contain information about the LysKOM server. The fields of `Info' and `Info-Old' are: `version' The server version encoded as a number AABBCC where AA is the major version number, BB the minor number and CC the secondary minor version. For instance, `10607' is version 1.6.7 of the server. If greater than 10699 the `get-version-info' (*note get-version-info::) should be used instead. `conf-pres-conf' The conference that contains conference presentations. `pers-pres-conf' The conference that contains person presentations. `motd-conf' The conference that contains conference and person notices. `kom-news-conf' The conference that contains news about LysKOM. `motd-of-lyskom' The number of an article to display when LysKOM is entered or zero if there is none. `aux-item-list' (Not present in `Info-Old'.) A list of aux-items that belong to the server. The fields of `Version-Info' are: `protocol-version' The version of protocol A the server is using. This may be used to ascertain which calls are available. `server-software' Human-readable name of the server software. `software-version' Human-readable name of the server software version. The `Static-Server-Info' contains information about the state of the server when it started. It contains the following fields: `boot-time' When did the server start? `save-time' When the server starts, it examines the database to see when it was saved. That information is available here. `db-status' The status of the database that the server found on startup. The value is implementation-defined. lyskomd reports `clean' (if the previous invocation of the server was shut down cleanly) or `backup' (which means that some information may have been lost in the last restart). Clients should be prepared to find other values here. `existing-texts' Number of texts that existed on startup. (To find out how many texts exists right now, you can use the `get-stats' call with `what' set to `texts'(*note get-stats::).) `highest-text-no' The highest text number that existed on startup. (To find the highest text number that exists right now, use the `first-unused-text-no' (*note first-unused-text-no::) and `find-previous-text-no' (*note find-previous-text-no::) calls.) `existing-confs' Number of conferences (including letterboxes) that existed on startup. (To find out how many conferences exists right now, you can use the `get-stats' call with `what' set to `confs'(*note get-stats::).) `existing-persons' Number of persons that existed on startup. (To find out how many persons exists right now, you can use the `get-stats' call with `what' set to `persons'(*note get-stats::).) `highest-conf-no' The highest conference number that existed on startup. (To find the highest conference number that exists right now, use the `first-unused-conf-no' (*note first-unused-conf-no::) and `find-previous-conf-no' (*note find-previous-conf-no::) calls.)  File: protocol-a.info, Node: Person Status Types, Next: Membership Information, Prev: Server Information, Up: LysKOM Data Types Person Status Types =================== Person ::= ( username : HOLLERITH; privileges : Priv-Bits; flags : Personal-Flags; last-login : Time; user-area : Text-No; total-time-present : INT32; sessions : INT32; created-lines : INT32; created-bytes : INT32; read-texts : INT32; no-of-text-fetches : INT32; created-persons : INT16; created-confs : INT16; first-created-local-no : INT32; no-of-created-texts : INT32; no-of-marks : INT16; no-of-confs : INT16; ) Personal-Flags ::= BITSTRING ( unread-is-secret; flg2; flg3; flg4; flg5; flg6; flg7; flg8; ) Priv-Bits ::= BITSTRING ( wheel; admin; statistic; create-pers; create-conf; change-name; flg7; flg8; flg9; flg10; flg11; flg12; flg13; flg14; flg15; flg16; ) These types are used to specify information about persons. `Person' contains the information about a person, `Personal-Flags' contains flags set by the user and `Priv-Bits' contains the person's privileges (*note Security::). The fields of `Person' are `username' The name of the user. `privileges' The privileges of the person. `flags' Flags set by the user. `last-login' The time when the person last logged on or off. `user-area' The text number of the person's user area or zero if the person has no user area. `total-time-present' The number of seconds the person has been using LysKOM. `sessions' The number of sessions the person has initiated. `created-lines' The number of lines of articles the person has written. `created-bytes' The number of characters the person has written. `read-texts' The number of articles the person has read. `no-of-text-fetches' The number of texts the person has retrieved from the server. `created-persons' The number of other persons this person has created. `created-confs' This holds the number of conferences created by the person. `first-created-local-no' The local number of the earliest existing article written by the person. The local number applies to a local-to-global mapping containing all articles written by the person. `no-of-created-texts' This holds the number of articles written by the person, not counting the articles created before the earliest existing article written by the person. To get the true number of created articles, compute `first-created-local-no' + `no-of-created-texts' - 1. `no-of-marks' The number of marked texts this person has. `no-of-confs' The number of conferences the person is a member of. The fields of `Personal-Flags' are `unread-is-secret' If this is set, only the person and his supervisors can see how many texts this persons have read in a certain conference. The server will clear the `read-ranges' field of `Membership' (and `read-texts', `last-time-read' and `last-text-read' fields of `Membership-10' and `Membership-Old') when other persons asks about the information. `flg2' `flg3' `flg4' `flg5' `flg6' `flg7' `flg8' Reserved for the future. Set them to 0, and ignore the values they have.  File: protocol-a.info, Node: Membership Information, Next: Article Marks, Prev: Person Status Types, Up: LysKOM Data Types Membership Information ====================== Membership-Type ::= BITSTRING ( invitation; passive; secret; passive-message-invert; reserved2; reserved3; reserved4; reserved5; ) The `Membership-Type' type contains flags that modify a membership. It is passed as part of both `Member' and `Membership' (and obsolete versions of those types). The flags are: `invitation' The member has been invited, but has not yet accepted membership. Clients should set this flag when adding other users as members. The server may force this flag to be set when adding another person as a member of a conference. `passive' The member is not actively participating in the conference. Passive members do not receive messages (*note async-send-message::) and should not be displayed as active members by clients. See also `passive-message-invert'. `secret' The member does not wish to disclose the membership. Secret memberships and members are cleared before being returned to a person who is not a supervisor of the member or has sufficient privileges enabled. `passive-message-invert' If this bit is set, the `passive' bit is inverted when checking for messages (*note async-send-message::) to this conference. In other words, messages are blocked if one (but not both) of the bits `passive' and `passive-message-invert' are set. The remaining flags in the `Membership-Type' structure are reserved and should be set to false on all new memberships and retained on all existing memberships. Member ::= ( member : Pers-No; added-by : Pers-No; added-at : Time; type : Membership-Type; ) The `Member' structure encodes information about a member in a conference. It is returned by the `get-members' call(*note get-members::). The fields of a `Member' structure are `member' The person who is a member of the conference. `added-by' The person who created the membership. This field is zero only if the membership was created before protocol version 10 was introduced. `added-at' The time when the membership was created. This field is meaningless if added-by is zero. `type' Flags modifying the membership. The contents of a `Member' structure can be cleared (all fields set to zero) if the person requesting the record has insufficient privileges to see the contents of the structure. Read-Range ::= ( first-read : Local-Text-No; last-read : Local-Text-No; ) Membership ::= ( position : INT32; last-time-read : Time; conference : Conf-No; priority : INT8; read-ranges : ARRAY Read-Range; added-by : Pers-No; added-at : Time; type : Membership-Type; ) Membership-Old ::= ( last-time-read : Time; conference : Conf-No; priority : INT8; last-text-read : Local-Text-No; read-texts : ARRAY Local-Text-No; ) Membership-10 ::= ( position : INT32; last-time-read : Time; conference : Conf-No; priority : INT8; last-text-read : Local-Text-No; read-texts : ARRAY Local-Text-No; added-by : Pers-No; added-at : Time; type : Membership-Type; ) The `Membership' structure encodes information about a person's membership in a conference. It is returned by the `query-read-texts' (*note query-read-texts::) and `get-membership' calls(*note get-membership::). The `Membership-10' and `Membership-Old' types are obsolete variants of the same type, returned by older requests. `Membership-Old' contains less information. The encoding of the read texts in `Membership-10' is very inefficient in the common case where you have read many texts after the first unread text. `position' The position of this membership in the membership list. `last-time-read' The time when the person last read anything from the conference. This will contain the start of the epoch if the `unread-is-secret' bit of the `Personal-Flags' is set and you don't have enough privileges to get the info anyhow. `conference' The conference this membership data pertains to. `priority' The priority the person has assigned to the conference. The higher the number, the higher the priority. In the past, priority zero indicated a passive membership. This usage is now obsolete. `last-text-read' The local number of last text read in the conference. This will be set to 0 if `unread-is-secret' is set, unless you have access to the data anyhow. This field is not available in `Membership', but you can easily derive the same information from `read-ranges'. `read-texts' Additional texts beyond `last-text-read' that have also been read. This will be empty if `unread-is-secret' is set, unless you have access to the data anyhow. `read-ranges' A list of ranges of all read texts. This will be empty if `unread-is-secret' is set, unless you have access to the data anyhow. `added-by' The person who created the membership. This field is zero if the membership was created before protocol version 10 was introduced. `added-at' The time when the membership was created. This field is meaningless if added-by is zero. `type' Flags modifying the membership. A membership record may be cleared by the server (all fields set to zero) if the person requesting the membership has insufficient privileges to see the contents membership, but has sufficient privileges to know about the person.  File: protocol-a.info, Node: Article Marks, Next: Article Information, Prev: Membership Information, Up: LysKOM Data Types Article Marks ============= Mark ::= ( text-no : Text-No; type : INT8; ) This data type hold information about a person's marks on articles. The fields of `Mark' are `text-no' The text number marked. `type' The mark value. Before version eight of protocol A, the meaning of the mark value was unspecified. Work is underway to specify the meaning of certain mark values.  File: protocol-a.info, Node: Article Information, Next: Who Information, Prev: Article Marks, Up: LysKOM Data Types Article Information =================== Misc-Info ::= SELECTION ( 0=recpt recipient : Conf-No; 1=cc-recpt cc-recipient : Conf-No; 2=comm-to comment-to : Text-No; 3=comm-in commented-in : Text-No; 4=footn-to footnote-to : Text-No; 5=footn-in footnoted-in : Text-No; 6=loc-no local-no : Local-Text-No; 7=rec-time received-at : Time; 8=sent-by sender : Pers-No; 9=sent-at sent-at : Time; 15=bcc-recpt bcc-recipient : Conf-No; ) Info-Type ::= ENUMERATION-OF(Misc-Info) Text-Stat-Old ::= ( creation-time : Time; author : Pers-No; no-of-lines : INT32; no-of-chars : INT32; no-of-marks : INT16; misc-info : ARRAY Misc-Info; ) Text-Stat ::= ( creation-time : Time; author : Pers-No; no-of-lines : INT32; no-of-chars : INT32; no-of-marks : INT16; misc-info : ARRAY Misc-Info; aux-items : ARRAY Aux-Item; ) These two structures contain information about a single article. `Text-Stat' contains core information about the article and `Misc-Info' contains miscellaneous information related to the article. A `Text-Stat' consists of the following: `creation-time' The time when the article was created. `author' The author of the article. `no-of-lines' The number of lines in the article. `no-of-chars' The number of characters in the article. `no-of-marks' The number of marks added to this article by persons. `misc-info' The `Misc-Info' list for this article. `aux-items' The list of aux items for this article. `Misc-Info', when sent to the client, is sent in a particular order (*note The Misc-Info List::). The variants `Misc-Info' are (briefly): `recpt' Used to specify recipients of the article. `cc-recpt' Specifies recipients who have received a copy of the article but who will not receive comments. `comm-to' Specifies an article this article is a comment to. `comm-in' Specifies an article in which there are comments to this article. `footn-to' Specifies an article this article is a footnote to. `footn-in' Specifies an article to which this article is a footnote. `loc-no' Specifies the local text number of this article in the conference specified by `recpt', `cc-recpt' or `bcc-recpt'. `rec-time' Specifies the time when this article was received by the conference specified by `recpt', `cc-recpt' or `bcc-recpt'. `sent-by' Specifies who sent this article to the conference specified by `recpt', `cc-recpt' or `bcc-recpt'. `sent-at' Specifies when the article was sent to the conference specified by `recpt', `cc-recpt' or `bcc-recpt'. `bcc-recpt' Specifies a blind carbon copy recipient. This item is only accepted by protocol version 10 servers and is only sent in responses and messages introduced in protocol version 10 or later.  File: protocol-a.info, Node: Who Information, Next: Session Information, Prev: Article Information, Up: LysKOM Data Types Who Information =============== Who-Info-Old ::= ( person : Pers-No; working-conference : Conf-No; what-am-i-doing : HOLLERITH; ) Who-Info ::= ( person : Pers-No; working-conference : Conf-No; session : Session-No; what-am-i-doing : HOLLERITH; username : HOLLERITH; ) Who-Info-Ident ::= ( person : Pers-No; working-conference : Conf-No; session : Session-No; what-am-i-doing : HOLLERITH; username : HOLLERITH; hostname : HOLLERITH; ident-user : HOLLERITH; ) These structures are used to retrieve information on who is currently using LysKOM. All the requests using these types are obsolete, but `Who-Info' is used by `async-i-am-on' (*note async-i-am-on::). The fields of `Who-Info-Old' are `person' The person the information is about. `working-conference' The conference the person is currently in. `what-am-i-doing' A client-supplied string saying what the person is doing. The fields of `Who-Info' are `person' The person the information is about. `working-conference' The conference the person is currently in. `session' The person's session number. `what-am-i-doing' A client-supplied string saying what the person is doing. `username' The name of the "real" user constructed from `hostname' and `ident-user' (see below) and information from the client. The fields of `Who-Info-Ident' are `person' The person the information is about. `working-conference' The conference the person is currently in. `session' The person's session number. `what-am-i-doing' A client-supplied string saying what the person is doing. `username' The name of the "real" user constructed from `hostname' and `ident-user'. `hostname' The host the connection originated at. `ident-user' The user name according to the Ident daemon at the user's machine or "unknown" if Ident was not used.  File: protocol-a.info, Node: Session Information, Next: Statistics, Prev: Who Information, Up: LysKOM Data Types Session Information =================== Session-Info ::= ( person : Pers-No; working-conference : Conf-No; session : Session-No; what-am-i-doing : HOLLERITH; username : HOLLERITH; idle-time : INT32; connection-time : Time; ) Session-Info-Ident ::= ( person : Pers-No; working-conference : Conf-No; session : Session-No; what-am-i-doing : HOLLERITH; username : HOLLERITH; hostname : HOLLERITH; ident-user : HOLLERITH; idle-time : INT32; connection-time : Time; ) Static-Session-Info ::= ( username : HOLLERITH; hostname : HOLLERITH; ident-user : HOLLERITH; connection-time : Time; ) Session-Flags ::= BITSTRING ( invisible; user-active-used; user-absent; reserved3; reserved4; reserved5; reserved6; reserved7; ) Dynamic-Session-Info ::= ( session : Session-No; person : Pers-No; working-conference : Conf-No; idle-time : INT32; flags : Session-Flags; what-am-i-doing : HOLLERITH; ) Scheduling-Info ::= ( priority : INT16; weight : INT16; ) These data types give information about a particular LysKOM session. The types `Session-Info' and `Session-Info-Ident' have been superseded by `Static-Session-Info' and `Dynamic-Session-Info'. The static session info represents information about a session that does not change during the lifetime of the session. Therefore static session infos can be aggressively cached by the client. The fields of `Session-Info' are `person' The person using this session. `working-conference' The conference the session is currently in. `session' The number of this session. `what-am-i-doing' A client-supplied string saying what the person is currently doing. `username' The name of the "real" user (see `Who-Info' above.) `idle-time' The number of seconds since `user-active' was used by this session(*note user-active::), or since the session was created if `user-active' has not been used yet. See also `user-active-used' below. `connection-time' The time when the connection was initiated. This is not the same as the amount of time the person has been on. The fields of `Session-Info-Ident' are `person' The person using this session. `working-conference' The conference the session is currently in. `session' The number of this session. `what-am-i-doing' A client-supplied string saying what the person is currently doing. `username' The name of the "real" user (see `Who-Info-Ident' above.) `hostname' The host the connection originated at. `ident-user' The user name according to the Ident daemon at the user's machine or "unknown" if Ident was not used. `idle-time' The number of seconds since `user-active' was used by this session(*note user-active::), or since the session was created if `user-active' has not been used yet. See also `user-active-used' below. `connection-time' The time when the connection was initiated. This is not the same as the amount of time the person has been on. The fields of `Static-Session-Info' are `username' The name of the "real" user (see `Who-Info-Ident' above.) `hostname' The host the connection originated at. `ident-user' The user name according to the Ident daemon at the user's machine or "unknown" if Ident was not used. `connection-time' The time when the connection was initiated. This is not the same as the amount of time the person has been on. The bits in `Session-Flags' are: `invisible' When true, the user requested an invisible session (*note login::). Sessions where no-one is logged in also have the `invisible' flag set. `user-active-used' When true, the `user-active' call(*note user-active::) has been issued by the session, which in turn means that `idle-time' fields of `Dynamic-Session-Info', `Session-Info' and `Session-Info-Ident' are valid. When false, the `idle-time' fields contains the number of seconds since the session was created. `user-absent' This flag is currently not used. The fields of a `Dynamic-Session-Info' are `session' The session number of the session. `person' The person currently logged on, or zero if the session has not yet logged on. `working-conference' The conference the session is currently in. `idle-time' The number of seconds since `user-active' was used by this session(*note user-active::), or since the session was created if `user-active' has not been used yet. See also `user-active-used' above. `flags' The dynamic session flags (see above.) `what-am-i-doing' What the client is doing. This string is set by the client. The `Scheduling-Info' type determines how the resources are shared between different sessions(1). See `get-scheduling' (*note get-scheduling::) and `set-scheduling' (*note set-scheduling::) for more information. It contains these fields: `priority' Clients with a numerically lower `priority' value will have priority over other clients. A client with `priority' set to 0 can totally starve clients with `priority' set to 1, 2 or anything higher. `weight' Within a priority class, the resources are shared in proportion to the `weight' value. If one client has a weight of 200 and another of 50, the first client will get roughly four times as much work done (assuming that the server is the limiting factor). ---------- Footnotes ---------- (1) RFC 2782 (DNS SRV) provided inspiration when the `Scheduling-Info' structure was defined.  File: protocol-a.info, Node: Statistics, Prev: Session Information, Up: LysKOM Data Types Statistics ========== Stats ::= ( average : FLOAT; ascent-rate : FLOAT; descent-rate : FLOAT; ) Stats-Description ::= ( what : ARRAY HOLLERITH; when : ARRAY INT32; ) The `Stats' structure returns information about a measured value. `average' The `average' is the average value for the measurement period. If the measurement period is 0, this is instead the current value. `ascent-rate' `descent-rate' These fields indicate the activity for this value, measured in units per second. If the measured value is pending DNS requests, the `ascent-rate' would be the average number of issued requests per second, and the `descent-rate' would be the average number of received replies (or timeouts, errors, or other reasons why the request is no longer pending). When calculating the `ascent-rate', only events that cause the value to increase are considered. Likewise, the `descent-rate' only considers events that decrease the value. Example: if the measurement period is 60 seconds, the value starts at 5, and it is increased by one 90 times and decreased by one 60 times during the measurement period, the value will of course be 35 when the period ends. The ascent rate will be 1.5 per second, and the descent rate 1.0 per second. If the measurement period is 0, both `ascent-rate' and `descent-rate' are set to 0. The `Stats-Description' structure returns information about what kind of statistical information that the server gathers. It contains these fields: `what' A list of all things that the server collect statistics about. *Note Measured Properties::, for a list of things that might be included in this list. `when' The statistics returned by `get-stats' (*note get-stats::) is a number of values collected during various periods of time. This array contains the periods, measured in seconds. The value 0 means that the current value is returned. The values are only returned in ascending order, so if 0 is included it will be the first value. *Note Measured Properties::, for more info. lyskom-server-2.1.2/doc/protocol-a.info-30000664000015100472110000014140107723710263013666 This is protocol-a.info, produced by makeinfo version 4.2 from Protocol-A.texi. This is the LysKOM Protocol A specification, edition 11.1. It specifies version 11 of the protocol. It was first distributed with version 2.1.2 of lyskomd. Copyright (C) 1995-2003 Lysator ACS. Permission is granted to make and distribute verbatim copies of this specification provided the copyright notice and this permission notice are preserved on all copies. Modified versions of this document may be redistributed with the added condition that all modifications not cleared with the LysKOM development group are clearly marked and that the entire modified work be redistributed under the same conditions as the original. Permission is granted to copy and distribute translations of this manual into another language under the same conditions as for modified versions. INFO-DIR-SECTION LysKOM START-INFO-DIR-ENTRY * Protocol A: (protocol-a). The LysKOM Protocol A specification. END-INFO-DIR-ENTRY  File: protocol-a.info, Node: Protocol Requests, Next: Asynchronous Messages, Prev: LysKOM Data Types, Up: Top Protocol Requests ***************** This chapter documents all calls that can be made to the server. All calls are annotated with the protocol version in which they appeared and their current status. * Menu: * Protocol Notation:: The notation used when describing the requests and their replies. * login-old:: O Log in to LysKOM. Call 62 is preferred (0) * logout:: r Log out. Call 62 to log in again (1) * change-conference:: r Change current conference (2) * change-name:: r Change name of a conference or person (3) * change-what-i-am-doing:: r Change what-am-i-doing in who information (4) * create-person-old:: O Create a person (5) * get-person-stat-old:: O Get person information. Use call 49 (6) * set-priv-bits:: r Set privileges of a person (7) * set-passwd:: r Set password of a person (8) * query-read-texts-old:: O Get info on what is read (9) * create-conf-old:: O Create a conference (10) * delete-conf:: r Delete a conference (11) * lookup-name:: O Look up a name. Replaced by call 76 (12) * get-conf-stat-older:: O Get conference information. Use call 50 (13) * add-member-old:: O Add a member to a conference (14) * sub-member:: r Remove a member from a conference (15) * set-presentation:: r Set the presentation of a conference (16) * set-etc-motd:: r Set conference notice (17) * set-supervisor:: r Set supervisor of a conference (18) * set-permitted-submitters:: r Set permitted submitters of a conference (19) * set-super-conf:: r Set super-conference of a conference (20) * set-conf-type:: r Set the type of a conference (21) * set-garb-nice:: r Set garb-nice of a conference (22) * get-marks:: r Get marks for a person (23) * mark-text-old:: O Mark a text. Replaced by calls 72 and 73 (24) * get-text:: r Get an article or part of an article (25) * get-text-stat-old:: O Get text status information (26) * mark-as-read:: r Mark an article as read in a conference (27) * create-text-old:: O Create an article (28) * delete-text:: r Delete an article (29) * add-recipient:: r Add a recipient to an article (30) * sub-recipient:: r Remove a recipient from an article (31) * add-comment:: r Add a comment to an article (32) * sub-comment:: r Remove a comment from an article (33) * get-map:: O Map local text nos to global. Use 103 (34) * get-time:: r Get the current time (35) * get-info-old:: O Get server information (36) * add-footnote:: r Add an article as a footnote to another (37) * sub-footnote:: r Remove a footnote from an article (38) * who-is-on-old:: O Get active sessions. Replaced by call 63 (39) * set-unread:: r Set number of unread in a conference (40) * set-motd-of-lyskom:: r Set LysKOM message of the day (41) * enable:: r Set security level (42) * sync-kom:: r Save the database (43) * shutdown-kom:: r Shut LysKOM down (44) * broadcast:: O Broadcast a message. Replaced by call 53 (45) * get-membership-old:: O Get membership for a person. Use call 99 (46) * get-created-texts:: O Get texts created by a user. Use 104 (47) * get-members-old:: O Get members of a conference. Use 101 (48) * get-person-stat:: r Get status information for a person (49) * get-conf-stat-old:: O Get status information for a conference (50) * who-is-on:: O Get current sessions. Use call 63 (51) * get-unread-confs:: r Get conferences with unread articles (52) * send-message:: r Send a personal message (53) * get-session-info:: O Get session information. Use call 64 (54) * disconnect:: r Disconnect a session (55) * who-am-i:: r Get current session number (56) * set-user-area:: r Set a person's user area (57) * get-last-text:: r Get text created before a certain time (58) * create-anonymous-text-old:: O Create an anonymous text (59) * find-next-text-no:: r Get next text number (60) * find-previous-text-no:: r Get previous text number (61) * login:: r Log in to LysKOM (62) * who-is-on-ident:: O Get current sessions (63) * get-session-info-ident:: O Get session information (64) * re-lookup-person:: O Look up a person based on name (65) * re-lookup-conf:: O Look up a conference based on name (66) * lookup-person:: O Find persons matching abbreviated name (67) * lookup-conf:: O Find conference matching abbrev'd name (68) * set-client-version:: r Set the name and version the client (69) * get-client-name:: r Get the name of the client (70) * get-client-version:: r Get the version of the client (71) * mark-text:: r Mark a text (72) * unmark-text:: r Unmark a text (73) * re-z-lookup:: r Lookup for conferences and persons (74) * get-version-info:: r Get protocol version of server (75) * lookup-z-name:: r Look up an abbreviated name (76) * set-last-read:: r Set text last read in a conference (77) * get-uconf-stat:: r Get abbreviated conference status (78) * set-info:: r Set server information (79) * accept-async:: r Select asynchronous messages to receive (80) * query-async:: r Ask server which async messages are sent (81) * user-active:: r Tell the server that the user is active (82) * who-is-on-dynamic:: r Get a list of active users (83) * get-static-session-info:: r Get static information about a session (84) * get-collate-table:: r Get the current collate table (85) * create-text:: r Create a text (86) * create-anonymous-text:: r Create an anonymous text (87) * create-conf:: r Create a conference (88) * create-person:: r Create a person (89) * get-text-stat:: r Get text status information (90) * get-conf-stat:: r Get conference status information (91) * modify-text-info:: r Add or delete text aux items (92) * modify-conf-info:: r Add or delete conference aux items (93) * get-info:: r Get server information (94) * modify-system-info:: r Add or delete system aux items (95) * query-predefined-aux-items:: r Get list of aux-items the server knows (96) * set-expire:: e Set the expire field of a conference (97) * query-read-texts-10:: O Get info on what is read (98) * get-membership-10:: O Get membership for a person (99) * add-member:: r Add a member to a conference (100) * get-members:: r Get members of a conference (101) * set-membership-type:: r Modify the type of conference (102) * local-to-global:: r Map local text numbers to global ones (103) * map-created-texts:: r Map texts created by a person to global (104) * set-keep-commented:: r Set how new comments protect old texts (105) * set-pers-flags:: r Set personal flags (106) * query-read-texts:: r Get info on what is read (107) * get-membership:: r Get membership for a person (108) * mark-as-unread:: r Mark a text as not read (109) * set-read-ranges:: r Specify which texts that are read (110) * get-stats-description:: r Get a list of measured properties (111) * get-stats:: r Get a measurement (112) * get-boottime-info:: r Get server startup status information (113) * first-unused-conf-no:: r Get first unused conference number (114) * first-unused-text-no:: r Get first unused text number (115) * find-next-conf-no:: r Get next conference number (116) * find-previous-conf-no:: r Get previous conference number (117) * get-scheduling:: e Get client priority information (118) * set-scheduling:: e Alter client priority (119) * set-connection-time-format:: r Use UTC or local timezone of server? (120) * local-to-global-reverse:: r Map local text numbers to global ones (121) * map-created-texts-reverse:: r Map texts created by a person to global (122)  File: protocol-a.info, Node: Protocol Notation, Next: login-old, Up: Protocol Requests Protocol Notation ================= The heading for each call looks something like this: create-person-old [5] (1) Obsolete (10) The heading consists of several parts: The name: `create-person-old' This is the name of the call. The name is not considered part of the protocol. It may change in future versions of this document. Since the name is never sent over the network it doesn't matter that much. The call number: `[5]' The call number is what really matters, since it is sent over the network. It will never change. Introduced: `(1)' The protocol version when the call was first implemented. Some calls added more functionality in a later protocol version. The description for those calls describes such changes. The status: `Obsolete' The status of the call (see below). Made obsolete: `(10)' This figure is only present for some obsolete calls, and it states in which protocol version the call was obsoleted. The status of a call can be any of: `Experimental' The call is experimental. No client should rely on the existence of this call. Experimental calls that are useful will usually become recommended in future versions. `Recommended' The call is a standard call. Clients are recommended to use these calls rather than experimental or obsolete ones. Servers are required to implement all recommended calls. `Obsolete' The call should no longer be used by clients. Servers should implement these, or they will be incompatible with old client versions. _Please note:_ the documentation for the obsolete calls may be incomplete. Many of them perform compatibility magic to ensure that they never return anything that old clients don't expect. This compatibility magic is often documented, but we may have forgotten to document it in some places. A note about the examples: The examples consist of a number of calls and replies. Extra newlines are sometimes inserted in the examples to avoid overly long lines.  File: protocol-a.info, Node: login-old, Next: logout, Prev: Protocol Notation, Up: Protocol Requests login-old [0] (1) Obsolete (4) ============================== login-old [0] (( person : Pers-No; passwd : HOLLERITH )) -> ( ); Log in as a person. This call has been replaced by `login' (*note login::). Error codes ----------- `undefined-person' `person' is not an existing person. `login-disallowed' Logins are not allowed and `person' does not have the `wheel' bit set. `invalid-password' `passwd' is not the correct password for `person'. The `error-status' indicates the person number.  File: protocol-a.info, Node: logout, Next: change-conference, Prev: login-old, Up: Protocol Requests logout [1] (1) Recommended ========================== logout [1] ( ) -> ( ); Log out from LysKOM. This call does not disconnect the session; use `disconnect' for that(*note disconnect::). After issuing a `logout' call the client can reconnect as the same or a different person using the `login' call(*note login::). For a client that needs to log in as several different users, issuing multiple logout and login requests during one session is faster and places less load on the server than does creating new sessions. Error codes ----------- This call never fails.  File: protocol-a.info, Node: change-conference, Next: change-name, Prev: logout, Up: Protocol Requests change-conference [2] (1) Recommended ===================================== change-conference [2] ( conference : Conf-No ) -> ( ) ; Change current conference of a session. This call used to be called pepsi (the name was a very obscure and not very funny joke.) Error codes ----------- `login-first' The session is not logged in yet. `undefined-conference' Conference `conference' does not exist or is secret. `conference-zero' `conference' is zero. `not-member' The user currently logged in is not a member of `conference'.  File: protocol-a.info, Node: change-name, Next: change-what-i-am-doing, Prev: change-conference, Up: Protocol Requests change-name [3] (1) Recommended =============================== change-name [3] (( conference : Conf-No; new-name : HOLLERITH )) -> ( ) ; This call changes the name of a conference or a person. To change the name of a conference the session issuing the call must be logged in as a person who either has special privileges or is the supervisor of the conference. Error codes ----------- `login-first' The session is not logged in yet. `undefined-conference' Conference `conference' does not exist or is secret. `conference-zero' `conference' is zero. `permission-denied' Permission denied. The `change-name' bit is not set or the user does not have enough access to `conference'. `conference-exists' `new-name' is already occupied by another conference. `string-too-long' `new-name' is too long for a valid conference name. `bad-name' There are invalid characters in `new-name'.  File: protocol-a.info, Node: change-what-i-am-doing, Next: create-person-old, Prev: change-name, Up: Protocol Requests change-what-i-am-doing [4] (1) Recommended ========================================== change-what-i-am-doing [4] ( what-am-i-doing : HOLLERITH ) -> ( ); This call tells the server what the logged-in user is doing. The string is usually displayed when a user requests that a client list who is using LysKOM. Clients are encouraged to use this call creatively. Error codes ----------- `string-too-long' `what-am-i-doing' is too long.  File: protocol-a.info, Node: create-person-old, Next: get-person-stat-old, Prev: change-what-i-am-doing, Up: Protocol Requests create-person-old [5] (1) Obsolete (10) ======================================= create-person-old [5] (( name : HOLLERITH; passwd : HOLLERITH )) -> ( Pers-No ); This call requests that the server create a new person with the name and password given as arguments. To create a person the session may have to be logged in as a person with sufficient privileges, if the server is configured that way. If the session was not logged in an automatic visible login to the new person will be performed. The new person will be a member of exactly one conference: the associated mailbox. That membership will have priority 255 and (of course) position 0. All flags of the membership will be 0. Example: 1 5 24HLysKOM Statistics Daemon 6Hsecret =1 6 This example creates a new person named "LysKOM statistics Daemon" with the password "secret". The server has returned the person number six for the person. Error codes ----------- `login-first' The session is not logged in and the server does not allow person creation before logging in. `permission-denied' The server does not allow everyone to create person and the person currently logged on does not have the `create-pers' bit set. `conference-exists' There is already a conference named `name'. `invalid-password' The string `passwd' is not a valid password. `index-out-of-range' Attempt to create a person failed because we reached the maximum number of conferences permitted. The `error-status' indicates the person number that should have been created if the limit hadn't been reached.  File: protocol-a.info, Node: get-person-stat-old, Next: set-priv-bits, Prev: create-person-old, Up: Protocol Requests get-person-stat-old [6] (1) Obsolete (1) ======================================== get-person-stat-old [6] (( person : Pers-No; mask : INT32 )) -> ( Person ); This call returns information about a person. If the low bit of `mask' is not set, the empty string is returned instead of the `username' field. This call is obsolete and has been replaced by `get-person-stat' (*note get-person-stat::). Error codes ----------- `login-first' This call can't be executed without logging in first. `undefined-person' Person `person' does not exist. `undefined-conference' Conference `person' does not exist or is secret. `conference-zero' `person' is zero.  File: protocol-a.info, Node: set-priv-bits, Next: set-passwd, Prev: get-person-stat-old, Up: Protocol Requests set-priv-bits [7] (1) Recommended ================================= set-priv-bits [7] (( person : Pers-No; privileges : Priv-Bits )) -> ( ); This call sets the privileges of `person' to `privileges'. *Note Security::. To successfully issue this call the session must be logged in as a person with sufficient privileges. Example: 1 7 6 0010000000000000 =1 This example sets the privileges of person 6 to nothing but `statistic'. This particular set of privileges might be useful for a person used by a statistics-collecting daemon. Error codes ----------- `login-first' This call can't be executed without logging in first. `undefined-person' `person' is not a valid person. `permission-denied' The person currently logged in does not have the `wheel' bit set and privilege level set to 6 or higher.  File: protocol-a.info, Node: set-passwd, Next: query-read-texts-old, Prev: set-priv-bits, Up: Protocol Requests set-passwd [8] (1) Recommended ============================== set-passwd [8] (( person : Pers-No; old-pwd : HOLLERITH; new-pwd : HOLLERITH )) -> ( ); This call is used to set the password of `person' to `new-pwd'. Any person may set it's own password. In addition persons with sufficient privileges may set other persons' passwords. The password of the person currently logged in must match `old-pwd'. Example: 1 8 5 6Hgazonk 7Ha9go8Hz =1 This example sets the password of the LysKOM administrator to "a9go8Hz" provided that the old password was "gazonk". Error codes ----------- `login-first' This call cannot be executed without logging in. `undefined-person' `person' is not a valid person. `permission-denied' Attempt to change password of another person without being the supervisor of that person and without the `wheel' bit set and privilege level 7 or higher enabled. `invalid-password' `old-pwd' is invalid or `new-pwd' is invalid as a password.  File: protocol-a.info, Node: query-read-texts-old, Next: create-conf-old, Prev: set-passwd, Up: Protocol Requests query-read-texts-old [9] (1) Obsolete (10) ========================================== query-read-texts-old [9] (( person : Pers-No; conference : Conf-No )) -> ( Membership-Old ); This call is used to find the number of unread texts in a conference. The data it returns is actually a membership structure which specifies which texts have been read. It is up to the client to transform the data to a more usable form. `person' is the person being queried and `conference' is the conference in question. Calling `query-read-texts-old' does not require the session to be logged in. Example: 1 9 6 1 =1 32 5 11 12 7 93 1 193 1 1 20 133 3 { 135 136 137 } This example finds the read texts for user 6 in conference 1. The returned data indicates that the user last read conference 1 (the tenth number) on Monday July 12th, 1993 at 11:05:32 (the first nine numbers), that the person has assigned priority 20 to the conference (the eleventh number) and that all articles up to and including local number 133 plus articles 135, 136 and 137 have been read. Error codes ----------- `undefined-person' `person' does not exist, or no access to person. `undefined-conference' Conference `conference' does not exist, or is secret. `conference-zero' `conference' is zero. `not-member' `person' is not a member of `conference'.  File: protocol-a.info, Node: create-conf-old, Next: delete-conf, Prev: query-read-texts-old, Up: Protocol Requests create-conf-old [10] (1) Obsolete (10) ====================================== create-conf-old [10] (( name : HOLLERITH; type : Any-Conf-Type )) -> ( Conf-No ); This call is used to create new conferences. `name' is the name of the new conference and `type' is its type. If successful, the call returns the conference number of the newly created conference. To use this call the session must have logged in as a user with privileges to create conferences (*note Security::). Example: 1 50 8 %1 9 0 1 10 13HInlägg }t mig 00001000 =1 8 1 50 8 =1 13HInlägg }t mig 0000 43 9 17 14 5 96 5 165 1 43 9 17 14 5 96 5 165 1 5 0 5 0 5 0 77 0 1 0 This example creates a new conference named "Inlägg }t mig"(1) which accepts all users as members and accepts anonymous articles. The server returns 7 as the new conference number. Error codes ----------- `login-first' Login required before issuing this call. `permission-denied' The server does not allow everyone to create a conference and user does not have the `create-conf' bit set. `conference-exists' A conference named `name' already exists. `bad-name' `name' contains invalid characters. `string-to-long' `name' is too long to be used as a conference name. `secret-public' The conference type `type' has the `secret' bit set, but the `rd-prot' bit is cleared. `index-out-of-range' Attempt to create a conference failed because we reached the maximum number of conferences permitted. The `error-status' indicates the conference number that should have been created if the limit hadn't been reached. ---------- Footnotes ---------- (1) This conference is a standard Lysator conference. It's all Padrone's fault.  File: protocol-a.info, Node: delete-conf, Next: lookup-name, Prev: create-conf-old, Up: Protocol Requests delete-conf [11] (1) Recommended ================================ delete-conf [11] ( conf : Conf-No ) -> ( ); This call deletes the conference `conf' from the LysKOM database. Only privileged users and the supervisors of a conference may delete it. If the conference is a mailbox the corresponding person will also be deleted. Example: 1 50 7 =1 4HTest 1001 16 4 19 10 5 96 1 161 1 16 4 19 10 5 96 1 161 1 7 0 7 0 0 0 77 1 1 0 1 11 7 =1 1 50 7 %1 9 0 This example shows the successful deletion of conference number seven. Error codes ----------- `login-first' Login required before issuing this call. `undefined-conference' `conf' does not exist or is secret. `conference-zero' `conf' is zero. `permission-denied' Not supervisor of `conf' and not enough privileges enabled. `undefined-person' `conf' is a mailbox but does not exist as a person (the database is corrupt.)  File: protocol-a.info, Node: lookup-name, Next: get-conf-stat-older, Prev: delete-conf, Up: Protocol Requests lookup-name [12] (1) Obsolete (7) ================================= lookup-name [12] ( name : HOLLERITH ) -> ( Conf-List-Archaic ); This call returns a list of conferences matching the string `name'. lookup-name has been superseded by `lookup-z-name' (*note lookup-z-name::). Example: 1 12 3Ha d =1 3 { 217 674 1582 } { 0000 1001 0000 } 2 12 3H::: =2 0 * * 3 76 3Ha d 1 1 =3 3 { 31HAlkohol- (och annan) drogdebatt 0000 217 13HAnna Degerman 1001 674 27HAnarchy discussion (import) 0000 1582 } 4 76 3H::: 1 1 =4 0 * This example shows two attempts to look up a name. The first example looks up `a d' and finds three matches (the middle, number 674, is a person). The second example looks up `:::' which doesn't match any conference (or person). Call number 3 and 4 issues the same lookup using the `lookup-z-name' call(*note lookup-z-name::). (The return value for call number 3 has been broken into three lines to fit on the page.) Error codes ----------- This call always succeeds.  File: protocol-a.info, Node: get-conf-stat-older, Next: add-member-old, Prev: lookup-name, Up: Protocol Requests get-conf-stat-older [13] (1) Obsolete (1) ========================================= get-conf-stat-older [13] (( conf-no : Conf-No; mask : INT32 )) -> ( Conference-Old ); This call retrieves the information associated with conference `conf-no' in the LysKOM server. This call should no longer be used; use `get-conf-stat' instead(*note get-conf-stat::). The `mask' argument determines if the name is returned or not. If the lowest bit is 1 the name is returned, otherwise the empty string is returned instead of the name. Error codes ----------- `undefined-conference' `conf-no' does not exist or is secret. `conference-zero' `conf-no' is zero.  File: protocol-a.info, Node: add-member-old, Next: sub-member, Prev: get-conf-stat-older, Up: Protocol Requests add-member-old [14] (1) Obsolete (10) ===================================== add-member-old [14] (( conf-no : Conf-No; pers-no : Pers-No; priority : INT8; where : INT16 )) -> ( ); Make the person `pers-no' a member of conference `conf-no'. The membership priority is set to `priority' and its position in the membership list is set to `where'. This call can be used to change the priority and position of a conference in the person's membership list if the person is already a member of the conference. In protocol version 10, setting the priority to zero sets the passive bit in the membership. The actual priority is not changed. Example: 1 46 119 0 10 0 =1 1 { 49 14 17 13 8 91 5 255 1 119 255 0 0 * } 1 14 1 119 250 0 =1 1 46 119 0 10 0 =1 2 { 52 30 14 11 5 96 2 162 1 1 250 0 0 * 49 14 17 13 8 91 5 255 1 119 255 0 0 * } This example makes person 119 (me) a member of conference number 1. The priority is set to 250 and the conference is placed first in the membership list. The first and last calls of the example show the membership list for person 119 before and after the call. Error codes ----------- `login-first' Login required before issuing this call. `undefined-conference' Conference `conf-no' does not exist or is secret. `conference-zero' `conf-no' is zero. `undefined-person' Person `pers-no' does not exist `access-denied' Not enough permissions or privileges to add members to conference `conf-no'. `permission-denied' Person `pers-no' is already a member of conference `conf-no', but the person logged on is not a supervisor and does not have enough privileges to change the priorities of person `pers-no'.  File: protocol-a.info, Node: sub-member, Next: set-presentation, Prev: add-member-old, Up: Protocol Requests sub-member [15] (1) Recommended =============================== sub-member [15] (( conf-no : Conf-No; pers-no : Pers-No )) -> ( ); Removes the person `pers-no' from the membership list of conference `conf-no' and remove the conference from the person's list of memberships. Example: 1 46 5 0 100 0 =1 2 { 44 14 19 10 5 96 1 161 1 1 0 0 0 * 49 14 17 13 8 91 5 255 1 5 255 0 0 * } 1 15 1 5 =1 1 46 5 0 100 0 =1 1 { 49 14 17 13 8 91 5 255 1 5 255 0 0 * } This example shows how person 5 is removed from conference one. The calls to `get-membership-old' demonstrate the effects on the LysKOM database. Error codes ----------- `login-first' Login required before issuing this call. `undefined-conference' Conference `conf-no' does not exist or is secret. `conference-zero' `conf-no' is zero. `undefined-person' Person `pers-no' does not exist. `not-member' Person `pers-no' is not a member of conference `conf-no'. `permission-denied' Not supervisor of conference `conf-no' or not supervisor of person `pers-no' and not enough privileges to issue the call anyway. `error-status' contains the conference number.  File: protocol-a.info, Node: set-presentation, Next: set-etc-motd, Prev: sub-member, Up: Protocol Requests set-presentation [16] (1) Recommended ===================================== set-presentation [16] (( conf-no : Conf-No; text-no : Text-No )) -> ( ); This call sets the presentation text of the conference or person `conf-no' to the text `text-no'. To remove a presentation, use a `text-no' of zero. This call protects the new presentation from being deleted automatically and removes such protection from the old presentation. In lyskomd this is implemented by increasing the mark count on presentation texts. Example: 1 50 6 =1 11HDavid Byers 1001 26 15 11 9 5 96 0 160 1 26 15 11 9 5 96 0 160 1 5 0 5 0 5 0 77 1 1 0 1 16 6 1 =1 1 50 6 =1 11HDavid Byers 1001 26 15 11 9 5 96 0 160 1 26 15 11 9 5 96 0 160 1 5 1 5 0 5 0 77 1 1 0 This example shows how the presentation of person 6 is being changed. To start with, the person had no presentation, as is shown by the `get-conf-stat-old' call(*note get-conf-stat-old::). Later, after `set-presentation' has been called, the presentation field has changed. Error codes ----------- `login-first' Login required before issuing this call. `undefined-conference' Conference `conf-no' does not exist or is secret. `conference-zero' `conf-no' is zero. `permission-denied' Not enough permissions to change presentation of conference `conf-no'. `no-such-text' Text `text-no' does not exist or no read permission. `mark-limit' Adding a mark to text `text-no' would cause it to have too many marks.  File: protocol-a.info, Node: set-etc-motd, Next: set-supervisor, Prev: set-presentation, Up: Protocol Requests set-etc-motd [17] (1) Recommended ================================= set-etc-motd [17] (( conf-no : Conf-No; text-no : Text-No )) -> ( ); This call sets the message of the day on the conference or person `conf-no' to the article `text-no' and removes the old message. To remove an old message without setting a new one, use a `text-no' of zero. This call protects the new message from automatic deletion and removes such protection from the old message just as `set-presentation' (*note set-presentation::). Example: 1 50 6 =1 11HDavid Byers 1001 26 15 11 9 5 96 0 160 1 26 15 11 9 5 96 0 160 1 5 0 5 0 5 0 77 1 1 0 1 17 6 1 =1 1 50 6 =1 11HDavid Byers 1001 26 15 11 9 5 96 0 160 1 26 15 11 9 5 96 0 160 1 5 0 5 0 5 1 77 1 1 0 This example shows how text number one is used as the message of the day for conference six (which happens to be a mailbox.) The `get-conf-stat-old' calls before and after demonstrate the change in the conference structure. Error codes ----------- `login-first' Login required before issuing this call. `undefined-conference' Conference `conf-no' does not exist or is secret. `conference-zero' `conf-no' is zero. `permission-denied' Not enough permissions to set the MOTD of conference `conf-no'. `mark-limit' Adding a mark to text `text-no' would cause it to have too many marks.  File: protocol-a.info, Node: set-supervisor, Next: set-permitted-submitters, Prev: set-etc-motd, Up: Protocol Requests set-supervisor [18] (1) Recommended =================================== set-supervisor [18] (( conf-no : Conf-No; admin : Conf-No )) -> ( ); The `set-supervisor' call changes the supervisor of an existing conference. The result is that all members of the conference `admin' become supervisors of the conference `conf-no'. Typically, but not always, `admin' will be a mailbox. Example: 1 50 4 =1 17HNyheter om LysKOM 0000 48 11 17 13 8 91 5 255 1 15 12 11 9 5 96 0 160 1 0 0 0 0 0 0 77 1 1 1 1 18 4 6 =1 1 50 4 =1 17HNyheter om LysKOM 0000 48 11 17 13 8 91 5 255 1 15 12 11 9 5 96 0 160 1 0 0 6 0 0 0 77 1 1 1 This example makes the members of conference six supervisors of conference four (which is usually the "News about LysKOM" conference). The change in the conference structure is evident from the `get-conf-stat-old' calls(*note get-conf-stat-old::) before and after the `set-supervisor' call. Note that the original supervisor was not set. In order to change the supervisor of such a conference, the session issuing the call must have administration privileges. Error codes ----------- `login-first' Login required before issuing this call. `undefined-conference' Conference `conf-no' or conference `admin' does not exist or is secret. `conference-zero' `conf-no' is zero. `permission-denied' Not enough permissions or privileges to change the supervisor of conference `conf-no'.  File: protocol-a.info, Node: set-permitted-submitters, Next: set-super-conf, Prev: set-supervisor, Up: Protocol Requests set-permitted-submitters [19] (1) Recommended ============================================= set-permitted-submitters [19] (( conf-no : Conf-No; perm-sub : Conf-No )) -> ( ); This call grants the right to send articles to the conference `conf-no' to all members of the conference `perm-sub'. If `perm-sub' is 0, everybody can send articles to the conference. (This is the default setting of new conferences and persons.) When a person tries to submit an article but does not have the right to do so, the server will send the article to the super-conference instead. Example: 1 50 4 =1 17HNyheter om LysKOM 0000 48 11 17 13 8 91 5 255 1 15 12 11 9 5 96 0 160 1 0 0 6 0 0 0 77 1 1 1 1 19 4 1 =1 1 50 4 =1 17HNyheter om LysKOM 0000 48 11 17 13 8 91 5 255 1 15 12 11 9 5 96 0 160 1 0 0 6 1 0 0 77 1 1 1 This example shows how all members of conference one are given permission to send articles to conference four. From the beginning, only members of conference four were permitted to submit articles. The change is evident from the `get-conf-stat-old' calls(*note get-conf-stat-old::) before and after the `set-permitted-submitters' call. Error codes ----------- `login-first' Login required before issuing this call. `undefined-conference' Conference `conf-no' or conference `perm-sub' does not exist or is secret. `conference-zero' `conf-no' is zero. `permission-denied' Not enough permissions to change the permitted submitters of conference `conf-no'.  File: protocol-a.info, Node: set-super-conf, Next: set-conf-type, Prev: set-permitted-submitters, Up: Protocol Requests set-super-conf [20] (1) Recommended =================================== set-super-conf [20] (( conf-no : Conf-No; super-conf : Conf-No )) -> ( ); Makes the conference `super-conf' the super-conference of the conference `conf-no'. *Note Conference Status Types::, for more info on what this field is used for. Example: 1 50 4 =1 17HNyheter om LysKOM 0000 48 11 17 13 8 91 5 255 1 15 12 11 9 5 96 0 160 1 0 0 6 0 0 0 77 1 1 1 2 20 4 8 =2 3 50 4 =3 17HNyheter om LysKOM 0000 48 11 17 13 8 91 5 255 1 15 12 11 9 5 96 0 160 1 0 0 6 0 8 0 77 1 1 1 This example demonstrates how the super-conference of conference 1 is set to conference 8. The calls to `get-conf-stat-old' (*note get-conf-stat-old::) demonstrate the change in the conference structure. Error codes ----------- `login-first' Login required before issuing this call. `undefined-conference' Conference `conf-no' or conference `super-conf' does not exist or is secret. `conference-zero' `conf-no' is zero. `permission-denied' Not enough permissions to change super-conference of conference `conf-no'.  File: protocol-a.info, Node: set-conf-type, Next: set-garb-nice, Prev: set-super-conf, Up: Protocol Requests set-conf-type [21] (1) Recommended ================================== set-conf-type [21] (( conf-no : Conf-No; type : Any-Conf-Type )) -> ( ); Sets the conference type of conference `conf-no' to `type'. Before protocol version 8, `type' could only be four bits. Starting with protocol version 8, either a four-bit `Conf-Type' or an eight-bit `Extended-Conf-Type' is allowed. Example: 1 78 4 =1 17HNyheter om LysKOM 00001000 1 77 1 21 4 00000000 =1 1 78 4 =1 17HNyheter om LysKOM 00000000 1 77 This example shows a user removing the `allow-anonymous' bit from conference four. The `get-uconf-stat' call(*note get-uconf-stat::) shows all eight bits of the conference type before and after the `set-conf-type' call. Error codes ----------- `login-first' Login required before issuing this call. `undefined-conference' Conference `conf-no' does not exist or is secret. `conference-zero' `conf-no' is zero. `secret-public' `type' has `secret' bit but not `rd-prot'. `permission-denied' Not enough permissions or privileges to change the conference type of conference `conf-no'. `letterbox' Attempt to change the `letterbox' flag. `invalid-membership-type' Attempt to change to a conference type that is not compatible with one of more members of the conference (for example, attempting to set `forbid-secret' on a conference with a secret member.) `error-status' is the id of the first person with an incompatible membership type.  File: protocol-a.info, Node: set-garb-nice, Next: get-marks, Prev: set-conf-type, Up: Protocol Requests set-garb-nice [22] (1) Recommended ================================== set-garb-nice [22] (( conf-no : Conf-No; nice : Garb-Nice )) -> ( ); Sets the expiration time for articles in conference `conf-no' to `nice' days. An article that is older than the maximum expiration time of each conference it is sent to may be deleted by the LysKOM server unless it has marks. Example: 1 78 4 =1 17HNyheter om LysKOM 00000000 1 77 1 22 4 7 =1 1 78 4 =1 17HNyheter om LysKOM 00000000 1 7 This example shows the expiration time of conference four being lowered from 77 to just seven days. Error codes ----------- `login-first' Login required before issuing this call. `undefined-conference' Conference `conf-no' does not exist or is secret. `conference-zero' `conf-no' is zero. `permission-denied' Not enough permissions to change the expiration time for conference `conf-no'.  File: protocol-a.info, Node: get-marks, Next: mark-text-old, Prev: set-garb-nice, Up: Protocol Requests get-marks [23] (1) Recommended ============================== get-marks [23] ( ) -> ( ARRAY Mark ); This call returns the list of marks the current user has set. Example: 1 23 =1 3 { 13020 100 13043 95 12213 95 } In this example, the current user has three marks, one on text 13020 with mark type 100, one on text 13042 with mark type 95 and one on text 12213 with mark type 95. The maximum number of marks may be arbitrarily limited in the LysKOM server. Error codes ----------- `login-first' Login required before issuing this call.  File: protocol-a.info, Node: mark-text-old, Next: get-text, Prev: get-marks, Up: Protocol Requests mark-text-old [24] (1) Obsolete (4) =================================== mark-text-old [24] (( text : Text-No; mark-type : INT8 )) -> ( ); This call has been replaced by `mark-text' (*note mark-text::) and `unmark-text' (*note unmark-text::) and should no longer be used. This call can only set `mark-type' to a value in the range 1 to 255 (inclusive). If `mark-type' is set to 0 the mark will be removed. Error codes ----------- `login-first' Login required before issuing this call. `no-such-text' The text `text' does not exist. `permission-denied' No read permission on text `text'. `undefined-person' The person currently logged in does not exist (can't happen error.) `too-many-marks' Marking the text would cause the person doing the marking to have too many marks, or cause the text to have too many marks.  File: protocol-a.info, Node: get-text, Next: get-text-stat-old, Prev: mark-text-old, Up: Protocol Requests get-text [25] (1) Recommended ============================= get-text [25] (( text : Text-No; start-char : INT32; end-char : INT32 )) -> ( HOLLERITH ); Retrieve text number `text' from the LysKOM database, starting at position `start-char' and ending at position `end-char'. The first character in the text is numbered 0 and the last can be retrieved using `get-text-stat' (*note get-text-stat::). It is also permitted to request a character position beyond the actual end of the text, in which case as much text as is available will be returned. Example: 1 25 100 0 32766 =1 25HYawn*Nothing is happening 2 25 100 5 32766 =2 20HNothing is happening 3 25 100 0 3 =3 4HYawn In the example, `*' represents a linefeed. In this example, text 100 is requested three times, first from position 0 to position 32766, then from position 5 to position 32766 and finally from position 0 to position 4. The first reply contains the entire text, the following two contain only the requested portion. Error codes ----------- `no-such-text' The text `text' does not exits or no read permission. This error code will also be used when attempting to fetch texts without logging in first. (There are some texts that are readable without logging in: the motd-of-lyskom (*note set-motd-of-lyskom::), and texts with the `world-readable' aux item set on them.) `text-zero' Attempt to retrieve text number 0. `index-out-of-range' `start-char' is larger than the length of the text.  File: protocol-a.info, Node: get-text-stat-old, Next: mark-as-read, Prev: get-text, Up: Protocol Requests get-text-stat-old [26] (1) Obsolete (10) ======================================== get-text-stat-old [26] ( text-no : Text-No ) -> ( Text-Stat-Old ); Get information about text number `text-no'. The text-stat contains information about the size of the text, its recipients, comments, author and more. For compatibility reasons this call will only return the misc-infos 0=recpt, 1=cc-recpt, 2=comm-to, 3=comm-in, 4=footn-to, 5=footn-in, 6=loc-no, 7=rec-time, 8=sent-by and 9=sent-at. Newer misc-infos will either be removed or converted to a similar one. Specifically, 15=bcc-recpt may (at the servers discretion) be converted to 1=cc-recpt or omitted entirely. Example: 1 26 100 =1 7 35 16 15 6 96 1 196 1 14 1 22 1 7 { 0 7 6 85 0 15 6 1 8 13 9 12 37 16 15 6 96 1 196 1 3 311 } In this example, text number 100 was created by person 7 at approximately 4:35PM on July 15 1996. Its recipients are conferences 7 and 15, and it was sent to conference 15 by person 13 at 16:37 on the day it was created. The text has a single comment: text 311. Error codes ----------- `no-such-text' The text `text-no' does not exist, or no read access. This error code will also be used when attempting to fetch texts without logging in first. (There are some texts that are readable without logging in: the motd-of-lyskom (*note set-motd-of-lyskom::), and texts with the `world-readable' aux item set on them.) `text-zero' Attempt to retrieve text number 0. lyskom-server-2.1.2/doc/protocol-a.info-40000664000015100472110000014026307723710263013674 This is protocol-a.info, produced by makeinfo version 4.2 from Protocol-A.texi. This is the LysKOM Protocol A specification, edition 11.1. It specifies version 11 of the protocol. It was first distributed with version 2.1.2 of lyskomd. Copyright (C) 1995-2003 Lysator ACS. Permission is granted to make and distribute verbatim copies of this specification provided the copyright notice and this permission notice are preserved on all copies. Modified versions of this document may be redistributed with the added condition that all modifications not cleared with the LysKOM development group are clearly marked and that the entire modified work be redistributed under the same conditions as the original. Permission is granted to copy and distribute translations of this manual into another language under the same conditions as for modified versions. INFO-DIR-SECTION LysKOM START-INFO-DIR-ENTRY * Protocol A: (protocol-a). The LysKOM Protocol A specification. END-INFO-DIR-ENTRY  File: protocol-a.info, Node: mark-as-read, Next: create-text-old, Prev: get-text-stat-old, Up: Protocol Requests mark-as-read [27] (1) Recommended ================================= mark-as-read [27] (( conference : Conf-No; text : ARRAY Local-Text-No )) -> ( ); Marks text `text' in conference number `conference' as read for the current user. This call updates the membership record for the user. Example: 1 9 6 7 =1 20 32 11 17 6 96 3 198 1 7 1 240 0 * 1 78 7 =1 13HInlägg }t mig 00001000 241 1 1 27 7 1 { 241 } =1 1 9 6 7 =1 20 32 11 17 6 96 3 198 1 7 1 241 0 * This example shows person 6 marking local text number 241 in conference 7 as read. In the first `query-read-texts-old' call the person has read local text 240, but nothing higher. The `mark-as-read' call is reflected in the second `query-read-texts-old' call, where the user is seen to have read text 241 in conference 7. To mark a global text number as read it is necessary to translate it into local text numbers by looking at the misc-info list in the `Text-Stat' and calling `mark-as-read' once for each recipient. There is no need to call `mark-as-read' on deleted texts. The server will automatically mark them as read, sooner or later. Error codes ----------- `login-first' Login required before issuing this call. `undefined-conference' The conference `conference' does not exist or is secret. `conference-zero' `conference' is zero. `not-member' The person logged on is not a member of conference `conference'. `no-such-local-text' One of the numbers in `text' is not a local text number in `conference'. The error argument indicates the index of the invalid number. `local-text-zero' One of the numbers in `text' is zero.  File: protocol-a.info, Node: create-text-old, Next: delete-text, Prev: mark-as-read, Up: Protocol Requests create-text-old [28] (1) Obsolete (10) ====================================== create-text-old [28] (( text : HOLLERITH; misc-info : ARRAY Misc-Info )) -> ( Text-No ); Creates a new text with contents from `text' and recipients etc. defined by `misc-info' (*note The Misc-Info List::). In addition to the result, the server will send an asynchronous message to all members of any of the recipients of the new text. It is not defined whether this messages comes before or after the reply to the create-text message. Clients should be prepared for either situation. The text up to the first linefeed is considered to be the subject line. The remaining text is the message body. Although messages with only a subject are valid, clients should avoid letting users create such messages. The only Misc-Info items valid for this call are `recpt', `cc-recpt', `bcc-recpt' (protocol version 10), `comm-to' and `footn-to'. Example: 1 28 20HExample*Message body 3 { 0 5 1 112 2 33467 } :16 0 33502 13 16 15 16 6 97 3 196 1 119 1 20 0 5 { 0 5 6 148 1 112 6 3438 2 33467 } =1 33502 In the example, `*' represents a linefeed. In this example, person 119 creates a text containing a subject and a one-line body. The recipient of the text is conference five, conference 112 is a CC recipient and the text is a comment to text 33467. The server reply indicates that the new text has been given number 33502. Finally there is an asynchronous message sent to all members of recipient conferences. Note how the message was sent before the reply to the client. The misc-info list in this message has two additional fields, the local numbers of the text in each of its recipient conferences. Error codes ----------- `login-first' Login required before issuing this call. `string-too-long' The string `text' is longer than the maximum length of a message. `temporary-failure' The text could not be created at the moment. `no-such-text' Attempt to comment or footnote a non-existent or secret text. `not-author' Attempt to footnote a text authored by someone else. `footnote-limit' Attempt to footnote a text with the maximum number of footnotes already set. `comment-limit' Attempt to comment a text with the maximum number of comments already set. `index-out-of-range' Attempt to create a text failed because we reached the maximum number of texts permitted. The `error-status' indicates the text number that should have been created if the limit hadn't been reached. `access-denied' Attempt to send a text to a conference failed because no access to the conference or any super conference that will accept a text. `anonymous-rejected' Attempt to send an anonymous text to a conference that does not accept anonymous texts. `illegal-misc' Invalid misc-info list. A recipient is listed more than once or there is an unknown misc item in the misc-info list.  File: protocol-a.info, Node: delete-text, Next: add-recipient, Prev: create-text-old, Up: Protocol Requests delete-text [29] (1) Recommended ================================ delete-text [29] ( text : Text-No ) -> ( ); Deletes the text `text' from the LysKOM database, if the person issuing the command may do so. Example: 1 29 33467 =1 This simple example shows the deletion of text number 33467. Error codes ----------- `login-first' Login required before issuing this call. `no-such-text' The text `text' does not exist or no read access. `not-author' The person logged in is not the text author or supervisor of the text author.  File: protocol-a.info, Node: add-recipient, Next: sub-recipient, Prev: delete-text, Up: Protocol Requests add-recipient [30] (1) Recommended ================================== add-recipient [30] (( text-no : Text-No; conf-no : Conf-No; recpt-type : Info-Type )) -> ( ); Adds `conf-no' as recipient to text `text-no'. If `recpt-type' is 1, then a `cc-recpt' (*note The Misc-Info List::) is created; otherwise a `recpt' is created. Since protocol version 8 this call can also be used to change a `cc-recpt' into a `recpt' and vice versa by simply adding a recipient that already exists. Since protocol version 10 the `recpt-type' parameter is a `Misc-Info'. Only infos `recpt', `cc-recpt' and `bcc-recpt' are accepted. In protocol version 9 and earlier this argument was a `BOOL', that indicated if the recipient should be a `cc-recpt' (when true) or `recpt' (when false). Example: 1 26 1 =1 2 22 12 17 6 97 4 197 1 5 4 256 1 0 * 1 30 1 5 0 =1 1 26 1 =1 2 22 12 17 6 97 4 197 1 5 4 256 1 3 { 0 5 6 1 9 34 34 17 17 6 97 4 197 1 } 1 30 1 5 1 =1 1 26 1 =1 2 22 12 17 6 97 4 197 1 5 4 256 1 3 { 1 5 6 1 9 34 34 17 17 6 97 4 197 1 } This example show how conference 5 is added first as a recipient of text 1, then changed to a carbon-copy recipient. The misc-info list reflects these changes. Error codes ----------- `login-first' Login required before issuing this call. `undefined-conference' The conference `conf-no' does not exist. `conference-zero' `conf-no' is zero. `no-such-text' The text `text-no' does not exist. `already-recipient' The conference `conf-no' is already a recipient of the same type as `recpt-type'. `illegal-info-type' `recpt-type' is not `recpt', `cc-recpt' or `bcc-recpt'. `recipient-limit' The text already has the maximum number of recipients. `permission-denied' Attempt to change recipient types of a recipient without being the supervisor of either the author, recipient, or sender of the recipient. `access-denied' Attempt to add a conference as recipient that the person logged on does not have permission to add texts to. The client may have to chase the super conf chain.  File: protocol-a.info, Node: sub-recipient, Next: add-comment, Prev: add-recipient, Up: Protocol Requests sub-recipient [31] (1) Recommended ================================== sub-recipient [31] (( text-no : Text-No; conf-no : Conf-No )) -> ( ); Removes `conf-no' from the list of recipients of text `text-no'. Recipients may be removed by the author of the text or by the supervisor of the recipients of the text or by the supervisor of the author. Example: 1 26 1 =1 2 22 12 17 6 97 4 197 1 5 4 256 1 3 { 1 5 6 1 9 34 34 17 17 6 97 4 197 1 } 1 31 1 5 =1 1 26 1 =1 2 22 12 17 6 97 4 197 1 5 4 256 1 0 * 1 31 1 5 %1 30 0 In this example, conference 5 is removed from the recipient list of text number 5. When the call is repeated, the server simply returns an error since conference 5 is not a recipient of the text. Error codes ----------- `login-first' Login required before issuing this call. `no-such-text' The text `text-no' does not exist or is secret. `not-recipient' The conference `conf-no' is not a recipient of text `text-no'. `undefined-conference' The conference `conf-no' does not exist or is secret. `conference-zero' `conf-no' is zero. `permission-denied' Not supervisor of text author or conference, and not sender of text to `conf-no' and not enough privileges set and enabled.  File: protocol-a.info, Node: add-comment, Next: sub-comment, Prev: sub-recipient, Up: Protocol Requests add-comment [32] (1) Recommended ================================ add-comment [32] (( text-no : Text-No; comment-to : Text-No )) -> ( ); Add a comment link between the text `comment-to' and the text `text-no' (`text-no' becomes a comment to the text `comment-to'). This call is used to add comment links after a text has been created. The normal procedure for creating comments is to add a `comm-to' element to the text's misc-info list when the text is created (*note The Misc-Info List::). Example: 1 26 1 =1 2 22 12 17 6 97 4 197 1 5 4 256 1 0 * 1 26 2 =1 49 49 18 17 6 97 4 197 1 5 1 52 1 2 { 0 2 6 1 } 1 32 2 1 =1 1 26 1 =1 2 22 12 17 6 97 4 197 1 5 4 256 1 1 { 3 2 } 1 26 2 =1 49 49 18 17 6 97 4 197 1 5 1 52 1 4 { 0 2 6 1 2 1 9 19 52 18 17 6 97 4 197 1 } In this example, text number two is added as a comment to text number one. The change is reflected in the Misc-Info List of the texts. Error codes ----------- `login-first' Login required before issuing this call. `index-out-of-range' The texts `text-no' and `comment-to' are identical. The `error-status' is `text-no'. `no-such-text' The text `text-no' of `comment-to' are undefined. `comment-limit' The text `comment-to' already has the maximum number of comments. `already-comment' The text `text-no' is already a comment of `comment-to'. `already-footnote' The text `text-no' is already a footnote of `comment-to', and a text cannot be both a comment and a footnote to the same text.  File: protocol-a.info, Node: sub-comment, Next: get-map, Prev: add-comment, Up: Protocol Requests sub-comment [33] (1) Recommended ================================ sub-comment [33] (( text-no : Text-No; comment-to : Text-No )) -> ( ); This call removes the text `text-no' from `comment-to''s list of comments. Example: 1 26 1 =1 2 22 12 17 6 97 4 197 1 5 4 256 1 1 { 3 2 } 1 26 2 =1 49 49 18 17 6 97 4 197 1 5 1 52 1 4 { 0 2 6 1 2 1 9 19 52 18 17 6 97 4 197 1 } 1 33 2 1 =1 1 26 1 =1 2 22 12 17 6 97 4 197 1 5 4 256 1 0 * 1 26 2 =1 49 49 18 17 6 97 4 197 1 5 1 52 1 2 { 0 2 6 1 } In this example text 2 is a comment to text 1, as shown by the misc-info lists of the two texts. The `sub-comment' is called. The misc-info lists are changed to reflect the change. Error codes ----------- `login-first' Login required before issuing this call. `no-such-text' One of the texts `text-no' or `comment-to' does not exist. `not-comment' The text `text-no' is not a comment to `comment-to'. `permission-denied' Not supervisor of author of `text-no' or not sender of the comment and not enough privileges set and enable to complete the call anyway.  File: protocol-a.info, Node: get-map, Next: get-time, Prev: sub-comment, Up: Protocol Requests get-map [34] (1) Obsolete (10) ============================== get-map [34] (( conf-no : Conf-No; first-local-no : Local-Text-No; no-of-texts : INT32 )) -> ( Text-List ); This call has been superseded by `local-to-global' (*note local-to-global::). This call retrieves an array mapping local text numbers to global numbers. It is most often used to get a list of unread texts in a conference. Clients will usually use the `query-read-texts' (*note query-read-texts::) or `get-membership' (*note get-membership::) calls to find the last local number a user has read in a particular conference, then use the `get-map' call to retrieve the global numbers of all unread texts in the conference. The `conf-no' parameter specifies which conference to get the map of. `first-local-no' is the local number of the first text returned by the call. `no-of-texts' is the maximum number of text the client wants. The result is a list of global text numbers. The first element of the list is the global number of local number `first-local-no', specified by the call; the second element is the global number of local number `first-local-no' plus one; and so forth. The list returned by the server is at most `no-of-texts' long, but may be shorter if the call specifies more texts that there are in the conference. If `first-local-no' is higher than the highest local text number, the server will return an error. If `first-local-no' is lower than the lowest number that still exists, the server will set `first-local-no' in the returned `Text-List' to the first text that still exists. The size of the returned array will be decreased by the same amount as `first-local-no' is increased. This may result in an empty array being returned. (This paragraph applies even when `first-local-no' is 0.) If no texts at all exists in `conf-no' the resulting array will be empty, and `first-local-no' will be set to the number the next text to be created will receive. Example: 1 34 119 10 5 =1 10 5 { 0 0 466 478 391 } 2 34 119 16 5 =2 16 3 { 481 0 491 } 3 34 119 19 5 %3 16 0 4 34 120 1 5 =4 4 2 { 480 485 } 5 34 120 1 2 =5 4 0 * This example shows five `get-map' calls. The first retrieves the mappings of local numbers 10 to 15; the second call returns local numbers 16 to 18. As this example shows the maps are not necessarily sorted in ascending order, since texts may be added after their creation, and the maps may contain zeroes anywhere. These represent texts that have been removed for some reason. Since the first example returned two leading zeroes we can be certain that at least one text with a local text number lower than 10 still exists. Otherwise the result would have been truncated in the front as it is in examples 4 and 5. The third exchange in the example shows what happens when `first-local-no' is too large. The forth and fifth examples shows what happens when an attempt to retrieve a mapping from a conference where the first local text numbers have been deleted. In the example local text numbers 1, 2 and 3 no longer exist, and 4 corresponds to 480, and 5 to 485. Error codes ----------- `login-first' Login required before issuing this call. `undefined-conference' Conference `conf-no' does not exist or is secret. `conference-zero' `conf-no' is zero. `access-denied' Conference `conf-no' is read protected. `no-such-local-text' `first-local-no' is higher than the highest local text number that ever has existed in this conference.  File: protocol-a.info, Node: get-time, Next: get-info-old, Prev: get-map, Up: Protocol Requests get-time [35] (1) Recommended ============================= get-time [35] ( ) -> ( Time ); This call simply returns the local time according to the server. Example: 1 35 =1 23 47 19 17 6 97 4 197 1 This example demonstrates the call. According to the server the time is 19:47:23, Thursday July 17, 1997. The result also shows that it is the 197th day of the year, and that daylight savings time is in effect. Error codes ----------- This call always succeeds  File: protocol-a.info, Node: get-info-old, Next: add-footnote, Prev: get-time, Up: Protocol Requests get-info-old [36] (1) Obsolete (10) =================================== get-info-old [36] ( ) -> ( Info-Old ); This call returns the `Info-Old' structure for the server (*note Info-Old::). Clients should call this in order to find out which conferences are used for presentations and such. This call has been superseded by `get-info' (*note get-info::). This call can be issued without logging in. Example: 1 36 =1 10900 1 2 3 4 1 In this example, the server version is 1.9, the conference for presentation of new conferences is conference 1, the conference for presentation of new persons is conference 2, the conference for door messages is conference 3, the LysKOM news conference is conference 4 and the login message is text number 1. Error codes ----------- This call always succeeds.  File: protocol-a.info, Node: add-footnote, Next: sub-footnote, Prev: get-info-old, Up: Protocol Requests add-footnote [37] (1) Recommended ================================= add-footnote [37] (( text-no : Text-No; footnote-to: Text-No )) -> ( ); Add a footnote link between the text `footnote-to' and the text `text-no' (`text-no' becomes a footnote to the text `footnote-to'). This call is used to add footnote links after a text has been created. Only the author of both texts is allowed to add the footnote link. Example: 1 26 1 =1 2 22 12 17 6 97 4 197 1 5 4 256 1 0 * 1 26 2 =1 49 49 18 17 6 97 4 197 1 5 1 52 1 2 { 0 2 6 1 } 1 37 2 1 =1 1 26 1 =1 2 22 12 17 6 97 4 197 1 5 4 256 1 1 { 5 2 } 1 26 2 =1 49 49 18 17 6 97 4 197 1 5 1 52 1 4 { 0 2 6 1 4 1 9 19 52 18 17 6 97 4 197 1 } In this example, text number two is added as a footnote to text number one. The change is reflected in the Misc-Info List of the texts. Error codes ----------- `login-first' Login required before issuing this call. `no-such-text' The text `text-no' or `footnote-to' does not exist or is secret. `index-out-of-range' The `text-no' and `footnote-to' arguments are equal, and the server does not support texts that are footnotes to themselves. `not-author' Not author of `footnote-to'. `footnote-limit' Text `footnote-to' already has the maximum number of footnotes. `already-footnote' Text `text-no' is already a footnote to `footnote-to'. `already-comment' Text `text-no' is already a comment to `footnote-to', and a text cannot be both a comment and a footnote to the same text.  File: protocol-a.info, Node: sub-footnote, Next: who-is-on-old, Prev: add-footnote, Up: Protocol Requests sub-footnote [38] (1) Recommended ================================= sub-footnote [38] (( text-no : Text-No; footnote-to : Text-No )) -> ( ); This call removes the text `text-no' from `footnote-to''s list of footnotes. Only the author of a footnote may remove it. Example: 1 26 1 =1 2 22 12 17 6 97 4 197 1 5 4 256 1 1 { 5 2 } 1 26 2 =1 49 49 18 17 6 97 4 197 1 5 1 52 1 4 { 0 2 6 1 4 1 9 19 52 18 17 6 97 4 197 1 } 1 38 2 1 =1 1 26 1 =1 2 22 12 17 6 97 4 197 1 5 4 256 1 0 * 1 26 2 =1 49 49 18 17 6 97 4 197 1 5 1 52 1 2 { 0 2 6 1 } In this example text 2 is a footnote to text 1, as shown by the misc-info lists of the two texts. The `sub-footnote' is called. The misc-info lists are changed to reflect the change. Error codes ----------- `login-first' Login required before issuing this call. `no-such-text' The text `text-no' or `footnote-to' does not exist or is secret. `not-footnote' The text `text-no' is not a footnote to `footnote-to'. `permission-denied' Not supervisor of the author of `text-no' and not enough privileges set and enabled to complete call anyway.  File: protocol-a.info, Node: who-is-on-old, Next: set-unread, Prev: sub-footnote, Up: Protocol Requests who-is-on-old [39] (1) Obsolete (1) =================================== who-is-on-old [39] ( ) -> ( ARRAY Who-Info-Old ); This call is obsolete. Use `get-static-session-info' (*note get-static-session-info::) and `who-is-on-dynamic' (*note who-is-on-dynamic::) instead. If the server does not support these calls, use `who-is-on' (*note who-is-on::) instead. The returned list contains all sessions where a person is logged in and the invisible flag of the session is unset. Error codes ----------- This call always succeeds.  File: protocol-a.info, Node: set-unread, Next: set-motd-of-lyskom, Prev: who-is-on-old, Up: Protocol Requests set-unread [40] (1) Recommended =============================== set-unread [40] (( conf-no : Conf-No; no-of-unread : INT32 )) -> ( ); Only read the last `no-of-unread' in the conference `conf-no'. This call modifies the `last-text-read' of current person's membership for the conference. This call is sometimes used to implement the "only read last N texts" command found in many clients. Due to possible race conditions(1), this call is usually better implemented using the `set-last-read' call(*note set-last-read::) which explicitly sets the `last-text-read' field of the membership. Example: 1 9 5 6 =1 1 34 21 17 6 97 4 197 1 6 100 0 0 * 1 40 6 0 =1 1 9 5 6 =1 1 34 21 17 6 97 4 197 1 6 100 4 0 * This example shows that person 5 last read text 0 in conference 6 (and since 0 is an illegal local text number, that implies that the person has not read anything in the conference.) After calling `set-unread' and asking to have zero unread texts in conference 6, this is reflected by the call to `query-read-texts-old'. Error codes ----------- `login-first' Login required before issuing this call. `undefined-conference' The conference `conf-no' does not exist or is secret. `not-member' Not a member of conference `conf-no'. ---------- Footnotes ---------- (1) Another client might create a new text immediately before the server processes this `set-unread' call, so you might end up setting `last-text-read' to something unexpected.  File: protocol-a.info, Node: set-motd-of-lyskom, Next: enable, Prev: set-unread, Up: Protocol Requests set-motd-of-lyskom [41] (1) Recommended ======================================= set-motd-of-lyskom [41] ( text-no : Text-No ) -> ( ); This call sets the login message of LysKOM. It can only be executed by a privileged person, with the proper privileges enabled. A somewhat less convenient way of doing this is to use the `set-info' call(*note set-info::). Example: 1 36 =1 10900 1 2 3 4 0 1 41 435 =1 1 36 =1 10900 1 2 3 4 435 This example shows how the login message of LysKOM is set using the set-motd-of-lyskom call. The results of the `get-info' calls demonstrate the effect. Error codes ----------- `login-first' Login required before issuing this call. `permission-denied' Administrator bit not set or privilege level not enabled. `no-such-text' The text `text-no' does not exist. `mark-limit' The text `text-no' already has the maximum number of marks.  File: protocol-a.info, Node: enable, Next: sync-kom, Prev: set-motd-of-lyskom, Up: Protocol Requests enable [42] (1) Recommended =========================== enable [42] ( level : INT8 ) -> ( ); Sets the security level for the current session to `level'. *Note Security::, for details about security levels. The only levels that make any sense right now are 0 and 255. This call may be issued by any person, but without the right privilege bits set, it has no effect. Example: 1 41 1 %1 12 0 1 42 255 =1 1 41 1 =1 This example shows how `enable' makes a privileged call possible, in this case a call to `set-motd-of-lyskom' (*note set-motd-of-lyskom::). Error codes ----------- `login-first' Login required before issuing this call.  File: protocol-a.info, Node: sync-kom, Next: shutdown-kom, Prev: enable, Up: Protocol Requests sync-kom [43] (1) Recommended ============================= sync-kom [43] ( ) -> ( ); This call instructs the LysKOM server to make sure the permanent copy of its database is current. Processing of requests is normally blocked until this call has completed, but the exact details depend on the server implementation. This call is privileged in most implementations. Example: 1 42 255 =1 1 43 :0 7 :0 7 =1 This example shows how the `enable' call is used to enable all privileges(*note enable::), then the `sync-kom' call is used to save the database. The server responds with two asynchronous messages signaling that the database is being saved. Error codes ----------- `login-first' Login required before issuing this call. `permission-denied' Administrator bit not set or privileges not enabled.  File: protocol-a.info, Node: shutdown-kom, Next: broadcast, Prev: sync-kom, Up: Protocol Requests shutdown-kom [44] (1) Recommended ================================= shutdown-kom [44] ( exit-val : INT8 ) -> ( ); This call instructs the server to save all data and shut down. `exit-val' is currently not used. This call is privileged. Example: 1 42 255 =1 1 44 0 =1 :2 13 5 3 This example shows the shutdown of a server. The asynchronous message sent after the call returns is the result of a session being forced to log out. Error codes ----------- `login-first' Login required before issuing this call. `permission-denied' Administrator bit not set or privileges not enabled.  File: protocol-a.info, Node: broadcast, Next: get-membership-old, Prev: shutdown-kom, Up: Protocol Requests broadcast [45] (1) Obsolete (1) =============================== broadcast [45] ( message : HOLLERITH ) -> ( ); This call can been replaced by `send-message' (*note send-message::). It is a privileged call. Error codes ----------- `login-first' Login required before issuing this call. `string-too-long' The string `message' is too long. `feature-disabled' Messages have been disabled.  File: protocol-a.info, Node: get-membership-old, Next: get-created-texts, Prev: broadcast, Up: Protocol Requests get-membership-old [46] (1) Obsolete (10) ========================================= get-membership-old [46] (( person : Pers-No; first : INT16; no-of-confs : INT16; want-read-texts : BOOL )) -> ( ARRAY Membership-Old ); This call retrieves the membership record for a list of conferences for a single person. `person' is the person whose memberships are to be retrieved. `first' is the first position in the membership list to retrieve, numbered from 0 and up. `no-of-confs' is the number of membership records to retrieve. If `want-read-texts' is `0' the server will not send the contents of the `read-texts' array of the memberships. (The size will be transmitted, but a single asterisk (`*') will be sent instead of the array itself.) The server will return a membership list that is shorter than `no-of-confs' if `no-of-confs' + `first' is larger than the number of conferences the person is a member of. Servers that support protocol version 10 will return a priority of zero if the passive bit in the membership record has been set (either by a set-membership-type or by setting the priority of the conference to zero.) Example: 1 46 5 0 3 1 =1 2 { 49 14 17 13 8 91 5 255 1 5 255 0 0 * 20 14 22 17 6 97 4 197 1 6 100 2 0 * } 1 46 5 0 1 1 =1 1 { 49 14 17 13 8 91 5 255 1 5 255 0 0 * } 1 46 5 1 4 1 =1 1 { 20 14 22 17 6 97 4 197 1 6 100 2 0 * } In this example we retrieve the memberships of person 5. The first call asks for three memberships, starting with number 0. Since this person is only a member of two conferences, the list returned only contains two memberships. (An extra newline has been inserted in the result of the first call to make the result more readable.) The next two calls retrieve a single membership each, the first by asking for only one, and the second by asking for four memberships, starting with number 1. Error codes ----------- `login-first' Login required before issuing this call. `undefined-person' The person `person' does not exist. `undefined-conference' The conference `person' does not exist or is secret. `index-out-of-range' `first' is higher than the index of the last conference in the person's membership list. `bad-bool' `want-read-texts' must be either `0' or `1'.  File: protocol-a.info, Node: get-created-texts, Next: get-members-old, Prev: get-membership-old, Up: Protocol Requests get-created-texts [47] (1) Obsolete (10) ======================================== get-created-texts [47] (( person : Pers-No; first : Local-Text-No; no-of-texts : INT32 )) -> ( Text-List ); This call is obsolete; instead you should use `map-created-texts' (*note map-created-texts::). This call returns a list of the texts written by a person. `person' is the person whose created texts are to be retrieved. `first' is the first text to retrieve. `no-of-texts' is the number of texts to retrieve. This call is essentially the same as `get-map' (*note get-map::), but instead of returning the texts sent to a single conference, it returns the texts written by a single person to any conference. The number of texts written by any one person is contained in the Person record for that person. If `first' is lower than the first text written by `person' that still exists, it will be automatically increased to the first still existing text written by `person'. The `get-created-texts' will still attempt to return information about `no-of-texts' texts. (In this regard `get-map' and `get-created-texts' differ, since `get-map' will never ever return information about a later text than specified in the arguments to the call.(1)) Example: 1 47 5 0 100 =1 1 8 { 1 2 3 4 5 6 7 8 } 2 47 5 4 2 =2 4 2 { 4 5 } 3 47 10 8 8 =3 12 8 { 309 312 324 327 329 339 0 387 } In this example we have retrieved all texts written by person five. The first call asked for 100 texts, but only 8 were returned, which implies that person number 5 only created a total of 8 texts. We can also see that person 5 wrote all the first 8 texts in the conference system. The second call shows how a part of the map can be retrieved. The third call asks for eight texts written by person 10, starting with the eighth number. Since the first eleven texts written by that person no longer exists the server instead returns information about eight texts staring from the twelfth text person 10 created. One of the eight texts has been deleted. Error codes ----------- `login-first' Login required before issuing this call. `undefined-person' The person `person' does not exist or is secret. `undefined-conference' The conference `person' does not exist or is secret. `no-such-local-text' `first' is higher than the local text number of the last created text. ---------- Footnotes ---------- (1) This difference was not intentional, but it is now too late to change the semantics of either `get-map' or `get-created-texts'. Besides, they are both obsolete calls.  File: protocol-a.info, Node: get-members-old, Next: get-person-stat, Prev: get-created-texts, Up: Protocol Requests get-members-old [48] (1) Obsolete (10) ====================================== get-members-old [48] (( conf : Conf-No; first : INT16; no-of-members : INT16 )) -> ( ARRAY Pers-No ); This call returns a list of members of the conference `conf'. `first' is the first index in the membership to return, numbered from zero and up. `no-of-members' is the maximum number of members to return. Example: 1 48 1 0 100 =1 4 { 7 8 9 10 } 1 48 6 0 100 =1 4 { 5 7 9 10 } 1 48 6 2 2 =1 2 { 9 10 } In this example the client first requests the first 100 members in conference 1. The second request is for the first 100 members of conference 6. The last request is for members 2 and 3 in conference 6. As can be seen from the examples, the returned list is truncated if there are fewer members than requested. Error codes ----------- `undefined-conference' The conference `conf' does not exist or is secret. `index-out-of-range' `first' is higher than the number of members in `conf'.  File: protocol-a.info, Node: get-person-stat, Next: get-conf-stat-old, Prev: get-members-old, Up: Protocol Requests get-person-stat [49] (1) Recommended ==================================== get-person-stat [49] ( pers-no : Pers-No ) -> ( Person ); This call returns the person `pers-no'. This call does not return all the information a client usually needs since the name is not included in the Person data structure. Use `get-conf-stat' (*note get-conf-stat::) on the same number to get additional information about the person. Example: 1 49 8 =1 44Hbyers@lage.lysator.liu.se 0000010000000000 00000000 44 21 19 18 6 97 5 198 1 0 2 3 0 0 0 0 0 0 1 0 0 2 1 50 8 =1 11HPaul Dekker 1001 8 6 19 18 6 97 5 198 1 8 6 19 18 6 97 5 198 1 8 0 8 0 0 0 77 1 1 0 This simple example shows how person number 8 is retrieved from the server. The second call shows the `get-conf-stat-old' call on the same ID number. Error codes ----------- `undefined-person' The person `pers-no' does not exist. `undefined-conference' The conference `pers-no' does not exist or is secret.  File: protocol-a.info, Node: get-conf-stat-old, Next: who-is-on, Prev: get-person-stat, Up: Protocol Requests get-conf-stat-old [50] (1) Obsolete (10) ======================================== get-conf-stat-old [50] ( conf-no : Conf-No ) -> ( Conference-Old ); This call retrieves the conference data structure for conference number `conf-no'. Important note: This call does not return the extra flag bits that were introduced in protocol version 8. To get this information, use the `get-uconf-stat' call instead. However, clients should be able to handle `Conference-Old' structures with an arbitrary number of flag bits since we may decide to change the behavior of this call in the future. Example: 1 50 1 =1 27HPresentation (av nya) möten 0000 48 11 17 13 8 91 5 255 1 18 34 21 17 6 97 4 197 1 0 0 0 0 0 0 77 0 1 1 1 50 8 =1 11HPaul Dekker 1001 8 6 19 18 6 97 5 198 1 8 6 19 18 6 97 5 198 1 8 0 8 0 0 0 77 1 1 0 This simple example retrieves conferences 1 and 8 from the server. Conference 1 is a regular conference, and conference 8 is a mailbox. Error codes ----------- `undefined-conference' The conference `conf-no' does not exist or is secret.  File: protocol-a.info, Node: who-is-on, Next: get-unread-confs, Prev: get-conf-stat-old, Up: Protocol Requests who-is-on [51] (1) Obsolete (9) =============================== who-is-on [51] ( ) -> ( ARRAY Who-Info ); This call is obsolete. Please use `who-is-on-dynamic' (*note who-is-on-dynamic::) and `get-static-session-info' calls instead(*note get-static-session-info::). Nonetheless, servers should support this call since many clients still use it. This call should simply return a list of visible sessions (sessions where a person is logged in and the invisible flag is unset). The data structure is described elsewhere (*note Who-Info::). Error codes ----------- This call always succeeds.  File: protocol-a.info, Node: get-unread-confs, Next: send-message, Prev: who-is-on, Up: Protocol Requests get-unread-confs [52] (1) Recommended ===================================== get-unread-confs [52] ( pers-no : Pers-No ) -> ( ARRAY Conf-No ); This call returns a list of conferences in which the person `pers-no' may have unread texts. This call will return a result for any valid `pers-no'. To retrieve information about secret persons, or to get information about unread texts in secret conference, the session must log on as a person with access to that information. The result is guaranteed to include all conferences where `pers-no' has unread texts. It may also return some extra conferences. Passive memberships are never returned. The returned conference numbers will be returned in the same order as they appear on the persons list of memberships. Example: 1 52 7 =1 2 { 1 6 } 1 52 1 %1 10 0 1 52 1000 %1 10 0 This example shows how a session first retrieves the list of conferences in which person 7 has unread texts. The next request is for the unread conferences of person 1, but that happens to be a conference. The last request is for the unread conferences of person 1000, but that person didn't exist in the test database. Error codes ----------- `login-first' Login required before issuing this call. `undefined-person' Person `pers-no' does not exist or is secret.  File: protocol-a.info, Node: send-message, Next: get-session-info, Prev: get-unread-confs, Up: Protocol Requests send-message [53] (1) Recommended ================================= send-message [53] (( recipient : Conf-No; message : HOLLERITH )) -> ( ); This call sends the message `message' to all members of `recipient' using `async-send-message' (*note async-send-message::). If `recipient' is 0, the message is sent to all sessions that are logged in. The message is sent to all members of `recipient' that are currently logged in, and where the `passive' and `passive-message-invert' bits of the `Membership-Type' (*note Membership-Type::) don't prevent the message from being delivered. Example: 1 53 4 14HThis is a test =1 1 53 1 14HThis is a test :3 12 1 8 14HThis is a test =1 1 53 0 14HThis is a test :3 12 0 8 14HThis is a test =1 1 53 5 14HThis is a test %1 16 0 1 53 3 14HThis is a test %1 42 0 Error codes ----------- `login-first' Login required before issuing this call. `string-too-long' The string `message' is too long. `undefined-conference' Conference `recipient' does not exist or is secret. `feature-disabled' The message feature has been disabled in the server. `message-not-sent' The message was not sent for some other reason. Perhaps the recipient is not accepting messages or no member of the recipient was logged on.  File: protocol-a.info, Node: get-session-info, Next: disconnect, Prev: send-message, Up: Protocol Requests get-session-info [54] (1) Obsolete (4) ====================================== get-session-info [54] ( session-no : Session-No ) -> ( Session-Info ); This call is obsolete. It has been replaced by `get-session-info-ident' (*note get-session-info-ident::), which in turn is also obsolete. See `get-session-info-ident' for more information. Error codes ----------- `login-first' Login required before issuing this call. `undefined-session' The session `session-no' does not exist.  File: protocol-a.info, Node: disconnect, Next: who-am-i, Prev: get-session-info, Up: Protocol Requests disconnect [55] (1) Recommended =============================== disconnect [55] ( session-no : Session-No ) -> ( ); This call disconnects the session `session-no' from the LysKOM server. A session can always disconnect itself, even without logging in. If the session is logged in as user foo it can also disconnect any session logged in as a person for which foo is the supervisor. Session number zero is always interpreted as the session making the call, so the easiest way to disconnect the current session is to disconnect session zero. Example: 1 56 =1 7 1 55 7 =1 :2 13 8 7 Connection closed by foreign host. In this example the client asks for its own session number, then disconnects itself (disconnection session 0 would have had the same effect.) The asynchronous message sent just before the session is disconnected is the logout message for the user that was logged on in the session. The "Connection closed by foreign host." is not part of the server output. This message was generated by telnet. Error codes ----------- `login-first' Login required before issuing this call if `session-no' is not the session issuing the call. `permission-denied' Attempt to disconnect another session and not supervisor of person logged in and not enough privileges set and enabled to complete the call anyway. `undefined-session' The session `session-no' does not exist.  File: protocol-a.info, Node: who-am-i, Next: set-user-area, Prev: disconnect, Up: Protocol Requests who-am-i [56] (1) Recommended ============================= who-am-i [56] ( ) -> ( Session-No ); This call simply returns the session number of the session issuing the call. Example: 1 56 =1 7 In this example the session number of the session issuing the call is seven. Error codes ----------- This call always succeeds.  File: protocol-a.info, Node: set-user-area, Next: get-last-text, Prev: who-am-i, Up: Protocol Requests set-user-area [57] (2) Recommended ================================== set-user-area [57] (( pers-no : Pers-No; user-area : Text-No )) -> ( ); This call sets the user-area field for the person `pers-no' in the database to the text `user-area'. The user area is used to store client data for a particular person. *Note The User Area::, for more details. Example: 1 49 7 =1 25Hdavby@lage.lysator.liu.se 0000010000000000 00000000 6 58 21 19 6 97 6 199 1 0 458 7 3 12 7 12 0 0 3 0 0 4 1 57 7 11 =1 1 49 7 =1 25Hdavby@lage.lysator.liu.se 0000010000000000 00000000 6 58 21 19 6 97 6 199 1 11 458 7 71 2592 7 13 0 0 3 1 0 4 In this example the user area of person 7 is set to text number 11. The original user area was text numbers zero, which means that the person had no user area. Error codes ----------- `login-first' Login required before issuing this call. `undefined-person' The person `pers-no' does not exist or is secret. `permission-denied' Not enough access to person `pers-no' to complete the call.  File: protocol-a.info, Node: get-last-text, Next: create-anonymous-text-old, Prev: set-user-area, Up: Protocol Requests get-last-text [58] (3) Recommended ================================== get-last-text [58] ( before : Time ) -> ( Text-No ); This call returns the number of the last text created before `before'. There is no guarantee that the text is readable by the person making the request, or that the text even exists. This call assumes that all texts are written in chronological order, when the time is expressed in the local time zone of the server. That may not always be the case in real life. When daylight savings time reverts to standard time the same time span will occur twice. The clock of the server may also have been adjusted manually from time to time. This protocol specification does not mandate what the server should do in such cases. If `set-connection-time-format' (*note set-connection-time-format::) has been used with `use-utc' set to 1, the `before' time should be expressed in UTC. Daylight savings time will not be an issue in that case. Example: 1 58 49 6 22 19 6 97 6 199 1 =1 11 1 58 49 6 22 18 6 97 6 199 1 =1 8 1 58 49 6 22 1 6 97 6 199 1 =1 0 In this example the text created most recently before 22:06 on July 19, 1997 was text number 11; the text created most recently before 22:06 on July 18 was text number 8; and the text created most recently before 22:06 on July 1st was text number 0, which means that there is no text that old in the database. Error codes ----------- `login-first' Login required before issuing this call. lyskom-server-2.1.2/doc/protocol-a.info-50000664000015100472110000014022107723710263013667 This is protocol-a.info, produced by makeinfo version 4.2 from Protocol-A.texi. This is the LysKOM Protocol A specification, edition 11.1. It specifies version 11 of the protocol. It was first distributed with version 2.1.2 of lyskomd. Copyright (C) 1995-2003 Lysator ACS. Permission is granted to make and distribute verbatim copies of this specification provided the copyright notice and this permission notice are preserved on all copies. Modified versions of this document may be redistributed with the added condition that all modifications not cleared with the LysKOM development group are clearly marked and that the entire modified work be redistributed under the same conditions as the original. Permission is granted to copy and distribute translations of this manual into another language under the same conditions as for modified versions. INFO-DIR-SECTION LysKOM START-INFO-DIR-ENTRY * Protocol A: (protocol-a). The LysKOM Protocol A specification. END-INFO-DIR-ENTRY  File: protocol-a.info, Node: create-anonymous-text-old, Next: find-next-text-no, Prev: get-last-text, Up: Protocol Requests create-anonymous-text-old [59] (3) Obsolete (10) ================================================ create-anonymous-text-old [59] (( text : HOLLERITH; misc-info : ARRAY Misc-Info )) -> ( Text-No ); Similar to `create-text-old' (*note create-text-old::), but the text is created with the `author' field set to zero. Not even the server has a record of who created the text. The original intended use for this call was for importing texts from other sources, such as WWW, FTP or Gopher, but some clients include explicit support for sending anonymous texts to a server. It is only possible to send anonymous texts to a conference with the right flag bit set. The only Misc-Info items valid for this call in the `misc-info' array are `recpt', `cc-recpt', `bcc-recpt' (introduced in protocol version 10), `comm-to' and `footn-to'. Example: 1 28 20HExample*Message body 3 { 0 5 1 112 2 33467 } :16 0 33502 13 16 15 16 6 97 3 196 1 0 1 20 0 5 { 0 5 6 148 1 112 6 3438 2 33467 } =1 33502 In the example, `*' represents a linefeed. In this example, person 119 creates a text containing a subject and a one-line body. The recipient of the text is conference five, conference 112 is a CC recipient and the text is a comment to text 33467. The server reply indicates that the new text has been given number 33502. Finally there is an asynchronous message sent to all members of recipient conferences. Note how the message was sent before the reply to the client. The misc-info list in this message has two additional fields, the local numbers of the text in each of its recipient conferences. Error codes ----------- `login-first' Login required before issuing this call. `string-too-long' The string `text' is longer than the maximum length of a message. `temporary-failure' The text could not be created at the moment. `no-such-text' Attempt to comment or footnote a non-existent or secret text. `not-author' Attempt to footnote a text authored by someone else. `footnote-limit' Attempt to footnote a text with the maximum number of footnotes already set. `comment-limit' Attempt to comment a text with the maximum number of comments already set. `access-denied' Attempt to send a text to a conference failed because no access to the conference or any super conference that will accept a text. `anonymous-rejected' Attempt to send an anonymous text to a conference that does not accept anonymous texts. `illegal-misc' Invalid misc-info list. A recipient is listed more than once or there is an unknown misc item in the misc-info list.  File: protocol-a.info, Node: find-next-text-no, Next: find-previous-text-no, Prev: create-anonymous-text-old, Up: Protocol Requests find-next-text-no [60] (3) Recommended ====================================== find-next-text-no [60] ( start : Text-No ) -> ( Text-No ); This call returns the next readable text in the database created after text `start'. `start' does not have to be a valid or readable text number, as shown in the examples. Example: 1 60 0 =1 2 1 60 2 =1 4 This example shows how to retrieve the first readable text in the LysKOM database by calling `find-next-text-no' with `start' set to zero. In the example, the first text is number 2. The second example gets the text following number 2, which happens to be text number 4. Error codes ----------- `login-first' Login required before issuing this call. `no-such-text' There is no text following text `start'.  File: protocol-a.info, Node: find-previous-text-no, Next: login, Prev: find-next-text-no, Up: Protocol Requests find-previous-text-no [61] (3) Recommended ========================================== find-previous-text-no [61] ( start : Text-No ) -> ( Text-No ); This call returns the first readable text in the database created most recently before `start'. `start' does not have to be a valid or readable text number, as shown in the examples. Example: 1 61 134217727 =1 11 1 61 4 =1 2 This example shows that the last readable text in the database is number 11 (unless by some odd coincidence all text from 11 to text number 134217727 have been deleted.) It also shows that the most recent text before number 4 is text number 2. Error codes ----------- `login-first' Login required before issuing this call. `no-such-text' There is no text preceding text `start'.  File: protocol-a.info, Node: login, Next: who-is-on-ident, Prev: find-previous-text-no, Up: Protocol Requests login [62] (4) Recommended ========================== login [62] (( person : Pers-No; passwd : HOLLERITH; invisible : BOOL )) -> ( ); This call is used to log in. The session is logged in as person number `person' if `passwd' is the correct password for that person. If `invisible' is true, the session is invisible: it will not be returned by `who-is-on' (*note who-is-on::) and `who-is-on-ident' (*note who-is-on-ident::), and the dynamic session info (*note Dynamic-Session-Info::) will have the invisible flag set. Invisible sessions are primarily used by software agents that do not act on the behalf of real users. Example: 1 62 7 6Hgazonk 1 =1 1 62 7 6Hgazonk 0 :2 9 7 1 1 62 7 6Hgazonk 0 :2 13 7 1 :2 9 7 1 =1 This example first shows a session log in as person seven with the invisible flag set. Because of this the asynchronous login message is not sent. The second call logs in as person seven again. This time a login message is sent, but not a logout message since the login was invisible. The third example shows a third login as person 7, but this time both the logout and login messages are sent. Error codes ----------- `undefined-person' The person `person' does not exist. `login-disallowed' Logins have been disabled and person `person' does not have enough privileges to override. `invalid-password' The password `passwd' is not the password of `person' and the currently logged in person is not the supervisor of `person' and does not have enough privileges set and enabled to log in anyway. `conference-zero' Attempt to log in as person number 0. `bad-bool' `invisible' must be either `0' or `1'.  File: protocol-a.info, Node: who-is-on-ident, Next: get-session-info-ident, Prev: login, Up: Protocol Requests who-is-on-ident [63] (4) Obsolete (9) ===================================== who-is-on-ident [63] ( ) -> ( ARRAY Who-Info-Ident ); This call is obsolete. It has been replaced by `who-is-on-dynamic' (*note who-is-on-dynamic::) and `get-static-session-info' (*note get-static-session-info::). It returns a list of all visible sessions. Error codes ----------- This call always succeeds.  File: protocol-a.info, Node: get-session-info-ident, Next: re-lookup-person, Prev: who-is-on-ident, Up: Protocol Requests get-session-info-ident [64] (4) Obsolete (9) ============================================ get-session-info-ident [64] ( session-no : Session-No ) -> ( Session-Info-Ident ); This call is obsolete. Use `who-is-on-dynamic' (*note who-is-on-dynamic::) combined with `get-static-session-info' (*note get-static-session-info::) instead. Error codes ----------- `login-first' Login required before issuing this call. `undefined-session' The session `session-no' does not exist.  File: protocol-a.info, Node: re-lookup-person, Next: re-lookup-conf, Prev: get-session-info-ident, Up: Protocol Requests re-lookup-person [65] (5) Obsolete (7) ====================================== re-lookup-person [65] ( regexp : HOLLERITH ) -> ( ARRAY Pers-No ); This call is obsolete. It has been replaced by `re-z-lookup' (*note re-z-lookup::). It returns a list of persons matching the regular expression `regexp'. The regexp syntax used is that of the `ed'(1) Unix utility. Error codes ----------- `regexp-error' Error compiling the regexp `regexp'. Perhaps the pattern is not a correct regexp.  File: protocol-a.info, Node: re-lookup-conf, Next: lookup-person, Prev: re-lookup-person, Up: Protocol Requests re-lookup-conf [66] (5) Obsolete (7) ==================================== re-lookup-conf [66] ( regexp : HOLLERITH ) -> ( ARRAY Conf-No ); This call is obsolete. It has been replaced by `re-z-lookup' (*note re-z-lookup::). It returns a list of conferences matching the regular expression `regexp'. The regexp syntax used is that of the `ed'(1) Unix utility. Error codes ----------- `regexp-error' Error compiling the regexp `regexp'. Perhaps the pattern is not a correct regexp.  File: protocol-a.info, Node: lookup-person, Next: lookup-conf, Prev: re-lookup-conf, Up: Protocol Requests lookup-person [67] (6) Obsolete (7) =================================== lookup-person [67] ( name : HOLLERITH ) -> ( ARRAY Pers-No ); This call is obsolete. It has been replaced by `lookup-z-name' (*note lookup-z-name::). This call returns a list of persons with names matching the contracted name in `name'. *Note Name Expansion::, for a description of the matching process. Error codes ----------- This call always succeeds.  File: protocol-a.info, Node: lookup-conf, Next: set-client-version, Prev: lookup-person, Up: Protocol Requests lookup-conf [68] (6) Obsolete (7) ================================= lookup-conf [68] ( name : HOLLERITH ) -> ( ARRAY Conf-No ); This call is obsolete. It has been replaced by `lookup-z-name' (*note lookup-z-name::). This call returns a list of conferences with names matching the contracted name in `name'. *Note Name Expansion::, for a description of the matching process. Error codes ----------- This call always succeeds.  File: protocol-a.info, Node: set-client-version, Next: get-client-name, Prev: lookup-conf, Up: Protocol Requests set-client-version [69] (6) Recommended ======================================= set-client-version [69] (( client-name : HOLLERITH; client-version : HOLLERITH )) -> ( ); This call is used to tell the server which client and which version of that client is being used. The name of the client is passed in `client-name' and the version in `client-version'. The information sent in this call is made available to other sessions through the `get-client-name' (*note get-client-name::) and `get-client-version' calls(*note get-client-version::). This call should be used exactly once per session. The following names are currently registered: elisp-client The famous CPU hog. nilkom C++ experiment tkom C++ experiment getmail Postmaster ttykom The one and second tty client by Linus WinKOM Windows client JySKom JSK Web Client Example: 1 56 =1 7 2 69 11Helisp-client 4H0.45 =2 3 70 7 =3 11Helisp-client 4 71 7 =4 4H0.45 In this example the `who-am-i' call is used to find the ID of the current session(*note who-am-i::). Next, `set-client-version' is used to set the name of the client to "elisp-client" and the version to "0.45". The third call is to `get-client-name' , which returns the string just sent to the server(*note get-client-name::). Finally `get-client-version' (*note get-client-version::) is used to retrieve the client version of session number 7, which is, as expected, the string "0.45". Error codes ----------- `string-too-long' The string `client-name' or `client-version' is too long. `client-is-crazy' The client attempted to use this call more than once. The `error-status' is undefined.  File: protocol-a.info, Node: get-client-name, Next: get-client-version, Prev: set-client-version, Up: Protocol Requests get-client-name [70] (6) Recommended ==================================== get-client-name [70] ( session : Session-No ) -> ( HOLLERITH ); This call returns the name of the client that owns session number `session'. This client name string returned is the one set by the client using `set-client-version' (*note set-client-version::). If `set-client-version' has not been issued in session number `session', the empty string is returned. *Note set-client-version::, for an example of this call. Error codes ----------- `login-first' Login required before issuing this call. `undefined-session' The session `session' does not exist.  File: protocol-a.info, Node: get-client-version, Next: mark-text, Prev: get-client-name, Up: Protocol Requests get-client-version [71] (6) Recommended ======================================= get-client-version [71] ( session : Session-No ) -> ( HOLLERITH ); This call returns the version of the client that owns session number `session'. This client version string returned is the one set by the client using `set-client-version' (*note set-client-version::). If `set-client-version' has not been issued in session number `session', the empty string is returned. *Note set-client-version::, for an example of this call. Error codes ----------- `login-first' Login required before issuing this call. `undefined-session' The session `session' does not exist.  File: protocol-a.info, Node: mark-text, Next: unmark-text, Prev: get-client-version, Up: Protocol Requests mark-text [72] (4) Recommended ============================== mark-text [72] (( text : Text-No; mark-type : INT8 )) -> ( ); This call associates the mark `mark-type' with the text `text'. The list of marks set by a person can be retrieved using the `get-marks' call(*note get-marks::). Currently, servers do not associate any particular meaning to the different types of marks, but that may change in the future. Currently, servers should not delete texts that have marks, except by user request. Example: 1 23 =1 0 * 2 72 110 230 =2 3 23 =3 1 { 110 230 } This example shows how a person with no marks set sets mark 230 on text number 110. The calls to `get-marks' (*note get-marks::) show the effect of the call. Error codes ----------- `login-first' Login required before issuing this call. `no-such-text' The text `text' does not exists or is secret. `permission-denied' No read access to text `text'. `undefined-person' The person currently logged in does not exist (can't happen error.) `mark-limit' Already the maximum number of marks on text `text'.  File: protocol-a.info, Node: unmark-text, Next: re-z-lookup, Prev: mark-text, Up: Protocol Requests unmark-text [73] (6) Recommended ================================ unmark-text [73] ( text-no : Text-No ) -> ( ); This call removes any marks the logged-in person has set on the text `text-no'. Example: 1 23 =1 1 { 110 230 } 2 73 110 =2 3 23 =3 0 * This example shows how a user with a mark set on text number 110 removes it using the `unmark-text' call. Error codes ----------- `login-first' Login required before issuing this call. `undefined-person' The person currently logged in does not exist (can't happen error.) `not-marked' The text `text-no' was not marked.  File: protocol-a.info, Node: re-z-lookup, Next: get-version-info, Prev: unmark-text, Up: Protocol Requests re-z-lookup [74] (7) Recommended ================================ re-z-lookup [74] (( regexp : HOLLERITH; want-persons : BOOL; want-confs : BOOL )) -> ( ARRAY Conf-Z-Info ); This call returns a list of those conferences and/or persons matching the regular expression `regexp'. If `want-confs' is true, then the result will include non-mailbox conferences. If `want-persons' is true, then the result will include mailbox conferences. See also *Note lookup-z-name::, for an alternative way to look up names. Refer to *Note Name Expansion::, for more details on how name lookup works. Example: 1 74 2H.* 1 1 =1 4 { 15HTest Conference 0000 10 11HDavid Byers 1001 6 21HTrains (-) Discussion 0000 11 4HJohn 1001 9 } 2 74 2H.* 0 1 =2 2 { 15HTest Conference 0000 10 21HTrains (-) Discussion 0000 11 } 3 74 7HT.*[cC] 1 1 =3 2 { 15HTest Conference 0000 10 21HTrains (-) Discussion 0000 11 } This example shows three calls to `re-z-lookup'. The first call returns all conferences and persons in the entire database, in this case two conferences and two persons. The second example uses the same regular expression, but in this case, the call specifies that the result is only to contain conferences, so the two persons are not returned. The third example simply returns all names matching the pattern "T.*[cC]". Error codes ----------- `regexp-error' Error compiling the regexp `regexp'. Perhaps the pattern is not a correct regexp. `bad-bool' `want-persons' and `want-confs' must be either `0' or `1'.  File: protocol-a.info, Node: get-version-info, Next: lookup-z-name, Prev: re-z-lookup, Up: Protocol Requests get-version-info [75] (7) Recommended ===================================== get-version-info [75] ( ) -> ( Version-Info ); This call returns information about the server version. The data returned by this call are primarily useful for presenting to the user. A client should not use this call to determine what the server's capabilities are. Example: 1 75 =1 9 7Hlyskomd 5H1.9.0 This example lets us know that the server is lyskomd, version 1.9.0, which at the time of writing this is the only really usable server. Error codes ----------- This call always succeeds.  File: protocol-a.info, Node: lookup-z-name, Next: set-last-read, Prev: get-version-info, Up: Protocol Requests lookup-z-name [76] (7) Recommended ================================== lookup-z-name [76] (( name : HOLLERITH; want-pers : BOOL; want-confs : BOOL )) -> ( ARRAY Conf-Z-Info ); This call looks up the name `name' in the server, and returns a list of all matching conferences and/or persons. If `want-confs' is true, then the result will include conferences that are not mailboxes. If `want-pers' is true, then the result will include conferences that are mailboxes. See also *Note re-z-lookup::, for an alternative way to look up names. Refer to *Note Name Expansion::, for details on the matching process. Example: 1 76 0H 1 1 =1 4 { 15HTest Conference 0000 10 11HDavid Byers 1001 6 21HTrains (-) Discussion 0000 11 4HJohn 1001 9 } 2 76 0H 0 1 =1 2 { 15HTest Conference 0000 10 21HTrains (-) Discussion 0000 11 } 3 76 3HT C 1 1 =3 1 { 15HTest Conference 0000 10 } This example shows three calls to `lookup-z-name'. The first call retrieves all conferences and persons in the server. The second request looks up the same name as the first, but this time the result is restricted to conferences. The final request requests all conferences and persons matching the pattern "T C". Error codes ----------- `bad-bool' `want-pers' and `want-confs' must be either `0' or `1'.  File: protocol-a.info, Node: set-last-read, Next: get-uconf-stat, Prev: lookup-z-name, Up: Protocol Requests set-last-read [77] (8) Recommended ================================== set-last-read [77] (( conference : Conf-No; last-read : Local-Text-No )) -> ( ); This call tells the server that the last local text number the person issuing the call has read in conference `conference' is `last-read'. This call is typically used when a user wants to have a specific number of unread texts in a particular conference. Example: 1 9 7 6 =1 2 4 22 18 6 97 5 198 1 6 100 6 0 * 2 77 6 3 =2 3 9 7 6 =3 2 4 22 18 6 97 5 198 1 6 100 3 0 * This example shows how person 7 originally had read everything up to and including local text number 6 in conference 6. After the call to `set-last-read', the `query-read-texts-old' (*note query-read-texts-old::) call reports that person 7 has read everything up to and including local text number 3. Error codes ----------- `login-first' Login required before issuing this call. `undefined-conference' The conference `conference' does not exist or is secret. `not-member' Not a member of conference `conference'.  File: protocol-a.info, Node: get-uconf-stat, Next: set-info, Prev: set-last-read, Up: Protocol Requests get-uconf-stat [78] (8) Recommended =================================== get-uconf-stat [78] ( conference : Conf-No ) -> ( UConference ); This call returns some information about conference `conference'. The information it returns is sufficient for most uses of conference information, and this call should be used instead of `get-conf-stat' wherever possible(*note get-conf-stat::). It uses less bandwidth and the lyskomd server always keeps all `UConference' objects in memory, so this call is significantly faster than `get-conf-stat'. This is also currently the only way to get all the flag bits of the conference. Example: 1 50 6 =1 8HTestconf 0000 1 34 21 17 6 97 4 197 1 37 3 22 18 6 97 5 198 1 5 4 5 0 5 0 77 4 1 6 2 78 6 =2 8HTestconf 00001000 6 77 3 50 7 =3 11HDavid Byers 1111 13 4 19 18 6 97 5 198 1 13 4 19 18 6 97 5 198 1 7 0 7 0 0 0 77 1 1 0 4 78 7 =4 11HDavid Byers 11111000 0 77 This example shows the difference between `get-conf-stat-old' (*note get-conf-stat-old::) and `get-uconf-stat'. In the first two examples conference 6 is retrieved, and in the second two, conference 7, which happens to be a person, is retrieved. Note the difference in length of the flag field. Error codes ----------- `undefined-conference' The conference `conference' does not exist or is secret. `conference-zero' `conference' is zero.  File: protocol-a.info, Node: set-info, Next: accept-async, Prev: get-uconf-stat, Up: Protocol Requests set-info [79] (9) Recommended ============================= set-info [79] ( info : Info-Old ) -> ( ); This call sets the server information retrieved by `get-info-old' (*note get-info-old::). The version number in the info structure is ignored (but must be present); all other fields are stored permanently in the LysKOM database. This is a privileged call. Example: 1 79 10901 1 2 3 4 1080 =1 This example sets the conference presentation conference to one, the user presentation conference to two, the motd conference to three and the news conference to four. It also sets the login message to text 1080. It also attempts to set the version number to 1.9.1, but that number is silently ignored by the server. Error codes ----------- `login-first' Login required before issuing this call. `permission-denied' Administrator bit not set or privileges not enabled. `undefined-conference' One of the conferences in `info' does not exist. `no-such-text' The MOTD text in `info' does not exist. `mark-limit' The MOTD text in `info' already has the maximum number of marks. `text-zero' This error message should never be returned, but lyskomd 1.9.0 erroneously returned this error message if the MOTD text in `info' was set to 0. That should mean that there should be no message of the day, and the current implementation of the server does accept MOTD to be 0.  File: protocol-a.info, Node: accept-async, Next: query-async, Prev: set-info, Up: Protocol Requests accept-async [80] (9) Recommended ================================= accept-async [80] ( request-list : ARRAY INT32 ) -> ( ); This call advises the server that the client wants to receive the asynchronous messages listed in `request-list'. The server must send these messages to the client when applicable, but may also send other types of messages if it so desires. The list of currently requested asynchronous messages may be retrieved using the `query-async' call(*note query-async::). Don't forget that message type 12 is personal, group and global text messages. Most users will not want these turned off. Example: 1 80 2 { 7 9 } =1 This example tells the server that the client wants to receive asynchronous messages when the database is being synched (message 7) and when someone logs in (message 9). Error codes ----------- If the client requests a message that the server does not send, the server will reply with an error message saying which message number it does not support. The call will succeed anyway. This mechanism is useful for clients that want new versions of some messages, but need to be compatible with older servers. `unknown-async' At least one of the numbers in `request-list' is not the number of an async message the server knows about. The `error-status' indicates the first offending number. Please note that a bug in lyskomd 1.9.0 prevented the server from sending this error message (frankly, we simply forgot about it.) `long-array' The `request-list' was too long. Servers should always accept a `request-list' that contains a lot more asynchronous messages than the server sends, so that it can deal with newer clients. This error message should only be returned if the client tries to trigger a buffer overrun.  File: protocol-a.info, Node: query-async, Next: user-active, Prev: accept-async, Up: Protocol Requests query-async [81] (9) Recommended ================================ query-async [81] ( ) -> ( ARRAY INT32 ); This call queries the server for which asynchronous messages the client is receiving. Note that the client may not be able to turn off all messages returned in this list since the server may consider some messages to be mandatory. Also note that the client may still receive messages that are not listed in the result of this call. Even though those messages are turned off, the server may decide to send them under certain circumstances. Example: 1 81 =1 7 { 0 5 7 9 11 12 13 } In this example the client is receiving seven types of asynchronous messages: messages about new articles, changed names, database synching, new logins, rejected connections, personal messages and logouts. This particular set was the default for new connections to lyskomd 1.9 servers. *Note Asynchronous Messages::, for the currently recommended list of asynchronous messages that servers should preselect. Error codes ----------- This call always succeeds.  File: protocol-a.info, Node: user-active, Next: who-is-on-dynamic, Prev: query-async, Up: Protocol Requests user-active [82] (9) Recommended ================================ user-active [82] ( ) -> ( ); This call simply notifies the server that the user is active. The server uses the time of the last user-active call to calculate how long a user has been idle. The client should send this to the server every time the user actively does something LysKOM-related, such as reads a texts, writes on a comment, gives a command, de-iconifies the LysKOM window, et c. However, the call should not be issued more than twice per minute, to avoid excessive network and server load. Error codes ----------- This call always succeeds.  File: protocol-a.info, Node: who-is-on-dynamic, Next: get-static-session-info, Prev: user-active, Up: Protocol Requests who-is-on-dynamic [83] (9) Recommended ====================================== who-is-on-dynamic [83] (( want-visible : BOOL; want-invisible : BOOL; active-last : INT32 )) -> ( ARRAY Dynamic-Session-Info ); This call returns a list of information about sessions. Only sessions with the desired visibility and activeness are returned. If `want-visible' is true then information about visible sessions is returned. If `want-invisible' is true then information about invisible sessions is returned. If they are both true sessions will be included in the answer regardless of their visibility status. Sessions where no-one is logged in are considered invisible, and the `invisible' flag is set in the corresponding `Dynamic-Session-Info' that is returned. If `active-last' is zero then the result is a list of all sessions with the proper visibility. If `active-last' is nonzero then only sessions that have issued an `user-active' call within the last `active-last' seconds are included in the list. Sessions that have never issued an `user-active' call are always included (if they have the proper visibility). Error codes ----------- `bad-bool' `want-visible' and `want-invisible' must be either `0' or `1'.  File: protocol-a.info, Node: get-static-session-info, Next: get-collate-table, Prev: who-is-on-dynamic, Up: Protocol Requests get-static-session-info [84] (9) Recommended ============================================ get-static-session-info [84] ( session-no : Session-No ) -> ( Static-Session-Info ); This call returns information about session number `session-no'. The returned information cannot change until the session number is reused (and that cannot happen until the server is shut down), so clients are encouraged to cache the information. Error codes ----------- `login-first' Login required before issuing this call. `undefined-session' The session `session-no' does not exist.  File: protocol-a.info, Node: get-collate-table, Next: create-text, Prev: get-static-session-info, Up: Protocol Requests get-collate-table [85] (10) Recommended ======================================= get-collate-table [85] ( ) -> ( HOLLERITH ); This call returns the collate table being used by the server to match names. If index A and index B in the string are the same character, characters A and B are considered equivalent. An empty collate table indicates that the server considers all characters different. Currently, the lyskomd server only deals with 8-bit characters. Clients should be prepared for collate tables of any length. Characters whose code are greater than the length of the collate table should be considered to be unique. Error codes ----------- This call always succeeds.  File: protocol-a.info, Node: create-text, Next: create-anonymous-text, Prev: get-collate-table, Up: Protocol Requests create-text [86] (10) Recommended ================================= create-text [86] (( text : HOLLERITH; misc-info : ARRAY Misc-Info; aux-items : ARRAY Aux-Item-Input )) -> ( Text-No ); Creates a new text with contents from `text' and recipients etc. defined by `misc-info' (*note The Misc-Info List::). In addition to the result, the server will send an asynchronous message to all members of any of the recipients of the new text. It is not defined whether this messages comes before or after the reply to the create-text message. Clients should be prepared for either situation. The text up to the first linefeed is considered to be the subject line. The remaining text is the message body. Although messages with only a subject are valid, clients should avoid letting users create such messages. The items in `aux-items' are attached to the new text. The only Misc-Info items valid for this call are `recpt', `cc-recpt', `bcc-recpt' (introduced in protocol version 10), `comm-to' and `footn-to'. Error codes ----------- `login-first' Login required before issuing this call. `string-too-long' The string `text' is longer than the maximum length of a message. `temporary-failure' The text could not be created at the moment. `no-such-text' Attempt to comment or footnote a non-existent or secret text. `not-author' Attempt to footnote a text authored by someone else. `footnote-limit' Attempt to footnote a text with the maximum number of footnotes already set. `comment-limit' Attempt to comment a text with the maximum number of comments already set. `index-out-of-range' Attempt to create a text failed because we reached the maximum number of texts permitted. The `error-status' indicates the text number that should have been created if the limit hadn't been reached. `access-denied' Attempt to send a text to a conference failed because no access to the conference or any super conference that will accept a text. `anonymous-rejected' Attempt to send an anonymous text to a conference that does not accept anonymous texts. `illegal-misc' Invalid misc-info list. A recipient is listed more than once or there is an unknown misc item in the misc-info list. `illegal-aux-item' One of the aux-items in `aux-items' is illegal. The tag might be out of range, the item not applicable to texts or whatever `aux-item-permission' One of the items looks valid but could not be created anyway. `long-array' Too many Misc-Info items or aux-items were specified.  File: protocol-a.info, Node: create-anonymous-text, Next: create-conf, Prev: create-text, Up: Protocol Requests create-anonymous-text [87] (10) Recommended =========================================== create-anonymous-text [87] (( text : HOLLERITH; misc-info : ARRAY Misc-Info; aux-items : ARRAY Aux-Item-Input )) -> ( Text-No ); Similar to `create-text' (*note create-text::), but the text is created the author field set to zero. Not even the server has a record of who created the text. The original intended use for this call was for importing texts from other sources, such as WWW, FTP or Gopher, but some clients include explicit support for sending anonymous texts to a server. It is only possible to send anonymous texts to a conference with the right flag bit set. The only Misc-Info items valid for this call in the `misc-info' array are `recpt', `cc-recpt', `bcc-recpt' (introduced in protocol version 10), `comm-to' and `footn-to'. Error codes ----------- `login-first' Login required before issuing this call. `string-too-long' The string `text' is longer than the maximum length of a message. `temporary-failure' The text could not be created at the moment. `no-such-text' Attempt to comment or footnote a non-existent or secret text. `not-author' Attempt to footnote a text authored by someone else. `footnote-limit' Attempt to footnote a text with the maximum number of footnotes already set. `comment-limit' Attempt to comment a text with the maximum number of comments already set. `access-denied' Attempt to send a text to a conference failed because no access to the conference or any super conference that will accept a text. `anonymous-rejected' Attempt to send an anonymous text to a conference that does not accept anonymous texts. `illegal-misc' Invalid misc-info list. A recipient is listed more than once or there is an unknown misc item in the misc-info list. `illegal-aux-item' One of the aux-items in `aux-items' is illegal. The tag might be out of range, the item not applicable to texts or whatever `aux-item-permission' One of the items looks valid but could not be created anyway.  File: protocol-a.info, Node: create-conf, Next: create-person, Prev: create-anonymous-text, Up: Protocol Requests create-conf [88] (10) Recommended ================================= create-conf [88] (( name : HOLLERITH; type : Any-Conf-Type; aux-items : ARRAY Aux-Item-Input )) -> ( Conf-No ); This call is used to create new conferences. `name' is the name of the new conference and `type' is its type. If successful, the call returns the conference number of the newly created conference. The list `aux-items' contains the aux items to attach to the conference. To use this call the session must have logged in as a user with privileges to create conferences (*note Security::). Error codes ----------- `login-first' Login required before issuing this call. `permission-denied' The server does not allow everyone to create a conference and user does not have the `create-conf' bit set. May also be an attempt to create a conference with the `letterbox' bit set. `conference-exists' A conference named `name' already exists. `bad-name' `name' contains invalid characters. `string-to-long' `name' is too long to be used as a conference name. `secret-public' The conference type has the `secret' bit set, but the `rd-prot' bit is cleared. `illegal-aux-item' One of the aux-items in `aux-items' is illegal. The tag might be out of range, the item not applicable to conferences or whatever `aux-item-permission' One of the items looks valid but could not be created anyway. `index-out-of-range' Attempt to create a conference failed because we reached the maximum number of conferences permitted. The `error-status' indicates the conference number that should have been created if the limit hadn't been reached.  File: protocol-a.info, Node: create-person, Next: get-text-stat, Prev: create-conf, Up: Protocol Requests create-person [89] (10) Recommended =================================== create-person [89] (( name : HOLLERITH; passwd : HOLLERITH; flags : Personal-Flags; aux-items : ARRAY Aux-Item-Input )) -> ( Pers-No ); This call requests that the server create a new person with the name and password given as arguments. To create a person the session must be logged in as a person with sufficient privileges. The list `aux-items' contains the aux items that are to be attached to the new person's mailbox conference. The person flags are set to `flags'. The new person will be a member of exactly one conference: the associated mailbox. That membership will have priority 255 and (of course) position 0. All flags of the membership will be 0. Unlike call number 5, this call does not do an automatic login. Error codes ----------- `login-first' The session is not logged in and the server does not allow person creation before logging in. `permission-denied' The server does not allow everyone to create person and the person currently logged on does not have the `create-pers' bit set. `person-exists' There is already a person named `name'. `invalid-password' The string `passwd' is not a valid password. `illegal-aux-item' One of the aux-items in `aux-items' is illegal. The tag might be out of range, the item not applicable to conferences or mailboxes or whatever. `aux-item-permission' One of the items looks valid but could not be created anyway. `index-out-of-range' Attempt to create a person failed because we reached the maximum number of conferences permitted. The `error-status' indicates the person number that should have been created if the limit hadn't been reached.  File: protocol-a.info, Node: get-text-stat, Next: get-conf-stat, Prev: create-person, Up: Protocol Requests get-text-stat [90] (10) Recommended =================================== get-text-stat [90] ( text-no : Text-No ) -> ( Text-Stat ); Get information about text number `text-no'. The text-stat contains information about the size of the text, its recipients, comments, author and more. Error codes ----------- `no-such-text' The text `text-no' does not exist, or no read access. This error code will also be used when attempting to fetch texts without logging in first. (There are some texts that are readable without logging in: the motd-of-lyskom (*note set-motd-of-lyskom::), and texts with the `world-readable' aux item set on them.) `text-zero' Attempt to retrieve text number 0.  File: protocol-a.info, Node: get-conf-stat, Next: modify-text-info, Prev: get-text-stat, Up: Protocol Requests get-conf-stat [91] (10) Recommended =================================== get-conf-stat [91] ( conf-no : Conf-No ) -> ( Conference ); This call retrieves the conference data structure for conference number `conf-no'. Error codes ----------- `undefined-conference' The conference `conf-no' does not exist or is secret.  File: protocol-a.info, Node: modify-text-info, Next: modify-conf-info, Prev: get-conf-stat, Up: Protocol Requests modify-text-info [92] (10) Recommended ====================================== modify-text-info [92] (( text : Text-No; delete : ARRAY Aux-No; add : ARRAY Aux-Item-Input )) -> ( ); This call deletes the aux-items listed in `delete' from the text `text' and then adds the ones listed in `add' to the text. Either list may be empty, and the call is guaranteed to either completely fail or completely succeed. Error codes ----------- `login-first' Login required before issuing this call. `no-such-text' The text `text' does not exist or is secret. `aux-item-permission' No permission to delete one or more of the items in `delete', or not enough permissions to add one or more of the items in `add'. `illegal-aux-item' One of the items in `add' is illegal for some reason.  File: protocol-a.info, Node: modify-conf-info, Next: get-info, Prev: modify-text-info, Up: Protocol Requests modify-conf-info [93] (10) Recommended ====================================== modify-conf-info [93] (( conf : Conf-No; delete : ARRAY Aux-No; add : ARRAY Aux-Item-Input )) -> ( ); This call deleted the aux-items listed in `delete' from the conference `conf' and then adds the ones listed in `add' to the conference. Either list may be empty, and the call is guaranteed to either completely fail or completely succeed. Error codes ----------- `login-first' Login required before issuing this call. `undefined-conference' The conference `conf' does not exist or is secret. `aux-item-permission' No permission to delete one or more of the items in `delete', or not enough permissions to add one or more of the items in `add'. `illegal-aux-item' One of the items in `add' is illegal for some reason.  File: protocol-a.info, Node: get-info, Next: modify-system-info, Prev: modify-conf-info, Up: Protocol Requests get-info [94] (10) Recommended ============================== get-info [94] ( ) -> ( Info ); This call returns the `Info' structure for the server (*note Info::). Clients should call this in order to find out which conferences are used for presentations and such. It can be issued without logging in. Error codes ----------- This call always succeeds.  File: protocol-a.info, Node: modify-system-info, Next: query-predefined-aux-items, Prev: get-info, Up: Protocol Requests modify-system-info [95] (10) Recommended ======================================== modify-system-info [95] (( items-to-delete : ARRAY Aux-No; items-to-add : ARRAY Aux-Item-Input )) -> ( ); This call modifies the aux-item list of the server information (which can be retrieved using `get-info' (*note get-info::).) It only succeeds when issued by a person with the admin bit set and privileges enabled. The items in `items-to-delete' are removed, and the items in `items-to-add' are added. This call is atomic; either all deletions or additions succeeded, or none of them is made. Error codes ----------- `login-first' Login requires before issuing this call. `permission-denied' Admin bit not set or privileges not enabled. `illegal-aux-item' Attempt to create an invalid aux item. `aux-item-permission' Attempt to delete an undeletable item or create an uncreateable item.  File: protocol-a.info, Node: query-predefined-aux-items, Next: set-expire, Prev: modify-system-info, Up: Protocol Requests query-predefined-aux-items [96] (10) Recommended ================================================ query-predefined-aux-items [96] ( ) -> ( ARRAY INT32 ); Returns the list of aux-items that have specific definitions in the server. These items are the only items within the restricted tag ranges that can be created. The meanings of the various item types are defined in this document; see *Note Aux-Item Types::. Error codes ----------- This call always succeeds.  File: protocol-a.info, Node: set-expire, Next: query-read-texts-10, Prev: query-predefined-aux-items, Up: Protocol Requests set-expire [97] (10) Experimental ================================= set-expire [97] (( conf-no : Conf-No; expire : Garb-Nice )) -> ( ); This call sets the `expire' field of the conference `conf-no' to `expire'. This call can only be issued by the conference's supervisor or a privileged user. Error codes ----------- `login-first' Login required before issuing this call. `undefined-conference' The conference `conf-no' does not exist or is secret. `permission-denied' Not supervisor of conference `conf-no' and not privileged enough to complete the call anyway. lyskom-server-2.1.2/doc/protocol-a.info-60000664000015100472110000014332207723710263013675 This is protocol-a.info, produced by makeinfo version 4.2 from Protocol-A.texi. This is the LysKOM Protocol A specification, edition 11.1. It specifies version 11 of the protocol. It was first distributed with version 2.1.2 of lyskomd. Copyright (C) 1995-2003 Lysator ACS. Permission is granted to make and distribute verbatim copies of this specification provided the copyright notice and this permission notice are preserved on all copies. Modified versions of this document may be redistributed with the added condition that all modifications not cleared with the LysKOM development group are clearly marked and that the entire modified work be redistributed under the same conditions as the original. Permission is granted to copy and distribute translations of this manual into another language under the same conditions as for modified versions. INFO-DIR-SECTION LysKOM START-INFO-DIR-ENTRY * Protocol A: (protocol-a). The LysKOM Protocol A specification. END-INFO-DIR-ENTRY  File: protocol-a.info, Node: query-read-texts-10, Next: get-membership-10, Prev: set-expire, Up: Protocol Requests query-read-texts-10 [98] (10) Obsolete (11) =========================================== query-read-texts-10 [98] (( person : Pers-No; conference : Conf-No )) -> ( Membership-10 ); This call is obsolete. Use `query-read-texts' (*note query-read-texts::). This call is used to find the number of unread texts in a conference. The data it returns is actually a membership structure which specifies which texts have been read. It is up to the client to transform the data to a more usable form. `person' is the person being queried and `conference' is the conference in question. Calling `query-read-texts-10' does not require the session to be logged in. Example: 1 98 6 1 =1 4 32 5 11 12 7 93 1 193 1 1 20 133 3 { 135 136 137 } 5 43 8 3 12 7 93 1 193 1 01000000 This example finds the read texts for user 6 in conference 1. The returned data indicates that conference 1 is the fifth conference on the users' membership list (`4'; remember that the `position' starts its count at 0), user last read the conference on Monday July 12th, 1993 at 11:05:32 (`32 5 11 12 7 93 1 193 1'), that it is the membership in conference number 1 (`1'), that the person has assigned priority 20 to the conference (`20') and that all articles up to and including local number 133 (`133') plus articles 135, 136 and 137 (`3 { 135 136 137 }') have been read. The membership was added by person 5 (`5') at Monday July 12th, 1993 at 03:08:43 (`43 8 3 12 7 93 1 193 1') and it is passive (`01000000'). Error codes ----------- `undefined-person' `person' does not exist, or no access to person. `undefined-conference' Conference `conference' does not exist, or is secret. `conference-zero' `conference' is zero. `not-member' `person' is not a member of `conference' or insufficient privileges to find out if `person' is a member.  File: protocol-a.info, Node: get-membership-10, Next: add-member, Prev: query-read-texts-10, Up: Protocol Requests get-membership-10 [99] (10) Obsolete (11) ========================================= get-membership-10 [99] (( person : Pers-No; first : INT16; no-of-confs : INT16; want-read-texts : BOOL )) -> ( ARRAY Membership-10 ); This call is obsolete. Use `get-membership' (*note get-membership::). This call retrieves the membership record for a list of conferences for a single person. `person' is the person whose memberships are to be retrieved. `first' is the first position in the membership list to retrieve, numbered from 0 and up. `no-of-confs' is the number of membership records to retrieve. If `want-read-texts' is `0', the server will not send the contents of the `read-texts' array of the memberships. (The size will be transmitted, but a single asterisk (`*') will be sent instead of the array itself.) The server will return a membership list that is shorter than `no-of-confs' if `no-of-confs' + `first' is larger than the number of conferences the person is a member of. Elements of the member list that the person requesting the list does not have sufficient privileges to see may be cleared. Cleared elements simply have all fields set to zero. Example: 1 99 5 0 3 1 =1 2 { 0 49 14 17 13 8 91 5 255 1 5 255 0 0 * 5 49 14 17 13 8 91 5 255 1 00000000 1 20 14 22 17 6 97 4 197 1 6 100 2 0 * 5 49 14 17 13 8 91 5 255 1 00000000 } 2 99 5 0 1 1 =2 1 { 0 49 14 17 13 8 91 5 255 1 5 255 0 0 * 5 49 14 17 13 8 91 5 255 1 00000000 } 3 99 5 1 4 1 =3 1 { 1 20 14 22 17 6 97 4 197 1 6 100 2 0 * 5 49 14 17 13 8 91 5 255 1 00000000 } In this example we retrieve the memberships of person 5. The first call asks for three memberships, starting with number 0. Since this person is only a member of two conferences, the list returned only contains two memberships. The next two calls retrieve a single membership each. The first by asking for only one, and the second by asking for four memberships, starting with number 1. Error codes ----------- `login-first' Login required before issuing this call. `undefined-person' The person `person' does not exist. `undefined-conference' The conference `person' does not exist or is secret. `index-out-of-range' `first' is higher than the index of the last conference in the person's membership list. `bad-bool' `want-read-texts' must be either `0' or `1'.  File: protocol-a.info, Node: add-member, Next: get-members, Prev: get-membership-10, Up: Protocol Requests add-member [100] (10) Recommended ================================= add-member [100] (( conf-no : Conf-No; pers-no : Pers-No; priority : INT8; where : INT16; type : Membership-Type )) -> ( ); Make the person `pers-no' a member of conference `conf-no'. The membership priority is set to `priority' and its position in the membership list is set to `where'. The membership flags are set to `type'. If the current user is adding a user he isn't supervisor of, the `invitation' bit of `type' is automatically set by the server. This call can be used to change the priority, position and flags of a conference in the person's membership list if the person is already a member of the conference. The person doing this must either be a supervisor of the affected person, or have sufficient privileges enabled. Example: 1 99 119 0 10 0 =1 1 { 49 14 17 13 8 91 5 255 1 119 255 0 0 * 119 00001111 } 1 100 1 119 250 0 10000000 =1 1 100 119 119 251 1 00000000 =1 1 99 119 0 10 0 =1 2 { 52 30 14 11 5 96 2 162 1 1 250 0 0 * 119 00000000 49 14 17 13 8 91 5 251 1 119 255 0 0 * 10000000 } This example makes person 119 (me) a member of conference number 1 and changes the priority and some flags of the preexisting membership in conference 119. The priority is set to 250 and the conference is placed first in the membership list. The first and last calls of the example show the membership list for person 119 before and after the calls. Error codes ----------- `login-first' Login required before issuing this call. `undefined-conference' Conference `conf-no' does not exist or is secret. `conference-zero' `conf-no' is zero. `undefined-person' Person `pers-no' does not exist `access-denied' Not enough permissions or privileges to add members to `conf-no' or to change privileges, position or type of a preexisting membership. `permission-denied' Person `pers-no' is already a member of conference `conf-no', but the person logged on is not a supervisor and does not have enough privileges to change the priorities of person `pers-no'.  File: protocol-a.info, Node: get-members, Next: set-membership-type, Prev: add-member, Up: Protocol Requests get-members [101] (10) Recommended ================================== get-members [101] (( conf : Conf-No; first : INT16; no-of-members : INT16 )) -> ( ARRAY Member ); This call returns a list of members of the conference `conf'. `first' is the first index in the membership to return, numbered from zero and up. `no-of-members' is the maximum number of members to return. Some of the elements of the result may be cleared if the person requesting the information does not have sufficient privileges to see the contents. Cleared elements simply have all fields set to zero. Example: 1 101 1 0 100 =1 4 { 7 7 00000000 8 8 00000000 9 8 00000000 10 10 00000000 } 1 101 6 0 100 =1 4 { 5 5 01000000 7 7 01000000 9 8 10000000 10 10 00000000 } 1 101 6 2 2 =1 2 { 9 8 10000000 10 10 00000000 } In this example the client first requests the first 100 members in conference 1. The second request is for the first 100 members of conference 6. The last request is for members 2 and 3 in conference 6. Error codes ----------- `undefined-conference' The conference `conf' does not exist or is secret. `index-out-of-range' `first' is higher than the number of members in `conf'.  File: protocol-a.info, Node: set-membership-type, Next: local-to-global, Prev: get-members, Up: Protocol Requests set-membership-type [102] (10) Recommended ========================================== set-membership-type [102] (( pers : Pers-No; conf : Conf-No; type : Membership-Type )) -> ( ); This call modifies the type of a membership. The person `pers' membership in conference `conf' is affected. The server may impose arbitrary restrictions on how the membership type may be changed. Typically it will only be possible to clear the `invitation' bit. It is possible that the server will not permit the `secret' bit to be set. Attempting to set a membership type that does not agree with the server's restrictions will result in an error. Error codes ----------- `login-first' Login required before issuing this call. `conference-zero' `conf' is zero. `undefined-conference' The conference `conf' does not exist or is secret or the person `pers' does not exist or is secret. `permission-denied' Insufficient permissions to change the membership of `pers'. `not-member' Person `pers' is not a member of conference `conf'. `invalid-membership-type' The requested membership type `type' was not compatible with restrictions set on the server or on the conference `conf'  File: protocol-a.info, Node: local-to-global, Next: map-created-texts, Prev: set-membership-type, Up: Protocol Requests local-to-global [103] (10) Recommended ====================================== local-to-global [103] (( conf-no : Conf-No; first-local-no : Local-Text-No; no-of-existing-texts : INT32 )) -> ( Text-Mapping ); This call retrieves information that makes it possible to convert `no-of-existing-texts' existing local text numbers starting at `first-local-no' to global text numbers, provided that there are that many local texts. The `conf-no' parameter specifies which conference to look up local numbers in. `first-local-no' is the first number that the client is interested in. `no-of-existing-texts' is the maximum number of texts the client wants information about. Legal values for `no-of-existing-texts' are 1-255 (inclusive). The server will return a sparse or dense Text-Mapping depending on the how many deleted texts there are after `first-local-no'. The `local-to-global-reverse' (*note local-to-global-reverse::) request can be useful if you want to traverse the mapping from higher to lower numbers. Example: 1 103 93 1 5 =1 1 7 1 1 1 6 { 1003 1005 1009 1029 0 1034 } 2 103 93 1 6 =2 1 63 1 0 6 { 1 1003 2 1005 3 1009 4 1029 6 1034 62 1302 } 3 103 93 50 10 =3 50 70 0 0 2 { 62 1302 69 1006 } The above example shows three calls to `local-to-global'. (Extra newlines have been inserted in the result of the two final calls to make the result more readable.) The first call requests information about the first five existing texts in conference 93. The result contains information about texts in the range 1-7 (including the lower limit, but not the upper), and there are more texts. The server uses the dense form of the `Text-Mapping'. As can be seen from the result, they have local text numbers 1, 2, 3, 4 and 6. The global text number corresponding to local text number 5 is sent as 0, indicating that it doesn't exist. In the second call, the client requests the same information, but one additional text. The result looks dramatically different, since the next existing text in this example has local text number 62. The result contains information about texts in the range 1-63 (including the lower limit, and excluding the upper), and there are more texts. The server of course uses the sparse form of the `Text-Mapping'. The final call shows what happens when `first-local-no' doesn't exist. The result contains information about texts in the range 50-70 (including the lower limit and excluding the upper); only local text number 62 and 69 actually exists in that range. 69 is the highest local text number. (Note that local text number 69 corresponds to global text number 1006, which is lower than 1302. Situations like this often occurs when `add-recipient' is used.) Error codes ----------- `login-first' Login required before issuing this call. `long-array' `no-of-existing-texts' was larger than 255. `conf-zero' `conf-no' was set to 0. `local-text-zero' `first-local-no' was set to 0. `undef-conf' The conference does not exist, or the client is not allowed to know that it exists. `access-denied' The conference exists, but the client is not allowed to retrieve information about the texts in the conference. `no-such-local-text' `first-local-no' is greater than the highest local text number that ever existed in the conference.  File: protocol-a.info, Node: map-created-texts, Next: set-keep-commented, Prev: local-to-global, Up: Protocol Requests map-created-texts [104] (10) Recommended ======================================== map-created-texts [104] (( author : Pers-No; first-local-no : Local-Text-No; no-of-existing-texts : INT32 )) -> ( Text-Mapping ); Return text numbers for existing texts that `author' has written. Just as each conference has a mapping from local text numbers to global text numbers, each person has a mapping from the N:th text written by him to the global text number. This function can be used to retrieve part of that mapping. More information and examples may be found in *Note local-to-global::. The `map-created-texts-reverse' (*note map-created-texts-reverse::) request can be useful if you want to traverse the mapping from higher to lower numbers. Error codes ----------- `login-first' Login required before issuing this call. `long-array' `no-of-existing-texts' was larger than 255. `conf-zero' `author' was set to 0. `local-text-zero' `first-local-no' was set to 0. `undef-pers' The conference does not exist, or the client is not allowed to know that it exists. `no-such-local-text' `first-local-no' is greater than the highest local text number that ever existed in the conference. `access-denied' The conference exists, but the client is not allowed to retrieve information about the texts in the conference.  File: protocol-a.info, Node: set-keep-commented, Next: set-pers-flags, Prev: map-created-texts, Up: Protocol Requests set-keep-commented [105] (10) Recommended ========================================= set-keep-commented [105] (( conf-no : Conf-No; keep-commented : Garb-Nice )) -> ( ); Sets the `keep-commented' field of the conference `conf-no' to `keep-commented'. This call can only be issued by a conference's supervisor or a privileged user. Error codes ----------- `login-first' Login required before issuing this call. `undefined-conference' The conference `conf-no' does not exist or is secret. `permission-denied' Not supervisor of conference `conf-no' and not privileged enough to complete the call anyway.  File: protocol-a.info, Node: set-pers-flags, Next: query-read-texts, Prev: set-keep-commented, Up: Protocol Requests set-pers-flags [106] (10) Recommended ===================================== set-pers-flags [106] (( pers-no : Pers-No; flags : Personal-Flags )) -> ( ); Set the flags field of person `pers-no' to `flags'. This call can only be issued by the person supervisor or a privileged user. Error codes ----------- `login-first' Login required before issuing this call. `conference-zero' The `pers-no' parameter is zero. `undefined-person' The person does not exist, or the session does not have permission to know about the person. `permission-denied' Person exists, but the session does not have permission to change the flags.  File: protocol-a.info, Node: query-read-texts, Next: get-membership, Prev: set-pers-flags, Up: Protocol Requests query-read-texts [107] (11) Recommended ======================================= query-read-texts [107] (( person : Pers-No; conference : Conf-No; want-read-ranges : BOOL; max-ranges : INT32 )) -> ( Membership ); This call is used to find the number of unread texts in a conference. The data it returns is actually a membership structure which specifies which texts have been read. It is up to the client to transform the data to a more usable form. `person' is the person being queried and `conference' is the conference in question. If `want-read-ranges' is `0', the server will not send the contents of the `read-ranges' array of the memberships. (The size will be transmitted, but a single asterisk (`*') will be sent instead of the array itself.) The `max-ranges' argument is ignored in this case. If `want-read-ranges' is `1', the `read-ranges' array will be returned. If `max-ranges' is non-zero, the array will be truncated to `max-ranges' ranges. (It isn't possible to determine if the array has been truncated, or if the array actually contained exactly that many ranges.) Setting `max-ranges' to `1' gives you enough information to find out the first unread text. When you call this request with `want-read-ranges' set to `1', the ranges will expand to include any adjacent texts that are now deleted. This may not happen if `get-membership' (*note get-membership::) is used to retrieve the information. Calling `query-read-texts' does not require the session to be logged in. Example: 1 107 6 1 1 0 =1 4 32 5 11 12 7 93 1 193 1 1 20 2 { 1 133 135 137 } 5 43 8 3 12 7 93 1 193 1 01000000 This example finds the read texts for user 6 in conference 1. The returned data indicates that conference 1 is the fifth conference on the users' membership list (`4'; remember that the `position' starts its count at 0), user last read the conference on Monday July 12th, 1993 at 11:05:32 (`32 5 11 12 7 93 1 193 1'), that it is the membership in conference number 1 (`1'), that the person has assigned priority 20 to the conference (`20') and that all texts 1-133 and 135-137 have been read (`2 { 1 133 135 137 }'). The membership was added by person 5 (`5') at Monday July 12th, 1993 at 03:08:43 (`43 8 3 12 7 93 1 193 1') and it is passive (`01000000'). Error codes ----------- `undefined-person' `person' does not exist, or no access to person. `undefined-conference' Conference `conference' does not exist, or is secret. `conference-zero' `conference' is zero. `not-member' `person' is not a member of `conference' or insufficient privileges to find out if `person' is a member. `bad-bool' `want-read-ranges' must be either `0' or `1'.  File: protocol-a.info, Node: get-membership, Next: mark-as-unread, Prev: query-read-texts, Up: Protocol Requests get-membership [108] (11) Recommended ===================================== get-membership [108] (( person : Pers-No; first : INT16; no-of-confs : INT16; want-read-ranges : BOOL; max-ranges : INT32 )) -> ( ARRAY Membership ); This call retrieves the membership record for a list of conferences for a single person. `person' is the person whose memberships are to be retrieved. `first' is the first position in the membership list to retrieve, numbered from 0 and up. `no-of-confs' is the number of membership records to retrieve. If `want-read-ranges' is `0', the server will not send the contents of the `read-texts' array of the memberships. (The sizes will be transmitted, but a single asterisk (`*') will be sent instead of the array itself.) The `max-ranges' argument is ignored in this case. If `want-read-ranges' is `1', the `read-ranges' arrays of the memberships will be returned. If `max-ranges' is non-zero, each array will be truncated to `max-ranges' ranges. (It isn't possible to determine if an array has been truncated, or if that array actually contained exactly that many ranges.) Unlike `query-read-texts' (*note query-read-texts::), the ranges may not expand to include deleted texts, so it isn't certain that you get enough information to find the first unread text if you specify a non-zero `max-ranges' argument. The server will return a membership list that is shorter than `no-of-confs' if `no-of-confs' + `first' is larger than the number of conferences the person is a member of. Elements of the member list that the person requesting the list does not have sufficient privileges to see may be cleared. Cleared elements simply have all fields set to zero. Example: 1 108 5 0 3 1 0 =1 2 { 0 49 14 17 13 8 91 5 255 1 5 255 0 * 5 49 14 17 13 8 91 5 255 1 00000000 1 20 14 22 17 6 97 4 197 1 6 100 1 { 1 2 } 5 49 14 17 13 8 91 5 255 1 00000000 } 2 108 5 0 1 1 0 =2 1 { 0 49 14 17 13 8 91 5 255 1 5 255 0 * 5 49 14 17 13 8 91 5 255 1 00000000 } 3 108 5 1 4 1 0 =3 1 { 1 20 14 22 17 6 97 4 197 1 6 100 1 { 1 2 } 5 49 14 17 13 8 91 5 255 1 00000000 } In this example we retrieve the memberships of person 5. The first call asks for three memberships, starting with number 0. Since this person is only a member of two conferences, the list returned only contains two memberships. The next two calls retrieve a single membership each. The first by asking for only one, and the second by asking for four memberships, starting with number 1. Error codes ----------- `login-first' Login required before issuing this call. `undefined-person' The person `person' does not exist. `undefined-conference' The conference `person' does not exist or is secret. `index-out-of-range' `first' is higher than the index of the last conference in the person's membership list. `bad-bool' `want-read-ranges' must be either `0' or `1'.  File: protocol-a.info, Node: mark-as-unread, Next: set-read-ranges, Prev: get-membership, Up: Protocol Requests mark-as-unread [109] (11) Recommended ===================================== mark-as-unread [109] (( conference : Conf-No; text : Local-Text-No )) -> ( ); Marks text `text' in conference number `conference' as not read for the current user. This call updates the membership record for the user. It can be used to undo the effect of `mark-as-read' (*note mark-as-read::). Example: 1 9 6 7 =1 20 32 11 17 6 96 3 198 1 7 1 241 0 * 1 78 7 =1 13HInlägg }t mig 00001000 241 1 1 27 7 241 =1 1 9 6 7 =1 20 32 11 17 6 96 3 198 1 7 1 240 0 * This example shows person 6 marking local text number 241 in conference 7 as not read. In the first `query-read-texts-old' call the person has read local text 241, and nothing higher. The `mark-as-read' call is reflected in the second `query-read-texts-old' call, where the user is seen to have read text 240 in conference 7, but nothing higher. To mark a global text number as not read it is necessary to translate it into local text numbers by looking at the misc-info list in the `Text-Stat' and calling `mark-as-read' once for each recipient. Attempts to mark a deleted text as unread will appear to succeed, but might have no effect, since the server will automatically mark them as read, sooner or later. Error codes ----------- `login-first' Login required before issuing this call. `undefined-conference' The conference `conference' does not exist or is secret. `conference-zero' `conference' is zero. `not-member' The person logged on is not a member of conference `conference'. `no-such-local-text' `text' is not, and has never been, a local text number in `conference'. The error argument contains the invalid number. `local-text-zero' `text' is zero.  File: protocol-a.info, Node: set-read-ranges, Next: get-stats-description, Prev: mark-as-unread, Up: Protocol Requests set-read-ranges [110] (11) Recommended ====================================== set-read-ranges [110] (( conference : Conf-No; read-ranges : ARRAY Read-Range )) -> ( ); This call tells the server that the person issuing the call has read exactly those texts specified by `read-ranges' in conference `conference'. This call is typically used to migrate a membership from one person to another. It can also be used instead of `set-unread' (*note set-unread::) or `set-last-read' (*note set-last-read::). The server may automatically extend the ranges with adjacent local text numbers that are deleted. Example: 1 9 7 6 =1 2 4 22 18 6 97 5 198 1 6 100 6 0 * 2 110 6 3 { 1 20 23 23 25 28 } =2 3 9 7 6 =3 2 4 22 18 6 97 5 198 1 6 100 20 5 { 23 25 26 27 28 } This example shows how person 7 originally had read everything up to and including local text number 6 in conference 6. After the call to `set-read-ranges', the `query-read-texts-old' (*note query-read-texts-old::) call reports that person 7 has read the local text numbers 1-20, 23 and 25-28. Error codes ----------- `login-first' Login required before issuing this call. `undefined-conference' The conference `conference' does not exist or is secret. `conference-zero' `conference' is zero. `not-member' Not a member of conference `conference'. `local-text-zero' `read-ranges' contains the number 0. `no-such-local-text' `read-ranges' contains a local text number that never has existed. `long-array' The `read-ranges' array is too long. `error-status' indicates the maximum range allowed. `invalid-range' The `first-read' field in one of the ranges in `read-ranges' is greater than `last-read'. The `error-status' indicates the interval (0 for the first interval, 1 for the second, and so on). `invalid-range-list' The `first-read' field in one of the ranges in `read-ranges' is not greater than the `last-read' field of the previous range. The `error-status' indicates the interval (0 for the first interval, 1 for the second, and so on).  File: protocol-a.info, Node: get-stats-description, Next: get-stats, Prev: set-read-ranges, Up: Protocol Requests get-stats-description [111] (11) Recommended ============================================ get-stats-description [111] ( ) -> ( Stats-Description ); Return a list of the supported statistical measurements. This request always succeeds, and always returns the same value for the duration of a session, so a client doesn't need to use it more than once per session. *Note Stats-Description::, for more info about the data type. *Note Measured Properties::, for more info on what the returned values means. Example: 1 111 =1 2 { 3HX-a 3HX-b } 4 { 0 60 300 900 } Error codes ----------- This call always succeeds.  File: protocol-a.info, Node: get-stats, Next: get-boottime-info, Prev: get-stats-description, Up: Protocol Requests get-stats [112] (11) Recommended ================================ get-stats [112] ( what : HOLLERITH ) -> ( ARRAY Stats ); Return a list of the statistical measurements of `what'. The number of elements in the result corresponds to the `when' field of the `Stats-Description' returned by `get-stats-description' (*note get-stats-description::). *Note Measured Properties::, for more info on the `what' argument. See also *Note Stats-Description::. Example: 1 112 7Hclients =1 4 { 20 0 0 19.80 1.2 1.1 18.33 1.2 1.1 16.11 1.2 1.2e-02 } Assuming that the `when' field of `get-stats-description' contains the time periods 0, 60, 300 and 900, the above result indicates that there is currently 20 connected clients. The past averages for 1, 5 and 15 minutes are 19.8, 18.33 and 16.11 connected clients. You can use this call even if you are not logged in. Error codes ----------- `feature-disabled' The measurement that was requested has been disabled. `undefined-measurement' The server doesn't measure the value requested by `what'. `access-denied' The client isn't allowed to retrieve the requested value. The client might be granted the privilege by logging in as a privileged user, using the `enable' (*note enable::) request, by a receiving a privilege bit, or in an implementation-defined way.  File: protocol-a.info, Node: get-boottime-info, Next: first-unused-conf-no, Prev: get-stats, Up: Protocol Requests get-boottime-info [113] (11) Recommended ======================================== get-boottime-info [113] ( ) -> ( Static-Server-Info ); Return status information that was current when the server started. This include the time of the last restart. Clients are encouraged to cache the return value of this request, as it will never change while a client is connected. Error codes ----------- This call always succeeds  File: protocol-a.info, Node: first-unused-conf-no, Next: first-unused-text-no, Prev: get-boottime-info, Up: Protocol Requests first-unused-conf-no [114] (11) Recommended =========================================== first-unused-conf-no [114] ( ) -> ( Conf-No ); Return first conference number that is not yet used. Error codes ----------- This call always succeeds  File: protocol-a.info, Node: first-unused-text-no, Next: find-next-conf-no, Prev: first-unused-conf-no, Up: Protocol Requests first-unused-text-no [115] (11) Recommended =========================================== first-unused-text-no [115] ( ) -> ( Text-No ); Return first text number that is not yet used. Error codes ----------- This call always succeeds  File: protocol-a.info, Node: find-next-conf-no, Next: find-previous-conf-no, Prev: first-unused-text-no, Up: Protocol Requests find-next-conf-no [116] (11) Recommended ======================================== find-next-conf-no [116] ( start : Conf-No ) -> ( Conf-No ); This call returns the next conference that you are allowed to see in the database created after conference `start'. `start' does not have to be a valid or readable conference number, as shown in the examples. Example: 1 116 0 =1 2 1 116 2 =1 4 This example shows how to retrieve the first readable conference in the LysKOM database by calling `find-next-conf-no' with `start' set to zero. In the example, the first conference is number 2. The second example gets the conference following number 2, which happens to be conference number 4. Error codes ----------- `login-first' Login required before issuing this call. `undefined-conference' There is no conference following conf `start'.  File: protocol-a.info, Node: find-previous-conf-no, Next: get-scheduling, Prev: find-next-conf-no, Up: Protocol Requests find-previous-conf-no [117] (11) Recommended ============================================ find-previous-conf-no [117] ( start : Conf-No ) -> ( Conf-No ); This call returns the last accessible conference in the database created before `start'. `start' does not have to be a valid or readable conference number, as shown in the examples. Example: 1 114 =1 12345 2 117 12345 =2 12330 1 117 12330 =1 12329 This example uses `first-unused-conf-no' (*note first-unused-conf-no::) to find the largest number that can meaningfully be sent to `find-previous-conf-no'. It then uses the request twice to find that the two conferences with highest conference numbers that are accessible to the user logged in is 12329 and 12330. Error codes ----------- `login-first' Login required before issuing this call. `undefined-conference' There is no conf preceding conf `start'.  File: protocol-a.info, Node: get-scheduling, Next: set-scheduling, Prev: find-previous-conf-no, Up: Protocol Requests get-scheduling [118] (11) Experimental ====================================== get-scheduling [118] ( session-no : Session-No ) -> ( Scheduling-Info ); Get the current scheduling information for a session. You can use 0 as `session-no' to get information about the current session. `set-scheduling' (*note set-scheduling::) contains an example. Error codes ----------- The first error code in the list below that is applicable will be returned. `login-first' Login required before issuing this call, unless `session-no' is 0 or the number of the current session. `undefined-session' That session does not exist.  File: protocol-a.info, Node: set-scheduling, Next: set-connection-time-format, Prev: get-scheduling, Up: Protocol Requests set-scheduling [119] (11) Experimental ====================================== set-scheduling [119] (( session-no : Session-No; priority : INT16; weight : INT16 )) -> ( ); This call sets the scheduling priority and weight of the connection. *Note Scheduling-Info::, for more information. You can use 0 as `session-no' to set the info for the current session. Example: 1 118 0 =1 1 1000 2 119 0 0 1000 %2 58 1 3 119 0 1 2500 %2 59 1500 3 119 0 1 1500 =3 This example uses `get-scheduling' (*note get-scheduling::) to find out the current scheduling setting (priority 1 and weight 1000). The client then attempts to get a better priority (0), but is informed that priority 1 is the best priority available to this user (or before logging in). At request 3 the client attempts to increase the weight to 2500, but is informed that 1500 is the best weight available. It finally sets the weight to 1500. This will result in a 50% speedup compared to the default setting. The `set-scheduling' request makes it possible to implement a quite complex scheduling machinery in the server. Please note, however, that a server that only implements priority 0 and weight 1 (and thus treats all sessions equally) is fully compliant with this specification. The number of priorities and weights that are available is implementation-defined. They can vary depending on the privileges of the user that is logged in, and may be affected by the `enable' (*note enable::) call. Error codes ----------- The first error code in the list below that is applicable will be returned. `weight-zero' You must specify a non-zero `weight'. `login-first' Login required before issuing this call, unless `session-no' is 0 or the number of the current session. `undefined-session' That session does not exist. `access-denied' You don't have enough privileges to modify the priority of the specified session. You can only modify your own session and sessions logged in as a person you are supervisor of. `index-out-of-range' The `priority' argument is numerically too large. `error-status' indicates the numerically largest priority that the server supports. `priority-denied' You don't have enough privileges to lower your priority. `error-status' indicates the lowest priority that you have access to. `weight-denied' You don't have enough privileges to set the specified weight at the specified priority. `error-status' indicates the highest weight you have access to at the specified priority. The limit may differ at different priorities.  File: protocol-a.info, Node: set-connection-time-format, Next: local-to-global-reverse, Prev: set-scheduling, Up: Protocol Requests set-connection-time-format [120] (11) Recommended ================================================= set-connection-time-format [120] ( use-utc : BOOL ) -> ( ); This call specifies how `Time' values are sent over the protocol. By default, they are sent in the local time zone of the server. If `use-utc' is 1, they will instead be sent using UTC. This affects both times sent from the server to the client, and from the client to the server. Please note that there is a race condition. The time contained in any asynchronous message received after sending a `set-connection-time-format' request and before getting the reply may have been sent using either the old or the new setting. You should not trust them. Error codes ----------- `bad-bool' `use-utc' must be either `0' or `1'.  File: protocol-a.info, Node: local-to-global-reverse, Next: map-created-texts-reverse, Prev: set-connection-time-format, Up: Protocol Requests local-to-global-reverse [121] (11) Recommended ============================================== local-to-global-reverse [121] (( conf-no : Conf-No; local-no-ceiling : Local-Text-No; no-of-existing-texts : INT32 )) -> ( Text-Mapping ); This call retrieves information that makes it possible to convert `no-of-existing-texts' existing local text numbers smaller than `local-no-ceiling' to global text numbers, provided that there are that many local texts smaller than `local-no-ceiling'. In other words, this request is just link `local-to-global' (*note local-to-global::), but it searches backwards in the mapping. The `conf-no' parameter specifies which conference to look up local numbers in. `local-no-ceiling' is the first number that the client is not interested in. `no-of-existing-texts' is the maximum number of texts the client wants information about. Legal values for `no-of-existing-texts' are 1-255 (inclusive). The server will return a sparse or dense Text-Mapping depending on the how many deleted texts there are before `local-no-ceiling'. As a special case, if `local-no-ceiling' is 0, information will be returned about the `no-of-existing-texts' highest-numbered texts. Error codes ----------- `login-first' Login required before issuing this call. `long-array' `no-of-existing-texts' was larger than 255. `conf-zero' `conf-no' was set to 0. `undef-conf' The conference does not exist, or the client is not allowed to know that it exists. `access-denied' The conference exists, but the client is not allowed to retrieve information about the texts in the conference.  File: protocol-a.info, Node: map-created-texts-reverse, Prev: local-to-global-reverse, Up: Protocol Requests map-created-texts-reverse [122] (11) Recommended ================================================ map-created-texts-reverse [122] (( author : Pers-No; local-no-ceiling : Local-Text-No; no-of-existing-texts : INT32 )) -> ( Text-Mapping ); Return text numbers for existing texts that `author' has written. This is just like `map-created-texts' (*note map-created-texts::), but searches in the other direction. (Compare with `local-to-global-reverse' (*note local-to-global-reverse::).) As a special case, if `local-no-ceiling' is 0, information will be returned about the last `no-of-existing-texts' texts. Error codes ----------- `login-first' Login required before issuing this call. `long-array' `no-of-existing-texts' was larger than 255. `conf-zero' `author' was set to 0. `undef-pers' The conference does not exist, or the client is not allowed to know that it exists. `access-denied' The conference exists, but the client is not allowed to retrieve information about the texts in the conference.  File: protocol-a.info, Node: Asynchronous Messages, Next: Error Codes, Prev: Protocol Requests, Up: Top Asynchronous Messages ********************* Asynchronous messages are information messages sent from the server to the client. Most of them are used to inform the client about changes to the database (such as when a new text is created), so that the clients don't have to poll the server for new information. Some have other uses. The messages with status "O" are included here for historical purposes only. Servers are not required to handle them, and are encouraged to reject them if a client uses it as an argument to `accept-async' (*note accept-async::). * Menu: * About Asynchronous Messages:: Introductory information about asynchronous messages. * async-new-text-old:: O A text has been created (0) * async-i-am-off:: O Logged off (obsolete) (1) * async-i-am-on-obsolete:: O Client changed i-am-on string (obsolete) (2) * async-new-name:: r Conference or person changed name (5) * async-i-am-on:: r Client changed i-am-doing string (6) * async-sync-db:: r Server is saving the database (7) * async-leave-conf:: r Person has been removed from a conference (8) * async-login:: r Someone has logged in (9) * async-broadcast:: O Broadcast message (obsolete) (10) * async-rejected-connection:: r LysKOM is full. Log out to make room. (11) * async-send-message:: r Text message to group or person (12) * async-logout:: r A person has logged out (13) * async-deleted-text:: r A text was deleted (14) * async-new-text:: r A text has been created (15) * async-new-recipient:: r A new recipient has been added to a text (16) * async-sub-recipient:: r A recipient has been removed from a text (17) * async-new-membership:: r A user has been added to a conference (18) * async-new-user-area:: r A user-area was changed (19) * async-new-presentation:: r A presentation was changed (20) * async-new-motd:: r A motd was changed (21) * async-text-aux-changed:: r The aux-item list of a text was changed (22)  File: protocol-a.info, Node: About Asynchronous Messages, Next: async-new-text-old, Up: Asynchronous Messages About Asynchronous Messages =========================== Clients can select which messages to receive by issuing an `accept-async' call(*note accept-async::). They can find out which messages are being sent by issuing the `query-async' call(*note query-async::). Note that the server can send other messages as well. For example, a broadcast message from a person with admin bits set may get through even if the client has not requested broadcast messages. When a connection is opened some messages are selected by default. Clients should use the `accept-async' call to select which messages they want. Servers are encouraged to preselect the `async-new-text-old', `async-new-name', `async-sync-db', `async-leave-conf', `async-login', `async-rejected-connection', `async-send-message' and `async-logout' messages. These correspond to the useful messages that were sent prior to the introduction of `accept-async' (*note accept-async::). An asynchronous message is sent as a colon immediately followed by the number of message parameters, the message number and the message parameters. For example, message number 5 could be sent as :3 5 119 11HDavid Byers 13HDavid C Byers The parameters of each message are listed in the same format as server calls.  File: protocol-a.info, Node: async-new-text-old, Next: async-i-am-off, Prev: About Asynchronous Messages, Up: Asynchronous Messages async-new-text-old [0] (1) Obsolete (10) ======================================== async-new-text-old [0] (( text-no : Text-No; text-stat : Text-Stat-Old )); This message is sent when a text is created. The text number of the text is sent in `text-no' and the text stat in `text-stat'. This message is sent to all logged-in members of any recipient of the text, any text it is a comment of, and any text it is a footnote of. In protocol version 10 this call has been superseded by *Note async-new-text::.  File: protocol-a.info, Node: async-i-am-off, Next: async-i-am-on-obsolete, Prev: async-new-text-old, Up: Asynchronous Messages async-i-am-off [1] (1) Obsolete (1) =================================== async-i-am-off [1] ( person : Pers-No ); This message was sent when `person' logged off. It has been replaced by `async-logout' (*note async-logout::), since this asynchronous message could not differentiate between sessions if the same person was logged in more than once.  File: protocol-a.info, Node: async-i-am-on-obsolete, Next: async-new-name, Prev: async-i-am-off, Up: Asynchronous Messages async-i-am-on-obsolete [2] (1) Obsolete (1) =========================================== async-i-am-on-obsolete [2] (( person : Pers-No; conference : Conf-No; what-am-i-doing : HOLLERITH )); This message was sent when `person' changed his `what-i-am-doing' string to `what-am-i-doing' or his working conference to `conference'. It has been replaced by call number 6, `async-i-am-on' (*note async-i-am-on::), since this asynchronous message could not differentiate between sessions if the same person was logged in more than once.  File: protocol-a.info, Node: async-new-name, Next: async-i-am-on, Prev: async-i-am-on-obsolete, Up: Asynchronous Messages async-new-name [5] (1) Recommended ================================== async-new-name [5] (( conf-no : Conf-No; old-name : HOLLERITH; new-name : HOLLERITH )); This message is sent when a person or conference changes names. The conference whose name is being changed is sent in `conf-no', the old name in `old-name' and the new name in `new-name'.  File: protocol-a.info, Node: async-i-am-on, Next: async-sync-db, Prev: async-new-name, Up: Asynchronous Messages async-i-am-on [6] (1) Recommended ================================= async-i-am-on [6] ( info : Who-Info ); This message is sent when a session's working conference, `what-i-am-doing' string (*note change-what-i-am-doing::) or username changes. The new information is sent in `info'.  File: protocol-a.info, Node: async-sync-db, Next: async-leave-conf, Prev: async-i-am-on, Up: Asynchronous Messages async-sync-db [7] (1) Recommended ================================= async-sync-db [7] ( ); This message is sent once just before the server blocks to save its database and once just after it blocks. There is no good way to tell the difference between the two cases. lyskom-server-2.1.2/doc/protocol-a.info-70000664000015100472110000013551407723710263013702 This is protocol-a.info, produced by makeinfo version 4.2 from Protocol-A.texi. This is the LysKOM Protocol A specification, edition 11.1. It specifies version 11 of the protocol. It was first distributed with version 2.1.2 of lyskomd. Copyright (C) 1995-2003 Lysator ACS. Permission is granted to make and distribute verbatim copies of this specification provided the copyright notice and this permission notice are preserved on all copies. Modified versions of this document may be redistributed with the added condition that all modifications not cleared with the LysKOM development group are clearly marked and that the entire modified work be redistributed under the same conditions as the original. Permission is granted to copy and distribute translations of this manual into another language under the same conditions as for modified versions. INFO-DIR-SECTION LysKOM START-INFO-DIR-ENTRY * Protocol A: (protocol-a). The LysKOM Protocol A specification. END-INFO-DIR-ENTRY  File: protocol-a.info, Node: async-leave-conf, Next: async-login, Prev: async-sync-db, Up: Asynchronous Messages async-leave-conf [8] (1) Recommended ==================================== async-leave-conf [8] ( conf-no : Conf-No ); This message is sent to a user when the user's membership in the working conference is removed for any reason. The conference the user is being removed from is sent in `conf-no'. Earlier versions of the LysKOM Protocol A specifications stated that this message was only sent if the membership was "revoked forcefully". The exact meaning of that phrasing was never specified. The lyskomd implementation has probably always followed the current version of the specification, which means that this message is sent whatever the reason for the removal is. Possible reasons include: * The session issued a `sub-member' call(*note sub-member::). * Some other session issued a `sub-member' call(*note sub-member::). * The conference was deleted. This message is not sent if a membership is transformed from an active to a passive membership.  File: protocol-a.info, Node: async-login, Next: async-broadcast, Prev: async-leave-conf, Up: Asynchronous Messages async-login [9] (1) Recommended =============================== async-login [9] (( pers-no : Pers-No; session-no : Session-No )); This message is sent when someone logs in. The identity of the person logging in is sent in `pers-no', and the session number in `session-no'.  File: protocol-a.info, Node: async-broadcast, Next: async-rejected-connection, Prev: async-login, Up: Asynchronous Messages async-broadcast [10] (1) Obsolete (1) ===================================== async-broadcast [10] (( sender : Pers-No; message : HOLLERITH )); This message has been superseded by `async-send-message' which is more flexible(*note async-send-message::). It used to be sent when the administrator (`sender') broadcasted a string (`message') to all LysKOM users, but is no longer used.  File: protocol-a.info, Node: async-rejected-connection, Next: async-send-message, Prev: async-broadcast, Up: Asynchronous Messages async-rejected-connection [11] (1) Recommended ============================================== async-rejected-connection [11] ( ); This message is sent when someone fails to log in because the maximum number of allowed connections has been reached. Some clients may take this as a signal to log out. Administrators should take it as a signal to allow more connections.  File: protocol-a.info, Node: async-send-message, Next: async-logout, Prev: async-rejected-connection, Up: Asynchronous Messages async-send-message [12] (1) Recommended ======================================= async-send-message [12] (( recipient : Conf-No; sender : Pers-No; message : HOLLERITH )); This message is sent when someone (the `sender') sends a message string (the `message'). The recipient of the message is sent in `recipient'. If it is zero, then the message was sent to all connections. If it is a conference, then the message is being sent to all logged-in members of that conference. If it is a mailbox then the message is personal and is only sent to members of the mailbox conference. The `passive' and `passive-message-invert' bits of the membership influence if this message is sent. *Note Membership-Type::.  File: protocol-a.info, Node: async-logout, Next: async-deleted-text, Prev: async-send-message, Up: Asynchronous Messages async-logout [13] (1) Recommended ================================= async-logout [13] (( pers-no : Pers-No; session-no : Session-No )); This message is sent when someone logs out. `pers-no' is the person logging out and `session-no' is the session in which the person is logging out. This message might also be sent when a session disconnects, even if there is nobody logged on in the session.  File: protocol-a.info, Node: async-deleted-text, Next: async-new-text, Prev: async-logout, Up: Asynchronous Messages async-deleted-text [14] (10) Recommended ======================================== async-deleted-text [14] (( text-no : Text-No; text-stat : Text-Stat )); This message is sent when a text is deleted and the currently logged-in person is a member of one of the recipients, or a recipient of any text that is linked to this text via a comment or footnote link. The text number being deleted is sent in `text-no' and the text stat in `text-stat'.  File: protocol-a.info, Node: async-new-text, Next: async-new-recipient, Prev: async-deleted-text, Up: Asynchronous Messages async-new-text [15] (10) Recommended ==================================== async-new-text [15] (( text-no : Text-No; text-stat : Text-Stat )); This message indicates that a new text has been created. The text has number `text-no', and the text stat is `text-stat'. The message is sent to all logged-in members of any recipient of the text, any text it is a comment of, and any text it is a footnote of.  File: protocol-a.info, Node: async-new-recipient, Next: async-sub-recipient, Prev: async-new-text, Up: Asynchronous Messages async-new-recipient [16] (10) Recommended ========================================= async-new-recipient [16] (( text-no : Text-No; conf-no : Conf-No; type : Info-Type )); This message indicates that a new recipient has been added to text `text-no'. The recipient added is `conf-no' and the type of recipient is indicated by `type'. This message is sent to all recipients of the text (of any text that is linked to this text via a comment or footnote link) that are permitted to know about the new recipient.  File: protocol-a.info, Node: async-sub-recipient, Next: async-new-membership, Prev: async-new-recipient, Up: Asynchronous Messages async-sub-recipient [17] (10) Recommended ========================================= async-sub-recipient [17] (( text-no : Text-No; conf-no : Conf-No; type : Info-Type )); This message indicates that a recipient has been removed from text `text-no'. The recipient removed is `conf-no' and the type of recipient is indicated by `type'. This message is sent to everybody that were recipients of the text (or any text that is linked to this text via a comment or footnote link) and that were permitted to know about the recipient.  File: protocol-a.info, Node: async-new-membership, Next: async-new-user-area, Prev: async-sub-recipient, Up: Asynchronous Messages async-new-membership [18] (10) Recommended ========================================== async-new-membership [18] (( pers-no : Pers-No; conf-no : Conf-No )); This message indicates that the membership for `pers-no' in conference `conf-no' has been added. This message is currently sent only to `pers-no', but that may change in the future. See also *Note async-leave-conf::.  File: protocol-a.info, Node: async-new-user-area, Next: async-new-presentation, Prev: async-new-membership, Up: Asynchronous Messages async-new-user-area [19] (11) Recommended ========================================= async-new-user-area [19] (( pers-no : Pers-No; old-user-area : Text-No; new-user-area : Text-No )); This message indicates that the user-area of `pers-no' has changed from `old-user-area' to `new-user-area'. This message is sent to all supervisors of `pers-no' (which of course includes `pers-no' himself).  File: protocol-a.info, Node: async-new-presentation, Next: async-new-motd, Prev: async-new-user-area, Up: Asynchronous Messages async-new-presentation [20] (11) Recommended ============================================ async-new-presentation [20] (( conf-no : Conf-No; old-presentation : Text-No; new-presentation : Text-No )); This message indicates that the presentation of `conf-no' has changed from `old-presentation' to `new-presentation'. This message is sent to everybody who is allowed to see `conf-no'. If the conference had no presentation, `old-presentation' will be 0. Likewise, if the presentation of the conference was removed, `new-presentation' will be 0.  File: protocol-a.info, Node: async-new-motd, Next: async-text-aux-changed, Prev: async-new-presentation, Up: Asynchronous Messages async-new-motd [21] (11) Recommended ==================================== async-new-motd [21] (( conf-no : Conf-No; old-motd : Text-No; new-motd : Text-No )); This message indicates that the `msg-of-day' of `conf-no' has changed from `old-motd' to `new-motd'. This message is sent to everybody who is allowed to see `conf-no'. If the conference had no message-of-the-day, `old-motd' will be 0. Likewise, if the motd of the conference was removed, `new-motd' will be 0.  File: protocol-a.info, Node: async-text-aux-changed, Prev: async-new-motd, Up: Asynchronous Messages async-text-aux-changed [22] (11) Recommended ============================================ async-text-aux-changed [22] (( text-no : Text-No; deleted : ARRAY Aux-Item; added : ARRAY Aux-Item )); This message indicates that the aux-items of text `text-no' have been changed. (This message is not sent when the text is created or deleted.) `deleted' is a list of the deleted items, and `added' is a list of the added items. At least one of the arrays will be non-empty. Please note that all items in `deleted' will have the `deleted' bit of the `flags' field set.  File: protocol-a.info, Node: Error Codes, Next: Aux-Item Types, Prev: Asynchronous Messages, Up: Top Error Codes *********** Normal errors are sent in reply to syntactically correct calls to the server. The client should accept any error code in response to any call, even if the error code in question is not listed in the description of the call, and even if the error code in question is not defined in the protocol specification yet. This table lists the currently defined error codes together with a short explanation. The explanation given below is the default semantics for the error code. It can be updated by the descriptions found for a specific call. *Note Client-Server Dialog::, for more information about error responses, including the syntax of the error response. `no-error (0)' No error has occurred. `error-status' is undefined. This should never happen, but it might. `not-implemented (2)' The call has not been implemented yet. `error-status' is undefined. `obsolete-call (3)' The call is obsolete and no longer implemented. `error-status' is undefined. `invalid-password (4)' Attempt to set a password containing illegal characters, or to use an incorrect password. `string-too-long (5)' A string was too long (see descriptions of each call.) `error-status' indicates the maximum string length. `login-first (6)' Login is required before issuing the call. `error-status' is undefined. `login-disallowed (7)' The system is in single-user mode. You need to be privileged to log in despite this. `error-status' is undefined. `conference-zero (8)' Attempt to use conference number 0. `error-status' is undefined. `undefined-conference (9)' Attempt to access a non-existent or secret conference. `error-status' contains the conference number in question. `undefined-person (10)' Attempt to access a non-existent or secret person. `error-status' contains the person number in question. `access-denied (11)' No read/write access to something. This might be returned in response to an attempt to create a text, when the recipient conference and its super conferences are read-only, or when attempting to add a member to a conference without enough permission to do so. `error-status' indicates the object to which we didn't have enough permissions to. `permission-denied (12)' Not enough permissions to do something. The exact meaning of this response depends on the call. `error-status' indicated the object for which permission was lacking, or zero. `not-member (13)' The call requires the caller to be a member of some conference that the caller is not a member of. `error-status' indicates the conference in question. `no-such-text (14)' Attempt to access a text that either does not exist or is secret in some way. `error-status' indicates the text number in question. `text-zero (15)' Attempt to use text number 0. `error-status' is undefined. `no-such-local-text (16)' Attempt to access a text using a local text number that does not represent an existing text. `error-status' indicates the offending number. `local-text-zero (17)' Attempt to use local text number zero. `error-status' is undefined. `bad-name (18)' Attempt to use a name that's too long, too short or contains invalid characters. `error-status' is undefined. `index-out-of-range (19)' Attempt to use a number that's out of range. The range and meaning of the numbers depends on the call issued. `error-status' is undefined unless stated otherwise in the call documentation. `conference-exists (20)' Attempt to create a conference or person with a name that's already occupied. `error-status' is undefined. `person-exists (21)' Attempt to create a person with a name that's already occupied. `error-status' is undefined. This error code is probably not used, but you never know for sure. `secret-public (22)' Attempt to give a conference a type with `secret' bit set and the `rd-prot' bit unset. This is an error since such a conference type is inconsistent. `error-status' is undefined. `letterbox (23)' Attempt to change the `letterbox' flag of a conference. `error-status' indicates the conference number. `ldb-error (24)' Database is corrupted. `error-status' is an internal code. `illegal-misc (25)' Attempt to create an illegal misc item. `error-status' contains the index of the illegal item. `illegal-info-type (26)' Attempt to use a Misc-Info type (or Info-Type value) that the server knows nothing about. `error-status' is the type. `already-recipient (27)' Attempt to add a recipient that is already a recipient of the same type. `error-status' contains the recipient that already is. `already-comment (28)' Attempt to add a comment to a text twice over. `error-status' contains the text number of the text that already is a comment. `already-footnote (29)' Attempt to add a footnote to a text twice over. `error-status' contains the text number of the text that already is a footnote. `not-recipient (30)' Attempt to remove a recipient that isn't really a recipient. `error-status' contains the conference number in question. `not-comment (31)' Attempt to remove a comment link that does not exist. `error-status' contains the text number that isn't a comment. `not-footnote (32)' Attempt to remove a footnote link that does not exist. `error-status' contains the text number that isn't a footnote. `recipient-limit (33)' Attempt to add a recipient to a text that already has the maximum number of recipients. `error-status' is the text that has the maximum number of recipients. `comment-limit (34)' Attempt to add a comment to a text that already has the maximum number of comments. `error-status' is the text with the maximum number of comments. `footnote-limit (35)' Attempt to add a footnote to a text that already has the maximum number of footnote. `error-status' is the text with the maximum number of footnotes. `mark-limit (36)' Attempt to add a mark to a text that already has the maximum number of marks. `error-status' is the text with the maximum number of marks. `not-author (37)' Attempt to manipulate a text in a way that required the user to be the author of the text, when not in fact the author. `error-status' contains the text number in question. `no-connect (38)' Currently unused. `out-of-memory (39)' The server ran out of memory. `server-is-crazy (40)' Currently unused. `client-is-crazy (41)' The client used an illegal call sequence, such as calling `set-client-version' more than once. `undefined-session (42)' Attempt to access a session that does not exist. `error-status' contains the offending session number. `regexp-error (43)' Error using a regexp. The regexp may be invalid or the server unable to compile it for other reasons. `error-status' is undefined. `not-marked (44)' Attempt to manipulate a text in a way that requires the text to be marked, when in fact it is not marked. `error-status' indicates the text in question. `temporary-failure (45)' Temporary failure. Try again later. `error-status' is undefined. `long-array (46)' An array sent to the server was too long. `error-status' is undefined. `anonymous-rejected (47)' Attempt to send an anonymous text to a conference that does not accept anonymous texts. `error-status' is undefined. `illegal-aux-item (48)' Attempt to create an invalid aux-item. Probably the tag or data are invalid. `error-status' contains the index in the aux-item list where the invalid item appears. `aux-item-permission (49)' Attempt to manipulate an aux-item without enough permissions. This response is sent when attempting to delete an item set by someone else or an item that can't be deleted, and when attempting to create an item without permissions to do so. `error-status' contains the index at which the item appears in the aux-item list sent to the server. `unknown-async (50)' Sent in response to a request for an asynchronous message the server does not send. The call succeeds, but this is sent as a warning to the client. `error-status' contains the message type the server did not understand. `internal-error (51)' The server has encountered a possibly recoverable internal error. `error-status' is undefined. `feature-disabled (52)' Attempt to use a feature that has been explicitly disabled in the server. `error-status' is undefined. `message-not-sent (53)' Attempt to send an asynchronous message failed for some reason. Perhaps the recipient is not accepting messages at the moment or there are no viable members in the recipient of the message. `error-status' is undefined. `invalid-membership-type (54)' A requested membership type was not compatible with restrictions set on the server or on a specific conference. `error-status' is undefined unless specifically mentioned in the documentation for a specific call. `invalid-range (55)' The lower limit of a supplied range is greater than the upper limit. `error-status' is undefined. `invalid-range-list (56)' The lower limit of a supplied range is not greater than the upper limit of the previous range in the list. `error-status' is undefined. `undefined-measurement (57)' A request for a measurement that the server doesn't make has been made. `error-status' is undefined. `priority-denied (58)' You don't have enough privileges to lower your priority. `error-status' indicates the lowest priority that you have access to. `weight-denied (59)' You don't have enough privileges to set the specified weight. `weight-zero (60)' The scheduling weight must be non-zero. `error-status' is undefined. `bad-bool (61)' An argument of type `BOOL' was given a value that is neither `0' nor `1'. `error-status' is undefined.  File: protocol-a.info, Node: Aux-Item Types, Next: Name Expansion, Prev: Error Codes, Up: Top Aux-Item Types ************** Some of the aux-items below (mostly the ones that begin with "mx-") are used by mail importers. `content-type [1] (text)' Specifies the content type of a text. Data is a valid MIME type or one of the special LysKOM types (*note LysKOM Content Types::). This item may only be set by the author of a text. The inherit, secret and hide-owner bits are cleared. Only one content-type item can be created per creator. `fast-reply [2] (text)' Data is a string that constitutes a brief comment to the text. This comment should be displayed immediately after the text body. An item of this type will never be inherited, can always be deleted, is never anonymous and is never secret. `cross-reference [3] (text, conference, letterbox)' Data is a cross-reference to something else. The contents consist of a letter, a number, and optionally a space and a descriptive text. The letter must be one of T, C or P. T specifies that the cross-reference points to a text; C that it points to a conference; and P that it points to a person. The number is the id of the target of the cross reference. The descriptive text is simply that, a text that describes the cross-reference. For example, "T15 Check this out!" is a cross reference to text 15 with a description that reads "Check this out!", and "T17" is a cross reference without a description. The inherit bit is automatically cleared and the item can always be deleted. `no-comments [4] (text)' When this item is set, the author requests that nobody comments the text. This is advisory only; it is still possible to write comments, but clients should advise the user that this is contrary to the author's wishes. Data should be empty. This item may only be set by the author. The secret, hide-creator and inherit bits are automatically cleared. `personal-comment [5] (text)' When this item is set, the author requests only personal comments. This is advisory only; it is still possible to create regular comments, but clients should advise the user that the author prefers a personal comment. Data should be empty. This item may only be set by the author. The secret, hide-creator and inherit bits are automatically cleared. `request-confirmation [6] (text)' The author requests that everyone who reads the text confirms having done so by creating read-confirmation items on the text. Clients should ask users if they wish to confirm having read the text when it is displayed. Data should be empty. The hide-creator, secret and inherit bits are automatically cleared. `read-confirm [7] (text)' This item can be taken as confirmation that the item creator has read the text to which the item is attached. Clients should never ever create this item without an explicit confirmation from the user that the text has indeed been read. The hide-creator, secret and inherit bits are automatically cleared. Once created an item of this type cannot be deleted. `redirect [8] (conference, letterbox)' This item indicates that texts should not be sent to the conference, but be directed to some other target instead. Clients should notify users that attempt to send texts to the conference of the redirect and offer to send the text to the target of the redirect instead. A typical use of this item would be a user that does not read LysKOM very often and would like to advise other users to send e-mail instead. Data is PROTOCOL:ADDRESS where PROTOCOL is either "E-mail" or "LysKOM", and ADDRESS is either an e-mail address or a LysKOM conference number. Hopefully we'll be able to replace this with a forwarding mechanism later. This item can only be set by the conference supervisor or in the case of a mailbox, the person attached to the mailbox. The hide-creator and secret bits are cleared automatically. Only one redirect can be specified. `x-face [9] (conference, letterbox, server)' Data is the face of the person in compface format. Cool, innit? This item can only be set by the conference supervisor or in the case of a mailbox, the person attached to the mailbox. The hide-creator and secret bits are cleared automatically. `alternate-name [10] (text, conference, letterbox)' Data is a string that the client may use as an alternate to the name of a conference or the subject of a text. Note that the server does not match against this name when performing name lookups. Clients should only display alternate names created by the user currently logged on. The inherit flag is automatically cleared. `pgp-signature [11] (text)' Data is a PGP signature of the text. The signature should be the equivalent of what `pgp -sba' in PGP 2.6.2 generates. The secret, hide-creator and inherit bits are automatically cleared. Signatures cannot be deleted once they have been created. `pgp-public-key [12] (letterbox)' Data is the public key of the person. It is desirable that the public key contains a userid of the format "LysKOM +", where N is the number of the person in the LysKOM server specified in SERVER. This rule is currently not enforced. This item can only be set by the person himself. The hide-creator, secret and inherit bits are automatically cleared. `e-mail-address [13] (conference, letterbox, server)' Data is an RFC 822-style email address. When set on a mailbox, it should be the email address of the person. If the person has multiple email addresses he may set several e-mail-address aux-items. The meaning of this aux-item when set on a conference that isn't a mailbox is vague. For a conference that is used as to import a mailing list this should be the email address of the list. For other conferences we haven't really defined a sensible use. When this aux-item is set on the server it should contain the email address of the administrator (or administrators.) This aux-item can only be set by the supervisor of a conference or the server administrator. The creator cannot be hidden. `faq-text [14] (conference, letterbox, server)' Data is a decimal text number, which is a FAQ for the conference, letterbox or server. Creating an item of this type automatically causes creation of a faq-for-conf item. This item can only be set by the supervisor or server administrator. The hide-creator, secret, and inherit bits are automatically cleared. `creating-software [15] (text)' Data is the name and version number of the client that created the text. This aux-item can only be set by the author of the text. Once set, it cannot be removed or changed. A typical value would be `elisp-client 0.47.3'. Setting the creating-software aux-item is optional. The data should be the client name, a space, and the client version used in the `set-client-version' (*note set-client-version::) call. The server may enforce this restriction. `mx-author [16] (text)' Data is a string containing the name of the author of an imported e-mail, extracted from the `From' header. This aux-item may be missing, if the mail address in the `From' header consists of just the `addr-spec' (see the next aux-item). Clients should display this instead of the actual author of the text (which will be an importer ID) even if an mx-from aux-item is not present. Sample contents: `Joe Q. Public' which may come from a `From' header containing `"Joe Q. Public" '. `mx-from [17] (text)' Data is the proper e-mail address (called `addr-spec' in the mail standards) extracted from the `From' header of an imported e-mail. Clients should display this address together with the `mx-author', preferably inside angles. If `mx-author' is not present, this address should be shown anyway. It can also be used by clients to construct an address for personal (e-mail) replies to an imported message. Sample contents: `john.q.public@example.com' which may come from a `From' header containing `john.q.public@example.com' or something like `"Joe Q. Public" '. `mx-reply-to [18] (text)' Data is the proper e-mail address (called `addr-spec' in the mail standards) extracted from the `Reply-To' header of an imported e-mail. Clients should use this for constructing replies to imported messages. `mx-to [19] (text)' Data is a single e-mail address from an email `To' header. Multiple `mx-to' items may be present when multiple recipients are specified in the header. Clients should display these items along with the normal LysKOM recipient headers. Sample contents: Both `john.q.public@example.com' and `"Joe Q. Public" ' are valid. `mx-cc [20] (text)' Same as `mx-to', but applies to the `CC' header rather than the `To' header. `mx-date [21] (text)' Data is the date and time from the `Date' header of an imported email. Its format is "YYYY-MM-DD hh:mm:ss TZ". YYYY is the year the message was sent, MM is the month, DD is the day, hh is the hour, mm is the minute and ss is the second. This date and time are given in the timezone where the message was sent. TZ is the timezone the date is valid for. It must be of the form "+hhmm" or "-hhmm", where hh is the number of hours offset from UTC and mm is the number of minutes offset. Symbolic timezones are not permitted. The timezone specification is recommended but optional, since it is not always available. Clients should display this information as the date and time a text was written, since the imported text will have been created at a later time. The date and time when the message was imported would then be displayed elsewhere or not at all. `mx-message-id [22] (text)' Data is the `Message-ID' header of an imported e-mail, with whitespace and comments removed. The Message-ID should contain the surrounding angles. `mx-in-reply-to [23] (text)' Data is a string containing one item of the same form as the mx-message-id item described above. This is the Message-ID of another mail the current text is a comment to. Hopefully, this information comes from the `In-Reply-To' header of the imported e-mail, but it could also have been picked from the end of the `References' header line. If the text really comments more than one other text directly, it is allowed to attach more than one `mx-in-reply-to' items to it. `mx-misc [24] (text)' Data is a string that contains all of the headers of an imported email, including `Subject', and including those that are redundantly stored in other aux-items. The headers are concatenated with "\n". In other words, this item contains all headers of an imported e-mail as they appear in the message. Clients are encouraged to provide a command to display this information. `mx-allow-filter [25] (conference, letterbox)' This aux-item has been declared obsolete. It was intended to supply the importer with information on how to filter incoming messages based on regular expressions matching header lines. `mx-reject-forward [26] (conference, letterbox)' This aux-item has been declared obsolete. It was intended to supplement mx-allow-filter by telling where rejected mails should be sent. `notify-comments [27] (letterbox)' Data is a decimal text number that the user is interested in. Clients should monitor this text for unread comments and present these to the user in some convenient manner. This is typically used by users that want to read comments to some text of theirs as soon as they arrive, rather than in the normal reading order. This item can only be set by the owner of the letterbox. No flags are forced or cleared. `faq-for-conf [28] (text)' Data is a decimal number specifying the conference a certain text is a FAQ for. The special number zero denotes that the text is a FAQ for the entire system. Items of this kind can only be created by the LysKOM server itself. Texts with this item are protected from garbage collection. `recommended-conf [29] (server)' Data is a decimal number specifying a conference that new members should automatically be added to, optionally followed by a space and a recommended priority, optionally followed by a space and a membership type. In the future, additional data may be defined; clients should be prepared to accept and ignore a space and any trailing data that may follow the membership type. A few examples might clarify what the data may look like: `1' Conference number 1. `2 32' Conference number 2, with priority 32. `3 250 11100000' Conference number 3, with priority 250. The membership should be secret, passive and have the invitation bit set. `4 253 01000000 garbage' Conference number 4, with priority 253. The membership should be passive. The client should ignore the trailing garbage; it is reserved for future extensions. Note that clients are not allowed to create aux-items of this format, but they should be prepared to handle them correctly. This is a recommendation only; it is up to the client that creates a new person to also add him to the conferences that are specified via `recommended-conf'. `allowed-content-type [30] (conference, letterbox, server)' Data is a non-negative decimal priority number, followed by a space, followed by a LysKOM content type glob pattern. Clients should send texts to a conference only if the content-type matches any of the `allowed-content-type' glob patterns of that conference. If the conference doesn't have any `allowed-content-type', the `allowed-content-type' items of the server should be used. If the server also has no `allowed-content-type' aux-items, it should be interpreted as if a single `allowed-content-type' aux-item with the value `1 text/plain' exists. If there are `allowed-content-type' aux-items with different priority numbers, it is a hint to the client about which content-type is most desirable. Content-types that matches a lower priority number are preferred. As an example, consider a conference with the following four `allowed-content-type' aux-items: 1 text/plain 2 text/x-kom-basic 2 text/enriched 3 text/* These aux-items taken together means that `text/plain' is preferred, that `text/x-kom-basic' and `text/enriched' can be used if there is a reason why `text/plain' is inadequate, and that any text type (such as `text/html') is acceptable. Other content types, such as `x-kom/user-area', should not be used. The server does not currently enforce the above restriction on the content type of new texts. This mechanism is currently a hint to the client (or to the author of a new text). This may change in the future, if experience shows that it is desirable to have the server enforce the content type. `canonical-name [31] (server)' This should be set to the official domain name of the server, optionally followed by a colon and the port number. The port number should only be used if a non-standard port is used. Examples: `kom.lysator.liu.se:8300', `kom.lysator.liu.se'. The intent is that the `canonical-name' should be globally unique among all LysKOM servers. Only a single aux-item of this type can be set on the server. This aux-item can be used by clients that wish to do certain things only when connected to a specific server. `mx-list-name [32] (conference)' This item should only be used if the main purpose of the conference is to import a single external mailing list. The data should be the email address that is used to post to the list, such as `bug-lyskom@lysator.liu.se'. `send-comments-to [33] (letterbox)' Normally, when a comment is created, the LysKOM client adds the author of the commented text to the recipient list if he isn't a member of any of the recipients of the comment. By setting this aux-item on the letterbox, a person can request different treatment. Data is a decimal integer (a conference number) optionally followed by a space character and a decimal number (a recipient type). In the future, additional data may be defined; clients must be prepared to accept and ignore a space and any trailing data that may follow the recipient type. Clients must be prepared to accept items of this type that contain only the conference number. Comments should be sent to the specified conference number instead of to the author. The value `0' is special and means that the comment should not be sent to any special conference, even though that means that the author of the commented text will never see the comment. (The value `0' is useful for mail importers and other similar robots.) The recipient type is the type of recipient to add. If the recipient type is missing, clients should either assume recipient type zero (`recpt') or ask the user. Legal recipient types are `0' for `recpt', `1' for `cc-recpt' and `15' for `bcc-recpt' (these are the values used in `Info-Type'). Additional recipient types may be added in the future. Clients should treat unknown or invalid recipient types as if they were missing (i.e. treat them as zero or ask the user). *Note Recipients of comments::, for more information about how the client should select the conferences that a comment should be sent to. This aux-item can only be set by the supervisor of the person. `world-readable [34] (text)' Texts that has this aux-item set on them can be read by everybody. It is not even necessary to log in. Only the author of the text can set this item. The data must be the empty string. The hide-creator, secret, dont-garb and inherit bits are automatically cleared. `mx-refuse-import [35] (conference, letterbox)' This item tells the importer under what circumstances mail should be imported to the conference or letterbox. If no aux-item of this type is present, there are no limitations on import to this conference or letterbox. If the data is the string `all', the importer will never add this conference or letterbox as a recipient. If the data is the string `spam', the importer will not add this conference or letterbox as a recipient if the mail is considered to be spam according to some importer specific criteria (such as the presence of SpamAssassin flags). If the data is the string `html', the importer will not add this conference or letterbox as a recipient if the mail is considered to be in HTML format. In the future, other alternatives in addition to the above may be defined for this aux-item. An importer should silently ignore unrecognized ones. If more than one aux-item of this type is present, they will be combined in the most restrictive way, i.e. the recipient will not be added if any of the aux-items forbids import. Clients are encouraged to provide commands to manage aux-items of this type for conferences and letterboxes. `mx-mime-belongs-to [10100] (text)' Data is a decimal text number that this text is an attachment to. Most likely, the current text is also a comment (or perhaps a footnote) to the text mentioned in the aux-item. A client can use this aux-item to alter the display format of the text (stating that this is an attachment, not a normal comment). `mx-mime-part-in [10101] (text)' Data is a decimal text number of a text that is an attachment to the current one. In other words: this is the converse of mx-mime-belongs-to. A client can use this aux-item to know which comments to mark as attachments; the remaining comments are assumed to be normal. `mx-mime-misc [10102] (text)' Data is a string that contains all of the MIME headers for the current text. It is set by the importer. The fields are concatenated with "\n". Clients are encouraged to provide a command to display this. `mx-envelope-sender [10103] (text)' Data is the envelope sender of an imported text. The mail server is supposed to pass this information to the importer, for inclusion here. `mx-mime-file-name [10104] (text)' Data is the file name of an attachment. Most likely, the importer gets this information from a `name' parameter on a `Content-Type' MIME header line. Clients are encouraged to use this file name as the default file name when the user chooses to save the text. See also *Note Some Client-specific Aux-Item Types::, for information about some non-standardized aux-item types.  File: protocol-a.info, Node: Name Expansion, Next: LysKOM Content Types, Prev: Aux-Item Types, Up: Top Name Expansion ************** Names in LysKOM can be expanded according to two rules, regexp matching or KOM conventions. Regexp Matching =============== This type of expansion, used by the `re-z-lookup' call and its predecessors(*note re-z-lookup::) simply matches `ed'(1) style regular expressions to names in the database to find the list of matching names. The matching is case sensitive. KOM Conventions =============== This type of matching is a little more complicated. Patterns consist of words and parenthesized expressions, and contain implicit wildcards. The `lyskomd' program implements an approximation of theses conventions. Since `lyskomd' is the trendsetter, these semantics are good enough. The rules are simple. Any parenthesized expressions are removed from the pattern and the names being checked for matches. Then the words of the pattern are examined from beginning to end, and if every pattern word matches the prefix of the corresponding word in the name, the name matches the pattern. For example "L D" matches "LysKOM (client, server and protocol) Discussion (and) Ideas", but not "LysKOM Protocol Discussion". The matching is case insensitive. Character case is converted according to a collate table in the server. The collate table can be retrieved from the server with the `get-collate-table' call(*note get-collate-table::). The current collate table simply maps ISO 8859-1 uppercase and lowercase letters to equivalents, and also considered braces and suchlike equivalent according to swascii rules.  File: protocol-a.info, Node: LysKOM Content Types, Next: The User Area, Prev: Name Expansion, Up: Top LysKOM Content Types ******************** LysKOM defines a few special content types for texts. They are all described in this chapter. In addition to these, clients must support `text/plain', should support `text/enriched' and are encouraged to support `text/html'. Lines are separated by a single linefeed (ASCII 10) character. The linefeed character is used as a line separator, not as a line terminator. In other words, there should be no linefeed after the last line. * Menu: * Reformattable Text (text/x-kom-basic):: * The User Area (x-kom/user-area)::  File: protocol-a.info, Node: Reformattable Text (text/x-kom-basic), Next: The User Area (x-kom/user-area), Up: LysKOM Content Types Reformattable Text ================== This type of content corresponds to the mime type `text/x-kom-basic'. It is raw text that can be reformatted by the client without ill effects, but that can be legibly displayed on a text terminal without formatting. * Lines must be no longer than 70 characters. * Each line, except the last, is terminated by a single linefeed character. * Two linefeed characters in succession signal the end of the paragraph. * There must be no whitespace or linefeeds after the last character. * The end of the last line also signals the end of the paragraph. The following rules apply when reformatting: * The indentation of the first line of a paragraph is to be applied to all lines in the paragraph. * If the first line of a paragraph matches ">+ *" then the string that matched that regexp is to be prefixed to all lines of the paragraph. This content type was previously erroneously called `x-kom/basic', but as far as we know no client ever created texts that were labeled with that name. Please use the new name `text/x-kom-basic' instead. Historical note: version 0.46.1 and earlier of the elisp client created texts labeled with `x-kom/text'. Clients may treat that content type as `text/x-kom-basic' for improved interoperability.  File: protocol-a.info, Node: The User Area (x-kom/user-area), Prev: Reformattable Text (text/x-kom-basic), Up: LysKOM Content Types The User Area ============= This content type indicates that the article contains a user area. *Note The User Area::. lyskom-server-2.1.2/doc/protocol-a.info-80000664000015100472110000013713107723710263013700 This is protocol-a.info, produced by makeinfo version 4.2 from Protocol-A.texi. This is the LysKOM Protocol A specification, edition 11.1. It specifies version 11 of the protocol. It was first distributed with version 2.1.2 of lyskomd. Copyright (C) 1995-2003 Lysator ACS. Permission is granted to make and distribute verbatim copies of this specification provided the copyright notice and this permission notice are preserved on all copies. Modified versions of this document may be redistributed with the added condition that all modifications not cleared with the LysKOM development group are clearly marked and that the entire modified work be redistributed under the same conditions as the original. Permission is granted to copy and distribute translations of this manual into another language under the same conditions as for modified versions. INFO-DIR-SECTION LysKOM START-INFO-DIR-ENTRY * Protocol A: (protocol-a). The LysKOM Protocol A specification. END-INFO-DIR-ENTRY  File: protocol-a.info, Node: The User Area, Next: Membership visibility, Prev: LysKOM Content Types, Up: Top The User Area ************* The user area is a regular text that is used to store client-specific information in the server. Most clients use this to store settings a user has made that are specific to a particular server. There are also provisions to store settings that are shared between clients. The user-area is divided into several sub-blocks. The `common' block is shared by all clients, and its formats and contents are dictated by this protocol specification. Clients may also create one or more other blocks. In normal texts, everything up to the first linefeed is considered to be the subject line. The user area is an exception: it does not contain any subject line. Each block is encoded as a `HOLLERITH' string. A table of contents is also encoded as a `HOLLERITH' string and added first in the user area. There must be at last one space between each string, and there might be spaces at the beginning and/or end of the user-area. Thus, a user-area made up of three blocks will contain four `HOLLERITH'-encoded strings, each separated by at least one space, and maybe with extra spaces at the beginning or end of the text. The table of contents consists of one `HOLLERITH'-encoded string for each block in the user-area. Each string contains the name of the corresponding block. There is at least one space between each string, and there may be spaces before the first string and after the last string. Clients must never create two or more blocks with the same name. This format ensures that clients can copy or read past other clients' blocks without knowing their structure. Example: 13H7Hblock-a 1Hb 4Hasdf 5H hjkl In the above example, there are two blocks: `block-a' and `b'. `block-a' contains four bytes, `asdf', while `b' contains five bytes: ` hjkl' (note the leading space). Below are a few other ways to encode the same user-area: 14H 7Hblock-a 1Hb 4Hasdf 5H hjkl 16H 7Hblock-a 1Hb 4Hasdf 5H hjkl 13H1Hb 7Hblock-a 5H hjkl 4Hasdf The first two examples embed extra (redundant) spaces, and the last swaps the order of the two blocks. The following block names have been defined: `common' The common block shared by all clients. The format of the common block is described below. `elisp' The block created by the Emacs lisp client. The format is completely undocumented, but you'll need a lisp reader to parse it. `WWW-kom' The block created by the web gateway WWW-kom. It has the same syntax as the common block, but the keys and values are not documented. `rkom' Used by Anders Magnusson . If you're writing a client that uses the user-area, please let us know what you name your client's block. The Common Block ================ This defines the structure of the common block. The common block contains a list of variable settings. Each variable setting consists of a name, some whitespace, and a value. Settings are separated by a linefeed character. The values can be of several different types (such as integers, strings, booleans, lists of stuff) but they are all encoded as HOLLERITHs. The reason for this is to simplify for clients that need to ignore the value, and so it is possible to add new value types without confusing old clients. The grammar below defines the syntax of the common block. common-block : settings settings : settings setting | /* empty */ setting : variable ' ' value '\n' variable : [A-Za-z-_0-9]+ value : HOLLERITH The values contain structure within the HOLLERITH. The following grammar defines the data types that are currently used. Clients must be prepared to ignore values that have other data types. boolean : 1 | 0 integer : -?[0-9]+ string-list : string-list ' ' HOLLERITH | HOLLERITH Currently the following variables are used, but more may be added, and clients must cope with variables they know nothing of in the common block. (Doing so is easy, as all values are encoded as HOLLERITHs.) `created-texts-are-read' True if the user wants texts s/he creates to be marked as read automatically. `boolean'. `dashed-lines' True if the user wants dashed lines around the text body when it's displayed. `boolean'. `presence-messages' True if the user wants messages about people logging in and logging out of LysKOM. `boolean'. `print-number-of-unread-on-entrance' True if the user wants to see the number of unread texts when entering a conference. `boolean'. `read-depth-first' True if the user wants to read text in depth-first order. `boolean'. `reading-puts-comments-in-pointers-last' True if the user wants the client to display comment links after the text body. `boolean'. `confirm-multiple-recipients' True if the user wants the client to ask for confirmation before sending a text to many conferences. `boolean'. `default-mark' The default mark to set on marked texts. `integer'. `language' Preferred languages, in priority order. `string-list'. This contains a list of ISO 639 language codes. ISO 639-2 should be used for languages that have a 2-character language code. For other languages, ISO 639-1 should be used. `http://lcweb.loc.gov/standards/iso639-2/langcodes.html' contains a list of the current language codes. The client should configure its user interface to use the first language in the list that it supports. Example: a client that supports English and Swedish would use: * Swedish if the list is `2Hfr 2Hsv 2Hen' * English if the list is `2Hen 2Hsv 2Hfr' * either if the list is `2Hes 2Hfr'  File: protocol-a.info, Node: Membership visibility, Next: Garb, Prev: The User Area, Up: Top Membership visibility ********************* The details of the security model isn't properly documented. Much information can be extracted from various parts of the protocol specification, but there is no complete overview. In time, this chapter may become such an overview. For now, it only defines when a membership is visible. The various requests that return information about a membership can be grouped into three categories: * Category 1: given a conference, list (some of) the members. * `get-members' (*note get-members::) * `get-members-old' (*note get-members-old::) These requests fail if the conference is secret and you don't have access to it, even if a membership should be visible to you according to the rules below. * Category 2: given a person, list (some of) the conferences that the person is a member of. * `get-membership' (*note get-membership::) * `get-membership-10' (*note get-membership-10::) * `get-membership-old' (*note get-membership-old::) * `get-unread-confs' (*note get-unread-confs::) These requests fail if the person is secret and you don't have access to it, even if a membership should be visible to you according to the rules below. * Category 3: given a person and a conference, return the membership. * `query-read-texts' (*note query-read-texts::) * `query-read-texts-10' (*note query-read-texts-10::) * `query-read-texts-old' (*note query-read-texts-old::) These requests follows the rules below exactly. The rules for membership visibility are given below. In the explanation, the variables C, P and V are used like this: * a conference C * a person P who is a member of the conference C * a viewer V who wants to find out about P:s membership in C. The following flags also influences how much V can see: * the `unread-is-secret' flag of P * the `secret' flag of P:s membership in C The following rules determines if a membership is visible to V. The first rule that matches is used. * If V is supervisor of P, then the membership is visible. Both the `unread-is-secret' and `secret' flags are ignored. * If V is supervisor of C, then the membership is visible. The `secret' flag is ignored. The `unread-is-secret' flag is honored. * If V is allowed to see both P and C, and if `secret' is unset, then the membership is visible. The `unread-is-secret' flag is honored. * Otherwise, V is not allowed to se the membership.  File: protocol-a.info, Node: Garb, Next: Measured Properties, Prev: Membership visibility, Up: Top Automatic text removal (the garb) ********************************* Old texts are automatically removed by a process known as "the garb". By default, the garb will remove all texts when it looks at them. There are several things that can save a text from removal: - if the server is configured to never remove any texts. - if text is marked. See `mark-text' (*note mark-text::). - if the text is presentation of a conference. See `set-presentation' (*note set-presentation::). - if the text is message of the day for a conference. See `set-etc-motd' (*note set-etc-motd::). - if the text is message of the day for the system. See `set-motd-of-lyskom' (*note set-motd-of-lyskom::). - if the text is message of the user area of a person. See `set-user-area' (*note set-user-area::). - if the text is less than 24 hours old. - if the text has an aux-item with the `dont-garb' bit set. See *Note Aux-Item-Flags::. - if the text is less than `nice' days old, for any of the recipients. `nice' is part of the `Conference' status. `set-garb-nice' (*note set-garb-nice::). All recipient types, `recpt', `cc-recpt' and `bcc-recpt', counts. If the text was added to the conference after its creation, the check is made against the addition time instead of the creation time. See `set-garb-nice' (*note set-garb-nice::). - if the text was added as a comment or footnote to a text within the last 24 hours. See `add-comment' (*note add-comment::) and `add-footnote' (*note add-footnote::). - for each comment and footnote to the text, the time when it became a comment or a footnote of the text is considered. If it is less than 24 hours, the text is saved. If it is less than the `keep-commented' field of any of the recipients of the text and the comment/footnote, it is saved. All recipient types, `recpt', `cc-recpt' and `bcc-recpt', counts. See `set-keep-commented' (*note set-keep-commented::). Other texts will be removed. It is an implementation detail of the server exactly when texts will be removed.  File: protocol-a.info, Node: Measured Properties, Next: Extracted grammar, Prev: Garb, Up: Top Measured Properties ******************* The server measures a number of properties, and can return information about them to a client via the `get-stats' request(*note get-stats::). A server implementation may include experimental properties, whose name should begin with `X-'. All other properties should be defined in this chapter. Some of the properties that are suggested here might prove to be too hard to measure efficiently, or might prove to expose too much information. In that case, a server may select to not implement them. Clients must be prepared to receive a `feature-disabled' or `undefined-measurement' error if they call `get-stats' with a value that wasn't received from `get-stats-description' (*note get-stats-description::). For each measured value, both the levels and the ascent and descent rates are returned. *Note Stats::, for more information. Ascent and descent rates are always normalized to a number of events per 100 seconds. `run-queue-length' The number of clients that the server is currently refusing to serve since its time for the server to process other clients for a while. `pending-dns' The number of pending DNS requests. `pending-ident' The number of pending IDENT requests. `clients' The number of connected clients. `reqs' The number of Protocol A requests that is being processed. In the current implementation, this will always be a number between 0 and 1, but that might change in the future. `texts' The number of existing texts. `confs' The number of existing conferences (including letterboxes). `persons' The number of existing persons. `send-queue-bytes' `recv-queue-bytes' The number of bytes waiting in the send and receive queues.  File: protocol-a.info, Node: Extracted grammar, Next: Writing Clients, Prev: Measured Properties, Up: Top Extracted grammars (informative) ******************************** The file `Protocol-A.texi' is the authoritative standard for protocol A. However, it has a two problems: * The Texinfo markup makes it hard for a program to extract information-and once a program is written, we might change the Texinfo markup, so that the program has to be updated. * We often rename requests and data types, in order to have good names for the most recommended functions and types. However, a program that uses a data type might fail if that type suddenly is altered. To overcome these problems, and better server client writers that want to generate the protocol-level code automatically from the specification, a few variants of the grammar is available as separate files. In some of these files, the names have been changed to "stable" names that will not change as the protocol evolves. Currently, these three grammars exists: `protocol-a-full.txt' The full Protocol A specification, with stable names. `protocol-a-recommended.txt' The recommended requests and asynchronous messages, and all types they need, with stable names. `protocol-a-current.txt' The recommended requests and asynchronous messages, with the names used in this specification. The files are generated by `doc/checkargs.py' in the lyskom-server distribution. Adding more output formats is fairly easy. Let us know, preferably via Bugzilla, if a new output format would be useful for you. It is the intention that the format of the above-mentioned files will not change. The file format should be self-explanatory once you have read the protocol specification. It does contain some comments that should be useful. The stable names are generated by this process: * Don't modify builtin types such as `INT32'. * Remove the suffixes `-old', `-older' and `-Old', unless that would introduce an ambiguity. * Unless the name already has a version suffix, add one. All files mentioned above are reachable via `http://www.lysator.liu.se/lyskom/protocol/'.  File: protocol-a.info, Node: Writing Clients, Next: Importing and Exporting E-Mail, Prev: Extracted grammar, Up: Top Writing Clients (informative) ***************************** This appendix is not really part of the protocol specification, but it contains some information that may be useful for client writers. * Menu: * Common Commands:: Common commands and how they're implemented. * Client Conventions:: Conventions clients should follow.  File: protocol-a.info, Node: Common Commands, Next: Client Conventions, Up: Writing Clients Common Commands =============== Most clients will implement certain commands. This main purpose of this section is to get client writers started on some of these commands, and to answer some questions that seem to come up over and over again. * Menu: * What do I have unread:: How to figure out which articles to present.  File: protocol-a.info, Node: What do I have unread, Up: Common Commands What do I have unread --------------------- Each person has a membership list containing the conferences the person is a member of. Each element is an object of type `Membership'. Among other things it contains the number of the conference, the priority of the membership, when the person most recently marked a text as read in the conference, and which texts the person has read. The list of read texts consists of two parts: a local text number called `last-text-read' and a list of local text numbers called `read-texts'. The person has marked all texts up to and including `last-text-read' as read, and also the texts listed in `read-texts'. All other texts in the conference are unread. Clients can use either the `query-read-texts' or `get-membership' calls to get membership data. The standard procedure for finding out which texts are unread is the following: 1. Call `get-unread-confs' for the person. This returns a list of conferences in which the person may have unread texts. This call may return conferences that do not contain any unread texts, but it will never forget to return a conference that does contain an unread text. 2. Call `query-read-texts' for each conference returned in the previous step. This will return the membership data for all the conferences that may contain unread texts. 3. Call `get-uconf-stat' for each conference returned in the first step. The conference status will be needed shortly. Repeat the following steps for each conference. 4. Compare the highest existing local number in the conference (from the conference status) with the `last-text-read' field for the corresponding membership. If the highest existing local text is higher than `last-text-read', the conference may contain unread texts. 5. Get part of the local to global map from the conference starting at `last-text-read' and ending at the highest existing local number. Every local number in the map that is not read according to the membership data and that has a mapping to a global number is an unread text. You might say that you remove the read texts from the map to get the unread texts. Take care not to call get-map or get-membership too much since they tend to be expensive operations. Use `get-unread-confs' and `query-read-texts' to minimize the work. Another point to remember is that the server will send asynchronous messages with information about new texts. Clients need to listen to these messages.  File: protocol-a.info, Node: Client Conventions, Prev: Common Commands, Up: Writing Clients Client Conventions ================== There are certain conventions that most clients follow, and that users expect. These are not part of the protocol and are subject to change. In particular those conventions that address deficiencies in the protocol will go away when the protocol is updated to correct these deficiencies. * Menu: * Text formatting:: The format of texts in the database. * Content type specification:: Clients can tag the content type of a text. * Client-side name expansion:: By number, by word, by regexp. * Recipients of comments:: Where comments should be sent. * Order of misc-info groups:: Footnotes, comments, recipients.  File: protocol-a.info, Node: Text formatting, Next: Content type specification, Up: Client Conventions Text formatting --------------- Traditionally the only clients for LysKOM were text-based and only displayed texts exactly as they were stored in the server. Although there are a number of clients now that can wrap lines automatically, texts should still be stored in preformatted style, suitable for display in a monospaced font. If the client accepts texts from the user and then reformats them, such as a client with an editor with a variable-width font, it should ensure that it follows the following simple rules: * Lines should be no longer than 72 characters. * Lines are terminated with a single linefeed character. * Paragraphs are separated by two linefeeds in succession. * There are no empty lines at the end of the text. Clients that include editors but do not alter the text before sending it to the server should attempt to ensure that texts confirm to the above conventions. The same conventions apply to messages sent with the `send-message' call(*note send-message::).  File: protocol-a.info, Node: Content type specification, Next: Client-side name expansion, Prev: Text formatting, Up: Client Conventions Content type specification -------------------------- This convention is understood by all popular clients. If the first line is one of a few predefined strings, then this string specifies the type of text. Currently only the strings "html:" and "enriched:" are supported, specifying `text/html' and `text/enriched' respectively. Starting with protocol version 10, this ugly workaround is obsolete. Use aux-items to specify content type instead.  File: protocol-a.info, Node: Client-side name expansion, Next: Recipients of comments, Prev: Content type specification, Up: Client Conventions Client-side name expansion -------------------------- When a client needs to prompt the user for a conference (or person), it could offer the user several ways of specifying the conference: * By conference number * By name, using the `lookup-z-name' call(*note lookup-z-name::). * By name, using the `re-z-lookup' call(*note re-z-lookup::). * By name, transforming the string to a case insensitive regular expression, and then using the `re-z-lookup' call. It is beyond the scope of this document to specify how the client interacts with the user. The client should offer the user all the methods of specifying a conference listed above. At the very least, the two first methods should be supported.  File: protocol-a.info, Node: Recipients of comments, Next: Order of misc-info groups, Prev: Client-side name expansion, Up: Client Conventions Recipients of comments ---------------------- When a user writes a comment, the user should have full control over which conferences and/or letterboxes the comment is sent to. By default, the recipient list should be all `recpt' recipients. `cc-recpt' and `bcc-recpt' recipients should not be included. Conferences in the recipient list that have the `original' bit set, and a non-zero `super-conf', should be replaced by the `super-conf'. If the author of the commented text isn't a member of any of the new recipients, the client should check if the author has a `send-comments-to' aux item. If it is `0', nothing should be done. Otherwise, `send-comments-to' should be a valid conference number, and that conference should be added as a `recpt' recipient. If there is no `send-comments-to' aux-item, the user should be prompted to add the author of the commented text as a `recpt' or `cc-recpt' recipient. If the author of the new comment is not a member of any of the recipients, the client should check if the author has a `send-comments-to' aux item. If it is `0' nothing should be done. Otherwise, `send-comments-to' should be a valid conference number, and the user should be prompted to add that conference as a `recpt' or `cc-recpt' recipient. If there is no `send-comments-to', or `send-comments-to' is invalid, the user should be prompted to add his letterbox as a `recpt' or `cc-recpt' recipient. If a recipient is present more than once, all duplicates should be removed.  File: protocol-a.info, Node: Order of misc-info groups, Prev: Recipients of comments, Up: Client Conventions Order of misc-info groups ------------------------- The ordering of the groups of `Misc-Info' items are not defined by this protocol. However, when creating a new text, clients are recommended to use this order: * any `footn-to' items * any `comm-to' items * any `recpt' items * any `cc-recpt' items * any `bcc-recpt' items This is the order that the elisp-client normally uses, and users have come to expect that order.  File: protocol-a.info, Node: Importing and Exporting E-Mail, Next: Some Client-specific Aux-Item Types, Prev: Writing Clients, Up: Top Importing and Exporting E-Mail (informative) ******************************************** E-mail import has been implemented using various programs since the first LysKOM server became operational. Protocol version 10 introduces a lot of aux-items, a large part of which are intended for use by mail importers to enhance the functionality. As of this moment, there is one mail importer (`komimportmail') that is designed to take full advantage of all the new aux-items. E-mail export has never been used seriously. The first person to design and implement an exporter gets to rewrite this appendix based on his or her experiences. Importing e-mail ================ The main job of the mail importer is to figure out where to deliver mail, how to handle MIME coding and/or structure and how to deal with threading. During this, it creates one or more texts and a lot of aux-items. Recipients ---------- Although a mail message contains `To' and `CC' headers, they are not really useful when importing as it is the envelope recipients, not the header recipients, that should be used. To understand this, consider a mail where the `To' header contains a personal mail address. The mail is received using a tool like `procmail' and forwarded to the LysKOM importer. The envelope address will be correct, but the `To' header will still contain the personal address. The `komimportmail' importer uses addresses like "NUMBER@SERVER", where NUMBER is the number of the recipient and SERVER is the mail domain reserved for the LysKOM importer. For backwards compatibility with earlier importers, it is allowed to prepend a "p" before the number. Instead of the number, `komimportmail' can accept a name, as long as the name can be resolved to exactly one conference or letterbox. Before looking up the name, any underscore or period is translated into a space. Care should be taken when a mail is received more than once. This can happen if a mail is addressed to more than one address. For example, assume that a mail is sent to `john.q.public@example.com' and `sven.svensson@exempel.se'. Two different mail servers handle the two recipients, but both eventually decide to forward the mail to the LysKOM importer (but for different conferences). The LysKOM importer will receive the mail twice, with different envelope recipients. A solution is to keep a database containing a mapping from `Message-ID' to LysKOM text number for imported messages. If a message is seen more than once, the message is not imported. Instead, recipients are added to the existing text. On the other hand, that will introduce a security hole, where a person who knows the `Message-ID' of an interesting imported mail can add himself or some open conference as a recipient. Perhaps the importer should check for matching contents before adding recipients. The importer needs to be careful not to deliver messages to conferences that do not allow messages, even though the server might not complain. For mail delivery to work for any conference, the importer has to use a privileged person, or it will be unable to deliver mail to secret conferences. A potential problem is that this leaks secret information from the server. For the time being, the `komimportmail' importer avoids this problem by using an unprivileged person and requiring the members of secret conferences to invite the importer if they want e-mail import to work. Threading --------- The importer should do its best to thread messages. When the importer sees a new message it needs to look at the `In-Reply-To' header to see what the message is a reply to. If the `In-Reply-To' header does not exist, or if it exists but does not contain a valid Message-ID, the last valid Message-ID of a `References' header may be used instead. If the Message-ID of a previously imported e-mail is found, the new text should be made a comment of the replied-to text. If the Message-ID is of the form defined below (*note Message-ID::), and it refers to a text exported from this server, the new text should be made a comment of the replied-to text. This means that the importer will probably have to maintain its own database of imported texts that maps the message ID to the text number in the LysKOM database. There is no other way to find the text number for a particular imported text. Fortunately, this is exactly the same database we need to solve the multiple reception problem described above. It has been noted that messages on some mailing lists arrive in peculiar order, with replies before the original messages. Perhaps this is due to moderation. A smart importer should be prepared to handle this, by adding a comment link when the original message eventually arrives. One possible solution is to add a new kind of entry to the Message-ID database, mapping a Message-ID to a list of text numbers that should become comments to the message when it is imported. MIME issues ----------- An importer should try to handle e-mail messages containing MIME appendices as smart as possible. As the current LysKOM model lacks hierarchical structuring inside articles, appendices should probably be imported as comments or footnotes to the main message. One would think that it is easy to convert the hierarchical MIME structure to a corresponding LysKOM comment tree. However, this would require creating empty interior nodes to attach some comments to. Therefore, the `komimportmail' importer currently uses a rather naive algorithm: All leaf parts are found. The first one gets to be the main text, and the rest are included as comments to it. Appendices encoded with Base64 or Quoted-Printable should be decoded. When creating aux-items like `mx-author', text coded using the method in RFC 2047 should be decoded. Exporting e-mail ================ As of this writing, an experimental e-mail exporter exists, but it is a fairly recent creation. The author of this document knows very little about how it works, so this section contains very little information. Message-ID ---------- A standard for Message-ID creation has been established. The general format is: TEXT-NO.PORT.EXPORTER.RANDOMNESS@SERVER The different parts are explained below: TEXT-NO The text number of the text that was exported. PORT SERVER The `canonical-name' aux item defines a unique name for the LysKOM system that the text was exported from. The SERVER and PORT fields are set from it. If no port is specified in the `canonical-name', the PORT part is set to the empty string. EXPORTER The name of the software that exported the text. RANDOMNESS A string that ensures that the Message-ID is unique even if the same text is exported several times. This could contain a random string, a sequence number, or something else that makes the Message-ID unique.  File: protocol-a.info, Node: Some Client-specific Aux-Item Types, Next: Future changes, Prev: Importing and Exporting E-Mail, Up: Top Some Client-specific Aux-Item Types (informative) ************************************************* This appendix contains some contributed information from client writers about some of the aux-item types that they use. This information may be updated at any time by the client writers. How much the client writer cares about backward compatibility when they make changes to these aux-item types may be beyond the control of the authors of the Protocol A specification. If any of the aux-item types defined here becomes widely used by different clients, they should probably be standardized and moved to the *Note Aux-Item Types:: chapter. `elisp-client-read-faq [10000] (letterbox)' This item indicates FAQs that the user has read. Data is a decimal number indicating the conference for which a FAQ has been read, followed by a space character and a second decimal number indicating the text number of the FAQ. In the future, additional data may be defined; clients should be prepared to accept and ignore a space and any trailing data that may follow the second number. Note that aux-items of this type should always be secret since they may contain information about texts of conferences that are not publicly visible. A few examples might clarify what the data may look like: `459 11215' FAQ in text 11215 for conference 459 has been read. `459 11215 garbage' FAQ in text 11215 has been read. Clients must ignore the trailing garbage. Note that clients are not allowed to create aux-items of this format, but they should be prepared to handle them correctly. This aux-item is specific to the elisp client. Other clients are not required to use or understand this item type. `elisp-client-rejected-recommendation [10001] (letterbox)' This item indicates a rejected membership recommendation. Data is a decimal number indicating the conference for which the recommendation was rejected. In the future, additional data may be defined; clients should be prepared to accept and ignore a space and any trailing data that may follow the second number. Note that aux-items of this type should always be secret since future extensions may contain sensitive data. A few examples might clarify what the data may look like: `459' A recommendation for conference 459 has been rejected. `459 garbage' A recommendation for conference 459 has been rejected. Clients must ignore the trailing garbage. Note that clients are not allowed to create aux-items of this format, but they should be prepared to handle them correctly. This aux-item is specific to the elisp client. Other clients are not required to use or understand this item type.  File: protocol-a.info, Node: Future changes, Next: Protocol Version History, Prev: Some Client-specific Aux-Item Types, Up: Top Future changes (speculative) **************************** While useful and stable, this protocol is far from perfect. Here is a short list of things the current developers would like to change in future versions of the protocol. The list is not sorted. All changes will be made in a backwards compatible way. Clients will still be able to use the old requests. * Cryptography! LysKOM is sometimes used for sensitive information. It is unacceptable that everything is sent in the clear. Should we use TLS? This area needs further study. (This is bug 133 (http://bugzilla.lysator.liu.se/show_bug.cgi?id=133).) * The information contained in the `Misc-Info' array should be integrated into the `Text-Stat'. There should be one array of recipients, one of texts that comments this text, and so on. This would make the `Misc-Info' type obsolete. (This is bug 134 (http://bugzilla.lysator.liu.se/show_bug.cgi?id=134).) * The aux-items can be very large. It was a mistake to include them in the `Text-Stat'. They should probably be separated from the `Text-Stat'; retrieving the `Text-Stat' should only indicate which aux-items that exists. (This is bug 135 (http://bugzilla.lysator.liu.se/show_bug.cgi?id=135).) * The super conference is used for two purposes: to indicate where followups of original conferences should be sent, and to indicate where articles created by persons that are not permitted submitters should be sent. Occasionally one wants to send followups to one conference and unauthorized original articles to another conference. One way to fix this is to remove the `original' bit and introduce a `followups-to' field in the `Conference'. Doing this in a backwards-compatible way requires some thought... (This is bug 136 (http://bugzilla.lysator.liu.se/show_bug.cgi?id=136).) * The security system is too complex, yet unable to do many useful things, and should be rethought. (This is bug 137 (http://bugzilla.lysator.liu.se/show_bug.cgi?id=137).) * If the client issues several request without waiting for a reply, the replies will nevertheless always arrive in the same order as the requests were sent in. If a threaded version of the LysKOM server is ever made, it could possibly process two requests from the same client at the same time, and the answers could be returned in any order. However, the current clients are probably not written so that they can handle such reordering. In the future, a new call might be added, so that a client can give the server explicit permission to reorder the replies. The client would then have to rely on the `ref-no' to match each reply to the corresponding call. (This is bug 138 (http://bugzilla.lysator.liu.se/show_bug.cgi?id=138).) For more information about potential future changes, see Bugzilla @ Lysator (http://bugzilla.lysator.liu.se/). The above list is in no way complete.  File: protocol-a.info, Node: Protocol Version History, Next: Document Edition History, Prev: Future changes, Up: Top Protocol Version History (informative) ************************************** Protocol version 11 (first implemented in lyskomd 2.1.0) ======================================================== New Server Calls These new calls have status Recommended. * 107=query-read-texts * 108=get-membership * 109=mark-as-unread * 110=set-read-ranges * 111=get-stats-description * 112=get-stats * 113=get-boottime-info * 114=first-unused-conf-no * 115=first-unused-text-no * 116=find-next-conf-no * 117=find-previous-conf-no * 120=set-connection-time-format * 121=local-to-global-reverse * 122=map-created-texts-reverse These new calls have status Experimental. * 118=get-scheduling * 119=set-scheduling Status change The following calls have change status from Experimental to Recommended. * 105=set-keep-commented The following calls have changed status from Recommended or Experimental to Obsolete. * 98=query-read-texts-10 * 99=get-membership-10 New and Modified Types * Read-Range * Membership * Membership-Type * Stats * Stats-Description * Static-Server-Info * FLOAT New Asynchronous Messages * 19=async-new-user-area * 20=async-new-presentation * 21=async-new-motd * 22=async-text-aux-changed New aux-items *Note Document Edition History::, as new aux-items are added between protocol versions. New error codes *Note Document Edition History::. Notes * The `reserved1' bit of `Membership-Type' has been renamed to `passive-message-invert'. *Note Membership Information::. This affects `async-send-message' (*note async-send-message::) and `send-message' (*note send-message::). * The following requests can no longer be used until you have logged in: `get-last-text' (*note get-last-text::), `find-next-text-no' (*note find-next-text-no::) and `find-previous-text-no' (*note find-previous-text-no::). * You can now modify the type of a recipient with the `add-recipient' (*note add-recipient::) call if you are the supervisor of either the author, recipient or sender. The check used to be more restrictive. * The following asynchronous messages are also sent to recipients of texts linked to the relevant text via comment or footnote links: `async-new-text-old' (*note async-new-text-old::), `async-deleted-text' (*note async-deleted-text::), `async-new-text' (*note async-new-text::), `async-new-recipient' (*note async-new-recipient::) and `async-sub-recipient' (*note async-sub-recipient::). * All requests that take a `BOOL' argument now return the error `bad-bool' if the argument is anything but `0' or `1'. Protocol version 10 (first implemented in lyskomd 2.0.0) ======================================================== Error codes The error codes are now documented. Several error codes were changed to more sane values while documenting the new behavior. New Server Calls These new calls have status Recommended. * 85=get-collate-table * 86=create-text * 87=create-anonymous-text * 88=create-conf * 89=create-person * 90=get-text-stat * 91=get-conf-stat * 92=modify-text-info * 93=modify-conf-info * 94=get-info * 95=modify-system-info * 96=query-predefined-aux-items * 98=query-read-texts * 99=get-membership * 100=add-member * 101=get-members * 102=set-membership-type * 103=local-to-global * 104=map-created-texts * 106=set-pers-flags These new calls have status Experimental. * 97=set-expire * 105=set-keep-commented Name changes Old name New name 5=create-person 5=create-person-old 9=query-read-texts 9=query-read-texts-old 10=create-conf 10=create-conf-old 13=get-conf-stat-old 13=get-conf-stat-older 14=add-member 14=add-member-old 26=get-text-stat 26=get-text-stat-old 28=create-text 28=create-text-old 36=get-info 36=get-info-old 46=get-membership 46=get-membership-old 48=get-members 48=get-members-old 50=get-conf-stat 50=get-conf-stat-old 59=create-anonymous-text 59=create-anonymous-text-old Status change The following calls have change status from Experimental to Recommended. * 58=get-last-text * 77=set-last-read * 78=get-uconf-stat The following calls have changed status from Recommended or Experimental to Obsolete. * 5=create-person-old * 9=query-read-texts-old * 10=create-conf-old * 14=add-member-old * 26=get-text-stat-old * 28=create-text-old * 36=get-info-old * 46=get-membership-old * 47=get-created-texts * 48=get-members-old * 50=get-conf-stat-old * 59=create-anonymous-text-old New and Modified Structures * Aux-Item * Aux-Item-Input * Conference * Info * Member * Membership * Membership-Type * Misc-Info * Text-Stat Renamed Asynchronous Messages A `async-' prefix has been added to the name of all asynchronous messages. In addition, 0=new-text has been renamed to 0=async-new-text-old, and it is now considered obsolete. Clients should use 80=accept-async to listen to 15=async-new-text instead. New Asynchronous Messages * 14=async-deleted-text * 15=async-new-text * 16=async-new-recipient * 17=async-sub-recipient * 18=async-new-membership Notes * Since protocol version 9 setting a priority of zero for a conference was supposed to indicate passive membership in a conference. It was largely up to the client to implement this. True passive memberships have been introduced in this protocol version through the Membership-type extension to the Membership type. In order to maintain compatibility with clients that interpret priority 0 as passive membership, the old calls `add-member-old' (*note add-member-old::) and `get-membership-old' (*note get-membership-old::) perform magic, translating between priorities and membership types. The magic is documented with each call. Protocol version 9 (first implemented in lyskomd 1.9.0) ======================================================= New functionality * The server shall now reply with error `not-implemented' when a client attempts to use an unimplemented call. This feature requires that the client uses linefeed as call terminator. Added Commands * 79=set-info: Can change server information. * 80=accept-async: Can select asynchronous messages to receive. * 81=query-async: Can query which messages are being send. * 82=user-active * 83=who-is-on-dynamic * 84=get-static-session-info Changed names * `change-conference' was previously called `pepsi'. The name was changed, but not the functionality. Status change * 63=`who-is-on-ident' is now considered obsolete. * 64=`get-session-info-ident' is now considered obsolete. Protocol version 8 (first implemented in lyskomd 1.8.0) ======================================================= Added Functionality * 30=add-recipient: Can change `recpt' to `cc-recpt' and vice versa. * 21=set-conf-type: Accepts `Conf-Type' and `Extended-Conf-Type'. * 10=create-conf: Accepts `Conf-Type' and `Extended-Conf-Type'. New Commands * 77=set-last-read * 78=get-uconf-stat Protocol version 7 (first implemented in lyskomd 1.7.0) ======================================================= Added Functionality * 53=send-message: Recipient can be a conference or a person. New Commands * 74=re-z-lookup * 75=get-version-info * 76=lookup-z-name Other * The asynchronous message 1=i-am-off has been removed Protocol Version 6 (first implemented in lyskomd 1.4.0) ======================================================= New Calls * 67=lookup-person * 68=lookup-conf * 69=set-client-version * 70=get-client-name * 71=get-client-version * 72=mark-text * 73=unmark-text Protocol Version 5 (first implemented in lyskomd 1.3.0) ======================================================= New Calls * 65=re-lookup-person * 66=re-lookup-conf Protocol Version 4 (first implemented in lyskomd 1.1.1) ======================================================= New Calls * 62=login * 63=who-is-on-ident * 64=get-session-info-ident Protocol Version 3 (first implemented in lyskomd 1.1.0) ======================================================= New Calls * 61=find-previous-text-no * 60=find-next-text-no * 59=create-anonymous-text * 58=get-last-text Protocol Version 2 (first implemented in lyskomd 0.30.0) ======================================================== New Calls * 57=set-user-area Protocol Version 1 (first implemented in lyskomd 0.29.2) ======================================================== New Calls All calls from 0-56. lyskom-server-2.1.2/doc/protocol-a.info-90000664000015100472110000006662707723710263013714 This is protocol-a.info, produced by makeinfo version 4.2 from Protocol-A.texi. This is the LysKOM Protocol A specification, edition 11.1. It specifies version 11 of the protocol. It was first distributed with version 2.1.2 of lyskomd. Copyright (C) 1995-2003 Lysator ACS. Permission is granted to make and distribute verbatim copies of this specification provided the copyright notice and this permission notice are preserved on all copies. Modified versions of this document may be redistributed with the added condition that all modifications not cleared with the LysKOM development group are clearly marked and that the entire modified work be redistributed under the same conditions as the original. Permission is granted to copy and distribute translations of this manual into another language under the same conditions as for modified versions. INFO-DIR-SECTION LysKOM START-INFO-DIR-ENTRY * Protocol A: (protocol-a). The LysKOM Protocol A specification. END-INFO-DIR-ENTRY  File: protocol-a.info, Node: Document Edition History, Next: Index, Prev: Protocol Version History, Up: Top Document Edition History (informative) ************************************** 11.1: 2003-08-30 _Modified aux-item:_ `mx-refuse-import' [35] now supports the value `html'. *Note Aux-Item Types::. _Previously undocumented stuff:_ *Note Garb::, for information about how the garb works. _New appendix:_ *Note Extracted grammar::, for information about machine-readable grammars extracted from this specification. _Typographic improvements:_ The section heading of all asynchronous messages now contains the async number. _Fixed errors:_ In the info manual, the status codes in the menus of request and asynchronous messages were set to `r' instead of `O' for `who-is-on-ident', `get-session-info-ident' and `async-new-text-old'. Several section headings for obsolete requests was missing information about when the request became obsolete. Distributed with lyskomd 2.1.2. 11.0: 2003-08-24 _New aux-items:_ `mx-refuse-import' [35]. *Note Aux-Item Types::. _New types:_ `Read-Range' and `Membership' (the old `Membership' was renamed to `Membership-10'). *Note Membership Information::. `Stats' and `Stats-Description'. *Note Statistics::. `Static-Server-Info'. *Note Server Information::. `FLOAT'. *Note Simple Data Types::. _Status change:_ The `query-read-texts-10' (*note query-read-texts-10::) and `get-membership-10' (*note get-membership-10::) requests are now obsolete. The `set-keep-commented' (*note set-keep-commented::) request is now recommended. _New calls:_ * `query-read-texts' (*note query-read-texts::) * `get-membership' (*note get-membership::) * `mark-as-unread' (*note mark-as-unread::) * `set-read-ranges' (*note set-read-ranges::) * `get-stats-description' (*note get-stats-description::) * `get-stats' (*note get-stats::) * `get-boottime-info' (*note get-boottime-info::) * `first-unused-conf-no' (*note first-unused-conf-no::) * `first-unused-text-no' (*note first-unused-text-no::) * `find-next-conf-no' (*note find-next-conf-no::) * `find-previous-conf-no' (*note find-previous-conf-no::) * `get-scheduling' (*note get-scheduling::) * `set-scheduling' (*note set-scheduling::) * `set-connection-time-format' (*note set-connection-time-format::) * `local-to-global-reverse' (*note local-to-global-reverse::) * `map-created-texts-reverse' (*note map-created-texts-reverse::) _New error codes:_ `invalid-range', `invalid-range-list', `priority-denied', `weight-denied', `weight-zero', `undefined-measurement' and `bad-bool'. _New async messages:_ * `async-new-user-area' (*note async-new-user-area::) * `async-new-presentation' (*note async-new-presentation::) * `async-new-motd' (*note async-new-motd::) * `async-text-aux-changed' (*note async-text-aux-changed::) _Protocol change:_ Renamed the `reserved1' bit of `Membership-Type' to `passive-message-invert'. *Note Membership Information::. This affects `async-send-message' (*note async-send-message::) and `send-message' (*note send-message::). The following requests can no longer be used until you have logged in: `get-last-text' (*note get-last-text::), `find-next-text-no' (*note find-next-text-no::) and `find-previous-text-no' (*note find-previous-text-no::). You can now modify the type of a recipient with the `add-recipient' (*note add-recipient::) call if you are the supervisor of either the author, recipient or sender. The check used to be more restrictive. Aux-item tags 10200-10299 are now reserved for private test use. *Note Client-Specific Aux-Item Types::. The following asynchronous messages are also sent to recipients of texts linked to the relevant text via comment or footnote links: `async-new-text-old' (*note async-new-text-old::), `async-deleted-text' (*note async-deleted-text::), `async-new-text' (*note async-new-text::), `async-new-recipient' (*note async-new-recipient::) and `async-sub-recipient' (*note async-sub-recipient::). Two requests can now return more error codes than they used to: `add-comment' (*note add-comment::) `already-comment' and `already-footnote'. `add-footnote' (*note add-footnote::) `already-comment'. The field `later-texts-exists' in `Text-Mapping' has been renamed to `more-texts-exists', as this name is more meaningful for the new requests `local-to-global-reverse' (*note local-to-global-reverse::) and `map-created-texts-reverse' (*note map-created-texts-reverse::). _Fixed errors:_ The description of the error `index-out-of-range' was wrong for `add-footnote' (*note add-footnote::),missing for `create-person-old' (*note create-person-old::), `create-person' (*note create-person::), `create-conf-old' (*note create-conf-old::), `create-conf' (*note create-conf::) and `create-text-old' (*note create-text-old::), and incomplete for `create-text' (*note create-text::). `async-leave-conf' (*note async-leave-conf::) is not sent when the person is deleted, so don't say that it is. Distributed with lyskomd 2.1.0. 10.7: 2002-11-03 _Fixed errors:_ The description of common block of the user area was just plain wrong. *Note The User Area::, for the updated specification. The documentation for no-of-created-texts in the `Person' structure was wrong. *Note Person::. The documentation for the privilege bits `create-conf' and `create-pers' stated that they are by default on. In fact, they are by default ignored, but off. *Note Security::. The example for `re-z-lookup' (*note re-z-lookup::) was wrong. An example for `lookup-z-name' (*note lookup-z-name::) was wrong. _Protocol change:_ Added a new "language" value to the common block of the user area. *Note The User Area::. _New aux-items:_ `world-readable' [34]. *Note Aux-Item Types::. `elisp-client-read-faq' [10000] and `elisp-client-rejected-recommendation' [10001]. *Note Some Client-specific Aux-Item Types::. _Modified aux-item:_ `send-comments-to' [33] may now also contain an optional recipient type. *Note Aux-Item Types::. _Previously undocumented stuff:_ The rules for when a membership is visible are now documented. *Note Membership visibility::. Documented the `unread-is-secret' flag of `Person'. *Note Personal-Flags::. The documentation for `get-person-stat-old' was improved(*note get-person-stat-old::). The Message-ID of exported texts is now documented. *Note Message-ID::. A client should offer to add the author as a recipient of a text he is creating if he isn't a member of any of the recipients. *Note Recipients of comments::. There should be no linefeed after the last line of a text. *Note LysKOM Content Types::. *Note Reformattable Text (text/x-kom-basic)::. Added a recommendation for how groups of `Misc-Info' items should be sorted. *Note Order of misc-info groups::. _Editorial changes:_ Several spelling errors, typos, et c were fixed. Distributed with lyskomd 2.0.7. 10.6: 2002-03-29 _Fixed errors:_ The format of the user area was plain wrong. The examples for `query-read-texts-10' and `get-membership-10' were wrong. The `idle-time' field is only affected by the `user-active' request, not by all activity (*note Session Information::). _Protocol change:_ Expanded the documentation of `super-conf'. *Note Conference Status Types::. Simplified the rules for `super-conf'; a setting of 0 no longer means anything. A new section contains a summary of how a client should decide where to send a comment, and it contains the new rules. *Note Recipients of comments::. Most clients already implemented the new rules; the old rules were overly complex. _New aux-item:_ `send-comments-to' [33]. _Modified aux-item:_ `faq-text' [14] may now be set on a letterbox. _Previously undocumented stuff:_ Expanded the documentation of `permitted-submitters'. *Note set-permitted-submitters::. Clarify that a person is a supervisor of himself, except for the `set-supervisor' call; see *Note Conferences::. Document the `change-name' privilege bit; see *Note Security::. Document that `last-login' is also updated on logout; see *Note Person Status Types::. Clarify that the address part of `redirect' [8] is a conference number. _Compatibility info:_ Mention that the elisp client used to enter texts as `x-kom/text' instead of `text/x-kom-basic'. _Administrativia:_ Updated "Future changes" (*note Future changes::), and mention that we now use Bugzilla to keep track of bugs and feature requests. _Editorial changes:_ Added some of Texinfo markup and cross references. Several spelling errors, typos, et c were fixed. Distributed with lyskomd 2.0.6. 10.5: 2001-09-30 A new section (*note Client-side name expansion::) in the informative Client Conventions appendix was written. Distributed with lyskomd 2.0.5. 10.4: 2001-05-24 _Fixed errors:_ Fixed the description of the `old-pwd' argument to `set-passwd' (*note set-passwd::). The content-type `x-kom/basic' was renamed to `text/x-kom-basic'. _Previously undocumented stuff:_ Documented several previously undocumented aspects of the protocol: the hello string used during connection establishment, the `items-to-delete' and `items-to-add' arguments of `modify-system-info', the `type' argument of `add-member' (including the fact that the invitation membership flag is automatically set in some circumstances), that a client can issue many requests at once (and that the replies are sent back in order). _New stuff:_ Registered the "rkom" user-area block. _New aux-items:_ The following predefined aux-items were added: `canonical-name' [31], `mx-list-name' [32] `mx-mime-belongs-to' [10100], `mx-mime-part-in' [10101], `mx-mime-misc' [10102], `mx-envelope-sender' [10103] and `mx-mime-file-name' [10104]. Those aux-items with a number higher than 10000 were previously documented in this document, but they now have the status of predefined aux-items. _Editorial changes:_ Lots of editorial changes needed to publish an online version on the web at `http://www.lysator.liu.se/lyskom/protocol/'. Many minor syntax errors corrected, and much missing Texinfo markup added. The document now makes heavy use of Texinfo macros. Due to bugs in the current version of `texinfo.tex' this file cannot currently be typeset using TeX. (All bugs are reported to the Texinfo maintainers.) `get-membership-old', `get-membership-10' and `login' used to take an argument of type `BITSTRING(A-SINGLE-FIELD)'. The type has now been changed to `BOOL' instead, to simplify the description. The encoding of the protocol is unchanged. The indices are now joined into a single index. More terms have been added to it. Many sections of text were moved around to make it easier to find information. Some non-normative information was moved to appendices. Removed a few non-normative empty sections. This edition was published on the web; no lyskomd release was imminent when the edition was finished. Future editions will also be published on the web; most of them will likely be published at the same time as a lyskomd release is made. They will continue to be included in the lyskomd releases. 10.3: 2000-09-09 Several aux-items can be set on letterboxes and not only conferences. A few can now be set on the server. The `allowed-content-type' and `recommended-conf' aux-items were added. The `mx-allow-filter' and `mx-reject-forward' aux-items are marked obsolete. Text regarding mail import was improved, based on actual experience in writing an email importer. Reserved a range of aux-items for komimportmail. Several minor corrections and clarifications made. Distributed with lyskomd 2.0.4. 10.2: 1999-07-23 Some typos and other minor errors were fixed. Distributed with lyskomd 2.0.2. 10.1: 1999-07-12 Call `sub-comment' was incorrectly marked obsolete. This has been corrected. Regexps are case sensitive. The Info-Type enumeration was introduced in the description of the protocol. (Previous versions of the protocol had broken definitions of `add-recipient', `async-new-recipient' and `async-sub-recipient'.) Distributed with lyskomd 2.0.1. 10.0: 1999-06-27 The specification was translated to English and converted to Texinfo by David Byers. Protocol version 10. Distributed with lyskomd 2.0.0. Note: this edition incorrectly marked the `sub-comment' call as obsolete, and stated that regexp lookup was case insensitive. Both statements were wrong, and has since been fixed. 9.0: 1996-08-04 Protocol version 9. Distributed with lyskomd 1.9.0. 8.0: 1995-11-10 Protocol version 8. Distributed with lyskomd 1.8.0. 7.1: 1995-01-08. Protocol and document revision history were added by Per Cederqvist. Outline mode was used to make the document more manageable. This version was distributed with lyskomd 1.7.1. 7.0: 1994-12-31. The first specification with a version number. All calls that had been added since 1991-06-25 were documented. Pell and Per Cederqvist did the deed. This version was distributed with lyskomd 1.7.0. 1993-05-19. Linus Tolke wrote comments for some calls that were without comments. 1992-07-06. Linus Tolke converted the document to ISO 8859-1. 1991-08-12. Per Cederqvist started using version control for documentation. 1991-06-25. Lars Aronsson documented the protocol that was in use at the time.  File: protocol-a.info, Node: Index, Prev: Document Edition History, Up: Top Index ***** * Menu: * accept-async: accept-async. * add-comment: add-comment. * add-footnote: add-footnote. * add-member: add-member. * add-member-old: add-member-old. * add-recipient: add-recipient. * Any-Conf-Type: Conference Types. * ARRAY: Simple Data Types. * async-broadcast: async-broadcast. * async-deleted-text: async-deleted-text. * async-i-am-off: async-i-am-off. * async-i-am-on: async-i-am-on. * async-i-am-on-obsolete: async-i-am-on-obsolete. * async-leave-conf: async-leave-conf. * async-login: async-login. * async-logout: async-logout. * async-new-membership: async-new-membership. * async-new-motd: async-new-motd. * async-new-name: async-new-name. * async-new-presentation: async-new-presentation. * async-new-recipient: async-new-recipient. * async-new-text: async-new-text. * async-new-text-old: async-new-text-old. * async-new-user-area: async-new-user-area. * async-rejected-connection: async-rejected-connection. * async-send-message: async-send-message. * async-sub-recipient: async-sub-recipient. * async-sync-db: async-sync-db. * async-text-aux-changed: async-text-aux-changed. * Aux-Item: Auxiliary Information. * Aux-Item-Flags: Auxiliary Information. * Aux-Item-Input: Auxiliary Information. * Aux-No: Auxiliary Information. * BITSTRING: Simple Data Types. * BOOL: Simple Data Types. * broadcast: broadcast. * change-conference: change-conference. * change-name: change-name. * change-what-i-am-doing: change-what-i-am-doing. * character set: Simple Data Types. * Conf-List-Archaic: Archaic way to list conferences. * Conf-No: Common Types. * Conf-Type: Conference Types. * Conf-Z-Info: Conference Search Results. * Conference: Conference Status Types. * Conference-Old: Conference Status Types. * create-anonymous-text: create-anonymous-text. * create-anonymous-text-old: create-anonymous-text-old. * create-conf: create-conf. * create-conf-old: create-conf-old. * create-person: create-person. * create-person-old: create-person-old. * create-text: create-text. * create-text-old: create-text-old. * delete-conf: delete-conf. * delete-text: delete-text. * disconnect: disconnect. * Dynamic-Session-Info: Session Information. * enable: enable. * ENUMERATION: Simple Data Types. * Extended-Conf-Type: Conference Types. * find-next-conf-no: find-next-conf-no. * find-next-text-no: find-next-text-no. * find-previous-conf-no: find-previous-conf-no. * find-previous-text-no: find-previous-text-no. * first-unused-conf-no: first-unused-conf-no. * first-unused-text-no: first-unused-text-no. * FLOAT: Simple Data Types. * Garb-Nice: Conference Status Types. * get-boottime-info: get-boottime-info. * get-client-name: get-client-name. * get-client-version: get-client-version. * get-collate-table: get-collate-table. * get-conf-stat: get-conf-stat. * get-conf-stat-old: get-conf-stat-old. * get-conf-stat-older: get-conf-stat-older. * get-created-texts: get-created-texts. * get-info: get-info. * get-info-old: get-info-old. * get-last-text: get-last-text. * get-map: get-map. * get-marks: get-marks. * get-members: get-members. * get-members-old: get-members-old. * get-membership: get-membership. * get-membership-10: get-membership-10. * get-membership-old: get-membership-old. * get-person-stat: get-person-stat. * get-person-stat-old: get-person-stat-old. * get-scheduling: get-scheduling. * get-session-info: get-session-info. * get-session-info-ident: get-session-info-ident. * get-static-session-info: get-static-session-info. * get-stats: get-stats. * get-stats-description: get-stats-description. * get-text: get-text. * get-text-stat: get-text-stat. * get-text-stat-old: get-text-stat-old. * get-time: get-time. * get-uconf-stat: get-uconf-stat. * get-unread-confs: get-unread-confs. * get-version-info: get-version-info. * HOLLERITH: Simple Data Types. * Info: Server Information. * Info-Old: Server Information. * Info-Type: Article Information. * INT16: Simple Data Types. * INT32: Simple Data Types. * INT8: Simple Data Types. * Local-Text-No: Common Types. * local-to-global: local-to-global. * Local-To-Global-Block: Mapping Local to Global Text Numbers. * local-to-global-reverse: local-to-global-reverse. * login: login. * login-old: login-old. * logout: logout. * lookup-conf: lookup-conf. * lookup-name: lookup-name. * lookup-person: lookup-person. * lookup-z-name: lookup-z-name. * map-created-texts: map-created-texts. * map-created-texts-reverse: map-created-texts-reverse. * Mark: Article Marks. * mark-as-read: mark-as-read. * mark-as-unread: mark-as-unread. * mark-text: mark-text. * mark-text-old: mark-text-old. * Member: Membership Information. * Membership: Membership Information. * Membership-10: Membership Information. * Membership-Old: Membership Information. * Membership-Type: Membership Information. * Misc-Info: Article Information. * modify-conf-info: modify-conf-info. * modify-system-info: modify-system-info. * modify-text-info: modify-text-info. * Pers-No: Common Types. * Person: Person Status Types. * Personal-Flags: Person Status Types. * Priv-Bits: Person Status Types. * query-async: query-async. * query-predefined-aux-items: query-predefined-aux-items. * query-read-texts: query-read-texts. * query-read-texts-10: query-read-texts-10. * query-read-texts-old: query-read-texts-old. * re-lookup-conf: re-lookup-conf. * re-lookup-person: re-lookup-person. * re-z-lookup: re-z-lookup. * Read-Range: Membership Information. * RPC: Simple Data Types. * Scheduling-Info: Session Information. * SELECTION: Simple Data Types. * send-message: send-message. * Session-Flags: Session Information. * Session-Info: Session Information. * Session-Info-Ident: Session Information. * Session-No: Common Types. * set-client-version: set-client-version. * set-conf-type: set-conf-type. * set-connection-time-format: set-connection-time-format. * set-etc-motd: set-etc-motd. * set-expire: set-expire. * set-garb-nice: set-garb-nice. * set-info: set-info. * set-keep-commented: set-keep-commented. * set-last-read: set-last-read. * set-membership-type: set-membership-type. * set-motd-of-lyskom: set-motd-of-lyskom. * set-passwd: set-passwd. * set-permitted-submitters: set-permitted-submitters. * set-pers-flags: set-pers-flags. * set-presentation: set-presentation. * set-priv-bits: set-priv-bits. * set-read-ranges: set-read-ranges. * set-scheduling: set-scheduling. * set-super-conf: set-super-conf. * set-supervisor: set-supervisor. * set-unread: set-unread. * set-user-area: set-user-area. * shutdown-kom: shutdown-kom. * Static-Server-Info: Server Information. * Static-Session-Info: Session Information. * Stats: Statistics. * Stats-Description: Statistics. * sub-comment: sub-comment. * sub-footnote: sub-footnote. * sub-member: sub-member. * sub-recipient: sub-recipient. * sync-kom: sync-kom. * Text-List: Common Types. * Text-Mapping: Mapping Local to Global Text Numbers. * Text-No: Common Types. * Text-Number-Pair: Mapping Local to Global Text Numbers. * Text-Stat: Article Information. * Text-Stat-Old: Article Information. * Time: Common Types. * UConference: Conference Status Types. * Unicode: Simple Data Types. * unmark-text: unmark-text. * user-active: user-active. * Version-Info: Server Information. * who-am-i: who-am-i. * Who-Info: Who Information. * Who-Info-Ident: Who Information. * Who-Info-Old: Who Information. * who-is-on: who-is-on. * who-is-on-dynamic: who-is-on-dynamic. * who-is-on-ident: who-is-on-ident. * who-is-on-old: who-is-on-old. lyskom-server-2.1.2/doc/lyskomd.info0000664000015100472110000000521507723710263013133 This is lyskomd.info, produced by makeinfo version 4.2 from lyskomd.texi. This is the reference manual for the lyskomd LysKOM server version 2.1.2. Copyright (C) 1995-2003 Lysator ACS. Permission is granted to make and distribute verbatim copies of this specification provided the copyright notice and this permission notice are preserved on all copies. INFO-DIR-SECTION LysKOM START-INFO-DIR-ENTRY * lyskomd: (lyskomd). lyskomd reference manual. END-INFO-DIR-ENTRY  Indirect: lyskomd.info-1: 495 lyskomd.info-2: 50186 lyskomd.info-3: 98025  Tag Table: (Indirect) Node: Top495 Node: Copying1426 Node: Overview1704 Ref: Overview-Footnote-12933 Ref: Overview-Footnote-23029 Node: Installation3078 Node: Configuration3405 Node: Server Configuration File3843 Node: Parameter Types4588 Node: Parameters6705 Ref: Parameters-Footnote-129832 Node: Aux-Item Definition File29941 Node: Running lyskomd37221 Node: Invoking lyskomd37661 Node: Signals38518 Node: Files39658 Node: Invoking updateLysKOM41944 Node: Invoking komrunning42717 Node: Administration43823 Node: Bugs47211 Node: DBCK Reference47586 Node: DBCK Overview48097 Node: Invoking dbck48677 Node: General Options49415 Node: Database Repair Options50186 Node: Format Conversion Options50916 Node: Database Maintenance Options52107 Node: Reporting Options54021 Node: DBCK Notes54538 Node: DBCK Files54939 Node: DBCK Bugs55863 Node: splitkomdb56081 Node: splitkomdb basics56717 Node: Invoking splitkomdb57912 Node: splitkomdb example58781 Node: splitkomdb restore59432 Node: Hacking60910 Node: The Database61713 Node: Adding Configuration Parameters61951 Node: Adding Asynchronous Messages62697 Node: Function Templates for prot-a-send-async.c64573 Node: Function Templates for send-async.c65321 Node: Adding a New Protocol Request67601 Node: Adding New Input Types71316 Node: Adding New Result Types72564 Node: Modifying Output Types73201 Node: Adding Aux-Item Types75260 Node: Modifying Stored Types76623 Node: Template for ram-output.c78180 Node: Template for ram-parse.c79632 Node: Notes81194 Node: Parsing Bit Fields81682 Node: Membership Notes83204 Node: Linking Pairs of Aux Items83506 Node: Notes for fncdef.txt85043 Node: Traversing Connections86857 Node: Debugging and Testing88016 Node: The Test Suite88534 Node: Configuration Options89758 Node: Coverage Testing91536 Node: Debug Calls92477 Node: memory-info93081 Node: set-marks93922 Node: backdate-text94450 Node: local-to-global94957 Node: Coding conventions95396 Node: lyskomd Database Specification97478 Node: Version 098025 Node: Version 1100272 Node: Version 2102573  End Tag Table lyskom-server-2.1.2/doc/lyskomd.info-10000664000015100472110000014201207723710263013266 This is lyskomd.info, produced by makeinfo version 4.2 from lyskomd.texi. This is the reference manual for the lyskomd LysKOM server version 2.1.2. Copyright (C) 1995-2003 Lysator ACS. Permission is granted to make and distribute verbatim copies of this specification provided the copyright notice and this permission notice are preserved on all copies. INFO-DIR-SECTION LysKOM START-INFO-DIR-ENTRY * lyskomd: (lyskomd). lyskomd reference manual. END-INFO-DIR-ENTRY  File: lyskomd.info, Node: Top, Next: Copying, Up: (dir) lyskomd ******* lyskomd is a server for the LysKOM conferencing system. This info file documents version 2.1.2 of lyskomd. * Menu: * Copying:: lyskomd is free software. * Overview:: Overview of LysKOM. * Installation:: How to install lyskomd. * Configuration:: How to configure lyskomd. * Running lyskomd:: How to run lyskomd. * Invoking updateLysKOM:: How to run updateLysKOM. * Invoking komrunning:: How to run komrunning. * Administration:: Administering a LysKOM server. * Bugs:: Known bugs in lyskomd. * DBCK Reference:: Checking and repairing the database. * splitkomdb:: How to backup the database. * Hacking:: Notes for server developers. * lyskomd Database Specification::  File: lyskomd.info, Node: Copying, Next: Overview, Prev: Top, Up: Top Copying ******* lyskomd is free software. It is distributed under the Gnu General Public License version 2. The file COPYING in the top level of the distribution contains the text of the license.  File: lyskomd.info, Node: Overview, Next: Installation, Prev: Copying, Up: Top Overview ******** LysKOM is a conferencing system(1). Similar systems were QZ-KOM and PortaCOM(2). The LysKOM system is copyrighted by Lysator Academic Computing Society and distributed under conditions of the GNU General Public License version 2. LysKOM and its documentation is provided "as is" without warranty of any kind. This reference manual documents version 2.1.2 of the lyskomd LysKOM server. The lyskomd server is the work of several people. The main contributors have been Per Cederqvist , Inge Wallin , Thomas Bellman , David Byers and Peter Eriksson . History ======= In 1990, Per Cederqvist and Peter Eriksson and a few other persons started to write the server. It was operational in the summer of 1990, even though the members of Lysator discovered a thing called MUD. We started using RCS on 20 May 1991. The first release was made on 16 Sept 1991. Around that time we switched from RCS to CVS to handle our source code. ---------- Footnotes ---------- (1) Or in modern terms, enabling technology for Computer-Supported Cooperative Work (CSCW). (2) Also known as "PottaKOM" and "BortaKOM".  File: lyskomd.info, Node: Installation, Next: Configuration, Prev: Overview, Up: Top Installation ************ Instructions for compiling and installing lyskomd are in the files `README' and `INSTALL', located in the top level of the lyskomd distribution. Installation should be straightforward on most platforms.  File: lyskomd.info, Node: Configuration, Next: Running lyskomd, Prev: Installation, Up: Top Configuration ************* There are two configuration files for lyskomd. One defines the server options and the other defines aux-item types *Note The Aux-Item List: (protocol-a)The Aux-Item List. * Menu: * Server Configuration File:: The server configuration file. * Aux-Item Definition File:: The aux-item definition file.  File: lyskomd.info, Node: Server Configuration File, Next: Aux-Item Definition File, Up: Configuration Server Configuration File ========================= The server reads its configuration from a configuration file. The default configuration file is `/usr/lyskom/etc/config'. The location of the configuration file can be changed at run-time by supplying an argument to lyskomd. The configuration file is line oriented. Each line consists of a parameter name followed by a colon, and the value of the parameter. Empty lines and lines whose first non-blank character is a `#' are ignored. * Menu: * Parameter Types:: Types of configuration parameters. * Parameters:: Valid configuration parameters.  File: lyskomd.info, Node: Parameter Types, Next: Parameters, Up: Server Configuration File Parameter Types --------------- Every parameter has a type. The standard types are: `bool' The parameter can be true or false. Legal values are `on', `true', `yes' and `1' for true and `off', `false', `no' and `0' for false. `locale-name' The parameter is a locale name. The value must be a legal locale name of the system where lyskomd is running. `path' The parameter is a path name. The value must be a legal path on the system where lyskomd is running. Most paths you can specify can be either absolute paths (if they begin with a `/') or paths relative to the installation prefix which is specified at compile time and can be overridden by the `Prefix:' parameter in the configuration file. `portname' The parameter is a TCP/IP port. It can be a symbolic port name (traditionally looked up in `/etc/services') or a port number. `int' The parameter is a number of some sort. It can be a conference number, text number or perhaps something else. `double' The parameter is a floating point number. Any syntax that the C function `strtod' accepts is OK. Examples of truly portable values: `1' or `1.3'. `timeval' The parameter is a time period. It consists of a floating point number (in the same format as for parameters of type `double'), optionally followed by optional whitespace and a suffix. If no suffix is specified, it defaults to the suffix mentioned in the description of the parameter. Valid suffixes includes: * seconds * second * sec * s * minutes * minute * min * hours * hour * h * days * day * d * milliseconds * millisecond * m * microseconds * microsecond * u A few parameters have ad-hoc types, that are used for a single parameter. They are documented in the description of that parameter.  File: lyskomd.info, Node: Parameters, Prev: Parameter Types, Up: Server Configuration File Parameters ---------- `Max conferences: INT' The maximum number of conferences possible in the server. This number must be larger than the number of conferences in the database. This parameter is required. There is no default. `Max texts: INT' The maximum number of texts possible in the server. This number must be larger than the number of texts in the database. This parameter is required. There is no default. `Locale: STRING' Use STRING as the locale to run in. This parameter is only available om systems which support the `setlocale' call. If this parameter is not set, no call to `setlocale' will be made. The default is unset. `Force ISO 8859-1: BOOL' This option is provided for those with dysfunctional computers that cannot handle `setlocale' properly. If this is set, lyskomd will handle texts according to the ISO 8859-1 (latin1) alphabet. Default is off. `Prefix: PATH' Specify the installation prefix. All relative filenames that the server uses are interpreted relative to this directory. The default value of this parameter is set at compile time. The default is `/usr/lyskom', but it can be changed by the `--prefix' argument of `configure' at compile time. `Send async: BOOL' Do not send any non-requested messages. This disables the sending of messages about events in the server to all connections. Use of this parameter is not recommended. Default is on. `Client host: HOSTNAME' Specify which IP number the server should use when listening for new clients. HOSTNAME may be a FQDN (such as `kom.lysator.liu.se') or an IP number (such as `10.0.0.1'). Default is to bind `INADDR_ANY', which means that the server will listen to all IP numbers of the computer it is running on. `Client port: PORTNAME' Listen for new clients on port PORTNAME. The default is 4894, which is what all clients expect. Do not change this parameter without really good reason. `Presentation of conferences: INT' The number of the conference where presentations should be sent. Defaults to 1. This option is ignored in lyskomd 1.9 and later. Set this using dbck or the *Note set-info: (protocol-a)set-info. `Presentation of persons: INT' The number of the conference where presentations should be sent. Defaults to 2. This option is ignored in lyskomd 1.9 and later. Set this using dbck or the *Note set-info: (protocol-a)set-info. `Motd-conference: INT' The number of the conference where "message-of-the-day" messages should be sent. Defaults to 3. This option is ignored in lyskomd 1.9 and later. Set this using dbck or the *Note set-info: (protocol-a)set-info. `News-conference: INT' The number of the conference where news of interest to the readers of this LysKOM server should be written. This is typically a conference with very low traffic which everyone shoule be a member of. Clients should offer new users to join it. Defaults to 4. This option is ignored in lyskomd 1.9 and later. Set this using dbck or the *Note set-info: (protocol-a)set-info. `Message of the day: INT' Default message-of-the-day of this server. The text will be shown automatically by conforming LysKOM clients when a user logs on. This option is ignored in lyskomd 1.9 and later. Set this using dbck or the *Note set-info: (protocol-a)set-info. `Garb: BOOL' Should the database be automatically purged of old texts? The default is on. `Never save: BOOL' Completely disables saving the database. Do not set this to `true' unless you really know what you're doing. The default is `false'. `Log accesses: PATH' This parameter can only be set if the server has been compiled with `LOGACCESSES' defined. It will save a trace of all activity in the database to a file, for later use in simulations et c. Compiling with `LOGACCESSES' slows the server down quite a lot, so it is normally not defined. `Data file: PATH' The path relative to the installation prefix(1) where part of the database is kept. The default is `var/lyskomd/db/lyskomd-data'. `Backup file: PATH' The path relative to the installation prefix where a backup of the database is kept. This file will always contain a complete database, but it may be a little out-of-date. Default is `var/lyskomd/db/lyskomd-backup'. `Backup file 2: PATH' The path relative to the installation prefix where a previous generation of the backup of the database is kept. This file may be needed if an error in the backup file is detected during the creation of the data file. Default is `var/lyskomd/db/lyskomd-backup-prev'. `Lock file: PATH' Name of the lock file that ensures that `dbck' and `lyskomd' never attempt to modify the database at the same time. It should always reside in the same directory as the `Data file'. Default is `var/lyskomd/db/lyskomd-lock'. `Text file: PATH' The path relative to the installation prefix where the actual texts in the database are kept. Default is `var/lyskomd/db/lyskomd-texts'. `Text backup file: PATH' When `dbck' is run with the `-g' option (*Note Invoking dbck::, it will store the previous contents of the text file in the file specified by this option. The path is relative to the installation prefix. This file is never used by `lyskomd' itself. Default is `var/lyskomd/db/lyskomd-texts-backup'. `Backup export directory: PATH' When `splitkomdb' is run, it will create a copy of the database in this directory. The copy will be split in a way that helps to keep incremental backups of that directory small. *Note splitkomdb::. The path is relative to the directory specified by `Prefix:'. This directory is never used by `lyskomd' itself. Default is `var/lyskomd/exportdb'. `Number file: PATH' `Number temp file: PATH' Name of the file where the first unused conference and text numbers are stored. This file contains a single line. It is rewritten each time a new conference or text is created, to ensure that numbers are never reused even if the server later crashes before it has time to save the database. The information is first written to `Number temp file:', and then renamed to `Number file:'. The path is relative to the installation prefix. Default is `var/lyskomd/db/number.txt' and `var/lyskomd/db/number.tmp', respectively. Both files must reside on the same partition. `Log file: PATH' The path relative to the installation prefix where log messages from lyskomd are written. Default is `var/lyskomd.log'. `Log statistics: PATH' Whenever lyskomd receives a SIGUSR1 it will append a timestamp and a count of how many different atomic calls have been made in this file. The path is relative to the installation prefix. Default is `var/lyskomd.stats'. `Pid file: PATH' When lyskomd is up and running it will write its pid in this file. The path is relative to the installation prefix. This file is used so the `updateLysKOM' script can easily find out what pid the LysKOM server has. Default is `var/run/lyskomd.pid'. This file should be removed when the computer reboots, before `komrunning' or `updateLysKOM' is run. `Memory usage file: PATH' When lyskomd exits normally it appends some info on its usage of memory to this file. The path is relative to the installation prefix. Almost any memory leak bugs should be detectable by looking in this file. Default is `var/lyskomd.memory'. `Aux-item definition file: PATH' This file defines which aux-items the server should support and how it should handle them. You will find the details in *Note Aux-Item Definition File::. The path is relative to the installation prefix. Default is `etc/aux-items.conf'. This file is re-read if a `SIGWINCH' singal is sent to the server. Warning: If the aux-item definition file contains an error so that it cannot be parsed, the server will call `restart_kom()', which will cause the server to abort without saving the database. Always test the file on a standby system first! `Core directory: PATH' The Directory where core dumps are written. This path is relative to the installation prefix. Default is `var/lyskomd.cores'. `Connection status file: PATH' `Connection status temp file: PATH' Where to store a status file that contains information about all connections. The status is written to the temp file and atomically renamed to the status file. The path is relative to the installation prefix. Defaults are `var/lyskomd.clients' and `var/lyskomd.clnt.tmp'. Both files must reside on the same file system. *Note Files::, for information about the file format. `Status file: PATH' This file is created by `komrunning' to indicate that lyskomd should currently not be running. When this file exists `updateLysKOM' will send it a `SIGTERM' signal, so that it saves the database and dies. Default is `var/lyskomd/db/status'. `Nologin file: PATH' If this file exists, the server will not allow any connections at all. Default is `/etc/nologin'. `Garb busy postponement: TIMEVAL' How often should the garb run when the server is busy serving clients? Default is once every `50 milliseconds'. `Garb timeout: TIMEVAL' How long to sleep when the server is garbage-collecting texts, and has nothing else important to do. Default is `0 milliseconds'. `Sync timeout: TIMEVAL' How long to sleep when lyskomd is saving its database. Defaults to `0 milliseconds'. `Permissive sync: BOOL' Turning this option on lets any session sync the LysKOM database. Turning it off restricts the operation to LysKOM administrators. Default is off. `Garb interval: TIMEVAL' How long to wait between each garb sweep. Defaults to `1440 minutes', which means that 24 hours will pass between each garb sweep. `Sync interval: TIMEVAL' How long to wait between syncs. The current version of lyskomd keeps changes to the database in memory until they are synced to disk. This parameter specifies how long the server waits before attempting to dump the database. The default is `5 minutes'. `Sync retry interval: TIMEVAL' If anything goes wrong while trying to dump the data base (such as if the disk is full), lyskomd will wait for this long before trying again. Default is `1 minute'. `Saved items per call: INT' When the server is saving the database, it does so in the background. It serves one call from a client, saves a few items to the new database file, serves another call, et c. This parameter sets the number of items (texts, conferences, persons) that are saved after each call. Default is `5'. `Penalty per call: INT' Penalty points given to a client once a call is completed. This affects the scheduling. Default is `10'. `Penalty per read: INT' Penalty points given to a client each time a `read(2)' is performed on the socket connected to the client. This affects the scheduling. Default is `1'. `Max penalty: INT' Once a client receives this many penalty points, the server will stop reading from the socket connected to the client. (Once the server becomes idle, all penalty points will be aged, so the server will soon start reading from it again.) Default is `100'. `Low penalty: INT' Once the penalty points for a client is reduced below this setting, the server will start reading from the client again. This should be lower than `Max penalty'. Default is `20'. `Default priority: INT' `Max priority: INT' The default and max scheduling priority of a client. Both values must currently be set to `0', which is the default. `Default weight: INT' `Max weight: INT' The default and max scheduling weight for a client. Defaults to `20' and `100'. `Connect timeout: TIMEVAL' If the client doesn't send the initial handshake (such as `A27Hceder@stanly.lysator.liu.se') within this time period, the client will be disconnected. Default is `30 seconds'. `Login timeout: TIMEVAL' `Active timeout: TIMEVAL' If nothing is sent to the client for this long, the client will be disconnected. Both asynchronous messages and replies to requests from the clients will reset the timer. The `Login timout:' value is used while nobody is logged in on the session. Default is `30 minutes' and `11.5 days', respectively. `Max client data length: INT' The maxiumum allowed length for client name and version data. The default is `60'. `Max conference name length: INT' The maximum length of conference names. The default is `60'. `Max password length: INT' Only the first eight characters of the password are currently significant, even if this number is much larger. The default is `128'. `Max what am I doing length: INT' The maximum length of the string permitted in the protocol A call *Note change-what-i-am-doing: (protocol-a)change-what-i-am-doing. The default is 60. `Max username length: INT' The maximum length permitted for user names. Default is 128. `Max text length: INT' The maximum length allowed for a text. The default is 131072 characters. `Max aux_item length: INT' The maximum length allowed for a single aux-item. The default is 16384 characters. `Max broadcast length: INT' The maximum length allowed for broadcast messges. The default is 1024 characters. `Max regexp length: INT' The maximum length allowed for regexps in various calls. The default is 1024 characters. `Statistic name length: INT' The maximum lenght allowed for the name of a measured statistics. The default is 64 characters. `Max marks per person: INT' The maximum number of marks a person is allowed to have. The default is 2048. `Max marks per text: INT' The maximum number of marks a text can have. The default is 1024. `Max recipients per text: INT' The maximum number of recipients of a text. The default is 512. `Max comments per text: INT' The maximum number of comments a text can have. The default is 128. `Max footnotes per text: INT' The maximum number of footnotes a text can have. The default is 32. `Max links per text: INT' The maximum number of misc info items that can be added to a text. `Max mark_as_read chunks: INT' `Max super_conf loop: INT' `Max accept_async len: INT' Maximum length of list accepted in the accept_async call. Default is 128. `Max aux_items deleted per call: INT' Maximum number of aux_items that can be deleted in one call. Default is 128. `Max aux_items added per call: INT' Maximum number of aux_items that can be added at once. Default is 128. `Max read_ranges per call: INT' Maximum number of read_ranges that can sent in a single request. Default is 512. `Default garb nice: INT' Each conference has a lifetime for texts written in it. The lifetime is counted in days, and can be set for each conference by the administrator of the conference. This is the default value assigned to new conferences. Default is 77 days. `Default keep commented nice: INT' A text will not be removed if it has comments newer than a certain number of days. This number can be set for each conference. This parameter specifies the default value for that number of days. The default is 77. `Max client message size' The maximum number of bytes that is read or written in a single system call. Defaults to 8176. (Attempts to set it to a larger value will currently only affect the input.) `Max client transmit queue messages: INT' `Max client transmit queue bytes: INT' Max number of pending data blocks (or total number of bytes) in the reply queue to a client. If there is ever more than this many data blocks in the queue the client will be disconnected. Each atomic question typically generates two data blocks. Default is 50 and 100000, respectively. `Stale timeout: TIMEVAL' If the transmit queue of a client is full for this long, without the server being able to send anything to the client, the client will be disconnected. Default is 60 minutes. `Max simultaneous client replies: INT' This is a performance tuning parameter of little real interest. Default is 10. `Open files: INT' Try to persuade the operating system to allow lyskomd to have this many open file descriptors simultaneously. Each client that is connected to the server occupies one file descriptor, and lyskomd needs several file descriptors for internal purposes. Default is to not use this parameter. `Use DNS: BOOL' The IP address of a client is looked up using DNS when it connects. Unfortunately, this lookup blocks the entire server, and it can take several minutes. You can disable DNS lookup with this parameter. Default is on. `DNS log threshold: DOUBLE' If the `Use DNS:' parameter is true, the server will measure the time each DNS lookup takes. If the time exceeds the specified threshold, an entry will be made in the log. The value is specified in seconds. The default value is 1.5 seconds. If your libc supports it, you can enter `+inf' to disable logging. `Anyone can create new persons: BOOL' If this is set, anyone can create a new person, even if he lacks special bits for doing so. Default is on. `Anyone can create new conferences: BOOL' If this is set, anyone can create a new conferences, even if he lacks special bits for doing so. Default is on. `Allow creation of persons before login: BOOL' If this is set, persons can connect the the server and create a new person without logging in. This is how new users register in open environments. If this option is off, then new persons can only be created by existing users. The default is on. `Default change name capability: BOOL' If this is set, new users are created with the ability to change their own name. Default is on. `Ident-authentication: POLICY' Decide how strictly the server should use the IDENT protocol. The policy can take any of three values: `off' or `never' Do not use the IDENT protocol. `on' or `try' Use it, but allow logins even if the lookup fails. `require' or `required' Disallow connections if the server cannot find a IDENT login name. `Log login: BOOL' Should logins be logged to the log file? Default value is off. `Cache conference limit: INT' How many conference statuses the server cache should hold in main memory. Default is 20. This parameter should be set to at least the number of expected simultaneous logins. `Cache person limit: INT' How many person statuses the server cache should hold in main memory. Default is 20. This parameter should be set to at least the number of expected simultaneous logins. `Cache text_stat limit: INT' How many text statuses the server cache should hold in main memory. The default is 20. This parameter should be increased on busy servers. `Echo: STRING' Write STRING in the log when the config file is read. `Jubel: PERS_NO TEXT_NO' `Jubel: public PERS_NO TEXT_NO' States that PERS_NO is not allowed to create text number TEXT_NO. Default is unset. This parameter may be used multiple times. The form with the string `public' means that the text must have a public conference as recipient. `Jubel: PERS_NO DIVIDEND REMAINDER' `Jubel: public PERS_NO DIVIDEND REMAINDER' States that PERS_NO is not allowed to create any text number T which meets the condition T % DIVIDEND == REMAINDER. Default is unset. This parameter may be used multiple times. The form with the string `public' means that the text must have a public conference as recipient. `Add members by invitation: BOOL' If this is set, then adding others as members to a conference sets the invitation bit of the membership. If this is off, the membership bit is set to whatever the caller specifies. The default is on. `Allow secret memberships: BOOL' If this is set, then memberships may be secret. Otherwise any attempt to create a secret membership or change an existing membership to a secret membership will fail. The default is on. `Allow reinvitations: BOOL' If this is set, then it is possible to set the invitation bit of a membership even after it has been cleared. If it is not set, then the invitation bit of a conference type can only be set when the membership is created. It can be cleared at any time. The default is off. `lyskomd path: PATH' Path to the `lyskomd' binary. This is used by `updateLysKOM' to find the right program to run. Defaults to `sbin/lyskomd'. `savecore path: PATH' Path to the `savecore-lyskom' program. If a file named `core' exists in the directory specified with `Core directory' when `updateLysKOM' is about to start `lyskomd', this program will be called first. It could, for instance, move the core file so that it is available for later debugging. The script supplied by the distribution does nothing. Defaults to `sbin/savecore-lyskom'. `Normal shutdown time: INT' In a normal setup, `updateLysKOM' will be run from `cron' once every ten minutes or so. If it detects that it has taken `lyskomd' more than INT minutes to shut down it will print a warning message. `Mail after downtime: INT' `Mail until downtime: INT' If `lyskomd' has been down for X minutes, where `Mail after downtime' <= X < `Mail until downtime', `updateLysKOM' will send a mail message to the mail address found on the first line of the status file. Actually, it is the age of the status file (named with `Status file') that is measured. The defaults are 60 and 120, respectively. `sendmail path: PATH' Path to the `sendmail'-compatible program that `updateLysKOM' should use to send mail. This program will be invoked with a `-t' option via a `popen()' call. It should accept an email header, a blank line, an email body, and a terminating line consisting of a single `.' on standard input. The default is found at configure time. The special value `:' means that no mail will ever be sent. ---------- Footnotes ---------- (1) The installation prefix can be specified at compile time, and overridden by the `Prefix:' parameter.  File: lyskomd.info, Node: Aux-Item Definition File, Prev: Server Configuration File, Up: Configuration Aux-Item Definition File ======================== The default aux-item definition file should not be changed unless it is really necessary. The need to change the definitions will probably only arise at installations used for client or server development. The location of the aux-item definition file is specified by the `Aux-item definition file' option in the server configuration file. The default location is `/usr/lyskom/etc/aux-items.conf'. Syntax of the Aux-Item Definition File -------------------------------------- The aux-item definition file contains a sequence of aux-item definitions. Each definition specifies one type of predefined aux-item: its number, name, and properties. Empty lines and all characters from a # character to the end of the line are ignored. Each entry has the following format: tag : name (target, target, ... ) { field = value; field = value; ... } TAG is an integer, the aux-item's tag. If a tag is defined more than once, the last definition is used. The TARGETs specify what kind of objects aux-items with tag TAG can be added to. Valid targets are: `any' Aux-items with the specified tag can be added to any object in the database. This is shorthand for `text,conference,letterbox,server'. `text' Aux-items with the specified tag can be added to texts. `conference' Aux-items with the specified tag can be added to conferences that are _not_ letterboxes. `letterbox' Aux-items with the specified tag can be added to conferences that are letterboxes. `server' Aux-items with the specified tag can be added to the server itself. It is legal to add one of the keywords `create' or `modify' before any target except `server'. If `create' is specified, aux-items with the specified tag can only be added when an object is being created. They cannot be added later. If `modify' is specified, aux-items with the specified tag can only be added after an object has been created. They cannot be added when the object is being created. Each FIELD/VALUE pair specifies a property of aux-items with the specified tag. Most values are boolean or trillian. Legal values for either type are `true' and `false'. Boolean values have reasonable defaults; trillian values can be unset. `author-only' Boolean, default false. When true, only the author of a text or supervisor of a conference can create items with this tag. This has no effect on items placed on the system. `supervisor-only' Boolean, default false. When true, only the supervisors of the author or letterbox can create items with this tag. In all likelihood, the implementation of this flag is screwed up in version 2.0 of lyskomd. This has no effect on items placed on the system. `system-only' Boolean, default false. When true, only the server can initiate creation of items with this tag. This is normally used for items that are created automatically in response to events in the system. `permanent' Boolean, default false. When true, aux-items with this tag cannot be deleted once they have been created. (They will be deleted automatically when the object they are assigned to is deleted.) `unique' Boolean, default false. When true, there can only be one non-deleted item with this tag per creator. `unique-data' Boolean, default false. When true, there can only be one non-deleted item with this tag that contains the same data (regardless of who creates the item). `owner-delete' Boolean, default false. When true, the owner of the object that this aux-item is attached to can always delete the aux-item. For a text, the owner is defined as the supervisor(s) of the author of the text. For a conference, the owner is defined as the supervisor(s) of the conference. `inherit-limit' Integer, default 0. The maximum number of times items with this tag can be inherited, plus one. Zero means an unlimited number of times, one means no times, 2 means once and so forth. This number overrides the inherit-limit set by the client only if that number is higher than this one. `inherit' Trillian. When set, the inherit bit on new items with this tag is forced to the specified value. `secret' Trillian. When set, the secret bit on new items with this tag is forced to the specified value. `hide-creator' Trillian. When set, the hide-creator bit on new items with this tag is forced to the specified value. `dont-garb' Trillian. When set, the dont-garb bit on new items will be forced to the specified value. `reserved-2' `reserved-3' `reserved-4' Trillian. When set, these flags force the values of the three reserved bits in the aux-item flags field. These should only be used by lyskomd developers, and then only very carefully. `validate' String or function, default none. When set to a string, this specifies a regexp that must match the data field in newly created items with this tag. If the regexp fails to match, then the item will not be created. The syntax for strings is essentially the same as the syntax used in C files. When set to a function, this specified a built-in validation function to call. The following validator functions are currently implemented: `existing-readable-text' Creation is only allowed if the item contains the number of an existing text that the item creator has permission to read. There are a few fields which specify actions the server is to take when something happens to aux-items with the specified tag. Each of these values is a function specification, the name of a trigger function defined in lyskomd. The syntax for functions is the name followed by an empty pair of parens. It is not possible to pass arguments to the functions yet. `add-trigger' Function to call when an item with the specified tag is added to an object. `delete-trigger' Function to call when an item with the specified tag is scheduled for deletion. `undelete-trigger' Function to call when an item with the specified tag scheduled for deletion is unscheduled. It should undo the effects of the delete trigger. The following trigger functions are currently defined: `mark-text' Increase the mark count for the text the item refers to. The item must contain the number of a text. This trigger should be combined with the existing-readable-text validation function. `unmark-text' Decrease the mark count for the text the item refers to. The item must contain the number of a text. This trigger should be combined with the existing-readable-text validation function. `link-faq' Create a faq-for-conf item linked to a faq-text item. This trigger is used exclusively for faq-text items. The item must contain the number of a text. This trigger must be combined with the existing-readable-text validation function.  File: lyskomd.info, Node: Running lyskomd, Next: Invoking updateLysKOM, Prev: Configuration, Up: Top Running lyskomd *************** This section explains how to run lyskomd, the files it uses and how it can be controlled while running. * Menu: * Invoking lyskomd:: How to run lyskomd. * Signals:: How to control lyskomd with Unix signals. * Files:: Files used by lyskomd.  File: lyskomd.info, Node: Invoking lyskomd, Next: Signals, Up: Running lyskomd Invoking lyskomd ================ lyskomd [-f] [-d] [CONFIG-FILE] The option `-d' adds one to the debug level. The amount of output on stderr/to the log file is increased for each time the option is specified on the command line. Using one `-d' makes the process print a `>' for every timeout, a message for every person that is connecting or disconnecting and a message for every successful or unsuccessful communication to the process. The option `-f' tells lyskomd to stay in forground mode, and not run in the background as a daemon. The output that is normally written to the log file is instead sent to stderr. The optional CONFIG-FILE argument can be used to specify the server configuration file. *Note Server Configuration File::.  File: lyskomd.info, Node: Signals, Next: Files, Prev: Invoking lyskomd, Up: Running lyskomd Signals ======= It is possible to control some aspects of lyskomd using Unix signals. The following signals have special meaning to the server: `SIGTERM' `SIGHUP' `SIGINT' Logs out all sessions, saves the database and exits normally. Use `SIGTERM'; the other signals currently have the same functionality, but that may be changed in the future. `SIGQUIT' Saves the database and dump core. (This should only be used for debugging purposes.) `SIGUSR1' Print statistics about how often different commands have been used since the process started. `SIGUSR2' Forks a child that immediately dumps core. The main process just waits until the child is done and then continues. `SIGWINCH' Re-read the aux-item definition file. Warning: If the aux-item definition file contains an error so that it cannot be parsed, the server will call `restart_kom()', which will cause the server to abort without saving the database. Always test the file on a standby system first!  File: lyskomd.info, Node: Files, Prev: Signals, Up: Running lyskomd Files Used by lyskomd ===================== All file names can be changed in the server configuration file. *Note Parameters::. `/usr/lyskom' Default value of the `Prefix' parameter. The default of this value is set at compile time, but it can be changed in the server configuration file. *Note Parameters::. `PREFIX/var/lyskomd/db/lyskomd-data' Half of the database: all status information. `PREFIX/var/lyskomd/db/lyskomd-texts' The other half of the database: the actual texts. `PREFIX/var/lyskomd/db/lyskomd-backup' A backup copy of `lyskomd-data'. Never, ever delete this file unless you know what you are doing, or you may lose the entire data base. Most of the time this is the only complete database file! `PREFIX/var/lyskomd/db/number.txt' Information about the highest used text- and conference numbers. In case of a crash, some objects may be lost. This file ensures that even if that happens, their numbers will not be reused. `PREFIX/var/run/lyskomd.pid' File with the pid of the lyskom-process. `PREFIX/var/lyskomd.memory' On normal exit, `lyskomd' will append some statistics to this file. It can be used for detecting memory leaks. `PREFIX/etc/aux-items.conf' This file contains definitions of the aux-items that the server should support. It is read by `lyskomd' at startup. `PREFIX/var/lyskomd.clients' A list of all currently connected clients, maintained by the server. The data about each client is collected on a single line: * The file descriptor * The session number * `1' if the handshake is OK, the reverse DNS has completed, and the IDENT lookup has completed. `0' otherwise. * The IP address of the client * The port number of the client In the following example, we see that file descriptor 437 is used by session 330978, and the connection is from 130.236.254.83:3156. 437 330978 130.236.254.83 3156 `/etc/nologin' If this file exists, lyskomd will not allow anyone to connect to the server. This path can be set with the `Nologin file' parameter in the server configuration file.  File: lyskomd.info, Node: Invoking updateLysKOM, Next: Invoking komrunning, Prev: Running lyskomd, Up: Top Invoking updateLysKOM ********************* updateLysKOM [-c CONFIG-FILE] [ -v ] [ -V ] `updateLysKOM' determines if `lyskomd' should be running. It can start or stop `lyskomd' if needed. It uses the same configuration file as `lyskomd' (*note Server Configuration File::). You can use `-c CONFIG-FILE' to override the compiled-in default. Note, however, that this option is not passed along to `lyskomd' if `updateLysKOM' starts it, so the option should be used with extreme caution. `-v' and `-V' causes `updateLysKOM' to report its version number and exit. `updateLysKOM' is normally run from `cron'; *note Administration::.  File: lyskomd.info, Node: Invoking komrunning, Next: Administration, Prev: Invoking updateLysKOM, Up: Top Invoking komrunning ******************* komrunning [-c config-file] [start | stop] komrunning -v | -V `komrunning', when invoked with no arguments, reports whether `lyskomd' is currently running or not, and whether it should be running or not. `komrunning start' attempts to start `lyskomd'. `komrunning stop' attempts to stop `lyskomd', and it will not return until the server has saved its database and exited. `komrunning' uses the same configuration file as `lyskomd' (*note Server Configuration File::). You can use `-c CONFIG-FILE' to override the compiled-in default. Note, however, that this option is not passed along to `updateLysKOM' if `komrunning' invokes it, so the option should be used with extreme caution. The `komrunning' can be installed in `/etc/init.d/'. Be careful, however, to ensure that the pid file is removed earlier during the boot sequence. `-v' and `-V' causes `komrunning' to report its version number and exit.  File: lyskomd.info, Node: Administration, Next: Bugs, Prev: Invoking komrunning, Up: Top Administration ************** The first thing you will have to do is to follow the instructions in the files `INSTALL' and `README'. This will set up the LysKOM system with a database containing a few necessary conferences and one person - the administrator. Once the LysKOM system is running, there is not much you will have to do to keep it that way. One thing to remember is that the current release of the server has an incomplete handling of garbage collection of the database. The database is split into two files, the information file and the text file. Newly written texts are concatenated to the text file and old texts are never removed. The information file contains information about conferences, users and where in the text file the texts are. This file is properly garbage collected, but not the text file. There is a program called `dbck' (Data Base Check) which is used to check the consistency of the LysKOM database. This program can also be used to shrink the text file. To do this, just type `dbck -g'. *Note DBCK Reference::. When `dbck' is to be run on the database, the LysKOM server _must_ be stopped, or unrepairable damage may result. See below for a description on how to stop the server. There is a program called `updateLysKOM' which is used to ensure continuous operation. This program should be run with certain intervals, for instance from `cron'. If the LysKOM server has died for some reason, `updateLysKOM' restarts it. If the server is still running properly, `updateLysKOM' sends a signal (`SIGUSR1') to it, which causes the server to write some statistics to a file named `var/lyskomd.stats' in the lyskom directory. Taking the server down cleanly can be done in two ways: through the use of the LysKOM protocol on a socket, preferably through the use of a suitable client, or by sending the signal `SIGTERM' to it. This will cause the server to save the database and close all client connections. It will also create a file named `var/lyskomd.memory' in which the memory usage of the server is reported. To prevent `updateLysKOM' from restarting a server, create a file named `/usr/lyskom/var/lyskomd/db/status'. The file should contain a valid mail address on the first line. `updateLysKOM' will not restart the server as long as that file exists. In addition, if the file is between 1 and 2 hours old (configurable) an email will be sent to the mail address found in the file. If the file is older than that, an error message will be printed on stderr and `updateLysKOM' will exit with a non-zero exit status. cron is expected to deliver the error message to an operator. The shell script `komrunning' can be used to start and stop the LysKOM server. With no arguments, it will report the status. komrunning stop will (attempt to) shut down the server, creating the file `/usr/lyskom/var/lyskomd/db/status'. If the user running `komrunning' doesn't have permission to send signals to `lyskomd' the actual shutdown will be delayed until the next time that `updateLysKOM' is run. komrunning start will restart the server. The actual starting of the server will be done by `updateLysKOM' the next time it is run. `komrunning' only removes the `/usr/lyskom/var/lyskomd/db/status' file.  File: lyskomd.info, Node: Bugs, Next: DBCK Reference, Prev: Administration, Up: Top Known Bugs ********** * lyskomd should re-read the config file when a `SIGHUP' is received. * The security policy is vague and the implementation is frayed at the edges. * The choice of asynchronous messages is not very good. * The server uses too much memory.  File: lyskomd.info, Node: DBCK Reference, Next: splitkomdb, Prev: Bugs, Up: Top DBCK Reference ************** dbck is a program that can is used for minor database maintenance tasks and for repairing a corrupt lyskomd database. * Menu: * DBCK Overview:: Overview of dbck. * Invoking dbck:: How to run dbck. * DBCK Notes:: Notes about running dbck. * DBCK Files:: Files used by dbck. * DBCK Bugs:: Known bugs in dbck.  File: lyskomd.info, Node: DBCK Overview, Next: Invoking dbck, Up: DBCK Reference Overview ======== The dbck program is used for minor maintenance of the LysKOM database and for repairing corrupt databases. In brief it performs the following functions: * Compact the text file to remove deleted texts. * Repair inconsistent membership information. * Repair invalid recipients * Repair inconsistent comment links * Correct invalid local text numbers * Correct invalid text maps * Set special conferences * Convert between database formats  File: lyskomd.info, Node: Invoking dbck, Next: DBCK Notes, Prev: DBCK Overview, Up: DBCK Reference Invoking dbck ============= The functionality of dbck is controlled through command-line switches. These are documented below. If `dbck' is invoked without any options it will read the database and report on its integrity. No files will be modified. * Menu: * General Options:: Controlling the overall behavior of dbck. * Database Repair Options:: Repairing errors in the LysKOM database. * Format Conversion Options:: Converting the database file to a new format. * Database Maintenance Options:: Options for database maintenance. * Reporting Options:: Options controlling status reports.  File: lyskomd.info, Node: General Options, Next: Database Repair Options, Up: Invoking dbck General Options --------------- These options control the general behavior of lyskomd. `-h' or `--help' Give a usage message (which includes the version number and the compiled-in default location of the config file) and exit immediately. `-v' or `--verbose' Verbose mode. Report not only errors but the status of the database. `-F' or `--force-output' This option forces dbck to write the database file. Normally `dbck' will only write a new database file if changes have been made for some other reason. If you want to simply convert a database from one version to another, you will probably have to give this option. lyskom-server-2.1.2/doc/lyskomd.info-20000664000015100472110000013631607723710263013301 This is lyskomd.info, produced by makeinfo version 4.2 from lyskomd.texi. This is the reference manual for the lyskomd LysKOM server version 2.1.2. Copyright (C) 1995-2003 Lysator ACS. Permission is granted to make and distribute verbatim copies of this specification provided the copyright notice and this permission notice are preserved on all copies. INFO-DIR-SECTION LysKOM START-INFO-DIR-ENTRY * lyskomd: (lyskomd). lyskomd reference manual. END-INFO-DIR-ENTRY  File: lyskomd.info, Node: Database Repair Options, Next: Format Conversion Options, Prev: General Options, Up: Invoking dbck Database Repair Options ----------------------- The following options control database repair. `-i' or `--interactive' Run interactively. If any inconsistency is found, a remedial cure will be suggested and the user must confirm the correction. `-r' or `--auto-repair' Repair simple errors without asking. `-c' or `--set-change-name' Consider it an error if the `change-name' capability of a person is not set. Due to a bug that capability was never set for newly created persons in release 1.6.1 of lyskomd. This option can be used to repair the damage.  File: lyskomd.info, Node: Format Conversion Options, Next: Database Maintenance Options, Prev: Database Repair Options, Up: Invoking dbck Format Conversion Options ------------------------- dbck can be used to conver the LysKOM database from one storage format to another. This is necessary only when moving the database to a new server version. `-F' or `--force-output' This option forces dbck to write the database file. Normally `dbck' will only write a new database file if changes have been made for some other reason. If you want to simply convert a database from one version to another, you will probably have to give this option. `-o' or `--output-version' This option is used to set the output version of the database. This option will normally be used in conjunction with the `-F' option. Version 1.9 of `lyskomd' requires database version 1; version 2.0 requires database version 2. Versions of `lyskomd' prior to 1.9 requires database version 0. Note that information is irrevocably lost when converting from a higher to a lower database version. This options requires an argument: the output format version.  File: lyskomd.info, Node: Database Maintenance Options, Next: Reporting Options, Prev: Format Conversion Options, Up: Invoking dbck Database Update Options ----------------------- dbck can be used to update certain aspects of the database that either were impossible to update in early versions of protocol A or that are inconvenient in all protocol versions. `-g' or `--compact-text-mass' Do garbage collection on the texts part of the database. This removes all unreferenced texts from the database. `-P' or `--clear-password' Clear the password of a specified user. This option is silently ignored if the user does not exist. This option requires an argument: the ID of the person whose password is to be cleared. `-G' or `--grant-all' Grant all privileges to the specified user. This option is silently ignored if the user does not exist. This option requires an argument: the ID of the person who is to be granted all privileges. `--pers-pres-conf' Set the person presentation conference of the server to the specified conference. Since version 1.9 of lyskomd the `set-info' call can be used to do this. `--conf-pres-conf' Set the conference presentation conference of the server to the specified conference. Since version 1.9 of lyskomd the `set-info' call can be used to do this. `--motd-conf' Set the message-of-the-day conference of the server to the specified conference. Since version 1.9 of lyskomd the `set-info' call can be used to do this. `--kom-news-conf' Set the news-about-lyskom conference of the server to the specified conference. Since version 1.9 of lyskomd the `set-info' call can be used to do this. `--motd-of-kom' Set the message of the day of the server to the specified text. Since version 1.9 of lyskomd the `set-info' call can be used to do this.  File: lyskomd.info, Node: Reporting Options, Prev: Database Maintenance Options, Up: Invoking dbck Reporting Options ----------------- These options control reporting of information about the database. `-s' or `--print-statistics' Gather statistics about the lengths of texts. A table containing the frequence of all lengths that are currently present is printed. `-t' or `--list-text-no' Print "Checking TEXT-NO" for every text that examined. Warning: This produces lots of output.  File: lyskomd.info, Node: DBCK Notes, Next: DBCK Files, Prev: Invoking dbck, Up: DBCK Reference Notes for DBCK ============== The messages "Conference CONF-NO has a bad Text-list. Starts with 0" and "Person PERS-NO has created NUM conferences, not NUM (as said in person-stat)." are normal. If you get them when you specify the `-g' option, let `dbck' repair them and run `dbck -g' again.  File: lyskomd.info, Node: DBCK Files, Next: DBCK Bugs, Prev: DBCK Notes, Up: DBCK Reference Files Used by dbck ================== dbck uses the same files as `lyskomd' (*Note (lyskomd)::.) All file names can be changed in the server configuration file. *Note (lyskomd)Parameters::. `/usr/lyskom' Default value of `Prefix:'. The default of this value is set at compile time, but it can be changed in the server configuration file. *Note (lyskomd)Parameters::. `PREFIX/var/lyskomd/db/lyskomd-data' Half of the database: all status information. `PREFIX/var/lyskomd/db/lyskomd-texts' The other half of the database: the actual texts. `PREFIX/var/lyskomd/db/lyskomd-backup' A backup copy of `lyskomd-data'. Never, ever delete this file unless you know what you are doing, or you may lose the entire data base. Most of the time this is the only complete database file!  File: lyskomd.info, Node: DBCK Bugs, Prev: DBCK Files, Up: DBCK Reference Known Bugs ========== * Should have an unlock database option. * Does not check that the data file and text file are consistent.  File: lyskomd.info, Node: splitkomdb, Next: Hacking, Prev: DBCK Reference, Up: Top Backups with splitkomdb *********************** The files created by `lyskomd' can become huge. They are more or less constantly modified, so if you do incremental backups the entire `lyskomd' database will be saved each time you perform a backup. The `splitkomdb' program improves the situation. * Menu: * splitkomdb basics:: How splitkomdb works. * Invoking splitkomdb:: splitkomdb reference. * splitkomdb example:: A typical setup of splitkomdb. * splitkomdb restore:: How to restore the database.  File: lyskomd.info, Node: splitkomdb basics, Next: Invoking splitkomdb, Up: splitkomdb splitkomdb theory of operation ============================== The `splitkomdb' program attempts to split the current database in several files, some of which will not be modified the next time you run `splitkomdb'. An incremental backup will thus only have to save some of the files created by `splitkomdb'. `splitkomdb' can be run while `lyskomd' is running. It will use the last completely saved snapshot, and make a copy of it in the directory specified by the `Backup export directory:' parameter (default: `/usr/lyskom/var/lyskomd/exportdb/'). There are two recommended ways to make backups of a `lyskomd' database: * Run `splitkomdb' before each backup, and instruct the backup program to backup `/usr/lyskom/var/lyskomd/exportdb', but ignore `/usr/lyskom/db'. Run `splitkomdb -f' before each full backup. * Backup all the files in `/usr/lyskom/db'. The first alternative needs more disk for the copy in `/usr/lyskom/var/lyskomd/exportdb' and is slightly more complex to set up; the second alternative saves the entire database each time you make a backup.  File: lyskomd.info, Node: Invoking splitkomdb, Next: splitkomdb example, Prev: splitkomdb basics, Up: splitkomdb Invoking splitkomdb =================== splitkomdb [-c config-file] [-f] splitkomdb -v | -V `splitkomdb' creates a splitted copy of the most recent database snapshot in the directory specified by the `Backup export directory:' parameter. If `-v' or `-V' is specified, `splitkomdb' prints its version number and exits. The `-f' option is a hint to `splitkomdb' that the next backup will be a full backup. When this option is used, `splitkomdb' might rewrite all the output files in a way so that future invocations of `splitkomdb' will create a little incremental data as possible. The optional CONFIG-FILE argument can be used to specify the server configuration file. *Note Server Configuration File::.  File: lyskomd.info, Node: splitkomdb example, Next: splitkomdb restore, Prev: Invoking splitkomdb, Up: splitkomdb Typical splitkomdb setup ======================== A typical way to run `splitkomdb' is from `cron'. A `crontab' entry might look like this: 50 2 26 * * /sw/lyskom/bin/splitkomdb -f 10 3 * * * /sw/lyskom/bin/splitkomdb This entry assumes that backups are started at 03:30. It gives `splitkomdb' 20 minutes to run. (That should be enough for most sites, but please check what is appropriate for your site.) Full backups are run on the 26th of each month. On those days, at 02:50, `splitkomdb -f' is run.  File: lyskomd.info, Node: splitkomdb restore, Prev: splitkomdb example, Up: splitkomdb Restoring the database from splitkomdb ====================================== The splitted format of the database is currently very simple: `var/lyskomd/exportdb/lyskomd-texts-base.backup' This file contains the first part of `Text file:' (default: `var/lyskomd/db/lyskomd-texts'). This file is created when the `-f' option is given to `splitkomdb'. `lyskomd-texts-tail.backup' This file contains the rest of `Text file:'. It is always recreated when `splitkomdb' is run. `lyskomd-data.backup' This file contains a copy of `Data file:' (default: `var/lyskomd/db/lyskomd-data'). If `Data file:' file wasn't clean when `splitkomdb' was run, `Backup file:' (default: `var/lyskomd/db/lyskomd-backup') will be copied instead. This means that it is easy to restore the database from the splitted database. If you use the default paths, all you have to do is run these commands: $ cd /usr/lyskom/var/lyskomd/exportdb $ cat lyskomd-texts-base.backup \ > lyskomd-texts-tail.backup \ > > ../db/lyskomd-texts $ cp lyskomd-data.backup ../db/lyskomd-data Future versions of `splitkomdb' may use a different format. It may even evolve into something so complex that you need a program to recreate the database. Always check the current documentation for information on how to restore the database.  File: lyskomd.info, Node: Hacking, Next: lyskomd Database Specification, Prev: splitkomdb, Up: Top Hacking lyskomd *************** * Menu: * The Database:: * Adding Configuration Parameters:: How to add configuration options. * Adding Asynchronous Messages:: Adding protocol A messages. * Adding a New Protocol Request:: Adding protocol A calls. * Adding New Input Types:: * Adding New Result Types:: * Modifying Output Types:: * Adding Aux-Item Types:: Adding predefined aux item types. * Modifying Stored Types:: Modifying types stored in the DB. * Notes:: Mixed notes. * Debugging and Testing:: How to test and debug the server. * local-to-global:: The Local_to_global structure. * Coding conventions:: Indentation style et c.  File: lyskomd.info, Node: The Database, Next: Adding Configuration Parameters, Up: Hacking The Database ============ This section is not translated to English yet. See a comment in the `lyskomd.texi' for the raw Swedish text.  File: lyskomd.info, Node: Adding Configuration Parameters, Next: Adding Asynchronous Messages, Prev: The Database, Up: Hacking Adding Configuration Parameters =============================== Make sure that you really understand what you want to configure. Think it over again. Find a good, descriptive name for it. Decide what values the parameter can be set to. Integers? Booleans? Document the parameter in `lyskomd.texi'. Add a field to `struct kom_par' in `param.h'. Add it to `parameters[]' in `server-config.c'. See `conf-file.h' and maybe `conf-file.c' for information on this structure. Make sure that the parameter is used instead of any previous hard-coded value. Make sure that `dbck' can cope with it.  File: lyskomd.info, Node: Adding Asynchronous Messages, Next: Adding a New Protocol Request, Prev: Adding Configuration Parameters, Up: Hacking Adding Asynchronous Messages ============================ `async.h' Add the message in `enum async { }'. Make sure that `ay_dummy_last' is one more than any other message. If the message is to be sent by default, which is _not_ recommended, place its number into `ASYNC_DEFAULT_MESSAGES'. `prot-a-send-async.c' `prot-a-send-async.h' Write a function that sends the message. This function is responsible for writing the message to a particular connection and for ensuring that the message is not sent to clients who do not want it. Make sure that the second argument to `async_header' really is the number of elements being sent. Arrays count as two elements: the item count and the elements. `send-async.c' `send-async.h' Write a function that sends the message to appropriate clients. This function is responsible for checking that async messages should be sent at all, for each client check if it allowed to see the message and ensure that the protocol specified by the connection is appropriate. The send function should either take a `struct connection *' as an argument and send the message to that connection, or loop over all connections. Most send functions take a connection pointer; the looping is dealt with elsewhere. `session.c' Add a case label for the `enum' in the large `switch' statement. Make sure that the message is sent in appropriate places. `testsuite/lyskomd.0/03.exp' A few tests will fail. Fix them. Document the message type in `Protocol-A.texi'. Write test cases for the new async message. * Menu: * Function Templates for prot-a-send-async.c:: * Function Templates for send-async.c::  File: lyskomd.info, Node: Function Templates for prot-a-send-async.c, Next: Function Templates for send-async.c, Up: Adding Asynchronous Messages Function Templates for prot-a-send-async.c ------------------------------------------ This is what a typical function in `prot-a-send-async.c' should look like. This function is responsible for checking that the client is accepting the message and writing the message itself to the connection. void prot_a_async_SOMETHING(Connection *cptr, PARAMETERS) { ASYNC_CHECK_ACCEPT(cptr, ay_SOMETHING); async_header(cptr, NUM_TOKENS, ay_SOMETHING); /* Output the body of the message */ async_trailer(cptr); }  File: lyskomd.info, Node: Function Templates for send-async.c, Prev: Function Templates for prot-a-send-async.c, Up: Adding Asynchronous Messages Function Templates for send-async.h ----------------------------------- This is what a typical function in `send-async.c' should look like. This function is responsible for sending the message to all connections that are appropriate, not sending it if the server is not supposed to send messages at all, and for checking that the protocol specified by the client is one the server knows. void async_SOMETHING( PARAMETERS ) { Connection *cptr; Session_no i = 0; if (!param.send_async_messages) return; while ((i = traverse_connections(i)) != 0) { cptr = get_conn_by_number(i); switch(cptr->protocol) { case 0: /* No protocol specified yet */ break; case 'A': /* Check that connection is logged on. We might want to check other things here too, such as if the connection is allowed to see the message */ if (handshake_ok(cptr, 0)) prot_a_async_SOMETHING(cptr, PARAMETERS); break; default: restart_kom("async_SOMETHING(): bad protocol.\n"); break; } } } Template for a function that sends to a single connection: void async_SOMETHING(struct connection *cptr, PARAMETERS) { if (!param.send_async_messages) return; switch(cptr->protocol) { case 0: /* No protocol specified yet */ break; case 'A': /* Check that connection is logged on. We might want to check other things here too, such as if the connection is allowed to see the message */ if (handshake_ok(cptr)) prot_a_async_SOMETHING(cptr, PARAMETERS); break; default: restart_kom("async_SOMETHING(): bad protocol.\n"); break; } }  File: lyskomd.info, Node: Adding a New Protocol Request, Next: Adding New Input Types, Prev: Adding Asynchronous Messages, Up: Hacking Adding a New Protocol Request ============================= Before doing anything, think again. Make sure that the protocol request is needed, is in line with the rest of the protocol, behaves the way people want it to, and that everyone involved agrees that it is a good idea. 1. Document the request in `Protocol-A.texi' 2. Declare the function in `include/services.h' 3. Declare the function _last_ in `server/fncdef.txt'. It should be given a call number one higher than the currently existing highest contiguous call number. 4. If the function takes an input parameter of a new type, changes need to be made in several places. *Note Adding New Input Types::. 5. If the function takes too many parameters of type `num', `string' or `c_string', the definition of `Connection' in `server/connection.h' has to be changed. 6. If the function has an output parameter of a new type, changes need to be made in several plaves. *Note Adding New Result Types::. 7. Write the function in a suitable place in the server directory. 8. Write tests for the new function in `server/testsuite/lyskomd.0'. Write one file for testing the functionality. Write tests in `01.exp' (behavior when the client is not logged on) and `03.exp' (normal behavior.) 9. Run the testsuite to make sure nothing old has been broken. Every request handler should call the `CHK_CONNECTION' macro before doing anything else. This ensures that the `active_connection' variable is non-NULL. The only time when this might not be the case is if the request handler is not called in response to a client request. This should never happen, but might if someone gets careless. If your function should not be available before the user is logged in, call the CHK_LOGIN macro after doing `CHK_CONNECTION'. Take care returning errors to the client. Previous versions of `lyskomd' leaked secret information through error returns. For example, the following code leaks information: Success service(Conf_no conf_no, Text_no text_no) { Conference *conf_stat; Text_stat *text_stat; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_C_STAT(conf_stat, conf_no, FAILURE); GET_T_STAT(text_stat, text_no, FAILURE); if (!has_access(conf_no, active_connection, read_protected)) { err_stat = conf_no; kom_errno = KOM_UNDEF_CONF; return FAILURE; } if (!text_read_access(active_connection, text_no, text_stat)) { err_stat = text_no; kom_errno = KOM_NO_SUCH_TEXT; return FAILURE; } /* Permissions checked. Do the deed. */ return OK; } This request can be used to gain precise information on which conferences and texts exist in the system. If an unprivileged user makes a request for any conference and readable text, and the user receives a `KOM_NO_SUCH_TEXT' error, the user can deduce that the conference exists, but is secret. If the user makes a request for a conference known to be secret and a text known not to be readable (either secret or deleted), and the user receives a `KOM_UNDEF_CONF' error, the user can deduce that the text does exist. To avoid traps like these, do permission checks for objects immediately after attempting to get them from the database. See also: * *Note Adding New Input Types:: * *Note Adding New Result Types:: * *Note Modifying Output Types::  File: lyskomd.info, Node: Adding New Input Types, Next: Adding New Result Types, Prev: Adding a New Protocol Request, Up: Hacking Adding New Input Types ====================== Changes need to be made in the following files: `Protocol-A.texi' Document the new type. `server/call-switch.awk' The new type has to be added to the cascaded ifs that translate the type name to code that points to the appropriate field in a `Connection' structure. `server/prot-a-parse-arg-c.awk' The new type has to be added to the cascaded ifs that create the argument list parser. `server/connections.h' The definition of `Connection' must be extended with a field where the parse value can be stored. Don't even think about trying to reuse an existing field. It's more trouble than it's worth. `server/connection.c' Free the contents of the field in `free_parsed'. `server/prot-a.c' Free the contents of the field in `prot_a_destruct'. `server/internal-connections.c' Initialize the contents of the field in `init_connection'. `server/testsuite/lyskomd.0/29.exp' Add test cases for disconnecting in the middle of the data type. This is important both for singletons and lists.  File: lyskomd.info, Node: Adding New Result Types, Next: Modifying Output Types, Prev: Adding New Input Types, Up: Hacking Adding New Result Types ======================= Changes need to be made in the following files: `Protocol-A.texi' Document the new type. `server/prot-a.c' Add a line in the `prot_a_reply' switch that calls the correct output function. `server/connections.h' Add the type in `enum res_type' and `union result_holder'. `server/prot-a-output.c' `server/prot-a-output.h' Write a function that outputs the new type to a connection. Use the existing functions as templates.  File: lyskomd.info, Node: Modifying Output Types, Next: Adding Aux-Item Types, Prev: Adding New Result Types, Up: Hacking Modifying Output Types ====================== When you modify an existing type you have to rename the old version of the type since it will still be used in existing calls. The convention has previously been to rename SOMETHING to SOMETHING`_old', but the preferred method is to append an underscore and the protocol version in which the current version of the type was introduced. For example, if the type `Gazonk' was introduced in protocol version 11, and a new version is to be introduced in protocol version 15, the current `Gazonk' structure is renamed to `Gazonk_11'. This is to avoid names like `Something_older', `Something_oldest' and `Something_Truly_Ancient'. Changes need to be made to the following files: `Protocol-A.texi' Document the new type in the appropriate section. Rename the existing type in the type documentation and in all calls that return it. Be thorough! `fncdef.txt' Rewrite all calls that use the modified type so they use the old version of the type. `prot-a.c' Modify the current line in `prot_a_reply' for the existing version of the type, and add a new line for the new version of the type. `connections.h' Modify the existing entry in `enum res_type' and `union result_holder', if necessary. This should only be necessary if the server uses both a new and old type internally, which is not recommended. Add new entries for the new version of the type. `prot-a-output.h' `prot-a-output.c' Rename the existing output routing according to the new name of the type. Write a new output routine for the new version of the type. `memory.c' If there are functions for the type in `memory.c', make sure that your new type is initialized, cleared and copied in an appropriate manner. If the type you modify is stored in the database, make sure it gets saved properly. *Note Modifying Stored Types::.  File: lyskomd.info, Node: Adding Aux-Item Types, Next: Modifying Stored Types, Prev: Modifying Output Types, Up: Hacking Adding Aux-Item Types ===================== 1. Document the new type in Protocol-A.texi 2. Write a definition of the new type in `run-support/aux-items.conf'. 3. Some tests in at least `server/testsuite/lyskomd.0/01.exp', `server/testsuite/lyskomd.0/03.exp' and `server/testsuite/lyskomd.0/18.exp' will fail when new predefined aux-items are added. Fix the tests. 4. Write test cases for the new aux-item. If the aux item can be set on a letterbox, do so in `server/testsuite/lyskomd.0/03.exp' where the comment containing `AUXITEM' says to do so. More complex aux-items should have more tests written for them. `server/testsuite/lyskomd.0/20.exp' might provide some inspiration. 5. If the new type requires add, delete or undelete triggers that do not already exist, declare the trigger functions in `aux-items.c' and add them to the `aux_item_triggers' array in the same file. 6. If the new type is so complex that is cannot be fully defined in `aux-items.conf', then add it to the `compiled_aux_items' array in `aux-items.c'. Note that this functionality has not been tested until someone actually adds one of these beasts, so watch your step.  File: lyskomd.info, Node: Modifying Stored Types, Next: Notes, Prev: Adding Aux-Item Types, Up: Hacking Modifying Stored Types ====================== If you want to modify an existing type that is stored in the database, think again. Can the job be done with aux-items instead? Is it really necessary? Be very, very careful when doing this. You have to make sure that the type as sent in old calls and async messages is not changed in any way. You have to make sure that the type can be stored to and read from the database. 1. Document the changes in Protocol-A.texi if the change is visible in the protocol. 2. Bump the database version number by one for the next release of the server. 3. Write a function in `ram-output.c' to output the new format. Update all old functions in `ram-output.c' that are database version dependent so that they can deal with the new database format. 4. Write a function in `ram-parse.c' to read the new format. Update all old functions in `ram-parse.c' that are database version dependent so that they can deal with the new database format. 5. Set the default database format in `ram-parse.c' and `ram-output.c'. The variables to change are `input_format' and `output_format', respectively. 6. Don't forget to update the functions in `memory.c' 7. Update dbck so that it can convert to the new format. 8. Add as many test cases as are needed for the dbck conversion. * Menu: * Template for ram-output.c:: * Template for ram-parse.c::  File: lyskomd.info, Node: Template for ram-output.c, Next: Template for ram-parse.c, Up: Modifying Stored Types Template for ram-output.c ------------------------- For types that can be output in several different formats, use the following templates for them. You have to be able to output in all formats, or `dbck' will be unable to convert between formats. static void foutput_SOMETHING_0(FILE *fp, SOMETHING *o) { /* Output version 0 of SOMETHING */ } static void foutput_SOMETHING_1(FILE *fp, SOMETHING *o) { /* Output version 1 of SOMETHING */ } static void foutput_SOMETHING_2(FILE *fp, SOMETHING *o) { /* Output version 2 of SOMETHING */ } void foutput_SOMETHING(FILE *fp, SOMETHING *o) { switch(output_format) { case 0: foutput_SOMETHING_0(fp, info); break; case 1: foutput_SOMETHING_1(fp, info); break; case 2: foutput_SOMETHING_2(fp, info); break; default: restart_kom("unknown database format: %d", output_format); break; } } Note that if two versions are the same, only write one function. For example, if version 0 and version 1 are the same, only write an `foutput_SOMETHING_0' function and call it from both case 0 and case 1.  File: lyskomd.info, Node: Template for ram-parse.c, Prev: Template for ram-output.c, Up: Modifying Stored Types Template for ram-parse.c ------------------------ static Success fparse_SOMETHING_0(FILE *fp, SOMETHING *o) { /* Parse version 0 */ return OK; } static Success fparse_SOMETHING_1(FILE *fp, SOMETHING *o) { /* Parse verson 1 */ return OK; } static Success fparse_SOMETHING_2(FILE *fp, SOMETHING *o) { /* Parse verson 2 */ return OK; } extern Success fparse_SOMETHING(FILE *fp, SOMETHING *o) { if ( fparse_long_errors != 0 ) { log("fparse_SOMETHING(): fparse_long_errors == %d on entry." " Reset.\n", fparse_long_errors); fparse_long_errors = 0; } switch (input_format) { case 0: return fparse_SOMETHING_0(fp, o); break; case 1: return fparse_SOMETHING_1(fp, o); break; case 2: return fparse_SOMETHING_2(fp, o); break; default: restart_kom("unknown input format: %d\n", input_format); return FAILURE; break; } } Note that if two versions are the same, only write one function. For example, if version 0 and version 1 are the same, only write an `fparse_SOMETHING_0' function and call it from both case 0 and case 1.  File: lyskomd.info, Node: Notes, Next: Debugging and Testing, Prev: Modifying Stored Types, Up: Hacking Hacking Notes ============= * Menu: * Parsing Bit Fields:: How to parse bit fields properly. * Membership Notes:: How members and memberships are handled. * Linking Pairs of Aux Items:: How to link pairs of aux items. * Notes for fncdef.txt:: Format of the fncdef.txt file. * Traversing Connections:: How to traverse connections in lyskomd.  File: lyskomd.info, Node: Parsing Bit Fields, Next: Membership Notes, Up: Notes Parsing Bit Fields ------------------ The parser for a bit field parameter type should be very tolerant of the length of the token. Anything from a single bit and up should be permitted. The parser should use default values for bits that are not provided and ignore extra bits. Here is a model function: void prot_a_parse_bitfield(Connection *client, Bitfield *res) { String token; String_size len; token = prot_a_get_token(client); len = s_strlen(token); if (len <= 0) longjmp(parse_env, ISC_PROTOCOL_ERR); init_bitfield(res); switch (len = s_strlen(token)) { default: case 8: res->bit_8 = token.string[7]; case 7: res->bit_7 = token.string[6]; case 6: res->bit_6 = token.string[5]; case 5: res->bit_5 = token.string[4]; case 4: res->bit_4 = token.string[3]; case 3: res->bit_3 = token.string[2]; case 2: res->bit_2 = token.string[1]; case 1: res->bit_1 = token.string[0]; } } The function gets the token, checks the sanity of the length, then initialized the result to its default values. Then it does a switch on all token lengths that are equal to or smaller than the number of bits the server knows about. The fall-through ensures that all bits in the token are read.  File: lyskomd.info, Node: Membership Notes, Next: Linking Pairs of Aux Items, Prev: Parsing Bit Fields, Up: Notes Membership Notes ---------------- The `position' field in the membership is _not_ stored. It has to be set every time a membership is requested for transmission to the client.  File: lyskomd.info, Node: Linking Pairs of Aux Items, Next: Notes for fncdef.txt, Prev: Membership Notes, Up: Notes Linking Pairs of Aux Items -------------------------- Sometimes two aux items need to work in tandem. The first instance of this was the FAQ and FAQ-for-conference items. The FAQ item contains the text number of a text that is a FAQ for a conference. The FAQ-for-conference item contains the conference for which a text is a FAQ. This is needed so that deletion of the text properly removes the aux-item on the conf (plus, it's nice to be able to see that a text is a FAQ.) The `linked_item' field in the Aux_item structure is for linking items. The linking must be managed through the use of triggers. This field is not visible in the protocol. It is saved in the database. It is not possible to have more than one link per item. Please remember the following points. * The target of a link should have a link back. All links need to go both ways. * In the add trigger for one end, create the other end of the link and set the `linked_item' field in both items. Don't forget to mark the objects at both ends as changed. * Deletion and undeletion of the other side of the link will be managed automatically. You don't need delete and undelete triggers simply to destroy the other side of a link. * Don't kill the server because one end is missing. It is possible for the administrator to remove an item manually. Log a message and continue working.  File: lyskomd.info, Node: Notes for fncdef.txt, Next: Traversing Connections, Prev: Linking Pairs of Aux Items, Up: Notes Notes for fncdef.txt -------------------- The fncdef.txt file is used to define the RPC functions. Each line consists of the call number, the return type of the call, the parameters and the output types of the call. Some examples: 10 number create_conf_old c_string (param.conf_name_len) conf_type 12 success lookup_name c_string (param.conf_name_len) : conf_list The first line defines a call named `create_conf_old' that takes two arguments, a string that can only be as long as `param.conf_name_len' and a `conf_type'. It returns a number to the client. If the service call returns -1, the server will return an error. The `create_conf_old' call has RPC number 10. The second line defines a call named `lookup_name' that takes a string argument that can be no longer than `param.conf_name_len', and returns a `conf_list'. The service call returns a `Success'. If it does not return `OK', the server will return an error. The `lookup_name' call has RPC number 12. Scripts That Use fncdef.txt ........................... The following scripts operate on `fncdef.txt'. If you make modifications to the format of `fncdef.txt', you have to update these scripts. `call-switch.awk' Generates `call-switch.incl', which is included by `connections.c' `com-h.awk' Generates `com.h', which is included by several files. `fnc-def-init.awk' Generates `fnc-def-init.incl', which is included by `connections.c'. `prot-a-is-legal-fnc.awk' Generates `prot-a-is-legal-fnc.incl', which is included by `prot-a.c' `prot-a-parse-arg-c.awk' `prot-a-parse-arg-h.awk' Generates `prot-a-parse-arg.c' and `prot-a-parse-arg.h'.  File: lyskomd.info, Node: Traversing Connections, Prev: Notes for fncdef.txt, Up: Notes Traversing Connections ---------------------- Since session 0 is interpreted as the currently active session by get_conn_by_number it is important to be careful when traversing sessions. Code like this does not work since it will do one iteration through the loop with `sess' set to zero. This formerly caused `get_conn_by_number' to return `NULL', but now causes it to return the session pointer for the current session. for (sess = 0; (sess = traverse_connections(sess)) != 0; ) { cptr = get_conn_by_number(sess); ... } The canonical traversal code looks like this: Session_no session = 0; while ((session = traverse_connections(session)) != 0) { cptr = get_conn_by_number(session); if (handshake_ok(cptr, 0)) /* can sometimes be skipped */ { ... } } This code has `session' set to a session number before ever entering the loop.  File: lyskomd.info, Node: Debugging and Testing, Next: local-to-global, Prev: Notes, Up: Hacking Debugging and Testing ===================== We're slowly adding support for debugging and testing lyskomd properly. * Menu: * The Test Suite:: The lyskomd regression test suite. * Configuration Options:: Debugging options for the configure script. * Coverage Testing:: How to do coverage testing with gcov. * Debug Calls:: Special protocol A calls for testing.  File: lyskomd.info, Node: The Test Suite, Next: Configuration Options, Up: Debugging and Testing The Test Suite -------------- The lyskomd test suite is in src/server/testsuite. Please extend this with additional test cases every time you make modifications to the server. Run the test suite often to make sure that your changes did not break anything. The file config/prot-a.exp contains some support for protocol A. Don't use these functions in test cases. Use them to set up the inital database and for things that have to be done, such as logins and enabling privileges, but that don't need to be tested. Also, don't count on all the code in prot-a.exp to be fully functional. Add new functions to this file as you see fit. The basic structure of a test case is the following: source "config/prot-a.exp" read_versions lyskomd_start client_start 0 talk_to client 0 kom_connect "DejaGnu test suite" The test cases talk_to client 0 kom_logout kom_login 5 [holl "gazonk"] 0 kom_enable 255 send "9999 44 0\n" simple_expect "=9999" client_death 0 lyskomd_death Use the existing test cases as templates.  File: lyskomd.info, Node: Configuration Options, Next: Coverage Testing, Prev: The Test Suite, Up: Debugging and Testing Configuration Options --------------------- There are several testing and debugging-related configuration options for lyskomd. Some of them also apply to libisc. `--with-purify' Build lyskomd with Purify. This currently does not work. `--with-efence' Build lyskomd with Electric Fence for checking buffer overruns. This option does work. `--with-checker' Build lyskomd with Gnu Checker for checking memory accesses, leaks, file descriptors and all kinds of stuff. As of Checker version 0.99.6, Gnu Checker cannot deal with lyskomd. Once built, and this requires modifications to Checker (at least on Linux) it reports spurious errors. Still, the option is here for those who want to try it out. `--with-gcov' Build lyskomd with instrumentation for `gcov'. You have to use this option if you want to run `gcov' on lyskomd. For `gcov' to be effective, you should turn off optimization as well. `--with-traced-allocations' There is some builtin support for detecting memory leaks in lyskomd. Whenever the server exits normally it reports how much memory it still uses to `var/lyskomd.memory'. The count should always be 0. If there is a leak you can use this option to trace it down. See `src/server/ram-smalloc.c' for more information. You need gdb and a lot of time to use this option. `--with-optimization=VALUE' Build lyskomd with the specified level of optimization. Use either numeric values to select the level of optimization, or say `--with-optimization=no' or `--without-optimization' to turn optimization off.  File: lyskomd.info, Node: Coverage Testing, Next: Debug Calls, Prev: Configuration Options, Up: Debugging and Testing Coverage Testing ---------------- When you write new code, make sure that it is completely covered by the test suite. Run the lyskomd configure script with the `--with-gcov', `--with-debug-calls' and `--without-optimization' flags to instrument the server for coverage testing with gcov. If you run configure without the `--without-optimization' option, the server will be compiled with optimizations on. This is fine, but the coverage data from gcov isn't completely reliable since parts of the program may have been optimized out of existance. Recompile everything, then run the test suite. Next do `gcov -f FILENAME' to compute coverage information for the file FILENAME. The resulting file FILENAME`.gcov' shows which lines have been executed, and which haven't been run. Try to get 100% coverage.  File: lyskomd.info, Node: Debug Calls, Prev: Coverage Testing, Up: Debugging and Testing Debug Calls ----------- Run the configure script with `--with-debug-calls' to compile in support for debugging calls in the server. These calls are strictly for making testing easier (or possible.) They are not official, and they may change at any time. * Menu: * memory-info:: Get information from malloc (1000) * set-marks:: Set the number of marks on a text (1001) * backdate-text:: Change the creation date of a text (1002)  File: lyskomd.info, Node: memory-info, Next: set-marks, Up: Debug Calls memory-info (DEBUG) Experimential ................................. memory-info [1000] ( ) -> (( arena : INT32; ordblks : INT32; smblks : INT32; hblks : INT32; hblkhd : INT32; usmblks : INT32; fsmblks : INT32; uordblks : INT32; fordblks : INT32; keepcost : INT32; )); This call returns the data returned by `mallinfo' in the server. See the man page for `mallinfo' for explanations of the fields.  File: lyskomd.info, Node: set-marks, Next: backdate-text, Prev: memory-info, Up: Debug Calls set-marks (DEBUG) Experimental .............................. set-marks [1001] (( text-no : Text_no; no-of-marks : INT32; )) -> ( ); Set the number of marks on text `text-no' to `no-of-marks', regardless of how many marks it really has. This call is useful for forcing the database into a state where the number of marks is incorrect in some way.  File: lyskomd.info, Node: backdate-text, Prev: set-marks, Up: Debug Calls backdate-text (DEBUG) Experimental .................................. backdate-text [1002] (( text-no : Text_no; seconds : INT32; )) -> ( ); Backdate a text in the server. Change the creation date of text `text-no' so it appears to have been created `seconds' earlier than it was actually created. This can be used to test the garbage collector.  File: lyskomd.info, Node: local-to-global, Next: Coding conventions, Prev: Debugging and Testing, Up: Hacking The local-to-global structure ============================= The data structure that stores the mapping from local to global text numbers is currently one of the more advanced structures used by lyskomd. This section is not translated to English yet. See a comment in the `lyskomd.texi' for the raw Swedish text.  File: lyskomd.info, Node: Coding conventions, Prev: local-to-global, Up: Hacking Coding conventions ================== When I write this chapter, lyskomd is over 13 years old. It shows. The code looks differently. Here are a few notes on the coding style that is preferred. When you make a substantial change in a function, please update it to this style as well. * Keep lines to at most 79 characters. (Exception: the DejaGNU test scripts can be as long as you like. Proper TCL quoting is a bigger nuisance than overly long lines.) * Don't make invisible whitespace changes: don't change tab to space or vice versa, don't add or remove trailing whitespace. It makes the output of `cvs diff' harder to read. * Document the public API of a function in the `.h' file, not the `.c' file. * Don't use `Bool' to return a failure indication. Use `Success' instead. That type has two values: `OK' and `FAILURE'. They cannot be mistaken, but it isn't obvious if `TRUE' means that some operation failed or if it succeeded. * If a function returns `Bool', its name should make it clear what `TRUE' means. Don't call the function `validate_existing_text'; call it `validate_text_exists'. (But it might be better to use `Success'.) * Follow this indentation example: int some_fun(int x, int y) { if (x > y) return x; else { if (y == 0 && x < y) { return x; } } return 0; } * Don't use redundant braces (as in the first `if' statement above), unless they help readability (as they do in the second `if' statement above). * If you break a line near a `&&' or `||' (or any other operator), put the operator at the beginning of the next line. * A suitable style for GNU Emacs can be found in `doc/kom-style.el'.  File: lyskomd.info, Node: lyskomd Database Specification, Prev: Hacking, Up: Top lyskomd Database Specification ****************************** This document specifies the format of the lyskomd database files. The specification is currently incomplete. Only the structure, not the actual data records are documented. * Menu: * Version 0:: Database used with early versions of lyskomd. * Version 1:: Database used with lyskomd 1.9.0. * Version 2:: Database used with lyskomd 2.0.0. lyskom-server-2.1.2/doc/lyskomd.info-30000664000015100472110000001465507723710263013303 This is lyskomd.info, produced by makeinfo version 4.2 from lyskomd.texi. This is the reference manual for the lyskomd LysKOM server version 2.1.2. Copyright (C) 1995-2003 Lysator ACS. Permission is granted to make and distribute verbatim copies of this specification provided the copyright notice and this permission notice are preserved on all copies. INFO-DIR-SECTION LysKOM START-INFO-DIR-ENTRY * lyskomd: (lyskomd). lyskomd reference manual. END-INFO-DIR-ENTRY  File: lyskomd.info, Node: Version 0, Next: Version 1, Up: lyskomd Database Specification Data File Version 0 =================== Version 0 was used by lyskomd versions up to 1.8. database : header /NL/ next-free-num /NL/ confs persons next-text-num /NL/ texts ; header : 'CLEAN' | 'DIRTY' ; next-free-num : /INTEGER/ ; confs : confs conf | /empty/ ; conf : empty-record | '+' conf-record /NL/ ; persons : persons person | /empty/ ; person : empty-record | '+' person-record /NL/ ; next-text-num : /INTEGER/ ; texts : texts text | /empty/ ; text : empty-record | '+' text-record 'NL' ; empty-record : '@' 'NL' ; The number of person and conference records is exactly one less than /next-free-num/. The number of text records is exactly one less than /next-text-num/. Records are stored sequentially. Conference number 18 is the 18th conference record in the file. This implies that deleted records must be stored as /empty-record/ records. /next-text-num/ is the number of the highest text. There are exactly one less than this number of text records in the database. /next-free-num/ is the number of the highest conference. There are exactly one less than this number of both person and conference records. This implies that if conference N is not a letterbox, then person record N will be an /empty-record/. If the header says "CLEAN", the database file is complete. If the header says "DIRTY", the server has not finished writing it completely.  File: lyskomd.info, Node: Version 1, Next: Version 2, Prev: Version 0, Up: lyskomd Database Specification Data File Version 1 =================== Version 1 was used by lyskomd version 1.9. database : header 'NL' 'records' ; header : 'CLEAN:00001' | 'DIRTY:00001' ; records : records record | /empty/ ; record : next-free-num | next-text-num | conference | person | info | text | deleted ; next-free-num : '#C' /INTEGER/ ; next-text-num : '#P' /INTEGER/ ; conference : 'C' /integer/ conf-record 'NL' | 'P' /integer/ person-record 'NL' | 'T' /integer/ text-record 'NL' | 'I' info-record 'NL' ; deleted : '-C' /integer/ 'NL' | '-P' /integer/ 'NL' | '-T' /integer/ 'NL' ; The integer in the conference, text and person records is the ID of the record. This implies that records can be in any order. The /next-free-num/ record is used to store the next available ID for conferences in the system. There may be several of these records in the database. The /next-text-num/ record is used to store the next available ID for texts in the system. There may be several of these records in the database. A conference or text must have a number lower than the closest /next-free-num/ or /next-text-num/ preceding it. The deletion records are used to indicate that an object found earlier in the database has been deleted. The implementation of these in lyskomd 1.9 does not work, and they are not used. The /-C/ record indicates deletion of a conference. The /-P/ record indicates deletion of a person. The /-T/ record indicates deletion of a text. The integer in the deletion record is the ID of the object being deleted.  File: lyskomd.info, Node: Version 2, Prev: Version 1, Up: lyskomd Database Specification Data File Version 2 =================== Version 2 is used by lyskomd version 2.0. The structure of the data file is similar to version 1. The header has been extended with a timestamp contaning the time when the database file was saved. This timestamp consists of twenty characters, the number of seconds since 00:00:00 GMT January 1, 1970 (a Unix `time_t'.) database : header 'NL' 'records' ; header : 'CLEAN:00001' 'NL' timestamp 'NL' | 'DIRTY:00001' 'NL' timestamp 'NL' ; timestamp : digit digit digit digit digit digit digit digit digit digit digit digit digit digit digit digit digit digit digit digit ; ; digit : '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' ; Furthermore several data types have been changed to accommodate additions introduced in version 10 of protocol A. The /server-info/, /conf-record/ and /text-record/ include information about aux-items (highest-aux-no and aux-item-list.) The /conf-record/ contains the expire field added to the conf-stat structure. The /conf-record/ and /person-record/ records use the new local-to-global structure for storing maps. lyskom-server-2.1.2/src/0000777000015100472110000000000007723710342010673 5lyskom-server-2.1.2/src/Makefile.am0000664000015100472110000000210107721716116012642 # $Id: Makefile.am,v 1.4 2003/08/23 16:38:21 ceder Exp $ # Copyright (C) 1998, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # include $(top_srcdir)/scripts/common.make SUBDIRS = include libraries server EXTRA_DIST = .cvsignore lyskom-server-2.1.2/src/Makefile.in0000664000015100472110000003455207723707423012675 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # $Id: Makefile.am,v 1.4 2003/08/23 16:38:21 ceder Exp $ # Copyright (C) 1998, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEBUG_CALLS = @DEBUG_CALLS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EFENCE = @EFENCE@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FLEX = @FLEX@ HAVE_PYTHON_FALSE = @HAVE_PYTHON_FALSE@ HAVE_PYTHON_TRUE = @HAVE_PYTHON_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSURE = @INSURE@ LANGUAGE_SUFFIX = @LANGUAGE_SUFFIX@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ SED = @SED@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRACED_ALLOCATIONS = @TRACED_ALLOCATIONS@ U = @U@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ YACC = @YACC@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ RM = rm -f dbdir = $(localstatedir)/lyskomd/db exportdir = $(localstatedir)/lyskomd/exportdb SUBDIRS = include libraries server EXTRA_DIST = .cvsignore subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = DIST_SOURCES = RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \ ps-recursive install-info-recursive uninstall-info-recursive \ all-recursive install-data-recursive install-exec-recursive \ installdirs-recursive install-recursive uninstall-recursive \ check-recursive installcheck-recursive DIST_COMMON = $(top_srcdir)/scripts/common.make Makefile.am Makefile.in DIST_SUBDIRS = $(SUBDIRS) all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/scripts/common.make $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) uninstall-info-am: # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ETAGS = etags ETAGSFLAGS = CTAGS = ctags CTAGSFLAGS = tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if (etags --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ else \ include_option=--include; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -f $$subdir/TAGS && \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$tags$$unique" \ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = .. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) $(mkinstalldirs) $(distdir)/../scripts @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d $(distdir)/$$subdir \ || mkdir $(distdir)/$$subdir \ || exit 1; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" \ distdir=../$(distdir)/$$subdir \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: info: info-recursive info-am: install-data-am: install-exec-am: install-info: install-info-recursive install-man: installcheck-am: maintainer-clean: maintainer-clean-recursive maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-info-am uninstall-info: uninstall-info-recursive .PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \ clean-generic clean-recursive ctags ctags-recursive distclean \ distclean-generic distclean-recursive distclean-tags distdir \ dvi dvi-am dvi-recursive info info-am info-recursive install \ install-am install-data install-data-am install-data-recursive \ install-exec install-exec-am install-exec-recursive \ install-info install-info-am install-info-recursive install-man \ install-recursive install-strip installcheck installcheck-am \ installdirs installdirs-am installdirs-recursive \ maintainer-clean maintainer-clean-generic \ maintainer-clean-recursive mostlyclean mostlyclean-generic \ mostlyclean-recursive pdf pdf-am pdf-recursive ps ps-am \ ps-recursive tags tags-recursive uninstall uninstall-am \ uninstall-info-am uninstall-info-recursive uninstall-recursive # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/src/.cvsignore0000664000015100472110000000002506551006355012606 Makefile Makefile.in lyskom-server-2.1.2/src/include/0000777000015100472110000000000007723710267012324 5lyskom-server-2.1.2/src/include/debug.h0000664000015100472110000000253207721716116013500 /* * $Id: debug.h,v 0.9 2003/08/23 16:38:21 ceder Exp $ * Copyright (C) 1991, 1994-1995, 1999, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ #ifndef NDEBUG #define BUG(s) if (buglevel > 0) printf s ; #define VBUG(s) if (buglevel > 1) printf s ; #define BUGSTR(str) if (buglevel > 0) s_puts(str) #define VBUGSTR(str) if (buglevel > 1) s_puts(str) #define BUGDECL extern int buglevel #else #define BUG(s) #define VBUG(s) #define BUGSTR(str) #define VBUGSTR(str) #define BUGDECL #endif lyskom-server-2.1.2/src/include/kom-types.h0000664000015100472110000004530407723626576014362 /* * $Id: kom-types.h,v 0.64 2003/08/29 10:39:48 ceder Exp $ * Copyright (C) 1990-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * KOM-types.h -- Types used by both server and client of LysKOM * * * Copyright (C) 1990-1999, 2001-2003 Lysator Computer Club, * Linkoping University, Sweden * * Everyone is granted permission to copy, modify and redistribute * this code, provided the people they give it to can. * * * Filecreator: Thomas Bellman * Lysator Computer Club * Linkoping University * Sweden * * email: Bellman@Lysator.LiU.SE */ #ifndef KOM_TYPES_H_ALREADY_INCLUDED #define KOM_TYPES_H_ALREADY_INCLUDED #include #include #include "s-string.h" /* Some objects in LysKOM need a type field. These are the valid values */ enum object_type { NO_OBJECT_TYPE, /* No object at all */ TEXT_OBJECT_TYPE, /* Text object */ CONF_OBJECT_TYPE, /* Conference object */ INFO_OBJECT_TYPE, /* System info object */ }; typedef unsigned short Pers_no; typedef unsigned short Conf_no; typedef unsigned long Text_no; typedef unsigned long Local_text_no; typedef unsigned long Session_no; #define MAX_PERS_NO ((Pers_no) USHRT_MAX) #define MAX_CONF_NO ((Conf_no) USHRT_MAX) #define MAX_TEXT_NO ((Text_no) ULONG_MAX) #define MAX_LOCAL_TEXT_NO ((Local_text_no) ULONG_MAX) #define PASSWD_LEN 64 typedef char Password[PASSWD_LEN]; typedef off_t Text_index; typedef time_t Time; /* * The privilige bits: says what priviliges a person has. E g * if he is allowed to read texts he normally shouldn't be allowed * to read. See file doc/Protocol-A.texi. */ typedef struct { unsigned int wheel : 1; unsigned int admin : 1; unsigned int statistic : 1; unsigned int create_pers: 1; unsigned int create_conf: 1; unsigned int change_name: 1; unsigned int flg7 : 1; /* For future use. */ unsigned int flg8 : 1; unsigned int flg9 : 1; unsigned int flg10 : 1; unsigned int flg11 : 1; unsigned int flg12 : 1; unsigned int flg13 : 1; unsigned int flg14 : 1; unsigned int flg15 : 1; unsigned int flg16 : 1; } Priv_bits; /* * Flags in the Person struct. */ typedef struct { unsigned int unread_is_secret : 1;/* FALSE if everyone is allowed to ask how many unread texts you have. */ unsigned int flg2 : 1; unsigned int flg3 : 1; unsigned int flg4 : 1; unsigned int flg5 : 1; unsigned int flg6 : 1; unsigned int flg7 : 1; unsigned int flg8 : 1; } Personal_flags; /* See file doc/Protocol-A.texi */ enum info_type { recpt = 0, /* 0 Recipient (conference) */ cc_recpt = 1, /* 1 Carbon Copy recipient (extra kopia) */ comm_to = 2, /* 2 Comment to (text) */ comm_in = 3, /* 3 Commented in (text) */ footn_to = 4, /* 4 This is a footnote to (text) */ footn_in = 5, /* 5 Footnote to this text in (text) */ loc_no = 6, /* 6 Sequence number within conference */ rec_time = 7, /* 7 Received at (time) */ sent_by = 8, /* 8 Sent by (person) */ sent_at = 9, /* 9 Sent at (time) */ bcc_recpt = 15, /* 15 BCC recipient (for kannedom) */ unknown_info = 4711 /* Internal use only. Unknown misc item encountered */ }; union info_datum { Conf_no recipient; /* recpt, cc_recpt, bcc_recpt */ Text_no text_link; /* comm_to, comm_in, footn_to, footn_in */ Local_text_no local_no; /* loc_no */ Time received_at; /* rec_time */ Pers_no sender; /* sent_by */ Time sent_at; /* sent_at */ enum info_type unknown_type; /* unknown_info */ }; /* This struct contains miscellaneous information about a text. */ typedef struct { enum info_type type; union info_datum datum; } Misc_info; typedef struct { unsigned short no_of_misc; Misc_info * misc; } Misc_info_list; typedef struct { unsigned int deleted : 1; /* This item has been deleted */ unsigned int inherit : 1; /* Copy to comments */ unsigned int secret : 1; /* Don't show anyone */ unsigned int hide_creator : 1; /* Don't show the creator */ unsigned int dont_garb : 1; /* Don't garb object */ unsigned int reserved3 : 1; unsigned int reserved4 : 1; unsigned int reserved5 : 1; } Aux_item_flags; typedef struct { enum object_type target_type; unsigned long target_item; union { Conf_no conf; Text_no text; } target_object; } Aux_item_link; typedef struct { unsigned long aux_no; Pers_no creator; Time sent_at; Aux_item_flags flags; unsigned long inherit_limit; unsigned long tag; String data; Aux_item_link linked_item; } Aux_item; typedef struct { unsigned short length; Aux_item * items; } Aux_item_list; /* Fields of this type is supposed to tell the garbage collector * which texts it should remove first. */ typedef unsigned long Garb_nice; /* Struct for text status */ typedef struct { Time creation_time; long file_pos; /* Start of the text in the text file. */ Pers_no author; unsigned short no_of_lines; String_size no_of_chars; unsigned short no_of_marks; /* Including syntetic marks. */ unsigned short no_of_misc; /* Recipients, times, comments, ... */ unsigned long highest_aux; Misc_info * misc_items; /* List of miscellaneous info. */ Aux_item_list aux_item_list; } Text_stat; typedef struct { unsigned int rd_prot : 1; /* !(Can anyone become a member?) */ unsigned int original : 1; /* Comments forbidden? */ unsigned int secret : 1; /* Secret conference? */ /* Note: if a letterbox is secret it * will be very hard for that person * to log in, since he can't map his * name to a pers_no. He must either * know his pers_no, or have another * identity which is his supervisor. */ unsigned int letter_box : 1; /* Is this a letter box? */ unsigned int allow_anon : 1; /* do we accept anonymous messages */ unsigned int forbid_secret : 1; /* do we allow secret members */ unsigned int reserved2 : 1; unsigned int reserved3 : 1; } Conf_type; typedef struct { unsigned int invitation : 1; unsigned int passive : 1; unsigned int secret : 1; unsigned int passive_message_invert : 1; unsigned int reserved2 : 1; unsigned int reserved3 : 1; unsigned int reserved4 : 1; unsigned int reserved5 : 1; } Membership_type; typedef struct { Pers_no member; Pers_no added_by; Time added_at; Membership_type type; } Member; /* Struct for marks */ typedef struct { Text_no text_no; unsigned char mark_type; /* It's up to the clients to decide the meaning of this field. */ } Mark; /* Information about a person's membership in a conference */ struct read_range { Local_text_no first_read; Local_text_no last_read; }; struct read_range_list { unsigned short length; struct read_range *ranges; }; typedef struct { unsigned long position; Conf_no conf_no; unsigned char priority; /* Interrupt priority */ Time last_time_read; /* Updated every time a text in this conference is marked as read. */ unsigned int no_of_read_ranges; struct read_range * read_ranges; /* Sorted in ascending order. */ Pers_no added_by; Time added_at; Membership_type type; /* read_ranges is cleared before it reaches the Protocol A output layer in certain situations, even though that layer wants to emit the last-text-read element. This happens for example when get-membership [99] is called with want-read-texts == 0. This variable maintains the last-text-read value. */ Bool skip_read_texts; } Membership; /* Some structs to handle variable-sized arrays. */ typedef struct { unsigned short no_of_marks; Mark * marks; /* Pointer to an array of marks. */ } Mark_list; typedef struct { unsigned short no_of_confs; Conf_no *conf_nos; } Conf_no_list; typedef struct { unsigned short no_of_members; Member * members; } Member_list; /* A list of conference numbers, also telling if it is a * mailbox (i e a person) or an ordinary conference. */ /* Delete this ugly variant as soon as possible! */ typedef struct { unsigned long no_of_conf_nos; Conf_no * conf_nos; Conf_type * type_of_conf; } Conf_list_old; /* This is the way it should look! */ typedef struct { Conf_no conf_no; Conf_type type; } Micro_conf; typedef struct { unsigned long no_of_confs; Micro_conf * confs; } Conf_list; /* A list of person numbers */ typedef struct { unsigned long no_of_persons; Pers_no * persons; } Pers_list; typedef struct { unsigned short no_of_confs; Membership * confs; } Membership_list; typedef struct { int length; long *data; } Number_list; /* The Info struct */ typedef struct { long version; Conf_no conf_pres_conf; /* Presentation of new confs */ Conf_no pers_pres_conf; /* Presentation of new persons */ Conf_no motd_conf; /* Conf that receive motds */ Conf_no kom_news_conf; /* News about kom */ Text_no motd_of_lyskom; /* To be displayed after login */ unsigned long highest_aux_no; /* Last aux-item number */ Aux_item_list aux_item_list; /* System aux items */ /* and maybe more... */ } Info; struct l2g_block_info; /* Nothing outside local-to-global.c should access the contents of a Local_to_global directly. Use the accessor functions declared in local-to-global.h instead. */ typedef struct { int num_blocks; Local_text_no first_unused; struct l2g_block_info * blocks; } Local_to_global; typedef struct { const Local_to_global *l2g; const struct l2g_block_info *binfo; int arrindex; Local_text_no beginval; /* First index in the search */ Local_text_no endval; /* Last index in the search + 1 */ int search_ended; /* 1 if finished, 0 otherwise */ Local_text_no lno; /* The Local_text_no to use */ Text_no tno; /* The Text_no to use */ } L2g_iterator; typedef struct { const Local_to_global *l2g; const struct l2g_block_info *binfo; int arrindex; Local_text_no beginval; /* First index in the search */ Local_text_no endval; /* Last index in the search + 1 */ int search_ended; /* 1 if finished, 0 otherwise */ Local_text_no lno; /* The Local_text_no to use */ Text_no tno; /* The Text_no to use */ } L2g_reverse_iterator; /* This struct holds the information that is needed to output a Text-Mapping. Please note that the protocol A Text-Mapping data type looks very different from this structure. */ typedef struct { Local_text_no first; unsigned long no_of_texts; const Local_to_global *l2g; } Text_mapping; /* This struct holds the information that is needed to output a Text-Mapping in the reverse order. Please note that the protocol A Text-Mapping data type looks very different from this structure. */ typedef struct { Local_text_no ceiling; unsigned long no_of_texts; const Local_to_global *l2g; } Text_mapping_reverse; /* For performance reasons, sort the fields in increasing size. The comments about number of bits are true on a Sun Sparc-2, not necessarily anything else. The code should work anyhow. */ typedef struct { /* 8-bit quantities */ Conf_type type; /* secret, rd_prot etc */ /* 16-bit quantities */ Pers_no creator; Conf_no supervisor; /* Supervisor conference. */ Conf_no permitted_submitters; /* People who are allowed to submit texts to this conf. 0 -> anyone may submit. */ Conf_no super_conf; /* Send unallowed submissions to the super_conf. 0 -> unallowed submissions bounce */ /* 32-bit quantities */ Time creation_time; Text_no presentation; Time last_written; /* Time of latest text in this conf. */ Text_no msg_of_day; /* Message to be displayed when this conf is referenced by the user. */ Garb_nice nice; /* How long do texts in this conf live? */ Garb_nice keep_commented; /* New comments protect texts */ Garb_nice expire; /* When do we auto-kill this */ String name; /* Name of conference */ unsigned long highest_aux; Aux_item_list aux_item_list; Member_list members; /* List of members in conf */ Local_to_global texts; /* List of texts */ } Conference; typedef struct { String name; /* Name of conference */ Conf_type type; /* secret, rd_prot etc */ Conf_no supervisor; /* Supervisor conference */ Local_text_no highest_local_no; /* highest local text no */ Garb_nice nice; /* Number of days to live */ Garb_nice keep_commented; /* New comments protect texts */ } Small_conf; typedef struct { String name; Conf_type type; Conf_no conf_no; } Conf_z_info; typedef struct { unsigned short no_of_confs; Conf_z_info * confs; } Conf_z_info_list; /* Struct for persons */ typedef struct { Text_no user_area; /* Misc info the clients might want to store. 0 = not used. */ Priv_bits privileges; Personal_flags flags; Time last_login; /* Or logout */ unsigned long total_time_present; /* Number of seconds. */ unsigned long sessions; /* Number of sessions */ unsigned long created_lines; /* No. of created lines (statistics) */ unsigned long created_bytes; /* No. of created bytes (statistics) */ unsigned long read_texts; /* No. of read texts (statistics) */ unsigned long no_of_text_fetches; /* (statistics) */ unsigned short created_persons; /* (statistics) */ unsigned short created_confs; /* (statistics) */ String username; /* User-name & hostname */ Local_to_global created_texts; Mark_list marks; /* List of marked texts */ Membership_list conferences; /* List of conferences the person is * a member in. */ Password pwd; /* Encrypted password */ } Person; /* * This struct is returned from the 'who_is_on' call. */ typedef struct { Pers_no person; String what_am_i_doing; Conf_no working_conference; } Who_info_old; typedef struct { Pers_no person; String what_am_i_doing; String username; /* Userid and hostname. */ Conf_no working_conference; Session_no session_no; /* Serial number of connection. */ } Who_info; typedef struct { Pers_no person; String what_am_i_doing; String username; /* Userid and hostname. */ String ident_user; /* According to Ident protocol. */ String hostname; /* According to TCP/IP. */ Conf_no working_conference; Session_no session_no; /* Serial number of connection. */ } Who_info_ident; typedef struct { Pers_no person; String what_am_i_doing; String username; /* Userid and hostname. */ Conf_no working_conference; Session_no session; /* Serial number of connection. */ Time connection_time; /* Not logintime. */ unsigned long idle_time; /* Seconds. */ } Session_info; typedef struct { unsigned int invisible : 1; unsigned int user_active_used : 1; unsigned int user_absent : 1; unsigned int reserved3 : 1; unsigned int reserved4 : 1; unsigned int reserved5 : 1; unsigned int reserved6 : 1; unsigned int reserved7 : 1; } Session_flags; typedef struct { Session_no session; Pers_no person; Conf_no working_conference; unsigned long idle_time; Session_flags flags; String what_am_i_doing; } Dynamic_session_info; typedef struct { long no_of_sessions; Dynamic_session_info * sessions; } Dynamic_session_info_list; typedef struct { String username; String hostname; String ident_user; Time connection_time; } Static_session_info; typedef struct { Pers_no person; String what_am_i_doing; String username; /* Userid and hostname, according to the client. */ String ident_user; /* According to Ident protocol. */ String hostname; /* According to TCP/IP. */ Conf_no working_conference; Session_no session; /* Serial number of connection. */ Time connection_time; /* Not logintime. */ unsigned long idle_time; /* Seconds. */ } Session_info_ident; typedef struct { unsigned short priority; unsigned short weight; } Scheduling_info; typedef struct { int no_of_persons; Who_info_old * info; } Who_info_list_old; typedef struct { int no_of_persons; Who_info * info; } Who_info_list; typedef struct { int no_of_persons; Who_info_ident * info; } Who_info_ident_list; typedef struct { unsigned long protocol_version; String server_name; String server_version; } Version_info; typedef struct { float average; float ascent_rate; float descent_rate; } Stats; typedef struct { int no_of_stats; Stats *stats; } Stats_list; typedef struct { int no_of_stats; String *stat_names; Number_list intervals; } Stats_description; typedef struct { time_t boot_time; time_t save_time; String db_status; Text_no existing_texts; Text_no highest_text_no; Conf_no existing_confs; Conf_no existing_persons; Conf_no highest_conf_no; } Static_server_info; #ifdef DEBUG_CALLS typedef struct { int arena; int ordblks; int smblks; int hblks; int hblkhd; int usmblks; int fsmblks; int uordblks; int fordblks; int keepcost; } Memory_info; #endif typedef struct { unsigned long protocol_version; const char *server_name; const char *server_version; } Version_info_internal; #endif /* ifndef KOM_TYPES_H_ALREADY_INCLUDED__ */ lyskom-server-2.1.2/src/include/kom-errno.h0000664000015100472110000001210607721716117014322 /* * $Id: kom-errno.h,v 0.28 2003/08/23 16:38:21 ceder Exp $ * Copyright (C) 1991-1994, 1996-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * kom_errno.h * * Created by ceder 1990-04-18 * * The values that kom_errno can take. */ #ifndef KOM_ERRNO_ALREADY_INCLUDED #define KOM_ERRNO_ALREADY_INCLUDED enum kom_err { KOM_NO_ERROR = 0, /* No error has occured */ KOM_NOT_IMPL = 2, /* Not implemented yet */ KOM_OBSOLETE = 3, /* No longer implemented */ KOM_PWD = 4, /* Wrong/illegal password */ KOM_LONG_STR = 5, /* String too long */ KOM_LOGIN = 6, /* Not logged in. */ KOM_LOGIN_DISALLOWED = 7, /* System is in 'singel-user mode' */ KOM_CONF_ZERO = 8, /* Attempt to use conference number 0. */ KOM_UNDEF_CONF = 9, /* Undefined or secret conference */ KOM_UNDEF_PERS = 10, /* Undefined or secret person */ KOM_ACCESS = 11, /* No 'read/write permission' */ KOM_PERM = 12, /* No permission */ KOM_NOT_MEMBER = 13, /* Not member in conf */ KOM_NO_SUCH_TEXT = 14, /* No such global text_no, or no access */ KOM_TEXT_ZERO = 15, /* Can't use text no 0 */ KOM_NO_SUCH_LOCAL_TEXT = 16, /* No such local text_no */ KOM_LOCAL_TEXT_ZERO = 17, /* Can't use local text no 0 */ KOM_BAD_NAME = 18, /* Too short/long or contains illegal chars */ KOM_INDEX_OUT_OF_RANGE = 19, /* */ KOM_CONF_EXISTS = 20, /* Already exists */ KOM_PERS_EXISTS = 21, /* Already exists */ KOM_SECRET_PUBLIC = 22, /* Cannot be secret and !rd_prot */ KOM_LETTER_BOX = 23, /* Cannot change letter_box flag */ KOM_LDB_ERR = 24, /* Database is corrupted. */ KOM_ILL_MISC = 25, /* Illegal misc field. err_stat holds field no */ KOM_ILLEGAL_INFO_TYPE = 26, /* Info_type parameter was illegal. This means that there is a bug in the client. */ KOM_ALREADY_RECIPIENT = 27, /* Already recipient to this text. */ KOM_ALREADY_COMMENT = 28, /* Already comment to this text. */ KOM_ALREADY_FOOTNOTE = 29, /* Already footnote to this text. */ KOM_NOT_RECIPIENT = 30, /* Not recipient */ KOM_NOT_COMMENT = 31, /* Not comment to this text. */ KOM_NOT_FOOTNOTE = 32, /* Not footnote to this text. */ KOM_RECIPIENT_LIMIT = 33, /* Too many recipients */ KOM_COMM_LIMIT = 34, /* Too many comments */ KOM_FOOT_LIMIT = 35, /* Too many footnotes */ KOM_MARK_LIMIT = 36, /* Too many marks. */ KOM_NOT_AUTHOR = 37, /* Only the author may add footnotes or delete texts. */ KOM_OUT_OF_MEMORY = 39, /* Couldn't get memory for result */ KOM_CLIENT_IS_CRAZY = 41, /* The client used an illegal call sequence. */ KOM_UNDEF_SESSION = 42, /* No such session exists. */ KOM_REGEX_ERROR = 43, /* Regexp compilation failed. */ KOM_NOT_MARKED = 44, /* Attempt to unmark an unmarked text. */ KOM_TEMPFAIL = 45, /* Try again later. */ KOM_LONG_ARRAY = 46, /* Too long array supplied. */ KOM_ANON_REJECTED = 47, /* Anonymous text not allowed in conference. */ KOM_ILL_AUX = 48, /* Bad misc item */ KOM_AUX_PERM = 49, /* No permission to set aux */ KOM_UNKNOWN_ASYNC = 50, /* Accepting an unknown async message */ KOM_INTERNAL_ERROR = 51, /* Internal server error */ KOM_FEATURE_DISABLED = 52, /* Server feature is disabled */ KOM_MESSAGE_NOT_SENT = 53, /* Message not sent (no recipient found) */ KOM_INVALID_MEMBERSHIP_TYPE = 54, /* Invalid membership type */ KOM_INVALID_RANGE = 55, /* Invalid range (low >= high) */ KOM_INVALID_RANGE_LIST = 56, /* Invalid range list (not properly sorted) */ KOM_UNDEFINED_MEASUREMENT = 57, /* Bad measurement name. */ KOM_PRIORITY_DENIED = 58, /* You cannot lower your priority that much. */ KOM_WEIGHT_DENIED = 59, /* You cannot increase your weight that much.*/ KOM_WEIGHT_ZERO = 60, /* You cannot increase your weight that much.*/ KOM_BAD_BOOL = 61, /* A Bool must be 0 or 1. */ KOM_num_errs /* End marker */ }; extern enum kom_err kom_errno; extern unsigned long err_stat; /* Additional information about the error */ /* * print a short description of the error to kom_errout (from config.h). */ void kom_perror(void); #endif /* _KOM_ERRNO_ALREADY_INCLUDED__ */ lyskom-server-2.1.2/src/include/misc-types.h0000664000015100472110000000625007721716117014511 /* * $Id: misc-types.h,v 0.13 2003/08/23 16:38:21 ceder Exp $ * Copyright (C) 1990-1991, 1994-1996, 1999, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * misc-types.h -- Miscellaneous types and constants that are useful * in many places in LysKOM, but are not very LysKOM- * specific. * * * Copyright (C) 1990-1991, 1994-1996, 1999, 2003 Lysator Computer Club, * Linkoping University, Sweden * * Everyone is granted permission to copy, modify and redistribute * this code, provided the people they give it to can. * * * Author: Thomas Bellman * Lysator Computer Club * Linkoping University * Sweden * * email: Bellman@Lysator.LiU.SE * */ #ifndef MISC_TYPES_ALREADY_INCLUDED #define MISC_TYPES_ALREADY_INCLUDED /* AIX 3.2 defines FALSE in . */ #ifdef FALSE # if FALSE != 0 # error FALSE was defined to a non-zero value # endif # undef FALSE #endif #ifdef TRUE # if TRUE != 1 # error TRUE was defined to a non-one value # endif # undef TRUE #endif /* Define TYPE_CHECK_COMPILATION to get warnings from the compiler if there is a mixup between Success and Bool. This doesn't produce working code. In fact, it doesn't even compile. You will get several errors, since a boolean expression cannot be assigned to a pointer. You have to manually check that all reported errors are due to the implementation below, and not because of a mixup. */ #undef TYPE_CHECK_COMPILATION /* Define SUCCESS_AS_PTR if you want the Success type to be a pointer rather than an enum. This should be a little less efficient, but might get more errors from the compiler. Implied by TYPE_CHECK_COMPILATION. */ #define SUCCESS_AS_PTR #if defined(TYPE_CHECK_COMPILATION) struct kom_bool { short unused; }; typedef const struct kom_bool *Bool; extern const struct kom_bool *const TRUE; extern const struct kom_bool *const FALSE; #else typedef enum { FALSE = 0, TRUE = 1 } Bool; #endif #if defined(SUCCESS_AS_PTR) || defined(TYPE_CHECK_COMPILATION) struct success { int unused[1]; }; typedef const struct success *Success; extern const struct success *const OK; extern const struct success *const FAILURE; #else typedef enum { OK = 017, FAILURE = 17 } Success; #endif #define NO_TIME ((time_t) 0) #endif /* _MISC_TYPES_ALREADY_INCLUDED__ */ lyskom-server-2.1.2/src/include/services.h0000664000015100472110000004010307722446216014233 /* * $Id: services.h,v 0.71 2003/08/25 17:14:06 ceder Exp $ * Copyright (C) 1991-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * services.h -- All the services the LysKOM server makes available * for clients. * * These functions match the requests defined in doc/Protocol-A.texi. * See the descriptions in that file for documentation. * * Created by ceder 1990-03-23 */ #ifndef SERVICES_H_ALREADY_INCLUDED #define SERVICES_H_ALREADY_INCLUDED /* * Session control */ extern Success login_old (Pers_no person, const String passwd); extern Success login (Pers_no person, const String passwd, Bool invisible); extern Success logout (void); /* can never fail */ /* Change Conference */ extern Success change_conference (Conf_no conference); /* Change name of a person or conference. */ extern Success change_name (Conf_no conf_no, const String new_name); extern Success change_what_i_am_doing (String what_am_i_doing); /* Client version: one call to set, two to retrieve. */ extern Success set_client_version (const String client_name, const String client_version); extern Success get_client_name (Session_no session_no, String *result); extern Success get_client_version (Session_no session_no, String *result); extern Success set_scheduling(Session_no session_no, unsigned short priority, unsigned short weight); /* Get info about a session */ extern Success get_session_info (Session_no session_no, Session_info *result); extern Success get_session_info_ident (Session_no session_no, Session_info_ident *result); extern Success get_static_session_info (Session_no session_no, Static_session_info *result); extern Success get_scheduling(Session_no session_no, Scheduling_info *result); /* * Disconnect a session. You can disconnect your own session (even if * you are not logged in) and any session where you are supervisor of * the user that is logged in on that session. */ extern Success disconnect (Session_no session_no); /* * Returns your session number */ extern Success who_am_i (Session_no *session_no); /* * Set state in the session */ extern Success user_active (void); extern Success set_connection_time_format(int use_utc); /****************************** * Person-related calls * ******************************/ /* * Create a new person. Returns 0 if any error occured. */ extern Pers_no create_person_old (const String name, const String passwd); extern Pers_no create_person (const String name, const String passwd, Personal_flags flags, Aux_item_list *conf_aux); extern Success set_pers_flags(Pers_no pers_no, Personal_flags flags); /* Obsolete call; use get_person_stat instead. */ extern Success get_person_stat_old (Pers_no person, int mask, Person * result); extern Success get_person_stat (Pers_no person, Person * result); extern Success get_created_texts (Pers_no person, Local_text_no first, unsigned long no_of_texts, L2g_iterator *created_texts); extern Success map_created_texts (Pers_no person, Local_text_no first, unsigned long no_of_texts, Text_mapping *created_texts); extern Success map_created_texts_reverse(Pers_no person, Local_text_no local_no_ceiling, unsigned long no_of_texts, Text_mapping_reverse *created_texts); extern Success get_membership_old (Pers_no person, unsigned short first, unsigned short no_of_confs, Bool want_read_texts, Membership_list * memberships); extern Success get_membership_10(Pers_no person, unsigned short first, unsigned short no_of_confs, Bool want_read_texts, Membership_list * memberships); extern Success get_membership(Pers_no person, unsigned short first, unsigned short no_of_confs, Bool want_read_ranges, unsigned long max_ranges, Membership_list * memberships); extern Success set_priv_bits (Pers_no person, Priv_bits privileges); /* Set the password of PERSON to NEW_PWD. OLD_PWD is the password * of the person who does the set. This is not necessarily the * same as the one who gets it set. */ extern Success set_passwd (Pers_no person, const String old_pwd, const String new_pwd); /* You can query for unread texts without logging in. */ extern Success query_read_texts_old (Pers_no pers_no, Conf_no conf_no, Membership * result ); extern Success query_read_texts_10(Pers_no pers_no, Conf_no conf_no, Membership * result); extern Success query_read_texts(Pers_no pers_no, Conf_no conf_no, Bool want_read_ranges, unsigned long max_ranges, Membership *result); extern Success get_unread_confs(Pers_no pers_no, Conf_no_list *result); extern Success set_user_area(Pers_no pers_no, Text_no user_area); /**************************************** * Conference-related calls * ****************************************/ extern Conf_no create_conf_old (const String name, Conf_type type); extern Conf_no create_conf (const String name, Conf_type type, Aux_item_list *aux); extern Success modify_conf_info (Conf_no conf_no, Number_list *items_to_delete, Aux_item_list *items_to_add); /* Delete a conference. Also used to delete persons. */ extern Success delete_conf (Conf_no conf); /* * Map conference name to number. Returns a list of the conferences * that match the name NAME. Can be done without logging in. * This should be phased out. */ extern Success lookup_name (const String name, Conf_list_old *result); extern Success lookup_z_name (const String name, int want_persons, int want_confs, Conf_z_info_list *result); /* Use these two lookup-calls instead of lookup_name */ extern Success lookup_person (const String pattern, Conf_no_list *result); extern Success lookup_conf (const String pattern, Conf_no_list *result); /* Two functions for matching regexps. */ extern Success re_lookup_person (const String regexp, Conf_no_list *result); extern Success re_lookup_conf (const String regexp, Conf_no_list *result); extern Success re_z_lookup (const String regexp, int want_persons, int want_confs, Conf_z_info_list *result); extern Success get_collate_table (String * result); extern Success get_conf_stat_older (Conf_no conf_no, int mask, Conference *result); extern Success get_conf_stat_old (Conf_no conf_no, Conference * result); extern Success get_conf_stat (Conf_no conf_no, Conference * result); extern Success get_uconf_stat (Conf_no conf_no, Small_conf * result); extern Success get_members (Conf_no conf, unsigned short first, unsigned short no_of_members, Member_list * members); extern Success get_members_old (Conf_no conf, unsigned short first, unsigned short no_of_members, Member_list * members ); /* add_member is also used to change the priority of a conference */ extern Success add_member (Conf_no conf_no, Pers_no pers_no, unsigned char priority, unsigned short where, /* Range of where is [0..] */ Membership_type * type); extern Success add_member_old (Conf_no conf_no, Pers_no pers_no, unsigned char priority, unsigned short where ); /* Range of where is [0..] */ extern Success set_membership_type (Pers_no pers_no, Conf_no conf_no, Membership_type *type ); extern Success sub_member (Conf_no conf_no, Pers_no pers_no); /* * Tell the server that I want to mark/unmark texts as read so that I * get no_of_unread unread texts in conf_no. * * The new alternative function marks last_read as the last read local * text. Use this one to avoid race conditions. */ extern Success set_unread (Conf_no conf_no, Text_no no_of_unread); extern Success set_last_read (Conf_no conf_no, Local_text_no last_read); /* * set_presentation and set_etc_motd also does some magic with the * no_of_marks field in the Text_stat structure of the old and new text. */ extern Success set_presentation (Conf_no conf_no, Text_no text_no); /* 0 to delete pres. */ extern Success set_etc_motd (Conf_no conf_no, Text_no text_no); extern Success set_supervisor (Conf_no conf_no, Conf_no admin ); extern Success set_permitted_submitters (Conf_no conf_no, Conf_no perm_sub); extern Success set_super_conf (Conf_no conf_no, Conf_no super_conf); extern Success set_conf_type (Conf_no conf_no, Conf_type type ); extern Success set_garb_nice (Conf_no conf_no, Garb_nice days); /* number of days */ extern Success set_expire (Conf_no conf_no, Garb_nice expire); /* number of days */ extern Success set_keep_commented(Conf_no conf_no, Garb_nice keep_commented); /* number of days */ extern Success first_unused_conf_no(Conf_no *result); /* * Return next/previous existing text-no. */ extern Success find_next_conf_no(Conf_no start, Conf_no *result); extern Success find_previous_conf_no(Conf_no start, Conf_no *result); /******************************** * Calls to handle marks * ********************************/ extern Success get_marks (Mark_list *result); /* * Will fail if the user is not allowed to read the text. */ /* This function uses mark_type==0 to delete the mark. */ extern Success mark_text_old (Text_no text, unsigned char mark_type); /* Using this function, you can set mark_type==0. */ extern Success mark_text (Text_no text, unsigned char mark_type); /* Remove a mark, reporting an error if you had not marked the text. */ extern Success unmark_text (Text_no text); /******************************* * Calls to handle texts * *******************************/ extern Success get_text (Text_no text, String_size start_char, String_size end_char, String * result); extern Success get_text_stat (Text_no text, Text_stat *result); extern Success get_text_stat_old (Text_no text, Text_stat *result); extern Success mark_as_read(Conf_no conference, const Number_list *texts); /* Local_text_no */ extern Success mark_as_unread(Conf_no conference, Local_text_no lno); extern Success set_read_ranges(Conf_no conference, const struct read_range_list *read_ranges); /* Returns 0 on error */ extern Text_no create_text (const String message, Misc_info_list * misc, Aux_item_list * aux); extern Text_no create_text_old (const String message, Misc_info_list * misc ); /* Returns 0 on error. */ extern Text_no create_anonymous_text (const String message, Misc_info_list * misc, Aux_item_list *aux); extern Text_no create_anonymous_text_old (const String message, Misc_info_list * misc); extern Success delete_text( Text_no text_no); extern Success modify_text_info(Text_no text, Number_list *items_to_delete, Aux_item_list *aux); extern Success add_recipient (Text_no text_no, Conf_no conf_no, enum info_type type); extern Success sub_recipient (Text_no text_no, Conf_no conf_no); extern Success add_comment (Text_no comment, Text_no comment_to); /* * Make the text COMMENT to not be a comment to text COMMENT_TO */ extern Success sub_comment (Text_no comment, Text_no comment_to); extern Success add_footnote (Text_no footnote, Text_no footnote_to); extern Success sub_footnote (Text_no footnote, Text_no parent); extern Success first_unused_text_no(Text_no *result); extern Success get_map (Conf_no conf_no, Local_text_no first_local_no, unsigned long no_of_texts, L2g_iterator *result); extern Success local_to_global (Conf_no conf_No, Local_text_no first_local_no, unsigned long no_of_texts, Text_mapping *result); extern Success local_to_global_reverse(Conf_no conf_No, Local_text_no local_no_ceiling, unsigned long no_of_texts, Text_mapping_reverse *result); /* * Ask what the server thinks the time is. This * might differ if on two different machines. */ extern Success get_time (time_t *t); /* * Gets the last text before a given time. */ extern Success get_last_text (struct tm *clk, Text_no *result); /* * Return next/previous existing text-no. */ extern Success find_next_text_no (Text_no start, Text_no *result); extern Success find_previous_text_no (Text_no start, Text_no *result); /* * Who is logged on now? */ extern Success who_is_on_old (Who_info_list_old * result); extern Success who_is_on (Who_info_list * result); extern Success who_is_on_ident (Who_info_ident_list *result); extern Success who_is_on_dynamic (int want_visible, int want_invisible, long active_last, Dynamic_session_info_list *result); /* * Return various information about the server */ extern Success get_info_old (Info *result); extern Success get_info (Info *result); extern Success get_version_info (Version_info *result); /* * Privileged calls. */ extern Success set_info(Info *info); extern Success modify_system_info(Number_list *items_to_delete, Aux_item_list *items_to_add); extern Success set_motd_of_lyskom (Text_no motd); /* * Set ena_level. 0 means don't use any privileges. */ extern Success enable (unsigned char ena_level); /* * Make LysKOM sync its files. */ extern Success sync_kom (void); /* * Close LysKOM. */ extern Success shutdown_kom (int exit_val); /* * Send a message to all clients. This is obsoleted by send_message(), * but will remain for compatibility reasons. */ extern Success broadcast (const String message); /* * Send a message to a person, or all persons. If recipient == 0 all * connections will receive the message. */ extern Success send_message (Conf_no recipient, const String message); /* * Selection of asynchronous messages */ extern Success accept_async(Number_list *accept_list); extern Success query_async(Number_list *result); /* * Aux-items */ extern Success query_predefined_aux_items(Number_list *result); /* * Measuread statistical numbers. */ extern Success get_stats_description(Stats_description *result); extern Success get_stats(const String what, Stats_list *result); /* * Boot-time information. */ extern Success get_boottime_info(Static_server_info *result); #ifdef DEBUG_CALLS extern Success get_memory_info(Memory_info *result); extern Success set_marks(Text_no text_no, unsigned long no_of_marks); extern Success backdate_text(Text_no text_no, unsigned long seconds); /* Modify the "sent_at" item. It must already exist. */ extern Success backdate_comment_link(Text_no parent, Text_no child, unsigned long seconds); extern Success start_garb(void); extern Success cache_sync_start(void); extern Success cache_sync_finish(void); extern Success dump_cfg_timevals(void); extern Success server_sleep(int secs); #endif #endif /* _SERVICES_H_ALREADY_INCLUDED__ */ lyskom-server-2.1.2/src/include/kom-config.h0000664000015100472110000000702507721716117014446 /* * $Id: kom-config.h,v 1.12 2003/08/23 16:38:21 ceder Exp $ * Copyright (C) 1991-1994, 1998-1999, 2002-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * config.h * * Configuration parameters for compiling. Contains among other * things all the stupid limits you really want to be without, all the * smart limits that has to be there to make it impossible to crash * the server, and lots of constants and configuration options. * * Almost all of this can currently be set in a configuration file. * There is normally no reason to change anything in this file. */ /* Collating sequence used. */ #define DEFAULT_COLLAT_TAB swedish_collate_tab /* The file kom_perror prints to. */ /* Yes! This should be stdout. At least during testing and debugging! /ceder */ #define kom_errout stdout extern const char *get_default_config_file_name(void); extern void free_default_config_file_name(void); /* Communications */ /* * MAX_NO_OF_CONNECTIONS must be small enough. Each connection takes one * file descriptor, and it is important that there are a few descriptors * left so that it is possible to save the data base. lyskomd might crash * if this number is too big and that many connection attempts are made * simultaneously. * * The following descriptors are open by LysKOM: * stdin, stdout, stderr (stdin and stdout could probably be closed. * The log() function prints to stderr.) * TEXTFILE_NAME (always open) * DATAFILE_NAME (often open) * STATISTIC_NAME (open after a SIGUSR1) * One TCP/IP ports (listening for normal connections) * One UDP/IP port (probably from -lresolv, but I'm not sure) * One TCP/IP port (if HAVE_LIBAUTHUSER is defined) * One TCP and one UDP port (used by ADNS) * Two pipes (used by signal.c in liboop) * Thus, the max number of connections is the number of available file * descriptors minus 13. This has not been fully tested for a long * while, so we subtract 9 more just to be on the safe side. * * Machines where less or more files are open should set this in the * configure script. * * Also defined in src/server/testsuite/config/unix.exp. */ #ifndef PROTECTED_FDS #define PROTECTED_FDS (13 + 9) #endif #if (defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE) \ && !defined(HAVE_BROKEN_NOFILE)) # define USING_RLIMIT_NOFILE 1 #else # undef USING_RLIMIT_NOFILE #endif /* * An upper limit of how many file descriptors lyskomd will have opened * simultaneously. This is set at the beginning of main(). The first * PROTECTED_FDS file descriptors are never used for clients. */ extern int fd_ceiling; /* What is whitespace? */ extern const char *WHITESPACE; lyskom-server-2.1.2/src/include/Makefile.am0000664000015100472110000000224307721716116014274 # $Id: Makefile.am,v 1.12 2003/08/23 16:38:21 ceder Exp $ # Copyright (C) 1998-1999, 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # include $(top_srcdir)/scripts/common.make noinst_HEADERS = debug.h kom-types.h kom-errno.h \ misc-types.h services.h kom-config.h SUBDIRS = server EXTRA_DIST = .cvsignore ChangeLog.1 lyskom-server-2.1.2/src/include/Makefile.in0000664000015100472110000003504207723707423014313 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # $Id: Makefile.am,v 1.12 2003/08/23 16:38:21 ceder Exp $ # Copyright (C) 1998-1999, 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEBUG_CALLS = @DEBUG_CALLS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EFENCE = @EFENCE@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FLEX = @FLEX@ HAVE_PYTHON_FALSE = @HAVE_PYTHON_FALSE@ HAVE_PYTHON_TRUE = @HAVE_PYTHON_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSURE = @INSURE@ LANGUAGE_SUFFIX = @LANGUAGE_SUFFIX@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ SED = @SED@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRACED_ALLOCATIONS = @TRACED_ALLOCATIONS@ U = @U@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ YACC = @YACC@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ RM = rm -f dbdir = $(localstatedir)/lyskomd/db exportdir = $(localstatedir)/lyskomd/exportdb noinst_HEADERS = debug.h kom-types.h kom-errno.h \ misc-types.h services.h kom-config.h SUBDIRS = server EXTRA_DIST = .cvsignore ChangeLog.1 subdir = src/include ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = DIST_SOURCES = HEADERS = $(noinst_HEADERS) RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \ ps-recursive install-info-recursive uninstall-info-recursive \ all-recursive install-data-recursive install-exec-recursive \ installdirs-recursive install-recursive uninstall-recursive \ check-recursive installcheck-recursive DIST_COMMON = $(noinst_HEADERS) $(top_srcdir)/scripts/common.make \ Makefile.am Makefile.in DIST_SUBDIRS = $(SUBDIRS) all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/scripts/common.make $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/include/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) uninstall-info-am: # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ETAGS = etags ETAGSFLAGS = CTAGS = ctags CTAGSFLAGS = tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if (etags --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ else \ include_option=--include; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -f $$subdir/TAGS && \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$tags$$unique" \ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = ../.. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) $(mkinstalldirs) $(distdir)/../../scripts @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d $(distdir)/$$subdir \ || mkdir $(distdir)/$$subdir \ || exit 1; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" \ distdir=../$(distdir)/$$subdir \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(HEADERS) installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: info: info-recursive info-am: install-data-am: install-exec-am: install-info: install-info-recursive install-man: installcheck-am: maintainer-clean: maintainer-clean-recursive maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-info-am uninstall-info: uninstall-info-recursive .PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \ clean-generic clean-recursive ctags ctags-recursive distclean \ distclean-generic distclean-recursive distclean-tags distdir \ dvi dvi-am dvi-recursive info info-am info-recursive install \ install-am install-data install-data-am install-data-recursive \ install-exec install-exec-am install-exec-recursive \ install-info install-info-am install-info-recursive install-man \ install-recursive install-strip installcheck installcheck-am \ installdirs installdirs-am installdirs-recursive \ maintainer-clean maintainer-clean-generic \ maintainer-clean-recursive mostlyclean mostlyclean-generic \ mostlyclean-recursive pdf pdf-am pdf-recursive ps ps-am \ ps-recursive tags tags-recursive uninstall uninstall-am \ uninstall-info-am uninstall-info-recursive uninstall-recursive # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/src/include/.cvsignore0000664000015100472110000000002506551006357014233 Makefile Makefile.in lyskom-server-2.1.2/src/include/ChangeLog.10000664000015100472110000001534106210047321014137 Sat Aug 3 01:46:14 1996 Per Cederqvist * services.h (who_is_on_dynamic): New argument: active_last. * misc-types.h (TRUE, FALSE): AIX porting: Undefine them if they are defined, but make sure they are defined to sensible values first. * kom-types.h (Conf_type): Renamed anarchy to allow_anon. * services.h (change_conference): New name for former pepsi. Fri Aug 2 01:41:36 1996 Per Cederqvist * Handle idle-time: * services.h (user_active): New function. (who_is_on_dynamic): New function. (get_static_session_info): New function. * kom-types.h (Session_flags): New type. (Dynamic_session_info): New type. (Dynamic_session_info_list): New type. (Static_session_info): New type. Sun Jul 28 17:42:14 1996 Per Cederqvist * kom-errno.h (Kom_err): New value: KOM_ANON_REJECTED. Fri Jul 26 02:20:25 1996 Per Cederqvist * kom-types.h (Number_list): Change the length from unsigned short to int. The length field should be fixed in all the data types in kom-types.h. More thought is necessary here. * kom-errno.h (Kom_err): New value: KOM_LONG_ARRAY. Sun Jul 14 23:02:34 1996 Per Cederqvist * Added the Jun 10 14:01:16 1996 entry which David Byers forgot. Sat Jul 13 15:54:24 1996 Per Cederqvist (ceder@lysator.liu.se) * services.h (set_last_read): The second argument is a Local_text_no, not a Text_no. Mon Jun 10 14:01:16 1996 David Byers * kom-types.h: (Number_list): New data type. * services.h: (accept_async, query_async): New function. Mon Jun 10 14:01:16 1996 David Byers * services.h (set_info): New function. Tue Sep 5 20:30:20 1995 Per Cederqvist (ceder@lysator.liu.se) * compiler.h (NORETURN): New define. (Volatile, Inline): Removed. Fri Sep 1 21:55:03 1995 Per Cederqvist (ceder@lysator.liu.se) * rcs.h (USE): Changes to shut up gcc 2.7.0. Sat Dec 31 16:13:15 1994 Per Cederqvist (ceder@lysator.liu.se) * services.h (lookup_z_name): New function. Tue Dec 27 00:30:26 1994 Per Cederqvist (ceder@lysator.liu.se) * services.h (re_z_lookup, get_version_info): New functions. (send_message): The recipient is now a Conf_no, not necessarily a Pers_no. * kom-types.h: (Conf_z_info, Conf_z_info_list, Version_info, Version_info_internal): New structs. * kom-errno.h (Kom_err): New explanation for KOM_LDB_ERR, which is now used if the database becomes corrupted. Deleted the unused values KOM_SERVER_IS_CRAZY and KOM_CLIENT_IS_CRAZY. Sat Aug 20 00:02:57 1994 Per Cederqvist (ceder@lysator.liu.se) * kom-errno.h (Kom_err): Deleted the unused value KOM_PERS_EXISTS. Sat Jun 18 20:48:34 1994 Per Cederqvist (ceder@lysator.liu.se) * debug.h: Don't include config.h. Test NDEUBG instead of DEBUG. * config.h (DEBUG, LOGACCESSES, DEFENSIVE_CHECKS): Removed. Use configure to set NDEBUG, LOGACCESSES or NDEFENSIVE_CHECKS instead. Sat Mar 5 18:20:39 1994 Per Cederqvist (ceder@lysator.liu.se) * Makefile.src: New file, template for Makefile.in. Sat Feb 19 05:51:13 1994 Per Cederqvist (ceder@lysator.liu.se) * kom-types.h: No longer supports -DCLIENT. Only -DSERVER works. lyskomd and the tty-client now have separate copies of this file. (DEFAULT_PRIV_BITS, DEFAULT_PERSONAL_FLAGS, EMPTY_TEXT_STAT, NULL_CONF_TYPE, EMPTY_MEMBERSHIP, EMPTY_MARK_LIST, EMPTY_CONF_NO_LIST, EMPTY_MEMBER_LIST, EMPTY_TEXT_LIST, EMPTY_CONF_LIST_OLD, EMPTY_CONF_LIST, EMPTY_PERS_LIST, EMPTY_MEMBERSHIP_LIST, EMPTY_CONFERENCE, EMPTY_SMALL_CONF, EMPTY_PERSON, EMPTY_WHO_INFO_IDENT, EMPTY_SESSION_INFO, EMPTY_SESSION_INFO_IDENT, EMPTY_WHO_INFO_OLD, EMPTY_WHO_INFO, EMPTY_WHO_INFO_LIST_OLD, EMPTY_WHO_INFO_LIST, EMPTY_WHO_INFO_IDENT_LIST): Removed. Fri Jan 14 20:08:55 1994 Per Cederqvist (ceder@lysator.liu.se) * kom-errno.h (KOM_TEMPFAIL): New error code. * config.h: Removed everything which can be set in the server configuration file. Wed Jan 12 02:23:44 1994 Per Cederqvist (ceder@lysator.liu.se) * kom-types.h (Conference): Reordered the fields, eliminating some unnecessary padding. * config.h (CONFIG_FILE): New constant. Mon Oct 18 13:03:23 1993 Per Cederqvist (ceder@lysator.liu.se) * kom-types.h: Don't include any files. Sat Oct 16 17:35:58 1993 Per Cederqvist (ceder@lysator.liu.se) * kom-types.h: Changes for vcc: Write "{ 0, NULL }" instead of "((Foo){ 0, NULL})". Cleanup. Wed Oct 13 00:24:13 1993 Per Cederqvist (ceder@lysator.liu.se) * services.h (get_last_text): Now takes a (struct tm *) in both the server and client parts. Sun Oct 10 12:58:00 1993 Per Cederqvist (ceder@lysator.liu.se) * services.h (shutdown_kom): Renamed shutdown to shutdown_kom, to avoid name clashes with libc. * (sync_kom): Renamed sync to sync_kom, for the same reason. * kom-types.h (EMPTY_tm_i): Added missing parenthesis. * config.h: Use sysconf instead of getdtablesize, if sysconf exists. Fri Oct 8 00:15:36 1993 Per Cederqvist (ceder@lysator.liu.se) * kom-types.h: Use "unsigned long" instead of "u_long". * kom-errno.h: Don't include . Use "unsigned long" instead of "u_long". Thu Aug 5 00:52:50 1993 Per Cederqvist (ceder@lysator.liu.se) * kom-errno.h (KOM_NOT_MARKED): New error number. * services.h (set_client_version, get_client_name, get_client_version): New functions. * services.h (lookup_person, lookup_conf): New functions. * services.h (mark_text_old, mark_text, unmark_text): New functions. The previous function mark_text() is removed. * services.h (create_text, create_anonymous_text): The first argument is const in the server as well as in the client. Thu Feb 25 00:01:40 1993 Linus Tolke Y (linus@bodil) * services.h (register_saving): New function. Mon Feb 1 02:00:41 1993 Linus Tolke Y (linus@rune) * services.h (register_directed_message): New function. Sun Jan 17 00:08:26 1993 Per Cederqvist (ceder@konrad) * rcs.h: New file. Use the USE macro to avoid warnings about unused variables. * Makefile (INSTALL-HDRS): Add rcs.h. Sat Dec 19 01:13:14 1992 Per Cederqvist (ceder@mauritz) * services.h (re_lookup_person, re_lookup_conf): New functions. * config.h (REGEXP_LEN): New constant. * kom-errno.h (KOM_REGEX_ERROR): New error. Sun Nov 22 16:04:11 1992 Per Cederqvist (ceder@mauritz) * config.h (LOGACCESSES): New symbol. Sat Apr 4 19:08:51 1992 Per Cederqvist (ceder@lysator) * kom-types.h (Who_info_ident, Who_info_ident_list, Session_info_ident): New types. Wed Apr 1 22:01:25 1992 Per Cederqvist (ceder@lysator) * services.h (login, get_session_info_ident, who_is_on_ident): New functions. * services.h (login_old): New name for login(). Tue Oct 29 06:11:40 1991 Per Cederqvist (ceder at lysator) * config.h (PROTECTED_FDS): 8 was not enough. Use 12. lyskom-server-2.1.2/src/include/server/0000777000015100472110000000000007723710270013624 5lyskom-server-2.1.2/src/include/server/smalloc.h0000664000015100472110000000377307721716117015363 /* * $Id: smalloc.h,v 0.13 2003/08/23 16:38:21 ceder Exp $ * Copyright (C) 1991-1992, 1994-1995, 1998-1999, 2002-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * Wrappers around malloc()/realloc()/free() that never returns NULL. */ /* * "safe" malloc. Handles the case when malloc returns NULL. smalloc * will never return on failure. Will always return a distinct * pointer, even when size is 0. The memory allocated memory must be * returned to sfree() or srealloc(), not to free() */ extern void * smalloc(size_t size); extern void sfree(void * ptr); /* it is legal to sfree a NULL pointer */ extern void * srealloc(void * ptr, size_t size); /* Never fails. It is legal to realloc the NULL ptr. */ /* * Allocate temporary memory, which is automatically freed after this * atomic call. */ void * tmp_alloc(unsigned long size); /* * Free all core which is allocated with tmp_alloc(). This is called from * end_of_atomic(). */ void free_tmp(void); /* * Free all memory used internally in tmp_alloc(). */ void free_all_tmp(void); /* * Write statistics of memory usage. */ void dump_smalloc_counts(FILE *stat_file); lyskom-server-2.1.2/src/include/server/Makefile.am0000664000015100472110000000207307721716117015604 # $Id: Makefile.am,v 1.4 2003/08/23 16:38:21 ceder Exp $ # Copyright (C) 1998, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # include $(top_srcdir)/scripts/common.make noinst_HEADERS = smalloc.h EXTRA_DIST = .cvsignore lyskom-server-2.1.2/src/include/server/Makefile.in0000664000015100472110000002544507723707423015627 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # $Id: Makefile.am,v 1.4 2003/08/23 16:38:21 ceder Exp $ # Copyright (C) 1998, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEBUG_CALLS = @DEBUG_CALLS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EFENCE = @EFENCE@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FLEX = @FLEX@ HAVE_PYTHON_FALSE = @HAVE_PYTHON_FALSE@ HAVE_PYTHON_TRUE = @HAVE_PYTHON_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSURE = @INSURE@ LANGUAGE_SUFFIX = @LANGUAGE_SUFFIX@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ SED = @SED@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRACED_ALLOCATIONS = @TRACED_ALLOCATIONS@ U = @U@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ YACC = @YACC@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ RM = rm -f dbdir = $(localstatedir)/lyskomd/db exportdir = $(localstatedir)/lyskomd/exportdb noinst_HEADERS = smalloc.h EXTRA_DIST = .cvsignore subdir = src/include/server ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = DIST_SOURCES = HEADERS = $(noinst_HEADERS) DIST_COMMON = $(noinst_HEADERS) $(top_srcdir)/scripts/common.make \ Makefile.am Makefile.in all: all-am .SUFFIXES: $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/scripts/common.make $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/include/server/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) uninstall-info-am: ETAGS = etags ETAGSFLAGS = CTAGS = ctags CTAGSFLAGS = tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$tags$$unique" \ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = ../../.. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) $(mkinstalldirs) $(distdir)/../../../scripts @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(HEADERS) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-am dvi-am: info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic ctags \ distclean distclean-generic distclean-tags distdir dvi dvi-am \ info info-am install install-am install-data install-data-am \ install-exec install-exec-am install-info install-info-am \ install-man install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags \ uninstall uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/src/include/server/.cvsignore0000664000015100472110000000002506551006363015536 Makefile Makefile.in lyskom-server-2.1.2/src/libraries/0000777000015100472110000000000007723710341012646 5lyskom-server-2.1.2/src/libraries/Makefile.am0000664000015100472110000000216007721716117014624 # $Id: Makefile.am,v 1.10 2003/08/23 16:38:21 ceder Exp $ # Copyright (C) 1998, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # include $(top_srcdir)/scripts/common.make SUBDIRS = adns liboop libisc-new libansi regex libcommon libmisc libeintr EXTRA_DIST = .cvsignore lyskom-server-2.1.2/src/libraries/Makefile.in0000664000015100472110000003466507723707423014656 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # $Id: Makefile.am,v 1.10 2003/08/23 16:38:21 ceder Exp $ # Copyright (C) 1998, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEBUG_CALLS = @DEBUG_CALLS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EFENCE = @EFENCE@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FLEX = @FLEX@ HAVE_PYTHON_FALSE = @HAVE_PYTHON_FALSE@ HAVE_PYTHON_TRUE = @HAVE_PYTHON_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSURE = @INSURE@ LANGUAGE_SUFFIX = @LANGUAGE_SUFFIX@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ SED = @SED@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRACED_ALLOCATIONS = @TRACED_ALLOCATIONS@ U = @U@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ YACC = @YACC@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ RM = rm -f dbdir = $(localstatedir)/lyskomd/db exportdir = $(localstatedir)/lyskomd/exportdb SUBDIRS = adns liboop libisc-new libansi regex libcommon libmisc libeintr EXTRA_DIST = .cvsignore subdir = src/libraries ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = DIST_SOURCES = RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \ ps-recursive install-info-recursive uninstall-info-recursive \ all-recursive install-data-recursive install-exec-recursive \ installdirs-recursive install-recursive uninstall-recursive \ check-recursive installcheck-recursive DIST_COMMON = $(top_srcdir)/scripts/common.make Makefile.am Makefile.in DIST_SUBDIRS = $(SUBDIRS) all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/scripts/common.make $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/libraries/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) uninstall-info-am: # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ETAGS = etags ETAGSFLAGS = CTAGS = ctags CTAGSFLAGS = tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if (etags --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ else \ include_option=--include; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -f $$subdir/TAGS && \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$tags$$unique" \ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = ../.. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) $(mkinstalldirs) $(distdir)/../../scripts @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d $(distdir)/$$subdir \ || mkdir $(distdir)/$$subdir \ || exit 1; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" \ distdir=../$(distdir)/$$subdir \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: info: info-recursive info-am: install-data-am: install-exec-am: install-info: install-info-recursive install-man: installcheck-am: maintainer-clean: maintainer-clean-recursive maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-info-am uninstall-info: uninstall-info-recursive .PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \ clean-generic clean-recursive ctags ctags-recursive distclean \ distclean-generic distclean-recursive distclean-tags distdir \ dvi dvi-am dvi-recursive info info-am info-recursive install \ install-am install-data install-data-am install-data-recursive \ install-exec install-exec-am install-exec-recursive \ install-info install-info-am install-info-recursive install-man \ install-recursive install-strip installcheck installcheck-am \ installdirs installdirs-am installdirs-recursive \ maintainer-clean maintainer-clean-generic \ maintainer-clean-recursive mostlyclean mostlyclean-generic \ mostlyclean-recursive pdf pdf-am pdf-recursive ps ps-am \ ps-recursive tags tags-recursive uninstall uninstall-am \ uninstall-info-am uninstall-info-recursive uninstall-recursive # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/src/libraries/.cvsignore0000664000015100472110000000002506551006366014564 Makefile Makefile.in lyskom-server-2.1.2/src/libraries/adns/0000777000015100472110000000000007723710276013602 5lyskom-server-2.1.2/src/libraries/adns/README0000664000015100472110000001750107705623127014402 This version of adns has been modified and crippled for the LysKOM project. See ../../../ChangeLog for a log of changes. If you want to use adns in your project, you are adviced to go get the original sources instead of this. Only parts of the adns distribution are included with the lyskom-server distribution. GNU adns Advanced, easy to use, asynchronous-capable DNS client library and utilities. adns is a resolver library for C (and C++) programs, and a collection of useful DNS resolver utilities. C library In contrast with the standard interfaces, gethostbyname et al and libresolv, it has the following features: * It is reasonably easy to use for simple programs which just want to translate names to addresses, look up MX records, etc. * It can be used in an asynchronous, non-blocking, manner. Many queries can be handled simultaneously. * Responses are decoded automatically into a natural representation for a C program - there is no need to deal with DNS packet formats. * Sanity checking (eg, name syntax checking, reverse/forward correspondence, CNAME pointing to CNAME) is performed automatically. * Time-to-live, CNAME and other similar information is returned in an easy-to-use form, without getting in the way. * There is no global state in the library; resolver state is an opaque data structure which the client creates explicitly. A program can have several instances of the resolver. * Errors are reported to the application in a way that distinguishes the various causes of failure properly. * Understands conventional resolv.conf, but this can overridden by environment variables. * Flexibility. For example, the application can tell adns to: ignore environment variables (for setuid programs), disable hostname syntax sanity checks to return arbitrary data, override or ignore resolv.conf in favour of supplied configuration, etc. * Believed to be correct ! For example, will correctly back off to TCP in case of long replies or queries, or to other nameservers if several are available. It has sensible handling of bad responses etc. DNS utility programs adns also comes with a number of utility programs for use from the command line and in scripts: * adnslogres is a much faster version of Apache's logresolv program. * adnsresfilter is a filter which copies its input to its output, replacing IP addresses by the corresponding names, without unduly delaying the output. For example, you can usefully pipe the output of netstat -n, tcpdump -ln, and the like, into it. * adnshost is a general-purpose DNS lookup utility which can be used easily in from the command line and from shell scripts to do simple lookups. In a more advanced mode it can be used as a general-purpose DNS helper program for scripting languages which can invoke and communicate with subprocesses. See the [1]adnshost usage message for a summary of its capabilities. Documentation I'm afraid there is no manual yet. However, competent C programmers should be able to use the library based on the [2]commented adns.h header file, and the usage messages for the programs should be sufficient. Feedback I'd be pleased if you would let me know if you're using my library in your project, and what you think of it. If you are subscribed to adns-discuss please send feedback, including bug reports, there; otherwise send mail to adns-bugreports@chiark.greenend.org.uk. If you'd prefer that your message wasn't forwarded to the adns-bugreports list, send it to adns-maint@chiark.greenend.org.uk. Mailinglists I have set up mailinglists adns-announce and adns-discuss. The announcements list is moderated and will contain only announcements of important bugs, new versions, etc. The bug reports address mentioned above is also a mailing list; feel free to subscribe to it. There are [3]archives and subscription web pages, or you can subscribe by sending mail containing the word `subscribe' to adns-announce-REQUEST@chiark.greenend.org.uk or adns-discuss-REQUEST@chiark.greenend.org.uk. Download Available for download from [4]chiark.greenend.org.uk are: * The [5]current release as a gzipped tarfile. * [6]adns.h API header file with comments, and [7]usage message for adnshost (currently there is no manual, sorry). * All versions released so far are also available via [8]anonymous FTP and [9]HTTP, * A mirror of my CVS repository is available via rsync from rsync.chiark.greenend.org.uk::ftp/users/ian/cvs-pub/adns (use FTP first to find your way around), or via [10]cvsweb. adns is also available from the [11]GNU Project FTP servers and their [12]mirrors. Technical note adns requires a real nameserver like [13]BIND or [14]Dents running on the same system or a nearby one, which must be willing to provide `recursive service'. I.e., adns is a `stub resolver'. All properly configured UN*X and GNU systems will already have such nameserver(s); they are usually listed in /etc/resolv.conf. Copyright and licensing adns is Copyright 1997-2000 Ian Jackson, Copyright 1999-2000 Tony Finch, and Copyright (C) 1991 Massachusetts Institute of Technology. adns 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 2 of the License, or (at your option) any later version. This program and documentation 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 [15]GNU General Public License for more details. You should have received a copy of the GNU General Public License along with adns, or one should be available above; if not, write to the [16]Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or email adns-maint@chiark.greenend.org.uk. _________________________________________________________________ [17]Ian Jackson / [18]adns-maint@chiark.greenend.org.uk; more [19]free software by me. [20]GNU home page; [21]chiark home page; [22]site or mirror home page This web page is Copyright (C)1996-2000 Ian Jackson. See the [23]Copyright/acknowledgements. Use any browser - [24]Campaign for a non-browser-specific WWW References 1. http://www.chiark.greenend.org.uk/~ian/adns/adnshost.txt 2. http://www.chiark.greenend.org.uk/~ian/adns/adns.h.txt 3. http://www.chiark.greenend.org.uk/mailman/listinfo 4. http://www.chiark.greenend.org.uk/~ian/adns/ 5. http://www.chiark.greenend.org.uk/~ian/adns/adns.tar.gz 6. http://www.chiark.greenend.org.uk/~ian/adns/adns.h.txt 7. http://www.chiark.greenend.org.uk/~ian/adns/adnshost.txt 8. ftp://ftp.chiark.greenend.org.uk/users/ian/adns/ 9. http://www.chiark.greenend.org.uk/~ian/adns/ftp/ 10. http://www.chiark.greenend.org.uk/ucgi/~ijackson/cvsweb/adns/ 11. http://www.gnu.org/ 12. http://www.gnu.org/order/ftp.html 13. http://www.isc.org/view.cgi?/products/BIND/index.phtml 14. http://www.dents.org/ 15. http://www.chiark.greenend.org.uk/~ian/COPYING.txt 16. http://www.fsf.org/ 17. http://www.chiark.greenend.org.uk/ 18. mailto:adns-maint@chiark.greenend.org.uk 19. http://www.chiark.greenend.org.uk/~ian/software/ 20. http://www.gnu.org/ 21. http://www.chiark.greenend.org.uk/ 22. file://localhost/ 23. http://www.chiark.greenend.org.uk/~ian/sw-www-copy.html 24. http://www.anybrowser.org/campaign/ lyskom-server-2.1.2/src/libraries/adns/COPYING0000664000015100472110000004312707705611222014551 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. lyskom-server-2.1.2/src/libraries/adns/INSTALL0000664000015100472110000001226307705611222014544 INSTALLATION INSTRUCTIONS for GNU ADNS 1. Read the security note below. 2. Standard GNU package build process: $ ./configure [--disable-dynamic] [--prefix=... ...] $ make # make install Unfortunately, there is no comprehensive documentation yet. For now, use the comments in the public header file adns.h, and for the C programs their usage messages. If you find this information ambiguous, incomplete or wrong, please report it as a bug. TESTED PLATFORMS The following platforms have been tested at at least some point and should work - please report if they don't: adns version OS 1.0 Linux glibc 2.1 (actually tested on Debian 2.2) 1.0 Solaris 2.6, 2.7, 2.8 [3] 1.0 FreeBSD 3.2, 4.0 (no poll(2), so no adnsresfilter) The following work, but only with --disable-dynamic: 1.0 IRIX 6.5 *not* with GCC [1], [2] 1.0 AIX 4.1.5 1.0 HP-UX 10.20, 11.00 Later versions of the same OS should work too. Usually entries in this table mean adns passes its own regression test, when compiled with GCC, and appears to install and run correctly. If you have more information for this table please let me know. Notes/known problems: [1] IRIX 6.5 inet_ntoa seems to break with GCC. [2] The SGI IRIX compiler produces many spurious warnings. [3] Dynamically linked, needs some help to find libadns.so.1.0. The following platforms are known to be deficient and will not work: Solaris 2.5 Lacks vsnprintf - install glibc ? TruUnix64 (DEC UNIX 4.0f) Lacks vsnprintf - install glibc ? Please don't report these problems unless you have a nice, straightforward solution or workaround for them. (I don't consider including a `vsnprintf' implementation nice, so don't send me one.) PORTABILITY INFORMATION You will find that adns requires a reasonably standard and up to date system. Systems which are neither GNU nor UNIX are not supported. The build system assumes by default that you have ELF shared libraries, and that the directory in which libadns.so.1 will be installed is on your dynamic library search path. If your system doesn't have ELF shared libraries then dynamic linking is not supported by adns. Use the --disable-shared configure option. Please don't send me patches to use libtool (which I dislike). Compilers other than GNU C should work, but are not well-tested. Feel free to send me patches to improve the situation. However, the Makefiles only know how to use GCC to make dynamic libraries. The adnsresfilter utility uses `tsearch' from the C library (a la SVID and X/Open). If you don't have tsearch configure will arranges for adnsresfilter not to be built. To fix this, install a C library containing tsearch, such as the GNU C library. It is best if tsearch uses an automatically-balancing tree algorithm, like the glibc version does. Simple binary trees may perform badly. If you change the m4 input files in regress/ you may need GNU m4. You will probably find that GNU Make is required. Please do not report this as a bug; install GNU Make instead. SECURITY AND PERFORMANCE - AN IMPORTANT NOTE adns is not a `full-service resolver': it does no caching of responses at all, and has no defence against bad nameservers or fake packets which appear to come from your real nameservers. It relies on the full-service resolvers listed in resolv.conf to handle these tasks. For secure and reasonable operation you MUST run a full-service nameserver on the same system as your adns applications, or on the same local, fully trusted network. You MUST only list such nameservers in the adns configuration (eg resolv.conf). You MUST use a firewall or other means to block packets which appear to come from these nameservers, but which were actually sent by other, untrusted, entities. Furthermore, adns is not DNSSEC-aware in this version; it doesn't understand even how to ask a DNSSEC-aware nameserver to perform the DNSSEC cryptographic signature checking. COPYRIGHT This file, INSTALL, contains installation instructions and other details for adns. It is Copyright (C) 1997-2000 Ian Jackson adns is Copyright (C) 1997-2000 Ian Jackson Copyright (C) 1999-2000 Tony Finch [1] Copyright (C) 1991 Massachusetts Institute of Technology [2] adns 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 2 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 adns as the file COPYING; if not, email me at the address above or write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. [1] Tony Finch holds the original copyright on client/adnslogres.c and client/fanftest.c, and some modifications to those files. [2] MIT hold the original copyright on the included install-sh, which came via GNU autoconf. # Local variables: # mode: text # End: lyskom-server-2.1.2/src/libraries/adns/Makefile.am0000664000015100472110000000067107722446220015552 # adns makefile for the lyskom-server environment. AUTOMAKE_OPTIONS = foreign # SUBDIRS omitted from the lyskom-server distribution of adns: # client: some useful programs. # dynamic: building a shared library. # regress: test suite. SUBDIRS = src client # Files omitted from the lyskom-server distribution of adns: # settings.make.in: obsoleted by our automake use. EXTRA_DIST = .cvsignore GPL-vs-LGPL README.html TODO changelog lyskom-server-2.1.2/src/libraries/adns/Makefile.in0000664000015100472110000003736007723707506015600 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # adns makefile for the lyskom-server environment. srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = . am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WARNS = @WARNS@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ prefix = @prefix@ program_transform_name = @program_transform_name@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ AUTOMAKE_OPTIONS = foreign # SUBDIRS omitted from the lyskom-server distribution of adns: # client: some useful programs. # dynamic: building a shared library. # regress: test suite. SUBDIRS = src client # Files omitted from the lyskom-server distribution of adns: # settings.make.in: obsoleted by our automake use. EXTRA_DIST = .cvsignore GPL-vs-LGPL README.html TODO changelog subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/src/config.h CONFIG_CLEAN_FILES = DIST_SOURCES = RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \ ps-recursive install-info-recursive uninstall-info-recursive \ all-recursive install-data-recursive install-exec-recursive \ installdirs-recursive install-recursive uninstall-recursive \ check-recursive installcheck-recursive DIST_COMMON = README COPYING INSTALL Makefile.am Makefile.in TODO \ acinclude.m4 aclocal.m4 configure configure.in depcomp \ install-sh missing mkinstalldirs DIST_SUBDIRS = $(SUBDIRS) all: all-recursive .SUFFIXES: am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe) $(top_builddir)/config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) cd $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): configure.in acinclude.m4 cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) uninstall-info-am: # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ETAGS = etags ETAGSFLAGS = CTAGS = ctags CTAGSFLAGS = tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if (etags --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ else \ include_option=--include; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -f $$subdir/TAGS && \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$tags$$unique" \ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = . distdir = $(PACKAGE)-$(VERSION) am__remove_distdir = \ { test ! -d $(distdir) \ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr $(distdir); }; } GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print distdir: $(DISTFILES) $(am__remove_distdir) mkdir $(distdir) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d $(distdir)/$$subdir \ || mkdir $(distdir)/$$subdir \ || exit 1; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" \ distdir=../$(distdir)/$$subdir \ distdir) \ || exit 1; \ fi; \ done -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r $(distdir) dist-gzip: distdir $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist dist-all: distdir $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist $(am__remove_distdir) GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf - chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && cd $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && $(mkinstalldirs) "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist-gzip \ && rm -f $(distdir).tar.gz \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck $(am__remove_distdir) @echo "$(distdir).tar.gz is ready for distribution" | \ sed 'h;s/./=/g;p;x;p;x' distuninstallcheck: @cd $(distuninstallcheck_dir) \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: info: info-recursive info-am: install-data-am: install-exec-am: install-info: install-info-recursive install-man: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-info-am uninstall-info: uninstall-info-recursive .PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \ clean-generic clean-recursive ctags ctags-recursive dist \ dist-all dist-gzip distcheck distclean distclean-generic \ distclean-recursive distclean-tags distcleancheck distdir \ distuninstallcheck dvi dvi-am dvi-recursive info info-am \ info-recursive install install-am install-data install-data-am \ install-data-recursive install-exec install-exec-am \ install-exec-recursive install-info install-info-am \ install-info-recursive install-man install-recursive \ install-strip installcheck installcheck-am installdirs \ installdirs-am installdirs-recursive maintainer-clean \ maintainer-clean-generic maintainer-clean-recursive mostlyclean \ mostlyclean-generic mostlyclean-recursive pdf pdf-am \ pdf-recursive ps ps-am ps-recursive tags tags-recursive \ uninstall uninstall-am uninstall-info-am \ uninstall-info-recursive uninstall-recursive # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/src/libraries/adns/TODO0000664000015100472110000000066007705611222014201 WISHLIST: * Make timeouts configurable. * `fake' reverse queries (give nnn.nnn.nnn.nnn either always or on error) * `fake' forward queries (allow nnn.nnn.nnn.nnn -> A) * DNSSEC compatibility - be able to retreive KEY and SIG RRs * DNSSEC minimum functionality - ignore Additional when AD set. * IPv6 name<->address translation - but which version ?? * IPv6 transport. * Threadsafe version/mode. * Caching in the library. * SRV RRs. lyskom-server-2.1.2/src/libraries/adns/acinclude.m40000664000015100472110000000461707705622146015717 # aclocal.m4 - package-specific macros for autoconf # # This file is # Copyright (C) 1997-1999 Ian Jackson # # It is part of adns, which is # Copyright (C) 1997-1999 Ian Jackson # Copyright (C) 1999-2000 Tony Finch # # This file is part of adns, which is Copyright (C) 1997-1999 Ian Jackson # # 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 2, 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, write to the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. dnl DPKG_CACHED_TRY_COMPILE(,,,,,) define(DPKG_CACHED_TRY_COMPILE,[ AC_MSG_CHECKING($1) AC_CACHE_VAL($2,[ AC_TRY_COMPILE([$3],[$4],[$2=yes],[$2=no]) ]) if test "x$$2" = xyes; then true $5 else true $6 fi ]) define(ADNS_C_GCCATTRIB,[ DPKG_CACHED_TRY_COMPILE(__attribute__((,,)),adns_cv_c_attribute_supported,, [extern int testfunction(int x) __attribute__((,,))], AC_MSG_RESULT(yes) AC_DEFINE(HAVE_GNUC25_ATTRIB) DPKG_CACHED_TRY_COMPILE(__attribute__((noreturn)),adns_cv_c_attribute_noreturn,, [extern int testfunction(int x) __attribute__((noreturn))], AC_MSG_RESULT(yes) AC_DEFINE(HAVE_GNUC25_NORETURN), AC_MSG_RESULT(no)) DPKG_CACHED_TRY_COMPILE(__attribute__((const)),adns_cv_c_attribute_const,, [extern int testfunction(int x) __attribute__((const))], AC_MSG_RESULT(yes) AC_DEFINE(HAVE_GNUC25_CONST), AC_MSG_RESULT(no)) DPKG_CACHED_TRY_COMPILE(__attribute__((format...)),adns_cv_attribute_format,, [extern int testfunction(char *y, ...) __attribute__((format(printf,1,2)))], AC_MSG_RESULT(yes) AC_DEFINE(HAVE_GNUC25_PRINTFFORMAT), AC_MSG_RESULT(no)), AC_MSG_RESULT(no)) ]) define(ADNS_C_GETFUNC,[ AC_CHECK_FUNC([$1],,[ AC_CHECK_LIB([$2],[$1],[$3],[ AC_MSG_ERROR([cannot find library function $1]) ]) ]) ]) lyskom-server-2.1.2/src/libraries/adns/aclocal.m40000664000015100472110000010120607723707470015362 # generated automatically by aclocal 1.7.6 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 # Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # aclocal.m4 - package-specific macros for autoconf # # This file is # Copyright (C) 1997-1999 Ian Jackson # # It is part of adns, which is # Copyright (C) 1997-1999 Ian Jackson # Copyright (C) 1999-2000 Tony Finch # # This file is part of adns, which is Copyright (C) 1997-1999 Ian Jackson # # 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 2, 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, write to the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. dnl DPKG_CACHED_TRY_COMPILE(,,,,,) define(DPKG_CACHED_TRY_COMPILE,[ AC_MSG_CHECKING($1) AC_CACHE_VAL($2,[ AC_TRY_COMPILE([$3],[$4],[$2=yes],[$2=no]) ]) if test "x$$2" = xyes; then true $5 else true $6 fi ]) define(ADNS_C_GCCATTRIB,[ DPKG_CACHED_TRY_COMPILE(__attribute__((,,)),adns_cv_c_attribute_supported,, [extern int testfunction(int x) __attribute__((,,))], AC_MSG_RESULT(yes) AC_DEFINE(HAVE_GNUC25_ATTRIB) DPKG_CACHED_TRY_COMPILE(__attribute__((noreturn)),adns_cv_c_attribute_noreturn,, [extern int testfunction(int x) __attribute__((noreturn))], AC_MSG_RESULT(yes) AC_DEFINE(HAVE_GNUC25_NORETURN), AC_MSG_RESULT(no)) DPKG_CACHED_TRY_COMPILE(__attribute__((const)),adns_cv_c_attribute_const,, [extern int testfunction(int x) __attribute__((const))], AC_MSG_RESULT(yes) AC_DEFINE(HAVE_GNUC25_CONST), AC_MSG_RESULT(no)) DPKG_CACHED_TRY_COMPILE(__attribute__((format...)),adns_cv_attribute_format,, [extern int testfunction(char *y, ...) __attribute__((format(printf,1,2)))], AC_MSG_RESULT(yes) AC_DEFINE(HAVE_GNUC25_PRINTFFORMAT), AC_MSG_RESULT(no)), AC_MSG_RESULT(no)) ]) define(ADNS_C_GETFUNC,[ AC_CHECK_FUNC([$1],,[ AC_CHECK_LIB([$2],[$1],[$3],[ AC_MSG_ERROR([cannot find library function $1]) ]) ]) ]) # Do all the work for Automake. -*- Autoconf -*- # This macro actually does too much some checks are only needed if # your package does certain things. But this isn't really a big deal. # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 10 AC_PREREQ([2.54]) # Autoconf 2.50 wants to disallow AM_ names. We explicitly allow # the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl # test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AM_MISSING_PROG(AMTAR, tar) AM_PROG_INSTALL_SH AM_PROG_INSTALL_STRIP # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl ]) ]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $1 | $1:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) # Copyright 2002 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.7"]) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION so it can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.7.6])]) # Helper functions for option handling. -*- Autoconf -*- # Copyright 2001, 2002 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 2 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # ------------------------------ # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ---------------------------------- # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # # Check to make sure that the build environment is sane. # # Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 3 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # -*- Autoconf -*- # Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 3 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # AM_AUX_DIR_EXPAND # Copyright 2001 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. # Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50]) AC_DEFUN([AM_AUX_DIR_EXPAND], [ # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. # Copyright 2001 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl install_sh=${install_sh-"$am_aux_dir/install-sh"} AC_SUBST(install_sh)]) # AM_PROG_INSTALL_STRIP # Copyright 2001 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # -*- Autoconf -*- # Copyright (C) 2003 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 1 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # serial 5 -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "GCJ", or "OBJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c : > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # (even with -Werror). So we grep stderr for any message # that says an option was ignored. if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, [ --disable-dependency-tracking Speeds up one-time builds --enable-dependency-tracking Do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH]) ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. #serial 2 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [for mf in $CONFIG_FILES; do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # So let's grep whole file. if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue # Extract the definition of DEP_FILES from the Makefile without # running `make'. DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"` test -z "$DEPDIR" && continue # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n -e '/^U = / s///p' < "$mf"` test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" # We invoke sed twice because it is the simplest approach to # changing $(DEPDIR) to its actual value in the expansion. for file in `sed -n -e ' /^DEP_FILES = .*\\\\$/ { s/^DEP_FILES = // :loop s/\\\\$// p n /\\\\$/ b loop p } /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each `.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 2 # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright 1997, 2000, 2001 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 5 AC_PREREQ(2.52) # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE]) AC_SUBST([$1_FALSE]) if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]) fi])]) lyskom-server-2.1.2/src/libraries/adns/configure0000775000015100472110000052473707723707511015447 #! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.57 for adns 1.0-lyskom-server. # # Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 # Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi # Support unset when possible. if (FOO=FOO; unset FOO) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" # Sed expression to map a string onto a valid variable name. as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` exec 6>&1 # # Initializations. # ac_default_prefix=/usr/local ac_config_libobj_dir=. cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. # This variable seems obsolete. It should probably be removed, and # only ac_max_sed_lines should be used. : ${ac_max_here_lines=38} # Identity of this package. PACKAGE_NAME='adns' PACKAGE_TARNAME='adns' PACKAGE_VERSION='1.0-lyskom-server' PACKAGE_STRING='adns 1.0-lyskom-server' PACKAGE_BUGREPORT='' # Factoring default headers for most tests. ac_includes_default="\ #include #if HAVE_SYS_TYPES_H # include #endif #if HAVE_SYS_STAT_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_STRING_H # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif # include #endif #if HAVE_STRINGS_H # include #endif #if HAVE_INTTYPES_H # include #else # if HAVE_STDINT_H # include # endif #endif #if HAVE_UNISTD_H # include #endif" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE am__leading_dot CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CPP RANLIB ac_ct_RANLIB AR EGREP WARNS LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_option in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` eval "enable_$ac_feature=no" ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "enable_$ac_feature='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package| sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "with_$ac_package='$ac_optarg'" ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/-/_/g'` eval "with_$ac_package=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` eval "$ac_envvar='$ac_optarg'" export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute paths. for ac_var in exec_prefix prefix do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* | NONE | '' ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # Be sure to have absolute paths. for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ localstatedir libdir includedir oldincludedir infodir mandir do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_confdir=`(dirname "$0") 2>/dev/null || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 { (exit 1); exit 1; }; } else { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi fi (cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 { (exit 1); exit 1; }; } srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` ac_env_build_alias_set=${build_alias+set} ac_env_build_alias_value=$build_alias ac_cv_env_build_alias_set=${build_alias+set} ac_cv_env_build_alias_value=$build_alias ac_env_host_alias_set=${host_alias+set} ac_env_host_alias_value=$host_alias ac_cv_env_host_alias_set=${host_alias+set} ac_cv_env_host_alias_value=$host_alias ac_env_target_alias_set=${target_alias+set} ac_env_target_alias_value=$target_alias ac_cv_env_target_alias_set=${target_alias+set} ac_cv_env_target_alias_value=$target_alias ac_env_CC_set=${CC+set} ac_env_CC_value=$CC ac_cv_env_CC_set=${CC+set} ac_cv_env_CC_value=$CC ac_env_CFLAGS_set=${CFLAGS+set} ac_env_CFLAGS_value=$CFLAGS ac_cv_env_CFLAGS_set=${CFLAGS+set} ac_cv_env_CFLAGS_value=$CFLAGS ac_env_LDFLAGS_set=${LDFLAGS+set} ac_env_LDFLAGS_value=$LDFLAGS ac_cv_env_LDFLAGS_set=${LDFLAGS+set} ac_cv_env_LDFLAGS_value=$LDFLAGS ac_env_CPPFLAGS_set=${CPPFLAGS+set} ac_env_CPPFLAGS_value=$CPPFLAGS ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} ac_cv_env_CPPFLAGS_value=$CPPFLAGS ac_env_CPP_set=${CPP+set} ac_env_CPP_value=$CPP ac_cv_env_CPP_set=${CPP+set} ac_cv_env_CPP_value=$CPP ac_env_AR_set=${AR+set} ac_env_AR_value=$AR ac_cv_env_AR_set=${AR+set} ac_cv_env_AR_value=$AR # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures adns 1.0-lyskom-server to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] _ACEOF cat <<_ACEOF Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data [PREFIX/share] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --infodir=DIR info documentation [PREFIX/info] --mandir=DIR man documentation [PREFIX/man] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of adns 1.0-lyskom-server:";; esac cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-dependency-tracking Speeds up one-time builds --enable-dependency-tracking Do not reject slow dependency extractors Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor AR ar program to use Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. _ACEOF fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. ac_popdir=`pwd` for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d $ac_dir || continue ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be # absolute. ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` cd $ac_dir # Check for guested configure; otherwise get Cygnus style configure. if test -f $ac_srcdir/configure.gnu; then echo $SHELL $ac_srcdir/configure.gnu --help=recursive elif test -f $ac_srcdir/configure; then echo $SHELL $ac_srcdir/configure --help=recursive elif test -f $ac_srcdir/configure.ac || test -f $ac_srcdir/configure.in; then echo $ac_configure --help else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi cd $ac_popdir done fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF adns configure 1.0-lyskom-server generated by GNU Autoconf 2.57 Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit 0 fi exec 5>config.log cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by adns $as_me 1.0-lyskom-server, which was generated by GNU Autoconf 2.57. Invocation command line was $ $0 $@ _ACEOF { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` hostinfo = `(hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_sep= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" # Get rid of the leading space. ac_sep=" " ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Be sure not to use single quotes in there, as some shells, # such as our DU 5.0 friend, will then `close' the trap. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, { (set) 2>&1 | case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in *ac_space=\ *) sed -n \ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" ;; *) sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------- ## ## Output files. ## ## ------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo sed "/^$/d" confdefs.h | sort echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core core.* *.core && rm -rf conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo >confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . $cache_file;; *) . ./$cache_file;; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in `(set) 2>&1 | sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val="\$ac_cv_env_${ac_var}_value" eval ac_new_val="\$ac_env_${ac_var}_value" case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers src/config.h" am__api_version="1.7" ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f $ac_dir/shtool; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} { (exit 1); exit 1; }; } fi ac_config_guess="$SHELL $ac_aux_dir/config.guess" ac_config_sub="$SHELL $ac_aux_dir/config.sub" ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL=$ac_install_sh fi fi echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo "$as_me:$LINENO: checking whether build environment is sane" >&5 echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6 # Just in case sleep 1 echo timestamp > conftest.file # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&5 echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&2;} { (exit 1); exit 1; }; } fi test "$2" = conftest.file ) then # Ok. : else { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! Check your system clock" >&5 echo "$as_me: error: newly created file is older than distributed files! Check your system clock" >&2;} { (exit 1); exit 1; }; } fi echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 test "$program_prefix" != NONE && program_transform_name="s,^,$program_prefix,;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s,\$,$program_suffix,;$program_transform_name" # Double any \ or $. echo might interpret backslashes. # By default was `s,x,x', remove it if useless. cat <<\_ACEOF >conftest.sed s/[\\$]/&&/g;s/;s,x,x,$// _ACEOF program_transform_name=`echo $program_transform_name | sed -f conftest.sed` rm conftest.sed # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_AWK+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then echo "$as_me:$LINENO: result: $AWK" >&5 echo "${ECHO_T}$AWK" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$AWK" && break done echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'` if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.make <<\_ACEOF all: @echo 'ac_maketemp="$(MAKE)"' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` if test -n "$ac_maketemp"; then eval ac_cv_prog_make_${ac_make}_set=yes else eval ac_cv_prog_make_${ac_make}_set=no fi rm -f conftest.make fi if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 SET_MAKE= else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} { (exit 1); exit 1; }; } fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE=adns VERSION=1.0 cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} AMTAR=${AMTAR-"${am_missing_run}tar"} install_sh=${install_sh-"$am_aux_dir/install-sh"} # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then echo "$as_me:$LINENO: result: $STRIP" >&5 echo "${ECHO_T}$STRIP" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 echo "${ECHO_T}$ac_ct_STRIP" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi STRIP=$ac_ct_STRIP else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" # We need awk for the "check" target. The system "awk" is bad on # some platforms. ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$ac_ct_CC" && break done CC=$ac_ct_CC fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO:" \ "checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 (eval $ac_compiler --version &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 (eval $ac_compiler -v &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 (eval $ac_compiler -V &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. echo "$as_me:$LINENO: checking for C compiler default output" >&5 echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6 ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 (eval $ac_link_default) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Find the output, starting from the most likely. This scheme is # not robust to junk in `.', hence go to wildcards (a.*) only as a last # resort. # Be careful to initialize this variable, since it used to be cached. # Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. ac_cv_exeext= # b.out is created by i960 compilers. for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; conftest.$ac_ext ) # This is the source file. ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` # FIXME: I believe we export ac_cv_exeext for Libtool, # but it would be cool to find out if it's true. Does anybody # maintain Libtool? --akim. export ac_cv_exeext break;; * ) break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6 # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether the C compiler works" >&5 echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6 echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` export ac_cv_exeext break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6 rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6 OBJEXT=$ac_cv_objext ac_objext=$OBJEXT echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS CFLAGS="-g" echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_prog_cc_g=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 if test "${ac_cv_prog_cc_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_stdc=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF # Don't try gcc -ansi; that turns off useful extensions and # breaks some systems' header files. # AIX -qlanglvl=ansi # Ultrix and OSF/1 -std1 # HP-UX 10.20 and later -Ae # HP-UX older versions -Aa -D_HPUX_SOURCE # SVR4 -Xc -D__EXTENSIONS__ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_stdc=$ac_arg break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext done rm -f conftest.$ac_ext conftest.$ac_objext CC=$ac_save_CC fi case "x$ac_cv_prog_cc_stdc" in x|xno) echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6 ;; *) echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 CC="$CC $ac_cv_prog_cc_stdc" ;; esac # Some people use a C++ compiler to compile C. Since we use `exit', # in C++ we need to declare it. In case someone uses the same compiler # for both compiling C and C++ we need to have the C++ compiler decide # the declaration of exit, since it's the most demanding environment. cat >conftest.$ac_ext <<_ACEOF #ifndef __cplusplus choke me #endif _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then for ac_declaration in \ ''\ '#include ' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int);' \ 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 continue fi rm -f conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest.$ac_ext done rm -f conftest* if test -n "$ac_declaration"; then echo '#ifdef __cplusplus' >>confdefs.h echo $ac_declaration >>confdefs.h echo '#endif' >>confdefs.h fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6 am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi echo "$as_me:$LINENO: result: $_am_result" >&5 echo "${ECHO_T}$_am_result" >&6 rm -f confinc confmf # Check whether --enable-dependency-tracking or --disable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then enableval="$enable_dependency_tracking" fi; if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c : > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # (even with -Werror). So we grep stderr for any message # that says an option was ignored. if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6 CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$CPP" >&6 ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then echo "$as_me:$LINENO: result: $RANLIB" >&5 echo "${ECHO_T}$RANLIB" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 echo "${ECHO_T}$ac_ct_RANLIB" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi RANLIB=$ac_ct_RANLIB else RANLIB="$ac_cv_prog_RANLIB" fi # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL=$ac_install_sh fi fi echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_path_AR+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $AR in [\\/]* | ?:[\\/]*) ac_cv_path_AR="$AR" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/ccs/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_AR="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done test -z "$ac_cv_path_AR" && ac_cv_path_AR="notfound" ;; esac fi AR=$ac_cv_path_AR if test -n "$AR"; then echo "$as_me:$LINENO: result: $AR" >&5 echo "${ECHO_T}$AR" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi if test "$AR" = "notfound"; then { { echo "$as_me:$LINENO: error: cannot find \`\`ar''" >&5 echo "$as_me: error: cannot find \`\`ar''" >&2;} { (exit 1); exit 1; }; } fi for ac_func in poll do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done echo "$as_me:$LINENO: checking for socket" >&5 echo $ECHO_N "checking for socket... $ECHO_C" >&6 if test "${ac_cv_func_socket+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* System header to define __stub macros and hopefully few prototypes, which can conflict with char socket (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char socket (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_socket) || defined (__stub___socket) choke me #else char (*f) () = socket; #endif #ifdef __cplusplus } #endif int main () { return f != socket; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_socket=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_socket=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_socket" >&5 echo "${ECHO_T}$ac_cv_func_socket" >&6 if test $ac_cv_func_socket = yes; then : else echo "$as_me:$LINENO: checking for socket in -lsocket" >&5 echo $ECHO_N "checking for socket in -lsocket... $ECHO_C" >&6 if test "${ac_cv_lib_socket_socket+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char socket (); int main () { socket (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_socket_socket=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_socket_socket=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_socket_socket" >&5 echo "${ECHO_T}$ac_cv_lib_socket_socket" >&6 if test $ac_cv_lib_socket_socket = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBSOCKET 1 _ACEOF LIBS="-lsocket $LIBS" else { { echo "$as_me:$LINENO: error: cannot find library function socket" >&5 echo "$as_me: error: cannot find library function socket" >&2;} { (exit 1); exit 1; }; } fi fi echo "$as_me:$LINENO: checking for inet_ntoa" >&5 echo $ECHO_N "checking for inet_ntoa... $ECHO_C" >&6 if test "${ac_cv_func_inet_ntoa+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* System header to define __stub macros and hopefully few prototypes, which can conflict with char inet_ntoa (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char inet_ntoa (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_inet_ntoa) || defined (__stub___inet_ntoa) choke me #else char (*f) () = inet_ntoa; #endif #ifdef __cplusplus } #endif int main () { return f != inet_ntoa; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_inet_ntoa=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_inet_ntoa=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_inet_ntoa" >&5 echo "${ECHO_T}$ac_cv_func_inet_ntoa" >&6 if test $ac_cv_func_inet_ntoa = yes; then : else echo "$as_me:$LINENO: checking for inet_ntoa in -lnsl" >&5 echo $ECHO_N "checking for inet_ntoa in -lnsl... $ECHO_C" >&6 if test "${ac_cv_lib_nsl_inet_ntoa+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char inet_ntoa (); int main () { inet_ntoa (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_nsl_inet_ntoa=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_nsl_inet_ntoa=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_inet_ntoa" >&5 echo "${ECHO_T}$ac_cv_lib_nsl_inet_ntoa" >&6 if test $ac_cv_lib_nsl_inet_ntoa = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBNSL 1 _ACEOF LIBS="-lnsl $LIBS" else { { echo "$as_me:$LINENO: error: cannot find library function inet_ntoa" >&5 echo "$as_me: error: cannot find library function inet_ntoa" >&2;} { (exit 1); exit 1; }; } fi fi echo "$as_me:$LINENO: checking for INADDR_LOOPBACK" >&5 echo $ECHO_N "checking for INADDR_LOOPBACK... $ECHO_C" >&6 if test "${adns_cv_decl_inaddrloopback+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include int main () { INADDR_LOOPBACK; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then adns_cv_decl_inaddrloopback=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 adns_cv_decl_inaddrloopback=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi if test "$adns_cv_decl_inaddrloopback" = yes; then echo "$as_me:$LINENO: result: found" >&5 echo "${ECHO_T}found" >&6 else echo "$as_me:$LINENO: result: not in standard headers, urgh..." >&5 echo "${ECHO_T}not in standard headers, urgh..." >&6 echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6 if test "${ac_cv_prog_egrep+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | (grep -E '(a|b)') >/dev/null 2>&1 then ac_cv_prog_egrep='grep -E' else ac_cv_prog_egrep='egrep' fi fi echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 echo "${ECHO_T}$ac_cv_prog_egrep" >&6 EGREP=$ac_cv_prog_egrep echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6 if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done if test "${ac_cv_header_rpc_types_h+set}" = set; then echo "$as_me:$LINENO: checking for rpc/types.h" >&5 echo $ECHO_N "checking for rpc/types.h... $ECHO_C" >&6 if test "${ac_cv_header_rpc_types_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_rpc_types_h" >&5 echo "${ECHO_T}$ac_cv_header_rpc_types_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking rpc/types.h usability" >&5 echo $ECHO_N "checking rpc/types.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking rpc/types.h presence" >&5 echo $ECHO_N "checking rpc/types.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc in yes:no ) { echo "$as_me:$LINENO: WARNING: rpc/types.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: rpc/types.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: rpc/types.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: rpc/types.h: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; no:yes ) { echo "$as_me:$LINENO: WARNING: rpc/types.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: rpc/types.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: rpc/types.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: rpc/types.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: rpc/types.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: rpc/types.h: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for rpc/types.h" >&5 echo $ECHO_N "checking for rpc/types.h... $ECHO_C" >&6 if test "${ac_cv_header_rpc_types_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_rpc_types_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_rpc_types_h" >&5 echo "${ECHO_T}$ac_cv_header_rpc_types_h" >&6 fi if test $ac_cv_header_rpc_types_h = yes; then cat >>confdefs.h <<\_ACEOF #define HAVEUSE_RPCTYPES_H 1 _ACEOF else { { echo "$as_me:$LINENO: error: cannot find INADDR_LOOPBACK or rpc/types.h" >&5 echo "$as_me: error: cannot find INADDR_LOOPBACK or rpc/types.h" >&2;} { (exit 1); exit 1; }; } fi fi echo "$as_me:$LINENO: checking for inet_aton" >&5 echo $ECHO_N "checking for inet_aton... $ECHO_C" >&6 if test "${ac_cv_func_inet_aton+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* System header to define __stub macros and hopefully few prototypes, which can conflict with char inet_aton (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char inet_aton (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_inet_aton) || defined (__stub___inet_aton) choke me #else char (*f) () = inet_aton; #endif #ifdef __cplusplus } #endif int main () { return f != inet_aton; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_inet_aton=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_inet_aton=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_inet_aton" >&5 echo "${ECHO_T}$ac_cv_func_inet_aton" >&6 if test $ac_cv_func_inet_aton = yes; then : else echo "$as_me:$LINENO: checking for inet_aton in -lresolv" >&5 echo $ECHO_N "checking for inet_aton in -lresolv... $ECHO_C" >&6 if test "${ac_cv_lib_resolv_inet_aton+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lresolv $LIBS" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char inet_aton (); int main () { inet_aton (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_resolv_inet_aton=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_resolv_inet_aton=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_inet_aton" >&5 echo "${ECHO_T}$ac_cv_lib_resolv_inet_aton" >&6 if test $ac_cv_lib_resolv_inet_aton = yes; then LIBS="-lresolv $LIBS"; { echo "$as_me:$LINENO: WARNING: inet_aton is in libresolv, urgh. Must use -lresolv." >&5 echo "$as_me: WARNING: inet_aton is in libresolv, urgh. Must use -lresolv." >&2;} else { { echo "$as_me:$LINENO: error: cannot find library function inet_aton" >&5 echo "$as_me: error: cannot find library function inet_aton" >&2;} { (exit 1); exit 1; }; } fi fi echo "$as_me:$LINENO: checking for inline" >&5 echo $ECHO_N "checking for inline... $ECHO_C" >&6 if test "${ac_cv_c_inline+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_inline=$ac_kw; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest.$ac_ext done fi echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 echo "${ECHO_T}$ac_cv_c_inline" >&6 case $ac_cv_c_inline in inline | yes) ;; no) cat >>confdefs.h <<\_ACEOF #define inline _ACEOF ;; *) cat >>confdefs.h <<_ACEOF #define inline $ac_cv_c_inline _ACEOF ;; esac echo "$as_me:$LINENO: checking __attribute__((,,))" >&5 echo $ECHO_N "checking __attribute__((,,))... $ECHO_C" >&6 if test "${adns_cv_c_attribute_supported+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { extern int testfunction(int x) __attribute__((,,)) ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then adns_cv_c_attribute_supported=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 adns_cv_c_attribute_supported=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi if test "x$adns_cv_c_attribute_supported" = xyes; then true echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 cat >>confdefs.h <<\_ACEOF #define HAVE_GNUC25_ATTRIB 1 _ACEOF echo "$as_me:$LINENO: checking __attribute__((noreturn))" >&5 echo $ECHO_N "checking __attribute__((noreturn))... $ECHO_C" >&6 if test "${adns_cv_c_attribute_noreturn+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { extern int testfunction(int x) __attribute__((noreturn)) ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then adns_cv_c_attribute_noreturn=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 adns_cv_c_attribute_noreturn=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi if test "x$adns_cv_c_attribute_noreturn" = xyes; then true echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 cat >>confdefs.h <<\_ACEOF #define HAVE_GNUC25_NORETURN 1 _ACEOF else true echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi echo "$as_me:$LINENO: checking __attribute__((const))" >&5 echo $ECHO_N "checking __attribute__((const))... $ECHO_C" >&6 if test "${adns_cv_c_attribute_const+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { extern int testfunction(int x) __attribute__((const)) ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then adns_cv_c_attribute_const=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 adns_cv_c_attribute_const=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi if test "x$adns_cv_c_attribute_const" = xyes; then true echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 cat >>confdefs.h <<\_ACEOF #define HAVE_GNUC25_CONST 1 _ACEOF else true echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi echo "$as_me:$LINENO: checking __attribute__((format...))" >&5 echo $ECHO_N "checking __attribute__((format...))... $ECHO_C" >&6 if test "${adns_cv_attribute_format+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { extern int testfunction(char *y, ...) __attribute__((format(printf,1,2))) ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then adns_cv_attribute_format=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 adns_cv_attribute_format=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi if test "x$adns_cv_attribute_format" = xyes; then true echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 cat >>confdefs.h <<\_ACEOF #define HAVE_GNUC25_PRINTFFORMAT 1 _ACEOF else true echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi else true echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi for ac_header in sys/select.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc in yes:no ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; no:yes ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done if test "${GCC-no}" = yes; then WARNS="-Wall -Wmissing-prototypes -Wwrite-strings -Wstrict-prototypes -Wcast-qual -Wpointer-arith" else WARNS= fi ac_config_files="$ac_config_files Makefile src/Makefile client/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. { (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } | sed ' t clear : clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ : end' >>confcache if diff $cache_file confcache >/dev/null 2>&1; then :; else if test -w $cache_file; then test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" cat confcache >$cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/; s/:*\${srcdir}:*/:/; s/:*@srcdir@:*/:/; s/^\([^=]*=[ ]*\):*/\1/; s/:*$//; s/^[^=]*=[ ]*$//; }' fi DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_i=`echo "$ac_i" | sed 's/\$U\././;s/\.o$//;s/\.obj$//'` # 2. Add them. ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi # Support unset when possible. if (FOO=FOO; unset FOO) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" # Sed expression to map a string onto a valid variable name. as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH exec 6>&1 # Open the log real soon, to keep \$[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. Logging --version etc. is OK. exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX } >&5 cat >&5 <<_CSEOF This file was extended by adns $as_me 1.0-lyskom-server, which was generated by GNU Autoconf 2.57. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ _CSEOF echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 echo >&5 _ACEOF # Files that config.status was made for. if test -n "$ac_config_files"; then echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS fi if test -n "$ac_config_headers"; then echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS fi if test -n "$ac_config_links"; then echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS fi if test -n "$ac_config_commands"; then echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS fi cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ adns config.status 1.0-lyskom-server configured by $0, generated by GNU Autoconf 2.57, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." srcdir=$srcdir INSTALL="$INSTALL" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "x$1" : 'x\([^=]*\)='` ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` ac_shift=: ;; -*) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; *) # This is not an option, so the user has probably given explicit # arguments. ac_option=$1 ac_need_defaults=false;; esac case $ac_option in # Handling of the options. _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --vers* | -V ) echo "$ac_cs_version"; exit 0 ;; --he | --h) # Conflict between --help and --header { { echo "$as_me:$LINENO: error: ambiguous option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; };; --help | --hel | -h ) echo "$ac_cs_usage"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # INIT-COMMANDS section. # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_config_target in $ac_config_targets do case "$ac_config_target" in # Handling of arguments. "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "client/Makefile" ) CONFIG_FILES="$CONFIG_FILES client/Makefile" ;; "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "src/config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS src/config.h" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason to put it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Create a temporary directory, and hook for its removal unless debugging. $debug || { trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./confstat$$-$RANDOM (umask 077 && mkdir $tmp) } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "\$CONFIG_FILES"; then # Protect against being on the right side of a sed subst in config.status. sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF s,@SHELL@,$SHELL,;t t s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t s,@exec_prefix@,$exec_prefix,;t t s,@prefix@,$prefix,;t t s,@program_transform_name@,$program_transform_name,;t t s,@bindir@,$bindir,;t t s,@sbindir@,$sbindir,;t t s,@libexecdir@,$libexecdir,;t t s,@datadir@,$datadir,;t t s,@sysconfdir@,$sysconfdir,;t t s,@sharedstatedir@,$sharedstatedir,;t t s,@localstatedir@,$localstatedir,;t t s,@libdir@,$libdir,;t t s,@includedir@,$includedir,;t t s,@oldincludedir@,$oldincludedir,;t t s,@infodir@,$infodir,;t t s,@mandir@,$mandir,;t t s,@build_alias@,$build_alias,;t t s,@host_alias@,$host_alias,;t t s,@target_alias@,$target_alias,;t t s,@DEFS@,$DEFS,;t t s,@ECHO_C@,$ECHO_C,;t t s,@ECHO_N@,$ECHO_N,;t t s,@ECHO_T@,$ECHO_T,;t t s,@LIBS@,$LIBS,;t t s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t s,@INSTALL_DATA@,$INSTALL_DATA,;t t s,@CYGPATH_W@,$CYGPATH_W,;t t s,@PACKAGE@,$PACKAGE,;t t s,@VERSION@,$VERSION,;t t s,@ACLOCAL@,$ACLOCAL,;t t s,@AUTOCONF@,$AUTOCONF,;t t s,@AUTOMAKE@,$AUTOMAKE,;t t s,@AUTOHEADER@,$AUTOHEADER,;t t s,@MAKEINFO@,$MAKEINFO,;t t s,@AMTAR@,$AMTAR,;t t s,@install_sh@,$install_sh,;t t s,@STRIP@,$STRIP,;t t s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t s,@AWK@,$AWK,;t t s,@SET_MAKE@,$SET_MAKE,;t t s,@am__leading_dot@,$am__leading_dot,;t t s,@CC@,$CC,;t t s,@CFLAGS@,$CFLAGS,;t t s,@LDFLAGS@,$LDFLAGS,;t t s,@CPPFLAGS@,$CPPFLAGS,;t t s,@ac_ct_CC@,$ac_ct_CC,;t t s,@EXEEXT@,$EXEEXT,;t t s,@OBJEXT@,$OBJEXT,;t t s,@DEPDIR@,$DEPDIR,;t t s,@am__include@,$am__include,;t t s,@am__quote@,$am__quote,;t t s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t s,@CCDEPMODE@,$CCDEPMODE,;t t s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t s,@CPP@,$CPP,;t t s,@RANLIB@,$RANLIB,;t t s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t s,@AR@,$AR,;t t s,@EGREP@,$EGREP,;t t s,@WARNS@,$WARNS,;t t s,@LIBOBJS@,$LIBOBJS,;t t s,@LTLIBOBJS@,$LTLIBOBJS,;t t CEOF _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_lines=48 ac_sed_frag=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_lines # Line after last line for current file. ac_more_lines=: ac_sed_cmds= while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag else sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag fi if test ! -s $tmp/subs.frag; then ac_more_lines=false else # The purpose of the label and of the branching condition is to # speed up the sed processing (if there are no `@' at all, there # is no need to browse any of the substitutions). # These are the two extra sed commands mentioned above. (echo ':t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" else ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" fi ac_sed_frag=`expr $ac_sed_frag + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_lines` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi fi # test -n "$CONFIG_FILES" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case $ac_file in - | *:- | *:-:* ) # input from stdin cat >$tmp/stdin ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; * ) ac_file_in=$ac_file.in ;; esac # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be # absolute. ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_builddir$INSTALL ;; esac if test x"$ac_file" != x-; then { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} rm -f "$ac_file" fi # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ if test x"$ac_file" = x-; then configure_input= else configure_input="$ac_file. " fi configure_input=$configure_input"Generated from `echo $ac_file_in | sed 's,.*/,,'` by configure." # First look for the input files in the build tree, otherwise in the # src tree. ac_file_inputs=`IFS=: for f in $ac_file_in; do case $f in -) echo $tmp/stdin ;; [\\/$]*) # Absolute (can't be DOS-style, as IFS=:) test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } echo $f;; *) # Relative if test -f "$f"; then # Build tree echo $f elif test -f "$srcdir/$f"; then # Source tree echo $srcdir/$f else # /dev/null tree { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } fi;; esac done` || { (exit 1); exit 1; } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s,@configure_input@,$configure_input,;t t s,@srcdir@,$ac_srcdir,;t t s,@abs_srcdir@,$ac_abs_srcdir,;t t s,@top_srcdir@,$ac_top_srcdir,;t t s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t s,@builddir@,$ac_builddir,;t t s,@abs_builddir@,$ac_abs_builddir,;t t s,@top_builddir@,$ac_top_builddir,;t t s,@abs_top_builddir@,$ac_abs_top_builddir,;t t s,@INSTALL@,$ac_INSTALL,;t t " $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out rm -f $tmp/stdin if test x"$ac_file" != x-; then mv $tmp/out $ac_file else cat $tmp/out rm -f $tmp/out fi done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # # CONFIG_HEADER section. # # These sed commands are passed to sed as "A NAME B NAME C VALUE D", where # NAME is the cpp macro being defined and VALUE is the value it is being given. # # ac_d sets the value in "#define NAME VALUE" lines. ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' ac_dB='[ ].*$,\1#\2' ac_dC=' ' ac_dD=',;t' # ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_uB='$,\1#\2define\3' ac_uC=' ' ac_uD=',;t' for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case $ac_file in - | *:- | *:-:* ) # input from stdin cat >$tmp/stdin ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; * ) ac_file_in=$ac_file.in ;; esac test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} # First look for the input files in the build tree, otherwise in the # src tree. ac_file_inputs=`IFS=: for f in $ac_file_in; do case $f in -) echo $tmp/stdin ;; [\\/$]*) # Absolute (can't be DOS-style, as IFS=:) test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } echo $f;; *) # Relative if test -f "$f"; then # Build tree echo $f elif test -f "$srcdir/$f"; then # Source tree echo $srcdir/$f else # /dev/null tree { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } fi;; esac done` || { (exit 1); exit 1; } # Remove the trailing spaces. sed 's/[ ]*$//' $ac_file_inputs >$tmp/in _ACEOF # Transform confdefs.h into two sed scripts, `conftest.defines' and # `conftest.undefs', that substitutes the proper values into # config.h.in to produce config.h. The first handles `#define' # templates, and the second `#undef' templates. # And first: Protect against being on the right side of a sed subst in # config.status. Protect against being in an unquoted here document # in config.status. rm -f conftest.defines conftest.undefs # Using a here document instead of a string reduces the quoting nightmare. # Putting comments in sed scripts is not portable. # # `end' is used to avoid that the second main sed command (meant for # 0-ary CPP macros) applies to n-ary macro definitions. # See the Autoconf documentation for `clear'. cat >confdef2sed.sed <<\_ACEOF s/[\\&,]/\\&/g s,[\\$`],\\&,g t clear : clear s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp t end s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp : end _ACEOF # If some macros were called several times there might be several times # the same #defines, which is useless. Nevertheless, we may not want to # sort them, since we want the *last* AC-DEFINE to be honored. uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs rm -f confdef2sed.sed # This sed command replaces #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. cat >>conftest.undefs <<\_ACEOF s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, _ACEOF # Break up conftest.defines because some shells have a limit on the size # of here documents, and old seds have small limits too (100 cmds). echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS echo ' :' >>$CONFIG_STATUS rm -f conftest.tail while grep . conftest.defines >/dev/null do # Write a limited-size here document to $tmp/defines.sed. echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS # Speed up: don't consider the non `#define' lines. echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS # Work around the forget-to-reset-the-flag bug. echo 't clr' >>$CONFIG_STATUS echo ': clr' >>$CONFIG_STATUS sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS echo 'CEOF sed -f $tmp/defines.sed $tmp/in >$tmp/out rm -f $tmp/in mv $tmp/out $tmp/in ' >>$CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail rm -f conftest.defines mv conftest.tail conftest.defines done rm -f conftest.defines echo ' fi # grep' >>$CONFIG_STATUS echo >>$CONFIG_STATUS # Break up conftest.undefs because some shells have a limit on the size # of here documents, and old seds have small limits too (100 cmds). echo ' # Handle all the #undef templates' >>$CONFIG_STATUS rm -f conftest.tail while grep . conftest.undefs >/dev/null do # Write a limited-size here document to $tmp/undefs.sed. echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS # Speed up: don't consider the non `#undef' echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS # Work around the forget-to-reset-the-flag bug. echo 't clr' >>$CONFIG_STATUS echo ': clr' >>$CONFIG_STATUS sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS echo 'CEOF sed -f $tmp/undefs.sed $tmp/in >$tmp/out rm -f $tmp/in mv $tmp/out $tmp/in ' >>$CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail rm -f conftest.undefs mv conftest.tail conftest.undefs done rm -f conftest.undefs cat >>$CONFIG_STATUS <<\_ACEOF # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ if test x"$ac_file" = x-; then echo "/* Generated by configure. */" >$tmp/config.h else echo "/* $ac_file. Generated by configure. */" >$tmp/config.h fi cat $tmp/in >>$tmp/config.h rm -f $tmp/in if test x"$ac_file" != x-; then if diff $ac_file $tmp/config.h >/dev/null 2>&1; then { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 echo "$as_me: $ac_file is unchanged" >&6;} else ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } rm -f $ac_file mv $tmp/config.h $ac_file fi else cat $tmp/config.h rm -f $tmp/config.h fi # Compute $ac_file's index in $config_headers. _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $ac_file | $ac_file:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null || $as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X$ac_file : 'X\(//\)[^/]' \| \ X$ac_file : 'X\(//\)$' \| \ X$ac_file : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X$ac_file | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'`/stamp-h$_am_stamp_count done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # # CONFIG_COMMANDS section. # for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue ac_dest=`echo "$ac_file" | sed 's,:.*,,'` ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_dir=`(dirname "$ac_dest") 2>/dev/null || $as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_dest" : 'X\(//\)[^/]' \| \ X"$ac_dest" : 'X\(//\)$' \| \ X"$ac_dest" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_dest" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be # absolute. ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 echo "$as_me: executing $ac_dest commands" >&6;} case $ac_dest in depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # So let's grep whole file. if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then dirpart=`(dirname "$mf") 2>/dev/null || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` else continue fi grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue # Extract the definition of DEP_FILES from the Makefile without # running `make'. DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"` test -z "$DEPDIR" && continue # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n -e '/^U = / s///p' < "$mf"` test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" # We invoke sed twice because it is the simplest approach to # changing $(DEPDIR) to its actual value in the expansion. for file in `sed -n -e ' /^DEP_FILES = .*\\\\$/ { s/^DEP_FILES = // :loop s/\\\\$// p n /\\\\$/ b loop p } /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`(dirname "$file") 2>/dev/null || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p $dirpart/$fdir else as_dir=$dirpart/$fdir as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5 echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;} { (exit 1); exit 1; }; }; } # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ;; esac done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi lyskom-server-2.1.2/src/libraries/adns/configure.in0000664000015100472110000000727007714212770016033 # configure.in - input to autoconf # # This file is # Copyright (C) 1997-2000 Ian Jackson # # It is part of adns, which is # Copyright (C) 1997-2000 Ian Jackson # Copyright (C) 1999-2000 Tony Finch # # 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 2, 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, write to the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. AC_INIT([adns], [1.0-lyskom-server]) AC_CONFIG_HEADERS([src/config.h]) AM_INIT_AUTOMAKE([adns], [1.0]) AC_PROG_CC AC_PROG_CPP AC_PROG_RANLIB AC_PROG_INSTALL AC_PATH_PROG([AR], [ar], [notfound], [$PATH$PATH_SEPARATOR/usr/ccs/bin]) AC_ARG_VAR([AR], [ar program to use]) [if test "$AR" = "notfound"; then] AC_MSG_ERROR([cannot find ``ar'']) [fi] AC_CHECK_FUNCS(poll) ADNS_C_GETFUNC(socket,socket) ADNS_C_GETFUNC(inet_ntoa,nsl) AC_MSG_CHECKING(for INADDR_LOOPBACK) AC_CACHE_VAL(adns_cv_decl_inaddrloopback,[ AC_TRY_COMPILE([ #include #include #include ],[ INADDR_LOOPBACK; ], adns_cv_decl_inaddrloopback=yes, adns_cv_decl_inaddrloopback=no)]) if test "$adns_cv_decl_inaddrloopback" = yes; then AC_MSG_RESULT(found) else AC_MSG_RESULT([not in standard headers, urgh...]) AC_CHECK_HEADER(rpc/types.h,[ AC_DEFINE(HAVEUSE_RPCTYPES_H) ],[ AC_MSG_ERROR([cannot find INADDR_LOOPBACK or rpc/types.h]) ]) fi ADNS_C_GETFUNC(inet_aton,resolv,[ LIBS="-lresolv $LIBS"; AC_MSG_WARN([inet_aton is in libresolv, urgh. Must use -lresolv.]) ]) AC_C_INLINE ADNS_C_GCCATTRIB AC_CHECK_HEADERS(sys/select.h) AC_SUBST(WARNS) if test "${GCC-no}" = yes; then WARNS="-Wall -Wmissing-prototypes -Wwrite-strings -Wstrict-prototypes -Wcast-qual -Wpointer-arith" else WARNS= fi AH_VERBATIM([LYSKOM_ADNS_EVERYTHING], [/* Include poll.h. */ #ifdef HAVE_POLL #include #else /* kludge it up */ struct pollfd { int fd; short events; short revents; }; #define POLLIN 1 #define POLLPRI 2 #define POLLOUT 4 #endif /* GNU C attributes. */ #ifndef FUNCATTR #ifdef HAVE_GNUC25_ATTRIB #define FUNCATTR(x) __attribute__(x) #else #define FUNCATTR(x) #endif #endif /* GNU C printf formats, or null. */ #ifndef ATTRPRINTF #ifdef HAVE_GNUC25_PRINTFFORMAT #define ATTRPRINTF(si,tc) format(printf,si,tc) #else #define ATTRPRINTF(si,tc) #endif #endif #ifndef PRINTFFORMAT #define PRINTFFORMAT(si,tc) FUNCATTR((ATTRPRINTF(si,tc))) #endif /* GNU C nonreturning functions, or null. */ #ifndef ATTRNORETURN #ifdef HAVE_GNUC25_NORETURN #define ATTRNORETURN noreturn #else #define ATTRNORETURN #endif #endif #ifndef NONRETURNING #define NONRETURNING FUNCATTR((ATTRNORETURN)) #endif /* Combination of both the above. */ #ifndef NONRETURNPRINTFFORMAT #define NONRETURNPRINTFFORMAT(si,tc) FUNCATTR((ATTRPRINTF(si,tc),ATTRNORETURN)) #endif /* GNU C constant functions, or null. */ #ifndef ATTRCONST #ifdef HAVE_GNUC25_CONST #define ATTRCONST const #else #define ATTRCONST #endif #endif #ifndef CONSTANT #define CONSTANT FUNCATTR((ATTRCONST)) #endif #ifdef HAVEUSE_RPCTYPES_H #include #endif #include #ifdef HAVE_SYS_SELECT_H #include #endif ]) AC_OUTPUT(Makefile src/Makefile client/Makefile) lyskom-server-2.1.2/src/libraries/adns/depcomp0000755000015100000310000003256107716517055015071 #! /bin/sh # depcomp - compile a program generating dependencies as side-effects # Copyright 1999, 2000 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # `libtool' can also be set to `yes' or `no'. if test -z "$depfile"; then base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'` dir=`echo "$object" | sed 's,/.*$,/,'` if test "$dir" = "$object"; then dir= fi # FIXME: should be _deps on DOS. depfile="$dir.deps/$base" fi tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> $depfile echo >> $depfile # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> $depfile else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. This file always lives in the current directory. # Also, the AIX compiler puts `$object:' at the start of each line; # $object doesn't have directory information. stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'` tmpdepfile="$stripped.u" outname="$stripped.o" if test "$libtool" = yes; then "$@" -Wc,-M else "$@" -M fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi if test -f "$tmpdepfile"; then # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; icc) # Intel's C compiler understands `-MD -MF file'. However on # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c # ICC 7.0 will fill foo.d with something like # foo.o: sub/foo.c # foo.o: sub/foo.h # which is wrong. We want: # sub/foo.o: sub/foo.c # sub/foo.o: sub/foo.h # sub/foo.c: # sub/foo.h: # ICC 7.1 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using \ : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1="$dir.libs/$base.lo.d" tmpdepfile2="$dir.libs/$base.d" "$@" -Wc,-MD else tmpdepfile1="$dir$base.o.d" tmpdepfile2="$dir$base.d" "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi if test -f "$tmpdepfile1"; then tmpdepfile="$tmpdepfile1" else tmpdepfile="$tmpdepfile2" fi if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a space and a tab in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for `:' # in the target name. This is to cope with DOS-style filenames: # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. "$@" $dashmflag | sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # X makedepend shift cleared=no for arg in "$@"; do case $cleared in no) set ""; shift cleared=yes ;; esac case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix="`echo $object | sed 's/^.*\././'`" touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E | sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. "$@" || exit $? IFS=" " for arg do case "$arg" in "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 lyskom-server-2.1.2/src/libraries/adns/install-sh0000775000015100472110000001272107705611223015517 #! /bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 lyskom-server-2.1.2/src/libraries/adns/missing0000755000015100000310000002403607716517055015111 #! /bin/sh # Common stub for a few missing GNU programs while installing. # Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi case "$1" in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case "$1" in -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch]" ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing 0.4 - GNU automake" ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; aclocal*) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case "$f" in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. You can get \`$1Help2man' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.h fi ;; esac fi if [ ! -f y.tab.h ]; then echo >y.tab.h fi if [ ! -f y.tab.c ]; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if [ ! -f lex.yy.c ]; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` fi if [ -f "$file" ]; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then # We have makeinfo, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` fi touch $file ;; tar) shift if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 fi # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case "$firstarg" in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case "$firstarg" in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequirements for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 lyskom-server-2.1.2/src/libraries/adns/mkinstalldirs0000755000015100000310000000370407716517055016317 #! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain errstatus=0 dirmode="" usage="\ Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." # process command line arguments while test $# -gt 0 ; do case $1 in -h | --help | --h*) # -h for help echo "$usage" 1>&2 exit 0 ;; -m) # -m PERM arg shift test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } dirmode=$1 shift ;; --) # stop option processing shift break ;; -*) # unknown option echo "$usage" 1>&2 exit 1 ;; *) # first non-opt arg break ;; esac done for file do if test -d "$file"; then shift else break fi done case $# in 0) exit 0 ;; esac case $dirmode in '') if mkdir -p -- . 2>/dev/null; then echo "mkdir -p -- $*" exec mkdir -p -- "$@" fi ;; *) if mkdir -m "$dirmode" -p -- . 2>/dev/null; then echo "mkdir -m $dirmode -p -- $*" exec mkdir -m "$dirmode" -p -- "$@" fi ;; esac for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case $pathcomp in -*) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr else if test ! -z "$dirmode"; then echo "chmod $dirmode $pathcomp" lasterr="" chmod "$dirmode" "$pathcomp" || lasterr=$? if test ! -z "$lasterr"; then errstatus=$lasterr fi fi fi fi pathcomp="$pathcomp/" done done exit $errstatus # Local Variables: # mode: shell-script # sh-indentation: 2 # End: # mkinstalldirs ends here lyskom-server-2.1.2/src/libraries/adns/.cvsignore0000664000015100472110000000021307705622443015512 *.tmp* Makefile Makefile.in aclocal.m4 adns-*.tar.gz autom4te.cache config.cache config.log config.status configure dist_tmp settings.make lyskom-server-2.1.2/src/libraries/adns/GPL-vs-LGPL0000664000015100472110000001302007705611222015232 GPL vs LGPL, in the context of adns ----------------------------------- Several people have asked me to release GNU adns under the GNU Lesser General Public Licence (LGPL, formerly the Library GPL) instead of the `stronger' GPL. This file is intended to answer most of these questions. If you still have questions or comments, please mail me at . Typically there are two or three kinds of situation where people make this request: the first is where someone is developing a proprietary program and wishes to make use of adns but doesn't wish to make their program free software. The second case is where a free software project is currently using an MIT-like licence or the LGPL and fear `GPL infection'. The third case, which often overlaps with the second, is where another free software project currently using a GPL-incompatible licence, wishes to use adns. 1. Proprietary applications of adns ----------------------------------- So, let me get this straight. You're writing a proprietary program, by which I mean that you will not be distributing source code and not allowing users to modify and share your software; most likely you are doing this for your own (personal or corporate) financial gain. However, you want to take advantage of adns, software which I have spent my time and effort on, and which I release as free software so that everyone can improve, share and use it. Don't you think that is a little hypocritical ? I'm sorry, but I don't want you to just take my nice convenient software, without giving something back to the free software community or giving the same rights to your users as I do to you. If you really aren't the nasty kind of person I've described here, for example if you have a good reason other than your own selfishness for wanting to restrict distribution of your program, then perhaps you should contact me to discuss it. 2. GPL-avoiding projects (MIT licence, et al) --------------------------------------------- Some free software projects prefer to avoid the GPL and other licences which force the software always to be free. Instead they use something like the MIT X licence, which allows proprietary versions of their software, or the in the case of some free libraries, the LGPL, which allows proprietary applications. I have to say that I think these people are misguided, but that doesn't mean that they don't have a perfect right to do that. Some of these people think that merely writing to an interface provided by GPL'd software will cause their program to become GPL'd too, even if they don't distribute the GPL'd software. I don't think this is the case. I'm perfectly happy for non-GPL'd but GPL-compatible software to refer to adns in its source code. However, I think that exectuables (or compiled libraries) which contain or are dynamically linked against adns must be GPL'd; likewise executable programs (whether compiled or in an interpreted language) which require utilities from adns to function properly must be GPL'd. So, you can distribute your non-GPL'd program source which needs adns to compile (provided it's under a GPL-compatible licence), but people who wish to distribute binaries must do so under the terms of the GNU GPL. This may make sense for some GPL-avoiding free software projects; people can still make proprietary programs from your code, provided that they make some provision to replace adns with something whose copyright allows proprietary versions. However, this doesn't make much sense for the authors of LGPL'd libraries. All I can say to them is to ask which is more important: that their library be well-constructed and use all the best technology available as free software, or whether it is worth degrading quality of their library in order to allow proprietary programs to use it ! To help the case of LGPL'd libraries for which adns is not a vital component - for example, a library which provides access to other libraries so that programs which use it need only use certain parts, I have released adns.h (just the public header file) under the LGPL as well as the GPL. See the copyright notice in adns.h for details. Note that this will not help you if it adns is essential to the functioning of your library, because all programs using your library must link against both your library and adns and so must be GPL'd. For some information and views from the Free Software Foundation on free software licensing, visit: Various licenses and comments about them at http://www.fsf.org/philosophy/license-list.html Why you shouldn't use the Library GPL for your next library at http://www.fsf.org/philosophy/why-not-lgpl.html 3. GPL-incompatible free software licences ------------------------------------------ Regrettably, there are a number of free software licences (and semi-free licences) in existence which are not compatible with the GPL. That is, they impose restrictions which are not present in the GPL, and therefore distributing a whole work which contains both such a program and a GPL'd program is not possible: either the combination would have to be distributed under the GPL (violating the restrictions made by the original author), or under the GPL-incompatible licence (violating the GPL). I may be prepared to make exceptions for such a licence. Please contact me at with the full text of the GPL-incompatible licence. However, I would usually prefer it if you could use a GPL-compatible licence for your project instead. -- Ian Jackson 17.9.2000 Local variables: mode: text End: lyskom-server-2.1.2/src/libraries/adns/README.html0000664000015100472110000002025707705611222015340 adns - advanced, alternative, asynchronous resolver

GNU adns

Advanced, easy to use, asynchronous-capable DNS client library and utilities.

adns is a resolver library for C (and C++) programs, and a collection of useful DNS resolver utilities.

C library

In contrast with the standard interfaces, gethostbyname et al and libresolv, it has the following features:
  • It is reasonably easy to use for simple programs which just want to translate names to addresses, look up MX records, etc.
  • It can be used in an asynchronous, non-blocking, manner. Many queries can be handled simultaneously.
  • Responses are decoded automatically into a natural representation for a C program - there is no need to deal with DNS packet formats.
  • Sanity checking (eg, name syntax checking, reverse/forward correspondence, CNAME pointing to CNAME) is performed automatically.
  • Time-to-live, CNAME and other similar information is returned in an easy-to-use form, without getting in the way.
  • There is no global state in the library; resolver state is an opaque data structure which the client creates explicitly. A program can have several instances of the resolver.
  • Errors are reported to the application in a way that distinguishes the various causes of failure properly.
  • Understands conventional resolv.conf, but this can overridden by environment variables.
  • Flexibility. For example, the application can tell adns to: ignore environment variables (for setuid programs), disable hostname syntax sanity checks to return arbitrary data, override or ignore resolv.conf in favour of supplied configuration, etc.
  • Believed to be correct ! For example, will correctly back off to TCP in case of long replies or queries, or to other nameservers if several are available. It has sensible handling of bad responses etc.

DNS utility programs

adns also comes with a number of utility programs for use from the command line and in scripts:
  • adnslogres is a much faster version of Apache's logresolv program.
  • adnsresfilter is a filter which copies its input to its output, replacing IP addresses by the corresponding names, without unduly delaying the output. For example, you can usefully pipe the output of netstat -n, tcpdump -ln, and the like, into it.
  • adnshost is a general-purpose DNS lookup utility which can be used easily in from the command line and from shell scripts to do simple lookups. In a more advanced mode it can be used as a general-purpose DNS helper program for scripting languages which can invoke and communicate with subprocesses. See the adnshost usage message for a summary of its capabilities.

Documentation

I'm afraid there is no manual yet. However, competent C programmers should be able to use the library based on the commented adns.h header file, and the usage messages for the programs should be sufficient.

Feedback

I'd be pleased if you would let me know if you're using my library in your project, and what you think of it.

If you are subscribed to adns-discuss please send feedback, including bug reports, there; otherwise send mail to adns-bugreports@chiark.greenend.org.uk. If you'd prefer that your message wasn't forwarded to the adns-bugreports list, send it to adns-maint@chiark.greenend.org.uk.

Mailinglists

I have set up mailinglists adns-announce and adns-discuss. The announcements list is moderated and will contain only announcements of important bugs, new versions, etc. The bug reports address mentioned above is also a mailing list; feel free to subscribe to it.

There are archives and subscription web pages, or you can subscribe by sending mail containing the word `subscribe' to adns-announce-REQUEST@chiark.greenend.org.uk or adns-discuss-REQUEST@chiark.greenend.org.uk.

Download

Available for download from chiark.greenend.org.uk are:
  • The current release as a gzipped tarfile.
  • adns.h API header file with comments, and usage message for adnshost (currently there is no manual, sorry).
  • All versions released so far are also available via anonymous FTP and HTTP,
  • A mirror of my CVS repository is available via rsync from rsync.chiark.greenend.org.uk::ftp/users/ian/cvs-pub/adns (use FTP first to find your way around), or via cvsweb.
adns is also available from the GNU Project FTP servers and their mirrors.

Technical note

adns requires a real nameserver like BIND or Dents running on the same system or a nearby one, which must be willing to provide `recursive service'. I.e., adns is a `stub resolver'. All properly configured UN*X and GNU systems will already have such nameserver(s); they are usually listed in /etc/resolv.conf.

Copyright and licensing

adns is Copyright 1997-2000 Ian Jackson, Copyright 1999-2000 Tony Finch, and Copyright (C) 1991 Massachusetts Institute of Technology.

adns 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 2 of the License, or (at your option) any later version.

This program and documentation 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 adns, or one should be available above; if not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or email adns-maint@chiark.greenend.org.uk.


Ian Jackson / adns-maint@chiark.greenend.org.uk; more free software by me.

GNU home page; chiark home page; site or mirror home page

This web page is Copyright (C)1996-2000 Ian Jackson. See the Copyright/acknowledgements.

Use any browser - Campaign for a non-browser-specific WWW lyskom-server-2.1.2/src/libraries/adns/changelog0000664000015100472110000003203207705623127015370 This version of adns has been modified and crippled for the LysKOM project. See ../../../ChangeLog for a log of changes. If you want to use adns in your project, you are adviced to go get the original sources instead of this. Only parts of the adns distribution are included with the lyskom-server distribution. adns (1.0); urgency=medium Bugfixes: * Treat 8-bit characters in email addrs as RFC822 `special' (=> quote). * Fix incorrect `compressed datagram contains loop' error. * Actually compile shared libraries by default ! * Fix adnsresfilter usage message to include correct default timeout. General improvements: * adnshost, adnslogres, adnsresfilter have options for config override. * adnsresfilter has --debug option. * Improvements to adnslogres (incl. new -c option) from Tony Finch. * adnslogres has --help option, all utilities support --version. * Documentation improved somewhat, including new GPL-vs-LGPL file. Changes for non-BETA release: * Change shared library soname to 1.0. * Do not install adnstest test utility. Regression test improvements: * Tests now include adnshost, adnslogres and adnsresfilter. * Test cancellation both before and after query completion. Portability fixes and cleanups: * adnstest: setvbuf(stdout,...) before we do first output. * Cope with compilers that don't do `inline'. * Add and fix various missing system #includes. * Find install-sh properly when we need to use it, and chmod it +x. * Do not use variadic macro, use stdarg instead (adnslogres.c). * Regression tests work even if some syscalls are already macros. * #include "config.h" before "adns.h". * Cast a sizeof(...) in src/event.c to unsigned long before printing. * Add pre-generated versions of m4-generated files in regress/. * Kill bogus warning, adh-main.c: `arg2' might be used uninitialized ... * Add extra {...} near adnslogres.c:167 to kill spurious warning. * Use `printf' instead of `echo -n'. * Add list of tested platforms in INSTALL file. -- Ian Jackson Sun, 17 Sep 2000 15:15:58 +0100 adns (0.9) BETA; urgency=high Bug fixes: * Don't make _processany always kill the TCP connection with the message `TCP connection failed: poll/select: exceptional condition detected'. * Call MEM_ROUND in __transfer_interim (avoids assert fail `qu->interim_allocd>=0' on some platforms eg 64 bit). * adnsresfilter doesn't resolve textual prefixes of addresses (eg, 10.0.0.1 out of 10.0.0.123) if input happens to block at that point. * Do not spin if TCP connection blocks for writing (and add test case). * Fail queries if TCP dies repeatedly, rather than retrying many times. * Do not abort in a couple of places if TCP unexpectedly broken. * Do not free something twice if query fails and is then cancelled. Portability/compilation fixes: * Move `extern "C" {' to after #include <...>'s. * Pass LDFLAGS from configure on to ld via settings.make.in. * make clean deletes *.so and *.so.* files. * New --disable-dynamic configure option for non-ELF systems. * Use AC_PROG_INSTALL (=> perhaps install-sh), to avoid bad `install'. Minor improvements: * Do not print warning if sendto() gives EAGAIN. * adnsresfilter default timeout changed to 1000ms. * m1test script can invoke `hrecord' differently. * regress/output-.report file contains more useful info. * TODO list and other docs updated slightly. * Referrals with RD+RA set, or RCODE=Refused, don't generate warnings, just debug messages. BIND does this kind of thing all the time. -- Ian Jackson Wed, 9 Aug 2000 16:59:28 +0100 adns (0.8) BETA; urgency=medium Bugfixes: * Race near adns_beforeselect which could cause infinite timeout fixed (it's now less agressive, and will more often return a zero timeout.) * Fixed infrequent race causing assertion failure in adns__tcp_broken `ads->tcpstate == server_connecting || ads->tcpstate == server_ok'. * Spurious `server failure on unidentifiable query' warning suppressed. * If we get a referral, don't also always complain falsely about RD==0. * adnslogres: cast chars to unsigned char before using ctype.h macros. * In _beforeselect, global failure now means zero timeout, and in tcp_events, really never try to do anything with the TCP connection if act is zero. This might possibly cause an infinite delay (ie, lockup) if things go badly wrong *and* a really unlikely race happens. * Test suite `lines of syscall left' value is correct; !0 is failure. Portability fixes: * install-sh (from autoconf 2.12 Debian r13) included. * adnslogres: do not call equivalent of printf("%.*s",0,(char*)0). Documentation improvements: * Security/performance note added, about local nameservers and DNSSEC. * Documented that adns_rr_info _rr_hostaddr ( ) for address list means permanent failure, and ? means temporary failure. * Typo (*now for now in _beforeselect description) in adns.h fixed. * Copyright notices updated. Changes to produce more defensive code: * In adns_wait, assert that the timeout is not infinite. * Make qu->id start out as -2 when initially allocated. -- Ian Jackson Sun, 7 May 2000 23:37:13 +0100 adns (0.7) BETA; urgency=medium * New adns_submit_reverse_any for eg RBL lookups, and corresponding option to adnshost. * README updated (from www home page). * In answers, quote all except alphanums and - _ / + (and document). * Don't reject specials in cnames even without adns_qf_quotefail_cname. * Better checking of long domain names and labels in queries. * answer->owner may be null on error. Documented, and adnshost copes. * Better reporting of unexpected or weird replies from nameserver. * Add test case for recursion (infinite loop) domain compression. -- Ian Jackson Thu, 2 Mar 2000 01:55:53 +0000 adns (0.6) BETA; urgency=high Core library bugfixes: * Avoid infinite timeouts, causing lockup, when they should be zero ! * TCP handling revamped (avoids undefined behaviour due to reentrancy). * Do not fail assertion if _qf_owner, _qf_search, domain ends in `.'. * Many memory leaks fixed. Cool new utility: * adnsresfilter is like `cat' but converts addresses to names without delaying the output. Pipe `netstat -n', `tcpdump -ln', etc. into it. Test and client program bug and portability fixes: * Dynamic library building works properly. * adnshost prints somewhat better messages about some wrong usages. * Include and in adnshost.h. * adnslogres: parsing and error checking improved (Tony Finch). * Regression tests can cope with zero-length reads. * Regression tests check for memory leaks. * adnstest copes with empty query type list. * adnstest uninitialised memory bug fixed. General improvements * Better control of adnshost output and error messages (new -F options). * New adns_if_logpid option (functionality suggested by Tony Finch). * New fanftest test program from Tony Finch (ignored by `make install'). * Reads /etc/resolv-adns.conf if it exists. * Declare flags parameters as enums again, not ints. -- Ian Jackson Wed, 24 Nov 1999 17:13:03 +0000 adns (0.5) unstable; urgency=high New features: * adnslogres, ~100x faster replacement for Apache logresolve; Thanks to Tony Finch for the program and the performance figure. * Internal consistency checking with assert if right options set. * adns_wait_poll function like adns_wait but uses poll, not select. * adns_reverse_submit function for easy in-addr queries. * adns_errtypeabbrev funcion for getting eg "permfail" from _s_nodata. * adnshost utility for scripts and the like (rather alpha). Incompatible changes: * RRs with mailboxes never rejected due to strange chars if _raw. * Lack of a mailbox produces `.' not `<>'. * Better usage messages (and no default query domain) for adnstest. * Return EAGAIN from _check instead of EWOULDBLOCK. * adns_rr_info on _r_mx etc. shows status type abbrev and status number. Bugfixes: * Do not invoke __autosys indirectly from __procdgram (result: coredump usually in memmove, unless adns_if_noautosys was used). * Do not scramble innards when a query on the output queue is cancelled. * Do not close tcp socket twice. * Mailboxes containing spaces in their names are quoted. * Give ESRCH, not EAGAIN, if _check called with no queries outstanding. * adns_rr_hostaddr naddrs is -1 on temporary failure (as documented). * Reject TXT RRs with no strings. * Correct error messages for qname CNAME foo, foo CNAME bar. * adns_processany actually does something. * Fixed typos in adns.h. General improvements: * Promise not to change fds in adns_beforepoll (if now is specified). * Improved textual error string for _s_prohibitedcname. * New comment in adns_processany and return 0 (not r which is 0). * Documentation of resolv.conf directives and options, and of environment variables understood, in adns.h * Regression test scripts set EF_DISABLE_BANNER (for Electric Fence). Portability and build improvements: * Give install the '-c' flag (otherwise some delete the original !). * Do not remove top-level Makefile on `make clean'. * Don't complain so much about poll(2) tests if not available. * Do not give -u 0 -g 0 options to install. * Remove trailing , from some enums in adns.h. * Dynamically linked clients now made with -l, so as to avoid rpath. * Do not use $^ in make rules (should help with non-GNU make). * Declare flags parameters as ints not enums because C++ is crap. -- Ian Jackson Wed, 13 Oct 1999 02:24:35 +0100 adns (0.4) unstable; urgency=high General important bugfixes: * make _qf_owner work if _qf_search not specified, and test it (oops!) * ads->configerrno now initialised (in setup.c). * timercmp(,,<=) doesn't work - use !timercmp(,,>). * Changed memory semantics of internal queries to fix bugs. * Restarting a TCP-using query (eg due to CNAME) doesn't abort. Fixes for handling of broken kinds of reply: * Only accept a reply from the subset of servers we sent the query. * Ignore CNAME(s) in answer after RR(s) (and test). Other bugfixes and improvements: * adns_s_systemfail is in table of errors (for eg adns_strerror). * Do not ship config.cache, Makefile, etc. * Improvements to install instructions, TODO, etc. * Regression tests compile on systems without poll(2). * Do not install adnstest_s. * _submit returns ENOSYS, not adns_s_unknownquery; documented, tested. * includes , , . -- Ian Jackson Thu, 5 Aug 1999 01:17:38 +0100 adns (0.3) unstable; urgency=low Incompatible changes: * Low adns_status values (below adns_s_max_tempfail) renumbered to make room for future locally-induced and locally-detected errors. * Event loop functions for use by select(2) renamed and tidied up. Features / improvements: * New adns_errabbrev() for getting status abbreviation strings. * regress/checkall prints summary list of failed tests, if any. * Event loop functions for poll(2), and some raw variants. * adnstest has ability to use poll(2), and user can set initflags. * checkall prints passed list as well as failed list, if any failed. * You can iterate over outstanding queries (but only once at a time). Bugfixes: * Non-RFC822 mailbox `domain' formatting now works, and clarified. * Rejection of bad characters in domains (without quoteok) works. * Clean up parents from adns->childw (otherwise would abort/segfault). * In adnstest, allocate enough space for, and terminate, query types. * In adnstest, don't print errno values as adns_status values. * Added TODO file. * Made adnstest.c test context pointers. -- Ian Jackson Thu, 15 Jul 1999 00:23:12 +0100 adns (0.2) experimental; urgency=low Portability fixes for compilation on various platforms: * Include and in files with . * Don't use GCC union assignment feature (.rrs=0 => .rrs.untyped=0). * Explictly cast things to [const] struct sockaddr* in syscall args. * Check whether we need -lsocket. * Include in a few more files. * Include and for select. * Look for inet_aton and inet_ntoa (in -lnsl and -lsocket). * LDLIBS removed from dependency lists (some makes don't support this). * An `ambiguous else' warning from some compilers in types.c is removed. Other changes: * Added COPYING (copy of the GPL). * Regression test failure output improved. * Missing targets in regress/Makefile.in added. * Regression test doesn't rely on value of fcntl flags eg O_NONBLOCK. -- Ian Jackson Thu, 20 May 1999 00:27:32 +0100 adns (0.1) experimental; urgency=low * Initial public alpha release. -- Ian Jackson Sat, 17 April 1999 17:42:19 Local variables: mode: debian-changelog fill-column: 75 End: lyskom-server-2.1.2/src/libraries/adns/src/0000777000015100472110000000000007723710276014371 5lyskom-server-2.1.2/src/libraries/adns/src/Makefile.am0000664000015100472110000000035507722446221016341 noinst_LIBRARIES = libadns.a libadns_a_SOURCES = \ adns.h \ check.c \ dlist.h \ event.c \ general.c \ internal.h \ parse.c \ poll.c \ query.c \ reply.c \ setup.c \ transmit.c \ tvarith.h \ types.c EXTRA_DIST = .cvsignore lyskom-server-2.1.2/src/libraries/adns/src/Makefile.in0000664000015100472110000003023307723707507016360 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WARNS = @WARNS@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ prefix = @prefix@ program_transform_name = @program_transform_name@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ noinst_LIBRARIES = libadns.a libadns_a_SOURCES = \ adns.h \ check.c \ dlist.h \ event.c \ general.c \ internal.h \ parse.c \ poll.c \ query.c \ reply.c \ setup.c \ transmit.c \ tvarith.h \ types.c EXTRA_DIST = .cvsignore subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) libadns_a_AR = $(AR) cru libadns_a_LIBADD = am_libadns_a_OBJECTS = check.$(OBJEXT) event.$(OBJEXT) general.$(OBJEXT) \ parse.$(OBJEXT) poll.$(OBJEXT) query.$(OBJEXT) reply.$(OBJEXT) \ setup.$(OBJEXT) transmit.$(OBJEXT) types.$(OBJEXT) libadns_a_OBJECTS = $(am_libadns_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I. depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/check.Po ./$(DEPDIR)/event.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/general.Po ./$(DEPDIR)/parse.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/poll.Po ./$(DEPDIR)/query.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/reply.Po ./$(DEPDIR)/setup.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/transmit.Po ./$(DEPDIR)/types.Po COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ DIST_SOURCES = $(libadns_a_SOURCES) DIST_COMMON = Makefile.am Makefile.in config.h.in SOURCES = $(libadns_a_SOURCES) all: config.h $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) config.h: stamp-h1 @if test ! -f $@; then \ rm -f stamp-h1; \ $(MAKE) stamp-h1; \ else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status src/config.h $(srcdir)/config.h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOHEADER) touch $(srcdir)/config.h.in distclean-hdr: -rm -f config.h stamp-h1 clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libadns.a: $(libadns_a_OBJECTS) $(libadns_a_DEPENDENCIES) -rm -f libadns.a $(libadns_a_AR) libadns.a $(libadns_a_OBJECTS) $(libadns_a_LIBADD) $(RANLIB) libadns.a mostlyclean-compile: -rm -f *.$(OBJEXT) core *.core distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/general.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/poll.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/query.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reply.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/setup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transmit.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/types.Po@am__quote@ distclean-depend: -rm -rf ./$(DEPDIR) .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ @am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ @am__fastdepCC_TRUE@ fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< .c.obj: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ @am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ @am__fastdepCC_TRUE@ fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` uninstall-info-am: ETAGS = etags ETAGSFLAGS = CTAGS = ctags CTAGSFLAGS = tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$tags$$unique" \ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = .. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) config.h installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am distclean-am: clean-am distclean-compile distclean-depend \ distclean-generic distclean-hdr distclean-tags dvi: dvi-am dvi-am: info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags distclean distclean-compile \ distclean-depend distclean-generic distclean-hdr distclean-tags \ distdir dvi dvi-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/src/libraries/adns/src/config.h.in0000664000015100472110000000615107723707477016346 /* src/config.h.in. Generated from configure.in by autoheader. */ /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `nsl' library (-lnsl). */ #undef HAVE_LIBNSL /* Define to 1 if you have the `socket' library (-lsocket). */ #undef HAVE_LIBSOCKET /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `poll' function. */ #undef HAVE_POLL /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SELECT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Include poll.h. */ #ifdef HAVE_POLL #include #else /* kludge it up */ struct pollfd { int fd; short events; short revents; }; #define POLLIN 1 #define POLLPRI 2 #define POLLOUT 4 #endif /* GNU C attributes. */ #ifndef FUNCATTR #ifdef HAVE_GNUC25_ATTRIB #define FUNCATTR(x) __attribute__(x) #else #define FUNCATTR(x) #endif #endif /* GNU C printf formats, or null. */ #ifndef ATTRPRINTF #ifdef HAVE_GNUC25_PRINTFFORMAT #define ATTRPRINTF(si,tc) format(printf,si,tc) #else #define ATTRPRINTF(si,tc) #endif #endif #ifndef PRINTFFORMAT #define PRINTFFORMAT(si,tc) FUNCATTR((ATTRPRINTF(si,tc))) #endif /* GNU C nonreturning functions, or null. */ #ifndef ATTRNORETURN #ifdef HAVE_GNUC25_NORETURN #define ATTRNORETURN noreturn #else #define ATTRNORETURN #endif #endif #ifndef NONRETURNING #define NONRETURNING FUNCATTR((ATTRNORETURN)) #endif /* Combination of both the above. */ #ifndef NONRETURNPRINTFFORMAT #define NONRETURNPRINTFFORMAT(si,tc) FUNCATTR((ATTRPRINTF(si,tc),ATTRNORETURN)) #endif /* GNU C constant functions, or null. */ #ifndef ATTRCONST #ifdef HAVE_GNUC25_CONST #define ATTRCONST const #else #define ATTRCONST #endif #endif #ifndef CONSTANT #define CONSTANT FUNCATTR((ATTRCONST)) #endif #ifdef HAVEUSE_RPCTYPES_H #include #endif #include #ifdef HAVE_SYS_SELECT_H #include #endif /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION /* Define as `__inline' if that's what the C compiler calls it, or to nothing if it is not supported. */ #undef inline lyskom-server-2.1.2/src/libraries/adns/src/adns.h0000664000015100472110000010045007705611250015375 /* * adns.h * - adns user-visible API (single-threaded, without any locking) */ /* * * This file is * Copyright (C) 1997-2000 Ian Jackson * * It is part of adns, which is * Copyright (C) 1997-2000 Ian Jackson * Copyright (C) 1999-2000 Tony Finch * * 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 2, 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. * * * For the benefit of certain LGPL'd `omnibus' software which * provides a uniform interface to various things including adns, I * make the following additional licence. I do this because the GPL * would otherwise force either the omnibus software to be GPL'd or * the adns-using part to be distributed separately. * * So: you may also redistribute and/or modify adns.h (but only the * public header file adns.h and not any other part of adns) under the * terms of the GNU Library General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * Note that adns itself is GPL'd. Authors of adns-using applications * with GPL-incompatible licences, and people who distribute adns with * applications where the whole distribution is not GPL'd, are still * likely to be in violation of the GPL. Anyone who wants to do this * should contact Ian Jackson. Please note that to avoid encouraging * people to infringe the GPL as it applies to the body of adns, Ian * thinks that if you take advantage of the special exception to * redistribute just adns.h under the LGPL, you should retain this * paragraph in its place in the appropriate copyright statements. * * * You should have received a copy of the GNU General Public License, * or the GNU Library General Public License, as appropriate, along * with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * * $Id: adns.h,v 1.1.1.1 2003/07/17 21:18:32 ceder Exp $ */ #ifndef ADNS_H_INCLUDED #define ADNS_H_INCLUDED #include #include #include #include #include #include #ifdef __cplusplus extern "C" { /* I really dislike this - iwj. */ #endif /* All struct in_addr anywhere in adns are in NETWORK byte order. */ typedef struct adns__state *adns_state; typedef struct adns__query *adns_query; typedef enum { adns_if_noenv= 0x0001, /* do not look at environment */ adns_if_noerrprint= 0x0002, /* never print output to stderr (_debug overrides) */ adns_if_noserverwarn= 0x0004, /* do not warn to stderr about duff nameservers etc */ adns_if_debug= 0x0008, /* enable all output to stderr plus debug msgs */ adns_if_logpid= 0x0080, /* include pid in diagnostic output */ adns_if_noautosys= 0x0010, /* do not make syscalls at every opportunity */ adns_if_eintr= 0x0020, /* allow _wait and _synchronous to return EINTR */ adns_if_nosigpipe= 0x0040, /* applic has SIGPIPE set to SIG_IGN, do not protect */ adns_if_checkc_entex= 0x0100, /* do consistency checks on entry/exit to adns funcs */ adns_if_checkc_freq= 0x0300 /* do consistency checks very frequently (slow!) */ } adns_initflags; typedef enum { adns_qf_search= 0x00000001, /* use the searchlist */ adns_qf_usevc= 0x00000002, /* use a virtual circuit (TCP connection) */ adns_qf_owner= 0x00000004, /* fill in the owner field in the answer */ adns_qf_quoteok_query= 0x00000010, /* allow special chars in query domain */ adns_qf_quoteok_cname= 0x00000000, /* allow ... in CNAME we go via - now default */ adns_qf_quoteok_anshost= 0x00000040, /* allow ... in things supposed to be hostnames */ adns_qf_quotefail_cname= 0x00000080, /* refuse if quote-req chars in CNAME we go via */ adns_qf_cname_loose= 0x00000100, /* allow refs to CNAMEs - without, get _s_cname */ adns_qf_cname_forbid= 0x00000200, /* don't follow CNAMEs, instead give _s_cname */ adns__qf_internalmask= 0x0ff00000 } adns_queryflags; typedef enum { adns__rrt_typemask= 0x0ffff, adns__qtf_deref= 0x10000, /* dereference domains and perhaps produce extra data */ adns__qtf_mail822= 0x20000, /* make mailboxes be in RFC822 rcpt field format */ adns_r_none= 0, adns_r_a= 1, adns_r_ns_raw= 2, adns_r_ns= adns_r_ns_raw|adns__qtf_deref, adns_r_cname= 5, adns_r_soa_raw= 6, adns_r_soa= adns_r_soa_raw|adns__qtf_mail822, adns_r_ptr_raw= 12, adns_r_ptr= adns_r_ptr_raw|adns__qtf_deref, adns_r_hinfo= 13, adns_r_mx_raw= 15, adns_r_mx= adns_r_mx_raw|adns__qtf_deref, adns_r_txt= 16, adns_r_rp_raw= 17, adns_r_rp= adns_r_rp_raw|adns__qtf_mail822, adns_r_addr= adns_r_a|adns__qtf_deref } adns_rrtype; /* * In queries without qf_quoteok_*, all domains must have standard * legal syntax, or you get adns_s_querydomainvalid (if the query * domain contains bad characters) or adns_s_answerdomaininvalid (if * the answer contains bad characters). * * In queries _with_ qf_quoteok_*, domains in the query or response * may contain any characters, quoted according to RFC1035 5.1. On * input to adns, the char* is a pointer to the interior of a " * delimited string, except that " may appear in it unquoted. On * output, the char* is a pointer to a string which would be legal * either inside or outside " delimiters; any character which isn't * legal in a hostname (ie alphanumeric or hyphen) or one of _ / + * (the three other punctuation characters commonly abused in domain * names) will be quoted, as \X if it is a printing ASCII character or * \DDD otherwise. * * If the query goes via a CNAME then the canonical name (ie, the * thing that the CNAME record refers to) is usually allowed to * contain any characters, which will be quoted as above. With * adns_qf_quotefail_cname you get adns_s_answerdomaininvalid when * this happens. (This is a change from version 0.4 and earlier, in * which failing the query was the default, and you had to say * adns_qf_quoteok_cname to avoid this; that flag is now deprecated.) * * In version 0.4 and earlier, asking for _raw records containing * mailboxes without specifying _qf_quoteok_anshost was silly. This * is no longer the case. In this version only parts of responses * that are actually supposed to be hostnames will be refused by * default if quote-requiring characters are found. */ /* * If you ask for an RR which contains domains which are actually * encoded mailboxes, and don't ask for the _raw version, then adns * returns the mailbox formatted suitably for an RFC822 recipient * header field. The particular format used is that if the mailbox * requires quoting according to the rules in RFC822 then the * local-part is quoted in double quotes, which end at the next * unescaped double quote (\ is the escape char, and is doubled, and * is used to escape only \ and "). If the local-part is legal * without quoting according to RFC822, it is presented as-is. In any * case the local-part is followed by an @ and the domain. The domain * will not contain any characters not legal in hostnames. * * Unquoted local-parts may contain any printing 7-bit ASCII * except the punctuation characters ( ) < > @ , ; : \ " [ ] * I.e. they may contain alphanumerics, and the following * punctuation characters: ! # % ^ & * - _ = + { } . * * adns will reject local parts containing control characters (byte * values 0-31, 127-159, and 255) - these appear to be legal according * to RFC822 (at least 0-127) but are clearly a bad idea. RFC1035 * syntax does not make any distinction between a single RFC822 * quoted-string containing full stops, and a series of quoted-strings * separated by full stops; adns will return anything that isn't all * valid atoms as a single quoted-string. RFC822 does not allow * high-bit-set characters at all, but adns does allow them in * local-parts, treating them as needing quoting. * * If you ask for the domain with _raw then _no_ checking is done * (even on the host part, regardless of adns_qf_quoteok_anshost), and * you just get the domain name in master file format. * * If no mailbox is supplied the returned string will be `.' in either * case. */ typedef enum { adns_s_ok, /* locally induced errors */ adns_s_nomemory, adns_s_unknownrrtype, adns_s_systemfail, adns_s_max_localfail= 29, /* remotely induced errors, detected locally */ adns_s_timeout, adns_s_allservfail, adns_s_norecurse, adns_s_invalidresponse, adns_s_unknownformat, adns_s_max_remotefail= 59, /* remotely induced errors, reported by remote server to us */ adns_s_rcodeservfail, adns_s_rcodeformaterror, adns_s_rcodenotimplemented, adns_s_rcoderefused, adns_s_rcodeunknown, adns_s_max_tempfail= 99, /* remote configuration errors */ adns_s_inconsistent, /* PTR gives domain whose A does not exist and match */ adns_s_prohibitedcname, /* CNAME found where eg A expected (not if _qf_loosecname) */ adns_s_answerdomaininvalid, adns_s_answerdomaintoolong, adns_s_invaliddata, adns_s_max_misconfig= 199, /* permanent problems with the query */ adns_s_querydomainwrong, adns_s_querydomaininvalid, adns_s_querydomaintoolong, adns_s_max_misquery= 299, /* permanent errors */ adns_s_nxdomain, adns_s_nodata, adns_s_max_permfail= 499 } adns_status; typedef struct { int len; union { struct sockaddr sa; struct sockaddr_in inet; } addr; } adns_rr_addr; typedef struct { char *host; adns_status astatus; int naddrs; /* temp fail => -1, perm fail => 0, s_ok => >0 */ adns_rr_addr *addrs; } adns_rr_hostaddr; typedef struct { char *(array[2]); } adns_rr_strpair; typedef struct { int i; adns_rr_hostaddr ha; } adns_rr_inthostaddr; typedef struct { /* Used both for mx_raw, in which case i is the preference and str the domain, * and for txt, in which case each entry has i for the `text' length, * and str for the data (which will have had an extra nul appended * so that if it was plain text it is now a null-terminated string). */ int i; char *str; } adns_rr_intstr; typedef struct { adns_rr_intstr array[2]; } adns_rr_intstrpair; typedef struct { char *mname, *rname; unsigned long serial, refresh, retry, expire, minimum; } adns_rr_soa; typedef struct { adns_status status; char *cname; /* always NULL if query was for CNAME records */ char *owner; /* only set if requested in query flags, and may be 0 on error anyway */ adns_rrtype type; /* guaranteed to be same as in query */ time_t expires; /* expiry time, defined only if _s_ok, nxdomain or nodata. NOT TTL! */ int nrrs, rrsz; /* nrrs is 0 if an error occurs */ union { void *untyped; unsigned char *bytes; char *(*str); /* ns_raw, cname, ptr, ptr_raw */ adns_rr_intstr *(*manyistr); /* txt (list of strings ends with i=-1, str=0) */ adns_rr_addr *addr; /* addr */ struct in_addr *inaddr; /* a */ adns_rr_hostaddr *hostaddr; /* ns */ adns_rr_intstrpair *intstrpair; /* hinfo */ adns_rr_strpair *strpair; /* rp, rp_raw */ adns_rr_inthostaddr *inthostaddr; /* mx */ adns_rr_intstr *intstr; /* mx_raw */ adns_rr_soa *soa; /* soa, soa_raw */ } rrs; } adns_answer; /* Memory management: * adns_state and adns_query are actually pointers to malloc'd state; * On submission questions are copied, including the owner domain; * Answers are malloc'd as a single piece of memory; pointers in the * answer struct point into further memory in the answer. * query_io: * Must always be non-null pointer; * If *query_io is 0 to start with then any query may be returned; * If *query_io is !0 adns_query then only that query may be returned. * If the call is successful, *query_io, *answer_r, and *context_r * will all be set. * Errors: * Return values are 0 or an errno value. * * For _init, _init_strcfg, _submit and _synchronous, system errors * (eg, failure to create sockets, malloc failure, etc.) return errno * values. * * For _wait and _check failures are reported in the answer * structure, and only 0, ESRCH or (for _check) EAGAIN is * returned: if no (appropriate) requests are done adns_check returns * EAGAIN; if no (appropriate) requests are outstanding both * adns_query and adns_wait return ESRCH. * * Additionally, _wait can return EINTR if you set adns_if_eintr. * * All other errors (nameserver failure, timed out connections, &c) * are returned in the status field of the answer. After a * successful _wait or _check, if status is nonzero then nrrs will be * 0, otherwise it will be >0. type will always be the type * requested. */ int adns_init(adns_state *newstate_r, adns_initflags flags, FILE *diagfile /*0=>stderr*/); int adns_init_strcfg(adns_state *newstate_r, adns_initflags flags, FILE *diagfile /*0=>discard*/, const char *configtext); /* Configuration: * adns_init reads /etc/resolv.conf, which is expected to be (broadly * speaking) in the format expected by libresolv, and then * /etc/resolv-adns.conf if it exists. adns_init_strcfg is instead * passed a string which is interpreted as if it were the contents of * resolv.conf or resolv-adns.conf. In general, configuration which * is set later overrides any that is set earlier. * * Standard directives understood in resolv[-adns].conf: * * nameserver

* Must be followed by the IP address of a nameserver. Several * nameservers may be specified, and they will be tried in the order * found. There is a compiled in limit, currently 5, on the number * of nameservers. (libresolv supports only 3 nameservers.) * * search ... * Specifies the search list for queries which specify * adns_qf_search. This is a list of domains to append to the query * domain. The query domain will be tried as-is either before all * of these or after them, depending on the ndots option setting * (see below). * * domain * This is present only for backward compatibility with obsolete * versions of libresolv. It should not be used, and is interpreted * by adns as if it were `search' - note that this is subtly * different to libresolv's interpretation of this directive. * * sortlist / ... * Should be followed by a sequence of IP-address and netmask pairs, * separated by spaces. They may be specified as * eg. 172.30.206.0/24 or 172.30.206.0/255.255.255.0. Currently up * to 15 pairs may be specified (but note that libresolv only * supports up to 10). * * options * Should followed by one or more options, separated by spaces. * Each option consists of an option name, followed by optionally * a colon and a value. Options are listed below. * * Non-standard directives understood in resolv[-adns].conf: * * clearnameservers * Clears the list of nameservers, so that further nameserver lines * start again from the beginning. * * include * The specified file will be read. * * Additionally, adns will ignore lines in resolv[-adns].conf which * start with a #. * * Standard options understood: * * debug * Enables debugging output from the resolver, which will be written * to stderr. * * ndots: * Affects whether queries with adns_qf_search will be tried first * without adding domains from the searchlist, or whether the bare * query domain will be tried last. Queries which contain at least * dots will be tried bare first. The default is 1. * * Non-standard options understood: * * adns_checkc:none * adns_checkc:entex * adns_checkc:freq * Changes the consistency checking frequency; this overrides the * setting of adns_if_check_entex, adns_if_check_freq, or neither, * in the flags passed to adns_init. * * There are a number of environment variables which can modify the * behaviour of adns. They take effect only if adns_init is used, and * the caller of adns_init can disable them using adns_if_noenv. In * each case there is both a FOO and an ADNS_FOO; the latter is * interpreted later so that it can override the former. Unless * otherwise stated, environment variables are interpreted after * resolv[-adns].conf are read, in the order they are listed here. * * RES_CONF, ADNS_RES_CONF * A filename, whose contets are in the format of resolv.conf. * * RES_CONF_TEXT, ADNS_RES_CONF_TEXT * A string in the format of resolv.conf. * * RES_OPTIONS, ADNS_RES_OPTIONS * These are parsed as if they appeared in the `options' line of a * resolv.conf. In addition to being parsed at this point in the * sequence, they are also parsed at the very beginning before * resolv.conf or any other environment variables are read, so that * any debug option can affect the processing of the configuration. * * LOCALDOMAIN, ADNS_LOCALDOMAIN * These are interpreted as if their contents appeared in a `search' * line in resolv.conf. */ int adns_synchronous(adns_state ads, const char *owner, adns_rrtype type, adns_queryflags flags, adns_answer **answer_r); /* NB: if you set adns_if_noautosys then _submit and _check do not * make any system calls; you must use some of the asynch-io event * processing functions to actually get things to happen. */ int adns_submit(adns_state ads, const char *owner, adns_rrtype type, adns_queryflags flags, void *context, adns_query *query_r); /* The owner should be quoted in master file format. */ int adns_check(adns_state ads, adns_query *query_io, adns_answer **answer_r, void **context_r); int adns_wait(adns_state ads, adns_query *query_io, adns_answer **answer_r, void **context_r); /* same as adns_wait but uses poll(2) internally */ int adns_wait_poll(adns_state ads, adns_query *query_io, adns_answer **answer_r, void **context_r); void adns_cancel(adns_query query); /* The adns_query you get back from _submit is valid (ie, can be * legitimately passed into adns functions) until it is returned by * adns_check or adns_wait, or passed to adns_cancel. After that it * must not be used. You can rely on it not being reused until the * first adns_submit or _transact call using the same adns_state after * it became invalid, so you may compare it for equality with other * query handles until you next call _query or _transact. * * _submit and _synchronous return ENOSYS if they don't understand the * query type. */ int adns_submit_reverse(adns_state ads, const struct sockaddr *addr, adns_rrtype type, adns_queryflags flags, void *context, adns_query *query_r); /* type must be _r_ptr or _r_ptr_raw. _qf_search is ignored. * addr->sa_family must be AF_INET or you get ENOSYS. */ int adns_submit_reverse_any(adns_state ads, const struct sockaddr *addr, const char *rzone, adns_rrtype type, adns_queryflags flags, void *context, adns_query *query_r); /* For RBL-style reverse `zone's; look up * . * Any type is allowed. _qf_search is ignored. * addr->sa_family must be AF_INET or you get ENOSYS. */ void adns_finish(adns_state ads); /* You may call this even if you have queries outstanding; * they will be cancelled. */ void adns_forallqueries_begin(adns_state ads); adns_query adns_forallqueries_next(adns_state ads, void **context_r); /* Iterator functions, which you can use to loop over the outstanding * (submitted but not yet successfuly checked/waited) queries. * * You can only have one iteration going at once. You may call _begin * at any time; after that, an iteration will be in progress. You may * only call _next when an iteration is in progress - anything else * may coredump. The iteration remains in progress until _next * returns 0, indicating that all the queries have been walked over, * or ANY other adns function is called with the same adns_state (or a * query in the same adns_state). There is no need to explicitly * finish an iteration. * * context_r may be 0. *context_r may not be set when _next returns 0. */ void adns_checkconsistency(adns_state ads, adns_query qu); /* Checks the consistency of adns's internal data structures. * If any error is found, the program will abort(). * You may pass 0 for qu; if you pass non-null then additional checks * are done to make sure that qu is a valid query. */ /* * Example expected/legal calling sequence for submit/check/wait: * adns_init * adns_submit 1 * adns_submit 2 * adns_submit 3 * adns_wait 1 * adns_check 3 -> EAGAIN * adns_wait 2 * adns_wait 3 * .... * adns_finish */ /* * Entrypoints for generic asynch io: * (these entrypoints are not very useful except in combination with * * some of the other I/O model calls which can tell you which fds to * be interested in): * * Note that any adns call may cause adns to open and close fds, so * you must call beforeselect or beforepoll again just before * blocking, or you may not have an up-to-date list of it's fds. */ int adns_processany(adns_state ads); /* Gives adns flow-of-control for a bit. This will never block, and * can be used with any threading/asynch-io model. If some error * occurred which might cause an event loop to spin then the errno * value is returned. */ int adns_processreadable(adns_state ads, int fd, const struct timeval *now); int adns_processwriteable(adns_state ads, int fd, const struct timeval *now); int adns_processexceptional(adns_state ads, int fd, const struct timeval *now); /* Gives adns flow-of-control so that it can process incoming data * from, or send outgoing data via, fd. Very like _processany. If it * returns zero then fd will no longer be readable or writeable * (unless of course more data has arrived since). adns will _only_ * use that fd and only in the manner specified, regardless of whether * adns_if_noautosys was specified. * * adns_processexceptional should be called when select(2) reports an * exceptional condition, or poll(2) reports POLLPRI. * * It is fine to call _processreabable or _processwriteable when the * fd is not ready, or with an fd that doesn't belong to adns; it will * then just return 0. * * If some error occurred which might prevent an event loop to spin * then the errno value is returned. */ void adns_processtimeouts(adns_state ads, const struct timeval *now); /* Gives adns flow-of-control so that it can process any timeouts * which might have happened. Very like _processreadable/writeable. * * now may be 0; if it isn't, *now must be the current time, recently * obtained from gettimeofday. */ void adns_firsttimeout(adns_state ads, struct timeval **tv_mod, struct timeval *tv_buf, struct timeval now); /* Asks adns when it would first like the opportunity to time * something out. now must be the current time, from gettimeofday. * * If tv_mod points to 0 then tv_buf must be non-null, and * _firsttimeout will fill in *tv_buf with the time until the first * timeout, and make *tv_mod point to tv_buf. If adns doesn't have * anything that might need timing out it will leave *tv_mod as 0. * * If *tv_mod is not 0 then tv_buf is not used. adns will update * *tv_mod if it has any earlier timeout, and leave it alone if it * doesn't. * * This call will not actually do any I/O, or change the fds that adns * is using. It always succeeds and never blocks. */ void adns_globalsystemfailure(adns_state ads); /* If serious problem(s) happen which globally affect your ability to * interact properly with adns, or adns's ability to function * properly, you or adns can call this function. * * All currently outstanding queries will be made to fail with * adns_s_systemfail, and adns will close any stream sockets it has * open. * * This is used by adns, for example, if gettimeofday() fails. * Without this the program's event loop might start to spin ! * * This call will never block. */ /* * Entrypoints for select-loop based asynch io: */ void adns_beforeselect(adns_state ads, int *maxfd, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval **tv_mod, struct timeval *tv_buf, const struct timeval *now); /* Find out file descriptors adns is interested in, and when it would * like the opportunity to time something out. If you do not plan to * block then tv_mod may be 0. Otherwise, tv_mod and tv_buf are as * for adns_firsttimeout. readfds, writefds, exceptfds and maxfd_io may * not be 0. * * If now is not 0 then this will never actually do any I/O, or change * the fds that adns is using or the timeouts it wants. In any case * it won't block, and it will set the timeout to zero if a query * finishes in _beforeselect. */ void adns_afterselect(adns_state ads, int maxfd, const fd_set *readfds, const fd_set *writefds, const fd_set *exceptfds, const struct timeval *now); /* Gives adns flow-of-control for a bit; intended for use after * select. This is just a fancy way of calling adns_processreadable/ * writeable/timeouts as appropriate, as if select had returned the * data being passed. Always succeeds. */ /* * Example calling sequence: * * adns_init _noautosys * loop { * adns_beforeselect * select * adns_afterselect * ... * adns_submit / adns_check * ... * } */ /* * Entrypoints for poll-loop based asynch io: */ struct pollfd; /* In case your system doesn't have it or you forgot to include * , to stop the following declarations from causing * problems. If your system doesn't have poll then the following * entrypoints will not be defined in libadns. Sorry ! */ int adns_beforepoll(adns_state ads, struct pollfd *fds, int *nfds_io, int *timeout_io, const struct timeval *now); /* Finds out which fd's adns is interested in, and when it would like * to be able to time things out. This is in a form suitable for use * with poll(2). * * On entry, usually fds should point to at least *nfds_io structs. * adns will fill up to that many structs will information for poll, * and record in *nfds_io how many structs it filled. If it wants to * listen for more structs then *nfds_io will be set to the number * required and _beforepoll will return ERANGE. * * You may call _beforepoll with fds==0 and *nfds_io 0, in which case * adns will fill in the number of fds that it might be interested in * in *nfds_io, and always return either 0 (if it is not interested in * any fds) or ERANGE (if it is). * * NOTE that (unless now is 0) adns may acquire additional fds * from one call to the next, so you must put adns_beforepoll in a * loop, rather than assuming that the second call (with the buffer * size requested by the first) will not return ERANGE. * * adns only ever sets POLLIN, POLLOUT and POLLPRI in its pollfd * structs, and only ever looks at those bits. POLLPRI is required to * detect TCP Urgent Data (which should not be used by a DNS server) * so that adns can know that the TCP stream is now useless. * * In any case, *timeout_io should be a timeout value as for poll(2), * which adns will modify downwards as required. If the caller does * not plan to block then *timeout_io should be 0 on entry, or * alternatively, timeout_io may be 0. (Alternatively, the caller may * use _beforeselect with timeout_io==0 to find out about file * descriptors, and use _firsttimeout is used to find out when adns * might want to time something out.) * * adns_beforepoll will return 0 on success, and will not fail for any * reason other than the fds buffer being too small (ERANGE). * * This call will never actually do any I/O. If you supply the * current time it will not change the fds that adns is using or the * timeouts it wants. * * In any case this call won't block. */ #define ADNS_POLLFDS_RECOMMENDED 2 /* If you allocate an fds buf with at least RECOMMENDED entries then * you are unlikely to need to enlarge it. You are recommended to do * so if it's convenient. However, you must be prepared for adns to * require more space than this. */ void adns_afterpoll(adns_state ads, const struct pollfd *fds, int nfds, const struct timeval *now); /* Gives adns flow-of-control for a bit; intended for use after * poll(2). fds and nfds should be the results from poll(). pollfd * structs mentioning fds not belonging to adns will be ignored. */ adns_status adns_rr_info(adns_rrtype type, const char **rrtname_r, const char **fmtname_r, int *len_r, const void *datap, char **data_r); /* * Get information about a query type, or convert reply data to a * textual form. type must be specified, and the official name of the * corresponding RR type will be returned in *rrtname_r, and * information about the processing style in *fmtname_r. The length * of the table entry in an answer for that type will be returned in * in *len_r. Any or all of rrtname_r, fmtname_r and len_r may be 0. * If fmtname_r is non-null then *fmtname_r may be null on return, * indicating that no special processing is involved. * * data_r be must be non-null iff datap is. In this case *data_r will * be set to point to a string pointing to a representation of the RR * data in master file format. (The owner name, timeout, class and * type will not be present - only the data part of the RR.) The * memory will have been obtained from malloc() and must be freed by * the caller. * * Usually this routine will succeed. Possible errors include: * adns_s_nomemory * adns_s_rrtypeunknown * adns_s_invaliddata (*datap contained garbage) * If an error occurs then no memory has been allocated, * and *rrtname_r, *fmtname_r, *len_r and *data_r are undefined. * * There are some adns-invented data formats which are not official * master file formats. These include: * * Mailboxes if __qtf_mail822: these are just included as-is. * * Addresses (adns_rr_addr): these may be of pretty much any type. * The representation is in two parts: first, a word for the address * family (ie, in AF_XXX, the XXX), and then one or more items for the * address itself, depending on the format. For an IPv4 address the * syntax is INET followed by the dotted quad (from inet_ntoa). * Currently only IPv4 is supported. * * Text strings (as in adns_rr_txt) appear inside double quotes, and * use \" and \\ to represent " and \, and \xHH to represent * characters not in the range 32-126. * * Hostname with addresses (adns_rr_hostaddr): this consists of the * hostname, as usual, followed by the adns_status value, as an * abbreviation, and then a descriptive string (encoded as if it were * a piece of text), for the address lookup, followed by zero or more * addresses enclosed in ( and ). If the result was a temporary * failure, then a single ? appears instead of the ( ). If the * result was a permanent failure then an empty pair of parentheses * appears (which a space in between). For example, one of the NS * records for greenend.org.uk comes out like * ns.chiark.greenend.org.uk ok "OK" ( INET 195.224.76.132 ) * an MX referring to a nonexistent host might come out like: * 50 sun2.nsfnet-relay.ac.uk nxdomain "No such domain" ( ) * and if nameserver information is not available you might get: * dns2.spong.dyn.ml.org timeout "DNS query timed out" ? */ const char *adns_strerror(adns_status st); const char *adns_errabbrev(adns_status st); const char *adns_errtypeabbrev(adns_status st); /* Like strerror but for adns_status values. adns_errabbrev returns * the abbreviation of the error - eg, for adns_s_timeout it returns * "timeout". adns_errtypeabbrev returns the abbreviation of the * error class: ie, for values up to adns_s_max_XXX it will return the * string XXX. You MUST NOT call these functions with status values * not returned by the same adns library. */ #ifdef __cplusplus } /* end of extern "C" */ #endif #endif lyskom-server-2.1.2/src/libraries/adns/src/check.c0000664000015100472110000001237607705611250015531 /* * check.c * - consistency checks */ /* * This file is * Copyright (C) 1997-1999 Ian Jackson * * It is part of adns, which is * Copyright (C) 1997-2000 Ian Jackson * Copyright (C) 1999-2000 Tony Finch * * 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 2, 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, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "internal.h" void adns_checkconsistency(adns_state ads, adns_query qu) { adns__consistency(ads,qu,cc_user); } #define DLIST_CHECK(list, nodevar, part, body) \ if ((list).head) { \ assert(! (list).head->part back); \ for ((nodevar)= (list).head; (nodevar); (nodevar)= (nodevar)->part next) { \ assert((nodevar)->part next \ ? (nodevar) == (nodevar)->part next->part back \ : (nodevar) == (list).tail); \ body \ } \ } #define DLIST_ASSERTON(node, nodevar, list, part) \ do { \ for ((nodevar)= (list).head; \ (nodevar) != (node); \ (nodevar)= (nodevar)->part next) { \ assert((nodevar)); \ } \ } while(0) static void checkc_query_alloc(adns_state ads, adns_query qu) { allocnode *an; DLIST_CHECK(qu->allocations, an, , { }); } static void checkc_query(adns_state ads, adns_query qu) { adns_query child; assert(qu->udpnextserver < ads->nservers); assert(!(qu->udpsent & (~0UL << ads->nservers))); assert(qu->search_pos <= ads->nsearchlist); if (qu->parent) DLIST_ASSERTON(qu, child, qu->parent->children, siblings.); } static void checkc_notcpbuf(adns_state ads) { assert(!ads->tcpsend.used); assert(!ads->tcprecv.used); assert(!ads->tcprecv_skip); } static void checkc_global(adns_state ads) { int i; assert(ads->udpsocket >= 0); for (i=0; insortlist; i++) assert(!(ads->sortlist[i].base.s_addr & ~ads->sortlist[i].mask.s_addr)); assert(ads->tcpserver >= 0 && ads->tcpserver < ads->nservers); switch (ads->tcpstate) { case server_connecting: assert(ads->tcpsocket >= 0); checkc_notcpbuf(ads); break; case server_disconnected: case server_broken: assert(ads->tcpsocket == -1); checkc_notcpbuf(ads); break; case server_ok: assert(ads->tcpsocket >= 0); assert(ads->tcprecv_skip <= ads->tcprecv.used); break; default: assert(!"ads->tcpstate value"); } assert(ads->searchlist || !ads->nsearchlist); } static void checkc_queue_udpw(adns_state ads) { adns_query qu; DLIST_CHECK(ads->udpw, qu, , { assert(qu->state==query_tosend); assert(qu->retries <= UDPMAXRETRIES); assert(qu->udpsent); assert(!qu->children.head && !qu->children.tail); checkc_query(ads,qu); checkc_query_alloc(ads,qu); }); } static void checkc_queue_tcpw(adns_state ads) { adns_query qu; DLIST_CHECK(ads->tcpw, qu, , { assert(qu->state==query_tcpw); assert(!qu->children.head && !qu->children.tail); assert(qu->retries <= ads->nservers+1); checkc_query(ads,qu); checkc_query_alloc(ads,qu); }); } static void checkc_queue_childw(adns_state ads) { adns_query parent, child; DLIST_CHECK(ads->childw, parent, , { assert(parent->state == query_childw); assert(parent->children.head); DLIST_CHECK(parent->children, child, siblings., { assert(child->parent == parent); assert(child->state != query_done); }); checkc_query(ads,parent); checkc_query_alloc(ads,parent); }); } static void checkc_queue_output(adns_state ads) { adns_query qu; DLIST_CHECK(ads->output, qu, , { assert(qu->state == query_done); assert(!qu->children.head && !qu->children.tail); assert(!qu->parent); assert(!qu->allocations.head && !qu->allocations.tail); checkc_query(ads,qu); }); } void adns__consistency(adns_state ads, adns_query qu, consistency_checks cc) { adns_query search; switch (cc) { case cc_user: break; case cc_entex: if (!(ads->iflags & adns_if_checkc_entex)) return; break; case cc_freq: if ((ads->iflags & adns_if_checkc_freq) != adns_if_checkc_freq) return; break; default: abort(); } checkc_global(ads); checkc_queue_udpw(ads); checkc_queue_tcpw(ads); checkc_queue_childw(ads); checkc_queue_output(ads); if (qu) { switch (qu->state) { case query_tosend: DLIST_ASSERTON(qu, search, ads->udpw, ); break; case query_tcpw: DLIST_ASSERTON(qu, search, ads->tcpw, ); break; case query_childw: DLIST_ASSERTON(qu, search, ads->childw, ); break; case query_done: DLIST_ASSERTON(qu, search, ads->output, ); break; default: assert(!"specific query state"); } } } lyskom-server-2.1.2/src/libraries/adns/src/dlist.h0000664000015100472110000000372607707157067015614 /* * dlist.h * - macros for handling doubly linked lists */ /* * This file is * Copyright (C) 1997-1999 Ian Jackson * * It is part of adns, which is * Copyright (C) 1997-2000 Ian Jackson * Copyright (C) 1999 Tony Finch * * 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 2, 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, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef ADNS_DLIST_H_INCLUDED #define ADNS_DLIST_H_INCLUDED #define ADNS_LIST_INIT(list) ((list).head= (list).tail= 0) #define ADNS_LINK_INIT(link) ((link).next= (link).back= 0) #define ADNS_LIST_UNLINK_PART(list,node,part) \ do { \ if ((node)->part back) (node)->part back->part next= (node)->part next; \ else (list).head= (node)->part next; \ if ((node)->part next) (node)->part next->part back= (node)->part back; \ else (list).tail= (node)->part back; \ } while(0) #define ADNS_LIST_LINK_TAIL_PART(list,node,part) \ do { \ (node)->part next= 0; \ (node)->part back= (list).tail; \ if ((list).tail) (list).tail->part next= (node); else (list).head= (node); \ (list).tail= (node); \ } while(0) #define ADNS_LIST_UNLINK(list,node) ADNS_LIST_UNLINK_PART(list,node,) #define ADNS_LIST_LINK_TAIL(list,node) ADNS_LIST_LINK_TAIL_PART(list,node,) #endif lyskom-server-2.1.2/src/libraries/adns/src/event.c0000664000015100472110000005007207707157070015577 /* * event.c * - event loop core * - TCP connection management * - user-visible check/wait and event-loop-related functions */ /* * This file is * Copyright (C) 1997-2000 Ian Jackson * * It is part of adns, which is * Copyright (C) 1997-2000 Ian Jackson * Copyright (C) 1999-2000 Tony Finch * * 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 2, 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, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include "internal.h" #include "tvarith.h" /* TCP connection management. */ static void tcp_close(adns_state ads) { int serv; serv= ads->tcpserver; close(ads->tcpsocket); ads->tcpsocket= -1; ads->tcprecv.used= ads->tcprecv_skip= ads->tcpsend.used= 0; } void adns__tcp_broken(adns_state ads, const char *what, const char *why) { int serv; adns_query qu; assert(ads->tcpstate == server_connecting || ads->tcpstate == server_ok); serv= ads->tcpserver; if (what) adns__warn(ads,serv,0,"TCP connection failed: %s: %s",what,why); if (ads->tcpstate == server_connecting) { /* Counts as a retry for all the queries waiting for TCP. */ for (qu= ads->tcpw.head; qu; qu= qu->next) qu->retries++; } tcp_close(ads); ads->tcpstate= server_broken; ads->tcpserver= (serv+1)%ads->nservers; } static void tcp_connected(adns_state ads, struct timeval now) { adns_query qu, nqu; adns__debug(ads,ads->tcpserver,0,"TCP connected"); ads->tcpstate= server_ok; for (qu= ads->tcpw.head; qu && ads->tcpstate == server_ok; qu= nqu) { nqu= qu->next; assert(qu->state == query_tcpw); adns__querysend_tcp(qu,now); } } void adns__tcp_tryconnect(adns_state ads, struct timeval now) { int r, fd, tries; struct sockaddr_in addr; struct protoent *proto; for (tries=0; triesnservers; tries++) { switch (ads->tcpstate) { case server_connecting: case server_ok: case server_broken: return; case server_disconnected: break; default: abort(); } assert(!ads->tcpsend.used); assert(!ads->tcprecv.used); assert(!ads->tcprecv_skip); proto= getprotobyname("tcp"); if (!proto) { adns__diag(ads,-1,0,"unable to find protocol no. for TCP !"); return; } fd= socket(AF_INET,SOCK_STREAM,proto->p_proto); if (fd<0) { adns__diag(ads,-1,0,"cannot create TCP socket: %s",strerror(errno)); return; } r= adns__setnonblock(ads,fd); if (r) { adns__diag(ads,-1,0,"cannot make TCP socket nonblocking: %s",strerror(r)); close(fd); return; } memset(&addr,0,sizeof(addr)); addr.sin_family= AF_INET; addr.sin_port= htons(DNS_PORT); addr.sin_addr= ads->servers[ads->tcpserver].addr; r= connect(fd,(const struct sockaddr*)&addr,sizeof(addr)); ads->tcpsocket= fd; ads->tcpstate= server_connecting; if (r==0) { tcp_connected(ads,now); return; } if (errno == EWOULDBLOCK || errno == EINPROGRESS) { ads->tcptimeout= now; timevaladd(&ads->tcptimeout,TCPCONNMS); return; } adns__tcp_broken(ads,"connect",strerror(errno)); ads->tcpstate= server_disconnected; } } /* Timeout handling functions. */ void adns__must_gettimeofday(adns_state ads, const struct timeval **now_io, struct timeval *tv_buf) { const struct timeval *now; int r; now= *now_io; if (now) return; r= gettimeofday(tv_buf,0); if (!r) { *now_io= tv_buf; return; } adns__diag(ads,-1,0,"gettimeofday failed: %s",strerror(errno)); adns_globalsystemfailure(ads); return; } static void inter_immed(struct timeval **tv_io, struct timeval *tvbuf) { struct timeval *rbuf; if (!tv_io) return; rbuf= *tv_io; if (!rbuf) { *tv_io= rbuf= tvbuf; } timerclear(rbuf); } static void inter_maxto(struct timeval **tv_io, struct timeval *tvbuf, struct timeval maxto) { struct timeval *rbuf; if (!tv_io) return; rbuf= *tv_io; if (!rbuf) { *tvbuf= maxto; *tv_io= tvbuf; } else { if (timercmp(rbuf,&maxto,>)) *rbuf= maxto; } /*fprintf(stderr,"inter_maxto maxto=%ld.%06ld result=%ld.%06ld\n", maxto.tv_sec,maxto.tv_usec,(**tv_io).tv_sec,(**tv_io).tv_usec);*/ } static void inter_maxtoabs(struct timeval **tv_io, struct timeval *tvbuf, struct timeval now, struct timeval maxtime) { /* tv_io may be 0 */ ldiv_t dr; /*fprintf(stderr,"inter_maxtoabs now=%ld.%06ld maxtime=%ld.%06ld\n", now.tv_sec,now.tv_usec,maxtime.tv_sec,maxtime.tv_usec);*/ if (!tv_io) return; maxtime.tv_sec -= (now.tv_sec+2); maxtime.tv_usec -= (now.tv_usec-2000000); dr= ldiv(maxtime.tv_usec,1000000); maxtime.tv_sec += dr.quot; maxtime.tv_usec -= dr.quot*1000000; if (maxtime.tv_sec<0) timerclear(&maxtime); inter_maxto(tv_io,tvbuf,maxtime); } static void timeouts_queue(adns_state ads, int act, struct timeval **tv_io, struct timeval *tvbuf, struct timeval now, struct query_queue *queue) { adns_query qu, nqu; for (qu= queue->head; qu; qu= nqu) { nqu= qu->next; if (!timercmp(&now,&qu->timeout,>)) { inter_maxtoabs(tv_io,tvbuf,now,qu->timeout); } else { if (!act) { inter_immed(tv_io,tvbuf); return; } ADNS_LIST_UNLINK(*queue,qu); if (qu->state != query_tosend) { adns__query_fail(qu,adns_s_timeout); } else { adns__query_send(qu,now); } nqu= queue->head; } } } static void tcp_events(adns_state ads, int act, struct timeval **tv_io, struct timeval *tvbuf, struct timeval now) { adns_query qu, nqu; for (;;) { switch (ads->tcpstate) { case server_broken: if (!act) { inter_immed(tv_io,tvbuf); return; } for (qu= ads->tcpw.head; qu; qu= nqu) { nqu= qu->next; assert(qu->state == query_tcpw); if (qu->retries > ads->nservers) { ADNS_LIST_UNLINK(ads->tcpw,qu); adns__query_fail(qu,adns_s_allservfail); } } ads->tcpstate= server_disconnected; case server_disconnected: /* fall through */ if (!ads->tcpw.head) return; if (!act) { inter_immed(tv_io,tvbuf); return; } adns__tcp_tryconnect(ads,now); break; case server_ok: if (ads->tcpw.head) return; if (!ads->tcptimeout.tv_sec) { assert(!ads->tcptimeout.tv_usec); ads->tcptimeout= now; timevaladd(&ads->tcptimeout,TCPIDLEMS); } case server_connecting: /* fall through */ if (!act || !timercmp(&now,&ads->tcptimeout,>)) { inter_maxtoabs(tv_io,tvbuf,now,ads->tcptimeout); return; } { /* TCP timeout has happened */ switch (ads->tcpstate) { case server_connecting: /* failed to connect */ adns__tcp_broken(ads,"unable to make connection","timed out"); break; case server_ok: /* idle timeout */ tcp_close(ads); ads->tcpstate= server_disconnected; return; default: abort(); } } break; default: abort(); } } return; } void adns__timeouts(adns_state ads, int act, struct timeval **tv_io, struct timeval *tvbuf, struct timeval now) { timeouts_queue(ads,act,tv_io,tvbuf,now, &ads->udpw); timeouts_queue(ads,act,tv_io,tvbuf,now, &ads->tcpw); tcp_events(ads,act,tv_io,tvbuf,now); } void adns_firsttimeout(adns_state ads, struct timeval **tv_io, struct timeval *tvbuf, struct timeval now) { adns__consistency(ads,0,cc_entex); adns__timeouts(ads, 0, tv_io,tvbuf, now); adns__consistency(ads,0,cc_entex); } void adns_processtimeouts(adns_state ads, const struct timeval *now) { struct timeval tv_buf; adns__consistency(ads,0,cc_entex); adns__must_gettimeofday(ads,&now,&tv_buf); if (now) adns__timeouts(ads, 1, 0,0, *now); adns__consistency(ads,0,cc_entex); } /* fd handling functions. These are the top-level of the real work of * reception and often transmission. */ int adns__pollfds(adns_state ads, struct pollfd pollfds_buf[MAX_POLLFDS]) { /* Returns the number of entries filled in. Always zeroes revents. */ assert(MAX_POLLFDS==2); pollfds_buf[0].fd= ads->udpsocket; pollfds_buf[0].events= POLLIN; pollfds_buf[0].revents= 0; switch (ads->tcpstate) { case server_disconnected: case server_broken: return 1; case server_connecting: pollfds_buf[1].events= POLLOUT; break; case server_ok: pollfds_buf[1].events= ads->tcpsend.used ? POLLIN|POLLOUT|POLLPRI : POLLIN|POLLPRI; break; default: abort(); } pollfds_buf[1].fd= ads->tcpsocket; return 2; } int adns_processreadable(adns_state ads, int fd, const struct timeval *now) { int want, dgramlen, r, udpaddrlen, serv, old_skip; byte udpbuf[DNS_MAXUDP]; struct sockaddr_in udpaddr; adns__consistency(ads,0,cc_entex); switch (ads->tcpstate) { case server_disconnected: case server_broken: case server_connecting: break; case server_ok: if (fd != ads->tcpsocket) break; assert(!ads->tcprecv_skip); do { if (ads->tcprecv.used >= ads->tcprecv_skip+2) { dgramlen= ((ads->tcprecv.buf[ads->tcprecv_skip]<<8) | ads->tcprecv.buf[ads->tcprecv_skip+1]); if (ads->tcprecv.used >= ads->tcprecv_skip+2+dgramlen) { old_skip= ads->tcprecv_skip; ads->tcprecv_skip += 2+dgramlen; adns__procdgram(ads, ads->tcprecv.buf+old_skip+2, dgramlen, ads->tcpserver, 1,*now); continue; } else { want= 2+dgramlen; } } else { want= 2; } ads->tcprecv.used -= ads->tcprecv_skip; memmove(ads->tcprecv.buf,ads->tcprecv.buf+ads->tcprecv_skip,ads->tcprecv.used); ads->tcprecv_skip= 0; if (!adns__vbuf_ensure(&ads->tcprecv,want)) { r= ENOMEM; goto xit; } assert(ads->tcprecv.used <= ads->tcprecv.avail); if (ads->tcprecv.used == ads->tcprecv.avail) continue; r= read(ads->tcpsocket, ads->tcprecv.buf+ads->tcprecv.used, ads->tcprecv.avail-ads->tcprecv.used); if (r>0) { ads->tcprecv.used+= r; } else { if (r) { if (errno==EAGAIN || errno==EWOULDBLOCK) { r= 0; goto xit; } if (errno==EINTR) continue; if (errno_resources(errno)) { r= errno; goto xit; } } adns__tcp_broken(ads,"read",r?strerror(errno):"closed"); } } while (ads->tcpstate == server_ok); r= 0; goto xit; default: abort(); } if (fd == ads->udpsocket) { for (;;) { udpaddrlen= sizeof(udpaddr); r= recvfrom(ads->udpsocket,udpbuf,sizeof(udpbuf),0, (struct sockaddr*)&udpaddr,&udpaddrlen); if (r<0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { r= 0; goto xit; } if (errno == EINTR) continue; if (errno_resources(errno)) { r= errno; goto xit; } adns__warn(ads,-1,0,"datagram receive error: %s",strerror(errno)); r= 0; goto xit; } if (udpaddrlen != sizeof(udpaddr)) { adns__diag(ads,-1,0,"datagram received with wrong address length %d" " (expected %lu)", udpaddrlen, (unsigned long)sizeof(udpaddr)); continue; } if (udpaddr.sin_family != AF_INET) { adns__diag(ads,-1,0,"datagram received with wrong protocol family" " %u (expected %u)",udpaddr.sin_family,AF_INET); continue; } if (ntohs(udpaddr.sin_port) != DNS_PORT) { adns__diag(ads,-1,0,"datagram received from wrong port %u (expected %u)", ntohs(udpaddr.sin_port),DNS_PORT); continue; } for (serv= 0; serv < ads->nservers && ads->servers[serv].addr.s_addr != udpaddr.sin_addr.s_addr; serv++); if (serv >= ads->nservers) { adns__warn(ads,-1,0,"datagram received from unknown nameserver %s", inet_ntoa(udpaddr.sin_addr)); continue; } adns__procdgram(ads,udpbuf,r,serv,0,*now); } } r= 0; xit: adns__consistency(ads,0,cc_entex); return r; } int adns_processwriteable(adns_state ads, int fd, const struct timeval *now) { int r; adns__consistency(ads,0,cc_entex); switch (ads->tcpstate) { case server_disconnected: case server_broken: break; case server_connecting: if (fd != ads->tcpsocket) break; assert(ads->tcprecv.used==0); assert(ads->tcprecv_skip==0); for (;;) { if (!adns__vbuf_ensure(&ads->tcprecv,1)) { r= ENOMEM; goto xit; } r= read(ads->tcpsocket,&ads->tcprecv.buf,1); if (r==0 || (r<0 && (errno==EAGAIN || errno==EWOULDBLOCK))) { tcp_connected(ads,*now); r= 0; goto xit; } if (r>0) { adns__tcp_broken(ads,"connect/read","sent data before first request"); r= 0; goto xit; } if (errno==EINTR) continue; if (errno_resources(errno)) { r= errno; goto xit; } adns__tcp_broken(ads,"connect/read",strerror(errno)); r= 0; goto xit; } /* not reached */ case server_ok: if (fd != ads->tcpsocket) break; while (ads->tcpsend.used) { adns__sigpipe_protect(ads); r= write(ads->tcpsocket,ads->tcpsend.buf,ads->tcpsend.used); adns__sigpipe_unprotect(ads); if (r<0) { if (errno==EINTR) continue; if (errno==EAGAIN || errno==EWOULDBLOCK) { r= 0; goto xit; } if (errno_resources(errno)) { r= errno; goto xit; } adns__tcp_broken(ads,"write",strerror(errno)); r= 0; goto xit; } else if (r>0) { ads->tcpsend.used -= r; memmove(ads->tcpsend.buf,ads->tcpsend.buf+r,ads->tcpsend.used); } } r= 0; goto xit; default: abort(); } r= 0; xit: adns__consistency(ads,0,cc_entex); return r; } int adns_processexceptional(adns_state ads, int fd, const struct timeval *now) { adns__consistency(ads,0,cc_entex); switch (ads->tcpstate) { case server_disconnected: case server_broken: break; case server_connecting: case server_ok: if (fd != ads->tcpsocket) break; adns__tcp_broken(ads,"poll/select","exceptional condition detected"); break; default: abort(); } adns__consistency(ads,0,cc_entex); return 0; } static void fd_event(adns_state ads, int fd, int revent, int pollflag, int maxfd, const fd_set *fds, int (*func)(adns_state, int fd, const struct timeval *now), struct timeval now, int *r_r) { int r; if (!(revent & pollflag)) return; if (fds && !(fd= maxfd) maxfd= fd+1; revents= pollfds[i].revents; fd_event(ads,fd, revents,POLLIN, maxfd,readfds, adns_processreadable,now,r_r); fd_event(ads,fd, revents,POLLOUT, maxfd,writefds, adns_processwriteable,now,r_r); fd_event(ads,fd, revents,POLLPRI, maxfd,exceptfds, adns_processexceptional,now,r_r); } } /* Wrappers for select(2). */ void adns_beforeselect(adns_state ads, int *maxfd_io, fd_set *readfds_io, fd_set *writefds_io, fd_set *exceptfds_io, struct timeval **tv_mod, struct timeval *tv_tobuf, const struct timeval *now) { struct timeval tv_nowbuf; struct pollfd pollfds[MAX_POLLFDS]; int i, fd, maxfd, npollfds; adns__consistency(ads,0,cc_entex); if (tv_mod && (!*tv_mod || (*tv_mod)->tv_sec || (*tv_mod)->tv_usec)) { /* The caller is planning to sleep. */ adns__must_gettimeofday(ads,&now,&tv_nowbuf); if (!now) { inter_immed(tv_mod,tv_tobuf); goto xit; } adns__timeouts(ads, 0, tv_mod,tv_tobuf, *now); } npollfds= adns__pollfds(ads,pollfds); maxfd= *maxfd_io; for (i=0; i= maxfd) maxfd= fd+1; if (pollfds[i].events & POLLIN) FD_SET(fd,readfds_io); if (pollfds[i].events & POLLOUT) FD_SET(fd,writefds_io); if (pollfds[i].events & POLLPRI) FD_SET(fd,exceptfds_io); } *maxfd_io= maxfd; xit: adns__consistency(ads,0,cc_entex); } void adns_afterselect(adns_state ads, int maxfd, const fd_set *readfds, const fd_set *writefds, const fd_set *exceptfds, const struct timeval *now) { struct timeval tv_buf; struct pollfd pollfds[MAX_POLLFDS]; int npollfds, i; adns__consistency(ads,0,cc_entex); adns__must_gettimeofday(ads,&now,&tv_buf); if (!now) goto xit; adns_processtimeouts(ads,now); npollfds= adns__pollfds(ads,pollfds); for (i=0; iudpw.head) adns__query_fail(ads->udpw.head, adns_s_systemfail); while (ads->tcpw.head) adns__query_fail(ads->tcpw.head, adns_s_systemfail); switch (ads->tcpstate) { case server_connecting: case server_ok: adns__tcp_broken(ads,0,0); break; case server_disconnected: case server_broken: break; default: abort(); } adns__consistency(ads,0,cc_entex); } int adns_processany(adns_state ads) { int r, i; struct timeval now; struct pollfd pollfds[MAX_POLLFDS]; int npollfds; adns__consistency(ads,0,cc_entex); r= gettimeofday(&now,0); if (!r) adns_processtimeouts(ads,&now); /* We just use adns__fdevents to loop over the fd's trying them. * This seems more sensible than calling select, since we're most * likely just to want to do a read on one or two fds anyway. */ npollfds= adns__pollfds(ads,pollfds); for (i=0; iiflags & adns_if_noautosys) return; adns_processany(ads); } int adns__internal_check(adns_state ads, adns_query *query_io, adns_answer **answer, void **context_r) { adns_query qu; qu= *query_io; if (!qu) { if (ads->output.head) { qu= ads->output.head; } else if (ads->udpw.head || ads->tcpw.head) { return EAGAIN; } else { return ESRCH; } } else { if (qu->id>=0) return EAGAIN; } ADNS_LIST_UNLINK(ads->output,qu); *answer= qu->answer; if (context_r) *context_r= qu->ctx.ext; *query_io= qu; free(qu); return 0; } int adns_wait(adns_state ads, adns_query *query_io, adns_answer **answer_r, void **context_r) { int r, maxfd, rsel; fd_set readfds, writefds, exceptfds; struct timeval tvbuf, *tvp; adns__consistency(ads,*query_io,cc_entex); for (;;) { r= adns__internal_check(ads,query_io,answer_r,context_r); if (r != EAGAIN) break; maxfd= 0; tvp= 0; FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); adns_beforeselect(ads,&maxfd,&readfds,&writefds,&exceptfds,&tvp,&tvbuf,0); assert(tvp); rsel= select(maxfd,&readfds,&writefds,&exceptfds,tvp); if (rsel==-1) { if (errno == EINTR) { if (ads->iflags & adns_if_eintr) { r= EINTR; break; } } else { adns__diag(ads,-1,0,"select failed in wait: %s",strerror(errno)); adns_globalsystemfailure(ads); } } else { assert(rsel >= 0); adns_afterselect(ads,maxfd,&readfds,&writefds,&exceptfds,0); } } adns__consistency(ads,0,cc_entex); return r; } int adns_check(adns_state ads, adns_query *query_io, adns_answer **answer_r, void **context_r) { struct timeval now; int r; adns__consistency(ads,*query_io,cc_entex); r= gettimeofday(&now,0); if (!r) adns__autosys(ads,now); r= adns__internal_check(ads,query_io,answer_r,context_r); adns__consistency(ads,0,cc_entex); return r; } lyskom-server-2.1.2/src/libraries/adns/src/general.c0000664000015100472110000002357507705611250016074 /* * general.c * - diagnostic functions * - vbuf handling */ /* * This file is * Copyright (C) 1997-2000 Ian Jackson * * It is part of adns, which is * Copyright (C) 1997-2000 Ian Jackson * Copyright (C) 1999-2000 Tony Finch * * 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 2, 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, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include "internal.h" /* Core diagnostic functions */ void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent, int serv, adns_query qu, const char *fmt, va_list al) { const char *bef, *aft; vbuf vb; if (!ads->diagfile || (!(ads->iflags & adns_if_debug) && (!prevent || (ads->iflags & prevent)))) return; if (ads->iflags & adns_if_logpid) { fprintf(ads->diagfile,"adns%s [%ld]: ",pfx,(long)getpid()); } else { fprintf(ads->diagfile,"adns%s: ",pfx); } vfprintf(ads->diagfile,fmt,al); bef= " ("; aft= "\n"; if (qu && qu->query_dgram) { adns__vbuf_init(&vb); fprintf(ads->diagfile,"%sQNAME=%s, QTYPE=%s", bef, adns__diag_domain(qu->ads,-1,0, &vb, qu->query_dgram,qu->query_dglen,DNS_HDRSIZE), qu->typei ? qu->typei->rrtname : ""); if (qu->typei && qu->typei->fmtname) fprintf(ads->diagfile,"(%s)",qu->typei->fmtname); bef=", "; aft=")\n"; adns__vbuf_free(&vb); } if (serv>=0) { fprintf(ads->diagfile,"%sNS=%s",bef,inet_ntoa(ads->servers[serv].addr)); bef=", "; aft=")\n"; } fputs(aft,ads->diagfile); } void adns__debug(adns_state ads, int serv, adns_query qu, const char *fmt, ...) { va_list al; va_start(al,fmt); adns__vdiag(ads," debug",0,serv,qu,fmt,al); va_end(al); } void adns__warn(adns_state ads, int serv, adns_query qu, const char *fmt, ...) { va_list al; va_start(al,fmt); adns__vdiag(ads," warning",adns_if_noerrprint|adns_if_noserverwarn,serv,qu,fmt,al); va_end(al); } void adns__diag(adns_state ads, int serv, adns_query qu, const char *fmt, ...) { va_list al; va_start(al,fmt); adns__vdiag(ads,"",adns_if_noerrprint,serv,qu,fmt,al); va_end(al); } /* vbuf functions */ void adns__vbuf_init(vbuf *vb) { vb->used= vb->avail= 0; vb->buf= 0; } int adns__vbuf_ensure(vbuf *vb, int want) { void *nb; if (vb->avail >= want) return 1; nb= realloc(vb->buf,want); if (!nb) return 0; vb->buf= nb; vb->avail= want; return 1; } void adns__vbuf_appendq(vbuf *vb, const byte *data, int len) { memcpy(vb->buf+vb->used,data,len); vb->used+= len; } int adns__vbuf_append(vbuf *vb, const byte *data, int len) { int newlen; void *nb; newlen= vb->used+len; if (vb->avail < newlen) { if (newlen<20) newlen= 20; newlen <<= 1; nb= realloc(vb->buf,newlen); if (!nb) { newlen= vb->used+len; nb= realloc(vb->buf,newlen); } if (!nb) return 0; vb->buf= nb; vb->avail= newlen; } adns__vbuf_appendq(vb,data,len); return 1; } int adns__vbuf_appendstr(vbuf *vb, const char *data) { int l; l= strlen(data); return adns__vbuf_append(vb,data,l); } void adns__vbuf_free(vbuf *vb) { free(vb->buf); adns__vbuf_init(vb); } /* Additional diagnostic functions */ const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, vbuf *vb, const byte *dgram, int dglen, int cbyte) { adns_status st; st= adns__parse_domain(ads,serv,qu,vb, pdf_quoteok, dgram,dglen,&cbyte,dglen); if (st == adns_s_nomemory) { return ""; } if (st) { vb->used= 0; if (!(adns__vbuf_appendstr(vb,"") && adns__vbuf_append(vb,"",1))) { return ""; } } if (!vb->used) { adns__vbuf_appendstr(vb,""); adns__vbuf_append(vb,"",1); } return vb->buf; } adns_status adns_rr_info(adns_rrtype type, const char **rrtname_r, const char **fmtname_r, int *len_r, const void *datap, char **data_r) { const typeinfo *typei; vbuf vb; adns_status st; typei= adns__findtype(type); if (!typei) return adns_s_unknownrrtype; if (rrtname_r) *rrtname_r= typei->rrtname; if (fmtname_r) *fmtname_r= typei->fmtname; if (len_r) *len_r= typei->rrsz; if (!datap) return adns_s_ok; adns__vbuf_init(&vb); st= typei->convstring(&vb,datap); if (st) goto x_freevb; if (!adns__vbuf_append(&vb,"",1)) { st= adns_s_nomemory; goto x_freevb; } assert(strlen(vb.buf) == vb.used-1); *data_r= realloc(vb.buf,vb.used); if (!*data_r) *data_r= vb.buf; return adns_s_ok; x_freevb: adns__vbuf_free(&vb); return st; } #define SINFO(n,s) { adns_s_##n, #n, s } static const struct sinfo { adns_status st; const char *abbrev; const char *string; } sinfos[]= { SINFO( ok, "OK" ), SINFO( nomemory, "Out of memory" ), SINFO( unknownrrtype, "Query not implemented in DNS library" ), SINFO( systemfail, "General resolver or system failure" ), SINFO( timeout, "DNS query timed out" ), SINFO( allservfail, "All nameservers failed" ), SINFO( norecurse, "Recursion denied by nameserver" ), SINFO( invalidresponse, "Nameserver sent bad response" ), SINFO( unknownformat, "Nameserver used unknown format" ), SINFO( rcodeservfail, "Nameserver reports failure" ), SINFO( rcodeformaterror, "Query not understood by nameserver" ), SINFO( rcodenotimplemented, "Query not implemented by nameserver" ), SINFO( rcoderefused, "Query refused by nameserver" ), SINFO( rcodeunknown, "Nameserver sent unknown response code" ), SINFO( inconsistent, "Inconsistent resource records in DNS" ), SINFO( prohibitedcname, "DNS alias found where canonical name wanted" ), SINFO( answerdomaininvalid, "Found syntactically invalid domain name" ), SINFO( answerdomaintoolong, "Found overly-long domain name" ), SINFO( invaliddata, "Found invalid DNS data" ), SINFO( querydomainwrong, "Domain invalid for particular DNS query type" ), SINFO( querydomaininvalid, "Domain name is syntactically invalid" ), SINFO( querydomaintoolong, "Domain name or component is too long" ), SINFO( nxdomain, "No such domain" ), SINFO( nodata, "No such data" ) }; static int si_compar(const void *key, const void *elem) { const adns_status *st= key; const struct sinfo *si= elem; return *st < si->st ? -1 : *st > si->st ? 1 : 0; } static const struct sinfo *findsinfo(adns_status st) { return bsearch(&st,sinfos,sizeof(sinfos)/sizeof(*sinfos),sizeof(*sinfos),si_compar); } const char *adns_strerror(adns_status st) { const struct sinfo *si; si= findsinfo(st); return si->string; } const char *adns_errabbrev(adns_status st) { const struct sinfo *si; si= findsinfo(st); return si->abbrev; } #define STINFO(max) { adns_s_max_##max, #max } static const struct stinfo { adns_status stmax; const char *abbrev; } stinfos[]= { { adns_s_ok, "ok" }, STINFO( localfail ), STINFO( remotefail ), STINFO( tempfail ), STINFO( misconfig ), STINFO( misquery ), STINFO( permfail ) }; static int sti_compar(const void *key, const void *elem) { const adns_status *st= key; const struct stinfo *sti= elem; adns_status here, min, max; here= *st; min= (sti==stinfos) ? 0 : sti[-1].stmax+1; max= sti->stmax; return here < min ? -1 : here > max ? 1 : 0; } const char *adns_errtypeabbrev(adns_status st) { const struct stinfo *sti; sti= bsearch(&st,stinfos,sizeof(stinfos)/sizeof(*stinfos),sizeof(*stinfos),sti_compar); return sti->abbrev; } void adns__isort(void *array, int nobjs, int sz, void *tempbuf, int (*needswap)(void *context, const void *a, const void *b), void *context) { byte *data= array; int i, place; for (i=0; i0 && needswap(context, data + (place-1)*sz, data + i*sz); place--); if (place != i) { memcpy(tempbuf, data + i*sz, sz); memmove(data + (place+1)*sz, data + place*sz, (i-place)*sz); memcpy(data + place*sz, tempbuf, sz); } } } /* SIGPIPE protection. */ void adns__sigpipe_protect(adns_state ads) { sigset_t toblock; struct sigaction sa; int r; if (ads->iflags & adns_if_nosigpipe) return; sigfillset(&toblock); sigdelset(&toblock,SIGPIPE); sa.sa_handler= SIG_IGN; sigfillset(&sa.sa_mask); sa.sa_flags= 0; r= sigprocmask(SIG_SETMASK,&toblock,&ads->stdsigmask); assert(!r); r= sigaction(SIGPIPE,&sa,&ads->stdsigpipe); assert(!r); } void adns__sigpipe_unprotect(adns_state ads) { int r; if (ads->iflags & adns_if_nosigpipe) return; r= sigaction(SIGPIPE,&ads->stdsigpipe,0); assert(!r); r= sigprocmask(SIG_SETMASK,&ads->stdsigmask,0); assert(!r); } lyskom-server-2.1.2/src/libraries/adns/src/internal.h0000664000015100472110000006265707705611250016304 /* * internal.h * - declarations of private objects with external linkage (adns__*) * - definitons of internal macros * - comments regarding library data structures */ /* * This file is * Copyright (C) 1997-2000 Ian Jackson * * It is part of adns, which is * Copyright (C) 1997-2000 Ian Jackson * Copyright (C) 1999-2000 Tony Finch * * 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 2, 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, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef ADNS_INTERNAL_H_INCLUDED #define ADNS_INTERNAL_H_INCLUDED #include "config.h" typedef unsigned char byte; #include #include #include #include #include #include #include #include "adns.h" #include "dlist.h" #ifdef ADNS_REGRESS_TEST # include "hredirect.h" #endif /* Configuration and constants */ #define MAXSERVERS 5 #define MAXSORTLIST 15 #define UDPMAXRETRIES 15 #define UDPRETRYMS 2000 #define TCPWAITMS 30000 #define TCPCONNMS 14000 #define TCPIDLEMS 30000 #define MAXTTLBELIEVE (7*86400) /* any TTL > 7 days is capped */ #define DNS_PORT 53 #define DNS_MAXUDP 512 #define DNS_MAXLABEL 63 #define DNS_MAXDOMAIN 255 #define DNS_HDRSIZE 12 #define DNS_IDOFFSET 0 #define DNS_CLASS_IN 1 #define DNS_INADDR_ARPA "in-addr", "arpa" #define MAX_POLLFDS ADNS_POLLFDS_RECOMMENDED typedef enum { cc_user, cc_entex, cc_freq } consistency_checks; typedef enum { rcode_noerror, rcode_formaterror, rcode_servfail, rcode_nxdomain, rcode_notimp, rcode_refused } dns_rcode; /* Shared data structures */ typedef union { adns_status status; char *cp; adns_rrtype type; int i; struct in_addr ia; unsigned long ul; } rr_align; typedef struct { int used, avail; byte *buf; } vbuf; typedef struct { adns_state ads; adns_query qu; int serv; const byte *dgram; int dglen, nsstart, nscount, arcount; struct timeval now; } parseinfo; typedef struct { adns_rrtype type; const char *rrtname; const char *fmtname; int rrsz; void (*makefinal)(adns_query qu, void *data); /* Change memory management of *data. * Previously, used alloc_interim, now use alloc_final. */ adns_status (*convstring)(vbuf *vb, const void *data); /* Converts the RR data to a string representation in vbuf. * vbuf will be appended to (it must have been initialised), * and will not be null-terminated by convstring. */ adns_status (*parse)(const parseinfo *pai, int cbyte, int max, void *store_r); /* Parse one RR, in dgram of length dglen, starting at cbyte and * extending until at most max. * * The RR should be stored at *store_r, of length qu->typei->rrsz. * * If there is an overrun which might indicate truncation, it should set * *rdstart to -1; otherwise it may set it to anything else positive. * * nsstart is the offset of the authority section. */ int (*diff_needswap)(adns_state ads, const void *datap_a, const void *datap_b); /* Returns !0 if RR a should be strictly after RR b in the sort order, * 0 otherwise. Must not fail. */ } typeinfo; typedef struct allocnode { struct allocnode *next, *back; } allocnode; union maxalign { byte d[1]; struct in_addr ia; long l; void *p; void (*fp)(void); union maxalign *up; } data; typedef struct { void *ext; void (*callback)(adns_query parent, adns_query child); union { adns_rr_addr ptr_parent_addr; adns_rr_hostaddr *hostaddr; } info; } qcontext; struct adns__query { adns_state ads; enum { query_tosend, query_tcpw, query_childw, query_done } state; adns_query back, next, parent; struct { adns_query head, tail; } children; struct { adns_query back, next; } siblings; struct { allocnode *head, *tail; } allocations; int interim_allocd, preserved_allocd; void *final_allocspace; const typeinfo *typei; byte *query_dgram; int query_dglen; vbuf vb; /* General-purpose messing-about buffer. * Wherever a `big' interface is crossed, this may be corrupted/changed * unless otherwise specified. */ adns_answer *answer; /* This is allocated when a query is submitted, to avoid being unable * to relate errors to queries if we run out of memory. During * query processing status, rrs is 0. cname is set if * we found a cname (this corresponds to cname_dgram in the query * structure). type is set from the word go. nrrs and rrs * are set together, when we find how many rrs there are. * owner is set during querying unless we're doing searchlist, * in which case it is set only when we find an answer. */ byte *cname_dgram; int cname_dglen, cname_begin; /* If non-0, has been allocated using . */ vbuf search_vb; int search_origlen, search_pos, search_doneabs; /* Used by the searching algorithm. The query domain in textual form * is copied into the vbuf, and _origlen set to its length. Then * we walk the searchlist, if we want to. _pos says where we are * (next entry to try), and _doneabs says whether we've done the * absolute query yet (0=not yet, 1=done, -1=must do straight away, * but not done yet). If flags doesn't have adns_qf_search then * the vbuf is initialised but empty and everything else is zero. */ int id, flags, retries; int udpnextserver; unsigned long udpsent; /* bitmap indexed by server */ struct timeval timeout; time_t expires; /* Earliest expiry time of any record we used. */ qcontext ctx; /* Possible states: * * state Queue child id nextudpserver udpsent tcpfailed * * tosend NONE null >=0 0 zero zero * tosend udpw null >=0 any nonzero zero * tosend NONE null >=0 any nonzero zero * * tcpw tcpw null >=0 irrelevant any any * * child childw set >=0 irrelevant irrelevant irrelevant * child NONE null >=0 irrelevant irrelevant irrelevant * done output null -1 irrelevant irrelevant irrelevant * * Queries are only not on a queue when they are actually being processed. * Queries in state tcpw/tcpw have been sent (or are in the to-send buffer) * iff the tcp connection is in state server_ok. * * +------------------------+ * START -----> | tosend/NONE | * +------------------------+ * / |\ \ * too big for UDP / UDP timeout \ \ send via UDP * send via TCP / more retries \ \ * when conn'd / desired \ \ * | | | * v | v * +-----------+ +-------------+ * | tcpw/tcpw | ________ | tosend/udpw | * +-----------+ \ +-------------+ * | | | UDP timeout | | * | | | no more | | * | | | retries | | * \ | TCP died | desired | | * \ \ no more | | | * \ \ servers | TCP / | * \ \ to try | timeout / | * got \ \ v |_ | got * reply \ _| +------------------+ / reply * \ | done/output FAIL | / * \ +------------------+ / * \ / * _| |_ * (..... got reply ....) * / \ * need child query/ies / \ no child query * / \ * |_ _| * +---------------+ +----------------+ * | childw/childw | ----------------> | done/output OK | * +---------------+ children done +----------------+ */ }; struct query_queue { adns_query head, tail; }; struct adns__state { adns_initflags iflags; FILE *diagfile; int configerrno; struct query_queue udpw, tcpw, childw, output; adns_query forallnext; int nextid, udpsocket, tcpsocket; vbuf tcpsend, tcprecv; int nservers, nsortlist, nsearchlist, searchndots, tcpserver, tcprecv_skip; enum adns__tcpstate { server_disconnected, server_connecting, server_ok, server_broken } tcpstate; struct timeval tcptimeout; /* This will have tv_sec==0 if it is not valid. It will always be * valid if tcpstate _connecting. When _ok, it will be nonzero if * we are idle (ie, tcpw queue is empty), in which case it is the * absolute time when we will close the connection. */ struct sigaction stdsigpipe; sigset_t stdsigmask; struct pollfd pollfds_buf[MAX_POLLFDS]; struct server { struct in_addr addr; } servers[MAXSERVERS]; struct sortlist { struct in_addr base, mask; } sortlist[MAXSORTLIST]; char **searchlist; }; /* From setup.c: */ int adns__setnonblock(adns_state ads, int fd); /* => errno value */ /* From general.c: */ void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent, int serv, adns_query qu, const char *fmt, va_list al); void adns__debug(adns_state ads, int serv, adns_query qu, const char *fmt, ...) PRINTFFORMAT(4,5); void adns__warn(adns_state ads, int serv, adns_query qu, const char *fmt, ...) PRINTFFORMAT(4,5); void adns__diag(adns_state ads, int serv, adns_query qu, const char *fmt, ...) PRINTFFORMAT(4,5); int adns__vbuf_ensure(vbuf *vb, int want); int adns__vbuf_appendstr(vbuf *vb, const char *data); /* does not include nul */ int adns__vbuf_append(vbuf *vb, const byte *data, int len); /* 1=>success, 0=>realloc failed */ void adns__vbuf_appendq(vbuf *vb, const byte *data, int len); void adns__vbuf_init(vbuf *vb); void adns__vbuf_free(vbuf *vb); const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, vbuf *vb, const byte *dgram, int dglen, int cbyte); /* Unpicks a domain in a datagram and returns a string suitable for * printing it as. Never fails - if an error occurs, it will * return some kind of string describing the error. * * serv may be -1 and qu may be 0. vb must have been initialised, * and will be left in an arbitrary consistent state. * * Returns either vb->buf, or a pointer to a string literal. Do not modify * vb before using the return value. */ void adns__isort(void *array, int nobjs, int sz, void *tempbuf, int (*needswap)(void *context, const void *a, const void *b), void *context); /* Does an insertion sort of array which must contain nobjs objects * each sz bytes long. tempbuf must point to a buffer at least * sz bytes long. needswap should return !0 if a>b (strictly, ie * wrong order) 0 if a<=b (ie, order is fine). */ void adns__sigpipe_protect(adns_state); void adns__sigpipe_unprotect(adns_state); /* If SIGPIPE protection is not disabled, will block all signals except * SIGPIPE, and set SIGPIPE's disposition to SIG_IGN. (And then restore.) * Each call to _protect must be followed by a call to _unprotect before * any significant amount of code gets to run, since the old signal mask * is stored in the adns structure. */ /* From transmit.c: */ adns_status adns__mkquery(adns_state ads, vbuf *vb, int *id_r, const char *owner, int ol, const typeinfo *typei, adns_queryflags flags); /* Assembles a query packet in vb. A new id is allocated and returned. */ adns_status adns__mkquery_frdgram(adns_state ads, vbuf *vb, int *id_r, const byte *qd_dgram, int qd_dglen, int qd_begin, adns_rrtype type, adns_queryflags flags); /* Same as adns__mkquery, but takes the owner domain from an existing datagram. * That domain must be correct and untruncated. */ void adns__querysend_tcp(adns_query qu, struct timeval now); /* Query must be in state tcpw/tcpw; it will be sent if possible and * no further processing can be done on it for now. The connection * might be broken, but no reconnect will be attempted. */ void adns__query_send(adns_query qu, struct timeval now); /* Query must be in state tosend/NONE; it will be moved to a new state, * and no further processing can be done on it for now. * (Resulting state is one of udp/timew, tcpwait/timew (if server not connected), * tcpsent/timew, child/childw or done/output.) * __query_send may decide to use either UDP or TCP depending whether * _qf_usevc is set (or has become set) and whether the query is too * large. */ /* From query.c: */ adns_status adns__internal_submit(adns_state ads, adns_query *query_r, const typeinfo *typei, vbuf *qumsg_vb, int id, adns_queryflags flags, struct timeval now, const qcontext *ctx); /* Submits a query (for internal use, called during external submits). * * The new query is returned in *query_r, or we return adns_s_nomemory. * * The query datagram should already have been assembled in qumsg_vb; * the memory for it is _taken over_ by this routine whether it * succeeds or fails (if it succeeds, the vbuf is reused for qu->vb). * * *ctx is copied byte-for-byte into the query. * * When the child query is done, ctx->callback will be called. The * child will already have been taken off both the global list of * queries in ads and the list of children in the parent. The child * will be freed when the callback returns. The parent will have been * taken off the global childw queue. * * The callback should either call adns__query_done, if it is * complete, or adns__query_fail, if an error has occurred, in which * case the other children (if any) will be cancelled. If the parent * has more unfinished children (or has just submitted more) then the * callback may choose to wait for them - it must then put the parent * back on the childw queue. */ void adns__search_next(adns_state ads, adns_query qu, struct timeval now); /* Walks down the searchlist for a query with adns_qf_search. * The query should have just had a negative response, or not had * any queries sent yet, and should not be on any queue. * The query_dgram if any will be freed and forgotten and a new * one constructed from the search_* members of the query. * * Cannot fail (in case of error, calls adns__query_fail). */ void *adns__alloc_interim(adns_query qu, size_t sz); void *adns__alloc_preserved(adns_query qu, size_t sz); /* Allocates some memory, and records which query it came from * and how much there was. * * If an error occurs in the query, all the memory from _interim is * simply freed. If the query succeeds, one large buffer will be made * which is big enough for all these allocations, and then * adns__alloc_final will get memory from this buffer. * * _alloc_interim can fail (and return 0). * The caller must ensure that the query is failed. * * The memory from _preserved is is kept and transferred into the * larger buffer - unless we run out of memory, in which case it too * is freed. When you use _preserved you have to add code to the * x_nomem error exit case in adns__makefinal_query to clear out the * pointers you made to those allocations, because that's when they're * thrown away; you should also make a note in the declaration of * those pointer variables, to note that they are _preserved rather * than _interim. If they're in the answer, note it here: * answer->cname and answer->owner are _preserved. */ void adns__transfer_interim(adns_query from, adns_query to, void *block, size_t sz); /* Transfers an interim allocation from one query to another, so that * the `to' query will have room for the data when we get to makefinal * and so that the free will happen when the `to' query is freed * rather than the `from' query. * * It is legal to call adns__transfer_interim with a null pointer; this * has no effect. * * _transfer_interim also ensures that the expiry time of the `to' query * is no later than that of the `from' query, so that child queries' * TTLs get inherited by their parents. */ void *adns__alloc_mine(adns_query qu, size_t sz); /* Like _interim, but does not record the length for later * copying into the answer. This just ensures that the memory * will be freed when we're done with the query. */ void *adns__alloc_final(adns_query qu, size_t sz); /* Cannot fail, and cannot return 0. */ void adns__makefinal_block(adns_query qu, void **blpp, size_t sz); void adns__makefinal_str(adns_query qu, char **strp); void adns__reset_preserved(adns_query qu); /* Resets all of the memory management stuff etc. to take account of * only the _preserved stuff from _alloc_preserved. Used when we find * an error somewhere and want to just report the error (with perhaps * CNAME, owner, etc. info), and also when we're halfway through RRs * in a datagram and discover that we need to retry the query. */ void adns__query_done(adns_query qu); void adns__query_fail(adns_query qu, adns_status stat); /* From reply.c: */ void adns__procdgram(adns_state ads, const byte *dgram, int len, int serv, int viatcp, struct timeval now); /* This function is allowed to cause new datagrams to be constructed * and sent, or even new queries to be started. However, * query-sending functions are not allowed to call any general event * loop functions in case they accidentally call this. * * Ie, receiving functions may call sending functions. * Sending functions may NOT call receiving functions. */ /* From types.c: */ const typeinfo *adns__findtype(adns_rrtype type); /* From parse.c: */ typedef struct { adns_state ads; adns_query qu; int serv; const byte *dgram; int dglen, max, cbyte, namelen; int *dmend_r; } findlabel_state; void adns__findlabel_start(findlabel_state *fls, adns_state ads, int serv, adns_query qu, const byte *dgram, int dglen, int max, int dmbegin, int *dmend_rlater); /* Finds labels in a domain in a datagram. * * Call this routine first. * dmend_rlater may be null. ads (and of course fls) may not be. * serv may be -1, qu may be null - they are for error reporting. */ adns_status adns__findlabel_next(findlabel_state *fls, int *lablen_r, int *labstart_r); /* Then, call this one repeatedly. * * It will return adns_s_ok if all is well, and tell you the length * and start of successive labels. labstart_r may be null, but * lablen_r must not be. * * After the last label, it will return with *lablen_r zero. * Do not then call it again; instead, just throw away the findlabel_state. * * *dmend_rlater will have been set to point to the next part of * the datagram after the label (or after the uncompressed part, * if compression was used). *namelen_rlater will have been set * to the length of the domain name (total length of labels plus * 1 for each intervening dot). * * If the datagram appears to be truncated, *lablen_r will be -1. * *dmend_rlater, *labstart_r and *namelen_r may contain garbage. * Do not call _next again. * * There may also be errors, in which case *dmend_rlater, * *namelen_rlater, *lablen_r and *labstart_r may contain garbage. * Do not then call findlabel_next again. */ typedef enum { pdf_quoteok= 0x001 } parsedomain_flags; adns_status adns__parse_domain(adns_state ads, int serv, adns_query qu, vbuf *vb, parsedomain_flags flags, const byte *dgram, int dglen, int *cbyte_io, int max); /* vb must already have been initialised; it will be reset if necessary. * If there is truncation, vb->used will be set to 0; otherwise * (if there is no error) vb will be null-terminated. * If there is an error vb and *cbyte_io may be left indeterminate. * * serv may be -1 and qu may be 0 - they are used for error reporting only. */ adns_status adns__parse_domain_more(findlabel_state *fls, adns_state ads, adns_query qu, vbuf *vb, parsedomain_flags flags, const byte *dgram); /* Like adns__parse_domain, but you pass it a pre-initialised findlabel_state, * for continuing an existing domain or some such of some kind. Also, unlike * _parse_domain, the domain data will be appended to vb, rather than replacing * the existing contents. */ adns_status adns__findrr(adns_query qu, int serv, const byte *dgram, int dglen, int *cbyte_io, int *type_r, int *class_r, unsigned long *ttl_r, int *rdlen_r, int *rdstart_r, int *ownermatchedquery_r); /* Finds the extent and some of the contents of an RR in a datagram * and does some checks. The datagram is *dgram, length dglen, and * the RR starts at *cbyte_io (which is updated afterwards to point * to the end of the RR). * * The type, class, TTL and RRdata length and start are returned iff * the corresponding pointer variables are not null. type_r, class_r * and ttl_r may not be null. The TTL will be capped. * * If ownermatchedquery_r != 0 then the owner domain of this * RR will be compared with that in the query (or, if the query * has gone to a CNAME lookup, with the canonical name). * In this case, *ownermatchedquery_r will be set to 0 or 1. * The query datagram (or CNAME datagram) MUST be valid and not truncated. * * If there is truncation then *type_r will be set to -1 and * *cbyte_io, *class_r, *rdlen_r, *rdstart_r and *eo_matched_r will be * undefined. * * qu must obviously be non-null. * * If an error is returned then *type_r will be undefined too. */ adns_status adns__findrr_anychk(adns_query qu, int serv, const byte *dgram, int dglen, int *cbyte_io, int *type_r, int *class_r, unsigned long *ttl_r, int *rdlen_r, int *rdstart_r, const byte *eo_dgram, int eo_dglen, int eo_cbyte, int *eo_matched_r); /* Like adns__findrr_checked, except that the datagram and * owner to compare with can be specified explicitly. * * If the caller thinks they know what the owner of the RR ought to * be they can pass in details in eo_*: this is another (or perhaps * the same datagram), and a pointer to where the putative owner * starts in that datagram. In this case *eo_matched_r will be set * to 1 if the datagram matched or 0 if it did not. Either * both eo_dgram and eo_matched_r must both be non-null, or they * must both be null (in which case eo_dglen and eo_cbyte will be ignored). * The eo datagram and contained owner domain MUST be valid and * untruncated. */ void adns__update_expires(adns_query qu, unsigned long ttl, struct timeval now); /* Updates the `expires' field in the query, so that it doesn't exceed * now + ttl. */ int vbuf__append_quoted1035(vbuf *vb, const byte *buf, int len); /* From event.c: */ void adns__tcp_broken(adns_state ads, const char *what, const char *why); /* what and why may be both 0, or both non-0. */ void adns__tcp_tryconnect(adns_state ads, struct timeval now); void adns__autosys(adns_state ads, struct timeval now); /* Make all the system calls we want to if the application wants us to. * Must not be called from within adns internal processing functions, * lest we end up in recursive descent ! */ void adns__must_gettimeofday(adns_state ads, const struct timeval **now_io, struct timeval *tv_buf); int adns__pollfds(adns_state ads, struct pollfd pollfds_buf[MAX_POLLFDS]); void adns__fdevents(adns_state ads, const struct pollfd *pollfds, int npollfds, int maxfd, const fd_set *readfds, const fd_set *writefds, const fd_set *exceptfds, struct timeval now, int *r_r); int adns__internal_check(adns_state ads, adns_query *query_io, adns_answer **answer, void **context_r); void adns__timeouts(adns_state ads, int act, struct timeval **tv_io, struct timeval *tvbuf, struct timeval now); /* If act is !0, then this will also deal with the TCP connection * if previous events broke it or require it to be connected. */ /* From check.c: */ void adns__consistency(adns_state ads, adns_query qu, consistency_checks cc); /* Useful static inline functions: */ static inline int ctype_whitespace(int c) { return c==' ' || c=='\n' || c=='\t'; } static inline int ctype_digit(int c) { return c>='0' && c<='9'; } static inline int ctype_alpha(int c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } static inline int ctype_822special(int c) { return strchr("()<>@,;:\\\".[]",c) != 0; } static inline int ctype_domainunquoted(int c) { return ctype_alpha(c) || ctype_digit(c) || (strchr("-_/+",c) != 0); } static inline int errno_resources(int e) { return e==ENOMEM || e==ENOBUFS; } /* Useful macros */ #define MEM_ROUND(sz) \ (( ((sz)+sizeof(union maxalign)-1) / sizeof(union maxalign) ) \ * sizeof(union maxalign) ) #define GETIL_B(cb) (((dgram)[(cb)++]) & 0x0ff) #define GET_B(cb,tv) ((tv)= GETIL_B((cb))) #define GET_W(cb,tv) ((tv)=0, (tv)|=(GETIL_B((cb))<<8), (tv)|=GETIL_B(cb), (tv)) #define GET_L(cb,tv) ( (tv)=0, \ (tv)|=(GETIL_B((cb))<<24), \ (tv)|=(GETIL_B((cb))<<16), \ (tv)|=(GETIL_B((cb))<<8), \ (tv)|=GETIL_B(cb), \ (tv) ) #endif lyskom-server-2.1.2/src/libraries/adns/src/parse.c0000664000015100472110000001625507705631170015571 /* * parse.c * - parsing assistance functions (mainly for domains inside datagrams) */ /* * This file is * Copyright (C) 1997-2000 Ian Jackson * * It is part of adns, which is * Copyright (C) 1997-2000 Ian Jackson * Copyright (C) 1999-2000 Tony Finch * * 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 2, 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, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "internal.h" int vbuf__append_quoted1035(vbuf *vb, const byte *buf, int len) { char qbuf[10]; int i, ch; while (len) { qbuf[0]= 0; for (i=0; i= 127) { sprintf(qbuf,"\\%03o",ch); break; } else if (!ctype_domainunquoted(ch)) { sprintf(qbuf,"\\%c",ch); break; } } if (!adns__vbuf_append(vb,buf,i) || !adns__vbuf_append(vb,qbuf,strlen(qbuf))) return 0; if (iads= ads; fls->qu= qu; fls->serv= serv; fls->dgram= dgram; fls->dglen= dglen; fls->max= max; fls->cbyte= dmbegin; fls->namelen= 0; fls->dmend_r= dmend_rlater; } adns_status adns__findlabel_next(findlabel_state *fls, int *lablen_r, int *labstart_r) { int lablen, jumpto; const char *dgram; dgram= fls->dgram; for (;;) { if (fls->cbyte >= fls->dglen) goto x_truncated; if (fls->cbyte >= fls->max) goto x_badresponse; GET_B(fls->cbyte,lablen); if (!(lablen & 0x0c0)) break; if ((lablen & 0x0c0) != 0x0c0) return adns_s_unknownformat; if (fls->cbyte >= fls->dglen) goto x_truncated; if (fls->cbyte >= fls->max) goto x_badresponse; GET_B(fls->cbyte,jumpto); jumpto |= (lablen&0x3f)<<8; if (fls->dmend_r) *(fls->dmend_r)= fls->cbyte; fls->cbyte= jumpto; fls->dmend_r= 0; fls->max= fls->dglen+1; } if (labstart_r) *labstart_r= fls->cbyte; if (lablen) { if (fls->namelen) fls->namelen++; fls->namelen+= lablen; if (fls->namelen > DNS_MAXDOMAIN) return adns_s_answerdomaintoolong; fls->cbyte+= lablen; if (fls->cbyte > fls->dglen) goto x_truncated; if (fls->cbyte > fls->max) goto x_badresponse; } else { if (fls->dmend_r) *(fls->dmend_r)= fls->cbyte; } *lablen_r= lablen; return adns_s_ok; x_truncated: *lablen_r= -1; return adns_s_ok; x_badresponse: adns__diag(fls->ads,fls->serv,fls->qu,"label in domain runs beyond end of domain"); return adns_s_invalidresponse; } adns_status adns__parse_domain(adns_state ads, int serv, adns_query qu, vbuf *vb, parsedomain_flags flags, const byte *dgram, int dglen, int *cbyte_io, int max) { findlabel_state fls; adns__findlabel_start(&fls,ads, serv,qu, dgram,dglen,max, *cbyte_io,cbyte_io); vb->used= 0; return adns__parse_domain_more(&fls,ads,qu, vb,flags,dgram); } adns_status adns__parse_domain_more(findlabel_state *fls, adns_state ads, adns_query qu, vbuf *vb, parsedomain_flags flags, const byte *dgram) { int lablen, labstart, i, ch, first; adns_status st; first= 1; for (;;) { st= adns__findlabel_next(fls,&lablen,&labstart); if (st) return st; if (lablen<0) { vb->used=0; return adns_s_ok; } if (!lablen) break; if (first) { first= 0; } else { if (!adns__vbuf_append(vb,".",1)) return adns_s_nomemory; } if (flags & pdf_quoteok) { if (!vbuf__append_quoted1035(vb,dgram+labstart,lablen)) return adns_s_nomemory; } else { ch= dgram[labstart]; if (!ctype_alpha(ch) && !ctype_digit(ch)) return adns_s_answerdomaininvalid; for (i= labstart+1; iads, serv,qu, dgram,dglen,dglen,cbyte,&cbyte); if (eo_dgram) { adns__findlabel_start(&eo_fls,qu->ads, -1,0, eo_dgram,eo_dglen,eo_dglen,eo_cbyte,0); mismatch= 0; } else { mismatch= 1; } for (;;) { st= adns__findlabel_next(&fls,&lablen,&labstart); if (st) return st; if (lablen<0) goto x_truncated; if (!mismatch) { st= adns__findlabel_next(&eo_fls,&eo_lablen,&eo_labstart); assert(!st); assert(eo_lablen>=0); if (lablen != eo_lablen) mismatch= 1; while (!mismatch && eo_lablen-- > 0) { ch= dgram[labstart++]; if (ctype_alpha(ch)) ch &= ~32; eo_ch= eo_dgram[eo_labstart++]; if (ctype_alpha(eo_ch)) eo_ch &= ~32; if (ch != eo_ch) mismatch= 1; } } if (!lablen) break; } if (eo_matched_r) *eo_matched_r= !mismatch; if (cbyte+10>dglen) goto x_truncated; GET_W(cbyte,tmp); *type_r= tmp; GET_W(cbyte,tmp); *class_r= tmp; GET_L(cbyte,ttl); if (ttl > MAXTTLBELIEVE) ttl= MAXTTLBELIEVE; *ttl_r= ttl; GET_W(cbyte,rdlen); if (rdlen_r) *rdlen_r= rdlen; if (rdstart_r) *rdstart_r= cbyte; cbyte+= rdlen; if (cbyte>dglen) goto x_truncated; *cbyte_io= cbyte; return adns_s_ok; x_truncated: *type_r= -1; return 0; } adns_status adns__findrr(adns_query qu, int serv, const byte *dgram, int dglen, int *cbyte_io, int *type_r, int *class_r, unsigned long *ttl_r, int *rdlen_r, int *rdstart_r, int *ownermatchedquery_r) { if (!ownermatchedquery_r) { return adns__findrr_anychk(qu,serv, dgram,dglen,cbyte_io, type_r,class_r,ttl_r,rdlen_r,rdstart_r, 0,0,0, 0); } else if (!qu->cname_dgram) { return adns__findrr_anychk(qu,serv, dgram,dglen,cbyte_io, type_r,class_r,ttl_r,rdlen_r,rdstart_r, qu->query_dgram,qu->query_dglen,DNS_HDRSIZE, ownermatchedquery_r); } else { return adns__findrr_anychk(qu,serv, dgram,dglen,cbyte_io, type_r,class_r,ttl_r,rdlen_r,rdstart_r, qu->cname_dgram,qu->cname_dglen,qu->cname_begin, ownermatchedquery_r); } } lyskom-server-2.1.2/src/libraries/adns/src/poll.c0000664000015100472110000000672607705611251015425 /* * poll.c * - wrappers for poll(2) */ /* * This file is * Copyright (C) 1997-1999 Ian Jackson * * It is part of adns, which is * Copyright (C) 1997-2000 Ian Jackson * Copyright (C) 1999-2000 Tony Finch * * 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 2, 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, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include "internal.h" #ifdef HAVE_POLL int adns_beforepoll(adns_state ads, struct pollfd *fds, int *nfds_io, int *timeout_io, const struct timeval *now) { struct timeval tv_nowbuf, tv_tobuf, *tv_to; int space, found, timeout_ms, r; struct pollfd fds_tmp[MAX_POLLFDS]; adns__consistency(ads,0,cc_entex); if (timeout_io) { adns__must_gettimeofday(ads,&now,&tv_nowbuf); if (!now) { *nfds_io= 0; r= 0; goto xit; } timeout_ms= *timeout_io; if (timeout_ms == -1) { tv_to= 0; } else { tv_tobuf.tv_sec= timeout_ms / 1000; tv_tobuf.tv_usec= (timeout_ms % 1000)*1000; tv_to= &tv_tobuf; } adns__timeouts(ads, 0, &tv_to,&tv_tobuf, *now); if (tv_to) { assert(tv_to == &tv_tobuf); timeout_ms= (tv_tobuf.tv_usec+999)/1000; assert(tv_tobuf.tv_sec < (INT_MAX-timeout_ms)/1000); timeout_ms += tv_tobuf.tv_sec*1000; } else { timeout_ms= -1; } *timeout_io= timeout_ms; } space= *nfds_io; if (space >= MAX_POLLFDS) { found= adns__pollfds(ads,fds); *nfds_io= found; } else { found= adns__pollfds(ads,fds_tmp); *nfds_io= found; if (space < found) { r= ERANGE; goto xit; } memcpy(fds,fds_tmp,sizeof(struct pollfd)*found); } r= 0; xit: adns__consistency(ads,0,cc_entex); return r; } void adns_afterpoll(adns_state ads, const struct pollfd *fds, int nfds, const struct timeval *now) { struct timeval tv_buf; adns__consistency(ads,0,cc_entex); adns__must_gettimeofday(ads,&now,&tv_buf); if (now) { adns__timeouts(ads, 1, 0,0, *now); adns__fdevents(ads, fds,nfds, 0,0,0,0, *now,0); } adns__consistency(ads,0,cc_entex); } int adns_wait_poll(adns_state ads, adns_query *query_io, adns_answer **answer_r, void **context_r) { int r, nfds, to; struct pollfd fds[MAX_POLLFDS]; adns__consistency(ads,0,cc_entex); for (;;) { r= adns__internal_check(ads,query_io,answer_r,context_r); if (r != EAGAIN) goto xit; nfds= MAX_POLLFDS; to= -1; adns_beforepoll(ads,fds,&nfds,&to,0); r= poll(fds,nfds,to); if (r == -1) { if (errno == EINTR) { if (ads->iflags & adns_if_eintr) { r= EINTR; goto xit; } } else { adns__diag(ads,-1,0,"poll failed in wait: %s",strerror(errno)); adns_globalsystemfailure(ads); } } else { assert(r >= 0); adns_afterpoll(ads,fds,nfds,0); } } xit: adns__consistency(ads,0,cc_entex); return r; } #endif lyskom-server-2.1.2/src/libraries/adns/src/query.c0000664000015100472110000003406107707157070015623 /* * query.c * - overall query management (allocation, completion) * - per-query memory management * - query submission and cancellation (user-visible and internal) */ /* * This file is * Copyright (C) 1997-2000 Ian Jackson * * It is part of adns, which is * Copyright (C) 1997-2000 Ian Jackson * Copyright (C) 1999-2000 Tony Finch * * 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 2, 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, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "internal.h" #include #include #include #include #include "internal.h" static adns_query query_alloc(adns_state ads, const typeinfo *typei, adns_queryflags flags, struct timeval now) { /* Allocate a virgin query and return it. */ adns_query qu; qu= malloc(sizeof(*qu)); if (!qu) return 0; qu->answer= malloc(sizeof(*qu->answer)); if (!qu->answer) { free(qu); return 0; } qu->ads= ads; qu->state= query_tosend; qu->back= qu->next= qu->parent= 0; ADNS_LIST_INIT(qu->children); ADNS_LINK_INIT(qu->siblings); ADNS_LIST_INIT(qu->allocations); qu->interim_allocd= 0; qu->preserved_allocd= 0; qu->final_allocspace= 0; qu->typei= typei; qu->query_dgram= 0; qu->query_dglen= 0; adns__vbuf_init(&qu->vb); qu->cname_dgram= 0; qu->cname_dglen= qu->cname_begin= 0; adns__vbuf_init(&qu->search_vb); qu->search_origlen= qu->search_pos= qu->search_doneabs= 0; qu->id= -2; /* will be overwritten with real id before we leave adns */ qu->flags= flags; qu->retries= 0; qu->udpnextserver= 0; qu->udpsent= 0; timerclear(&qu->timeout); qu->expires= now.tv_sec + MAXTTLBELIEVE; memset(&qu->ctx,0,sizeof(qu->ctx)); qu->answer->status= adns_s_ok; qu->answer->cname= qu->answer->owner= 0; qu->answer->type= typei->type; qu->answer->expires= -1; qu->answer->nrrs= 0; qu->answer->rrs.untyped= 0; qu->answer->rrsz= typei->rrsz; return qu; } static void query_submit(adns_state ads, adns_query qu, const typeinfo *typei, vbuf *qumsg_vb, int id, adns_queryflags flags, struct timeval now) { /* Fills in the query message in for a previously-allocated query, * and submits it. Cannot fail. Takes over the memory for qumsg_vb. */ qu->vb= *qumsg_vb; adns__vbuf_init(qumsg_vb); qu->query_dgram= malloc(qu->vb.used); if (!qu->query_dgram) { adns__query_fail(qu,adns_s_nomemory); return; } qu->id= id; qu->query_dglen= qu->vb.used; memcpy(qu->query_dgram,qu->vb.buf,qu->vb.used); adns__query_send(qu,now); } adns_status adns__internal_submit(adns_state ads, adns_query *query_r, const typeinfo *typei, vbuf *qumsg_vb, int id, adns_queryflags flags, struct timeval now, const qcontext *ctx) { adns_query qu; qu= query_alloc(ads,typei,flags,now); if (!qu) { adns__vbuf_free(qumsg_vb); return adns_s_nomemory; } *query_r= qu; memcpy(&qu->ctx,ctx,sizeof(qu->ctx)); query_submit(ads,qu, typei,qumsg_vb,id,flags,now); return adns_s_ok; } static void query_simple(adns_state ads, adns_query qu, const char *owner, int ol, const typeinfo *typei, adns_queryflags flags, struct timeval now) { vbuf vb_new; int id; adns_status stat; stat= adns__mkquery(ads,&qu->vb,&id, owner,ol, typei,flags); if (stat) { if (stat == adns_s_querydomaintoolong && (flags & adns_qf_search)) { adns__search_next(ads,qu,now); return; } else { adns__query_fail(qu,stat); return; } } vb_new= qu->vb; adns__vbuf_init(&qu->vb); query_submit(ads,qu, typei,&vb_new,id, flags,now); } void adns__search_next(adns_state ads, adns_query qu, struct timeval now) { const char *nextentry; adns_status stat; if (qu->search_doneabs<0) { nextentry= 0; qu->search_doneabs= 1; } else { if (qu->search_pos >= ads->nsearchlist) { if (qu->search_doneabs) { stat= adns_s_nxdomain; goto x_fail; return; } else { nextentry= 0; qu->search_doneabs= 1; } } else { nextentry= ads->searchlist[qu->search_pos++]; } } qu->search_vb.used= qu->search_origlen; if (nextentry) { if (!adns__vbuf_append(&qu->search_vb,".",1) || !adns__vbuf_appendstr(&qu->search_vb,nextentry)) { stat= adns_s_nomemory; goto x_fail; } } free(qu->query_dgram); qu->query_dgram= 0; qu->query_dglen= 0; query_simple(ads,qu, qu->search_vb.buf, qu->search_vb.used, qu->typei, qu->flags, now); return; x_fail: adns__query_fail(qu,stat); } static int save_owner(adns_query qu, const char *owner, int ol) { /* Returns 1 if OK, otherwise there was no memory. */ adns_answer *ans; ans= qu->answer; assert(!ans->owner); ans->owner= adns__alloc_preserved(qu,ol+1); if (!ans->owner) return 0; memcpy(ans->owner,owner,ol); ans->owner[ol]= 0; return 1; } int adns_submit(adns_state ads, const char *owner, adns_rrtype type, adns_queryflags flags, void *context, adns_query *query_r) { int r, ol, ndots; adns_status stat; const typeinfo *typei; struct timeval now; adns_query qu; const char *p; adns__consistency(ads,0,cc_entex); typei= adns__findtype(type); if (!typei) return ENOSYS; r= gettimeofday(&now,0); if (r) goto x_errno; qu= query_alloc(ads,typei,flags,now); if (!qu) goto x_errno; qu->ctx.ext= context; qu->ctx.callback= 0; memset(&qu->ctx.info,0,sizeof(qu->ctx.info)); *query_r= qu; ol= strlen(owner); if (!ol) { stat= adns_s_querydomaininvalid; goto x_adnsfail; } if (ol>DNS_MAXDOMAIN+1) { stat= adns_s_querydomaintoolong; goto x_adnsfail; } if (ol>=1 && owner[ol-1]=='.' && (ol<2 || owner[ol-2]!='\\')) { flags &= ~adns_qf_search; qu->flags= flags; ol--; } if (flags & adns_qf_search) { r= adns__vbuf_append(&qu->search_vb,owner,ol); if (!r) { stat= adns_s_nomemory; goto x_adnsfail; } for (ndots=0, p=owner; (p= strchr(p,'.')); p++, ndots++); qu->search_doneabs= (ndots >= ads->searchndots) ? -1 : 0; qu->search_origlen= ol; adns__search_next(ads,qu,now); } else { if (flags & adns_qf_owner) { if (!save_owner(qu,owner,ol)) { stat= adns_s_nomemory; goto x_adnsfail; } } query_simple(ads,qu, owner,ol, typei,flags, now); } adns__autosys(ads,now); adns__consistency(ads,qu,cc_entex); return 0; x_adnsfail: adns__query_fail(qu,stat); adns__consistency(ads,qu,cc_entex); return 0; x_errno: r= errno; assert(r); adns__consistency(ads,0,cc_entex); return r; } int adns_submit_reverse_any(adns_state ads, const struct sockaddr *addr, const char *zone, adns_rrtype type, adns_queryflags flags, void *context, adns_query *query_r) { const unsigned char *iaddr; char *buf, *buf_free; char shortbuf[100]; int r, lreq; flags &= ~adns_qf_search; if (addr->sa_family != AF_INET) return ENOSYS; iaddr= (const unsigned char*) &(((const struct sockaddr_in*)addr) -> sin_addr); lreq= strlen(zone) + 4*4 + 1; if (lreq > sizeof(shortbuf)) { buf= malloc(strlen(zone) + 4*4 + 1); if (!buf) return errno; buf_free= buf; } else { buf= shortbuf; buf_free= 0; } sprintf(buf, "%d.%d.%d.%d.%s", iaddr[3], iaddr[2], iaddr[1], iaddr[0], zone); r= adns_submit(ads,buf,type,flags,context,query_r); free(buf_free); return r; } int adns_submit_reverse(adns_state ads, const struct sockaddr *addr, adns_rrtype type, adns_queryflags flags, void *context, adns_query *query_r) { if (type != adns_r_ptr && type != adns_r_ptr_raw) return EINVAL; return adns_submit_reverse_any(ads,addr,"in-addr.arpa",type,flags,context,query_r); } int adns_synchronous(adns_state ads, const char *owner, adns_rrtype type, adns_queryflags flags, adns_answer **answer_r) { adns_query qu; int r; r= adns_submit(ads,owner,type,flags,0,&qu); if (r) return r; r= adns_wait(ads,&qu,answer_r,0); if (r) adns_cancel(qu); return r; } static void *alloc_common(adns_query qu, size_t sz) { allocnode *an; if (!sz) return qu; /* Any old pointer will do */ assert(!qu->final_allocspace); an= malloc(MEM_ROUND(MEM_ROUND(sizeof(*an)) + sz)); if (!an) return 0; ADNS_LIST_LINK_TAIL(qu->allocations,an); return (byte*)an + MEM_ROUND(sizeof(*an)); } void *adns__alloc_interim(adns_query qu, size_t sz) { void *rv; sz= MEM_ROUND(sz); rv= alloc_common(qu,sz); if (!rv) return 0; qu->interim_allocd += sz; return rv; } void *adns__alloc_preserved(adns_query qu, size_t sz) { void *rv; sz= MEM_ROUND(sz); rv= adns__alloc_interim(qu,sz); if (!rv) return 0; qu->preserved_allocd += sz; return rv; } void *adns__alloc_mine(adns_query qu, size_t sz) { return alloc_common(qu,MEM_ROUND(sz)); } void adns__transfer_interim(adns_query from, adns_query to, void *block, size_t sz) { allocnode *an; if (!block) return; an= (void*)((byte*)block - MEM_ROUND(sizeof(*an))); assert(!to->final_allocspace); assert(!from->final_allocspace); ADNS_LIST_UNLINK(from->allocations,an); ADNS_LIST_LINK_TAIL(to->allocations,an); sz= MEM_ROUND(sz); from->interim_allocd -= sz; to->interim_allocd += sz; if (to->expires > from->expires) to->expires= from->expires; } void *adns__alloc_final(adns_query qu, size_t sz) { /* When we're in the _final stage, we _subtract_ from interim_alloc'd * each allocation, and use final_allocspace to point to the next free * bit. */ void *rp; sz= MEM_ROUND(sz); rp= qu->final_allocspace; assert(rp); qu->interim_allocd -= sz; assert(qu->interim_allocd>=0); qu->final_allocspace= (byte*)rp + sz; return rp; } static void cancel_children(adns_query qu) { adns_query cqu, ncqu; for (cqu= qu->children.head; cqu; cqu= ncqu) { ncqu= cqu->siblings.next; adns_cancel(cqu); } } void adns__reset_preserved(adns_query qu) { assert(!qu->final_allocspace); cancel_children(qu); qu->answer->nrrs= 0; qu->answer->rrs.untyped= 0; qu->interim_allocd= qu->preserved_allocd; } static void free_query_allocs(adns_query qu) { allocnode *an, *ann; cancel_children(qu); for (an= qu->allocations.head; an; an= ann) { ann= an->next; free(an); } ADNS_LIST_INIT(qu->allocations); adns__vbuf_free(&qu->vb); adns__vbuf_free(&qu->search_vb); free(qu->query_dgram); qu->query_dgram= 0; } void adns_cancel(adns_query qu) { adns_state ads; ads= qu->ads; adns__consistency(ads,qu,cc_entex); if (qu->parent) ADNS_LIST_UNLINK_PART(qu->parent->children,qu,siblings.); switch (qu->state) { case query_tosend: ADNS_LIST_UNLINK(ads->udpw,qu); break; case query_tcpw: ADNS_LIST_UNLINK(ads->tcpw,qu); break; case query_childw: ADNS_LIST_UNLINK(ads->childw,qu); break; case query_done: ADNS_LIST_UNLINK(ads->output,qu); break; default: abort(); } free_query_allocs(qu); free(qu->answer); free(qu); adns__consistency(ads,0,cc_entex); } void adns__update_expires(adns_query qu, unsigned long ttl, struct timeval now) { time_t max; assert(ttl <= MAXTTLBELIEVE); max= now.tv_sec + ttl; if (qu->expires < max) return; qu->expires= max; } static void makefinal_query(adns_query qu) { adns_answer *ans; int rrn; ans= qu->answer; if (qu->interim_allocd) { ans= realloc(qu->answer, MEM_ROUND(MEM_ROUND(sizeof(*ans)) + qu->interim_allocd)); if (!ans) goto x_nomem; qu->answer= ans; } qu->final_allocspace= (byte*)ans + MEM_ROUND(sizeof(*ans)); adns__makefinal_str(qu,&ans->cname); adns__makefinal_str(qu,&ans->owner); if (ans->nrrs) { adns__makefinal_block(qu, &ans->rrs.untyped, ans->nrrs*ans->rrsz); for (rrn=0; rrnnrrs; rrn++) qu->typei->makefinal(qu, ans->rrs.bytes + rrn*ans->rrsz); } free_query_allocs(qu); return; x_nomem: qu->preserved_allocd= 0; qu->answer->cname= 0; qu->answer->owner= 0; adns__reset_preserved(qu); /* (but we just threw away the preserved stuff) */ qu->answer->status= adns_s_nomemory; free_query_allocs(qu); } void adns__query_done(adns_query qu) { adns_answer *ans; adns_query parent; cancel_children(qu); qu->id= -1; ans= qu->answer; if (qu->flags & adns_qf_owner && qu->flags & adns_qf_search && ans->status != adns_s_nomemory) { if (!save_owner(qu, qu->search_vb.buf, qu->search_vb.used)) { adns__query_fail(qu,adns_s_nomemory); return; } } if (ans->nrrs && qu->typei->diff_needswap) { if (!adns__vbuf_ensure(&qu->vb,qu->typei->rrsz)) { adns__query_fail(qu,adns_s_nomemory); return; } adns__isort(ans->rrs.bytes, ans->nrrs, ans->rrsz, qu->vb.buf, (int(*)(void*, const void*, const void*))qu->typei->diff_needswap, qu->ads); } ans->expires= qu->expires; parent= qu->parent; if (parent) { ADNS_LIST_UNLINK_PART(parent->children,qu,siblings.); ADNS_LIST_UNLINK(qu->ads->childw,parent); qu->ctx.callback(parent,qu); free_query_allocs(qu); free(qu->answer); free(qu); } else { makefinal_query(qu); ADNS_LIST_LINK_TAIL(qu->ads->output,qu); qu->state= query_done; } } void adns__query_fail(adns_query qu, adns_status stat) { adns__reset_preserved(qu); qu->answer->status= stat; adns__query_done(qu); } void adns__makefinal_str(adns_query qu, char **strp) { int l; char *before, *after; before= *strp; if (!before) return; l= strlen(before)+1; after= adns__alloc_final(qu,l); memcpy(after,before,l); *strp= after; } void adns__makefinal_block(adns_query qu, void **blpp, size_t sz) { void *before, *after; before= *blpp; if (!before) return; after= adns__alloc_final(qu,sz); memcpy(after,before,sz); *blpp= after; } lyskom-server-2.1.2/src/libraries/adns/src/reply.c0000664000015100472110000002710107707157070015606 /* * reply.c * - main handling and parsing routine for received datagrams */ /* * This file is * Copyright (C) 1997-2000 Ian Jackson * * It is part of adns, which is * Copyright (C) 1997-2000 Ian Jackson * Copyright (C) 1999-2000 Tony Finch * * 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 2, 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, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "internal.h" void adns__procdgram(adns_state ads, const byte *dgram, int dglen, int serv, int viatcp, struct timeval now) { int cbyte, rrstart, wantedrrs, rri, foundsoa, foundns, cname_here; int id, f1, f2, qdcount, ancount, nscount, arcount; int flg_ra, flg_rd, flg_tc, flg_qr, opcode; int rrtype, rrclass, rdlength, rdstart; int anstart, nsstart, arstart; int ownermatched, l, nrrs; unsigned long ttl, soattl; const typeinfo *typei; adns_query qu, nqu; dns_rcode rcode; adns_status st; vbuf tempvb; byte *newquery, *rrsdata; parseinfo pai; if (dglen>3; flg_tc= f1&0x02; flg_rd= f1&0x01; flg_ra= f2&0x80; rcode= (f2&0x0f); cname_here= 0; if (!flg_qr) { adns__diag(ads,serv,0,"server sent us a query, not a response"); return; } if (opcode) { adns__diag(ads,serv,0,"server sent us unknown opcode %d (wanted 0=QUERY)",opcode); return; } qu= 0; /* See if we can find the relevant query, or leave qu=0 otherwise ... */ if (qdcount == 1) { for (qu= viatcp ? ads->tcpw.head : ads->udpw.head; qu; qu= nqu) { nqu= qu->next; if (qu->id != id) continue; if (dglen < qu->query_dglen) continue; if (memcmp(qu->query_dgram+DNS_HDRSIZE, dgram+DNS_HDRSIZE, qu->query_dglen-DNS_HDRSIZE)) continue; if (viatcp) { assert(qu->state == query_tcpw); } else { assert(qu->state == query_tosend); if (!(qu->udpsent & (1<tcpw,qu); else ADNS_LIST_UNLINK(ads->udpw,qu); } } /* If we're going to ignore the packet, we return as soon as we have * failed the query (if any) and printed the warning message (if * any). */ switch (rcode) { case rcode_noerror: case rcode_nxdomain: break; case rcode_formaterror: adns__warn(ads,serv,qu,"server cannot understand our query (Format Error)"); if (qu) adns__query_fail(qu,adns_s_rcodeformaterror); return; case rcode_servfail: if (qu) adns__query_fail(qu,adns_s_rcodeservfail); else adns__debug(ads,serv,qu,"server failure on unidentifiable query"); return; case rcode_notimp: adns__warn(ads,serv,qu,"server claims not to implement our query"); if (qu) adns__query_fail(qu,adns_s_rcodenotimplemented); return; case rcode_refused: adns__debug(ads,serv,qu,"server refused our query"); if (qu) adns__query_fail(qu,adns_s_rcoderefused); return; default: adns__warn(ads,serv,qu,"server gave unknown response code %d",rcode); if (qu) adns__query_fail(qu,adns_s_rcodeunknown); return; } if (!qu) { if (!qdcount) { adns__diag(ads,serv,0,"server sent reply without quoting our question"); } else if (qdcount>1) { adns__diag(ads,serv,0,"server claimed to answer %d questions with one message", qdcount); } else if (ads->iflags & adns_if_debug) { adns__vbuf_init(&tempvb); adns__debug(ads,serv,0,"reply not found, id %02x, query owner %s", id, adns__diag_domain(ads,serv,0,&tempvb,dgram,dglen,DNS_HDRSIZE)); adns__vbuf_free(&tempvb); } return; } /* We're definitely going to do something with this packet and this query now. */ anstart= qu->query_dglen; arstart= -1; /* Now, take a look at the answer section, and see if it is complete. * If it has any CNAMEs we stuff them in the answer. */ wantedrrs= 0; cbyte= anstart; for (rri= 0; rriiflags & adns_if_debug) { adns__debug(ads,serv,qu,"ignoring RR with an unexpected owner %s", adns__diag_domain(ads,serv,qu, &qu->vb, dgram,dglen,rrstart)); } continue; } if (rrtype == adns_r_cname && (qu->typei->type & adns__rrt_typemask) != adns_r_cname) { if (qu->flags & adns_qf_cname_forbid) { adns__query_fail(qu,adns_s_prohibitedcname); return; } else if (qu->cname_dgram) { /* Ignore second and subsequent CNAME(s) */ adns__debug(ads,serv,qu,"allegedly canonical name %s is actually alias for %s", qu->answer->cname, adns__diag_domain(ads,serv,qu, &qu->vb, dgram,dglen,rdstart)); adns__query_fail(qu,adns_s_prohibitedcname); return; } else if (wantedrrs) { /* Ignore CNAME(s) after RR(s). */ adns__debug(ads,serv,qu,"ignoring CNAME (to %s) coexisting with RR", adns__diag_domain(ads,serv,qu, &qu->vb, dgram,dglen,rdstart)); } else { qu->cname_begin= rdstart; qu->cname_dglen= dglen; st= adns__parse_domain(ads,serv,qu, &qu->vb, qu->flags & adns_qf_quotefail_cname ? 0 : pdf_quoteok, dgram,dglen, &rdstart,rdstart+rdlength); if (!qu->vb.used) goto x_truncated; if (st) { adns__query_fail(qu,st); return; } l= strlen(qu->vb.buf)+1; qu->answer->cname= adns__alloc_preserved(qu,l); if (!qu->answer->cname) { adns__query_fail(qu,adns_s_nomemory); return; } qu->cname_dgram= adns__alloc_mine(qu,dglen); memcpy(qu->cname_dgram,dgram,dglen); memcpy(qu->answer->cname,qu->vb.buf,l); cname_here= 1; adns__update_expires(qu,ttl,now); /* If we find the answer section truncated after this point we restart * the query at the CNAME; if beforehand then we obviously have to use * TCP. If there is no truncation we can use the whole answer if * it contains the relevant info. */ } } else if (rrtype == (qu->typei->type & adns__rrt_typemask)) { wantedrrs++; } else { adns__debug(ads,serv,qu,"ignoring answer RR with irrelevant type %d",rrtype); } } /* We defer handling truncated responses here, in case there was a CNAME * which we could use. */ if (flg_tc) goto x_truncated; nsstart= cbyte; if (!wantedrrs) { /* Oops, NODATA or NXDOMAIN or perhaps a referral (which would be a problem) */ /* RFC2308: NODATA has _either_ a SOA _or_ _no_ NS records in authority section */ foundsoa= 0; soattl= 0; foundns= 0; for (rri= 0; rriflags & adns_qf_search) { adns__search_next(ads,qu,now); } else { adns__query_fail(qu,adns_s_nxdomain); } return; } if (foundsoa || !foundns) { /* Aha ! A NODATA response, good. */ adns__update_expires(qu,soattl,now); adns__query_fail(qu,adns_s_nodata); return; } /* Now what ? No relevant answers, no SOA, and at least some NS's. * Looks like a referral. Just one last chance ... if we came across * a CNAME in this datagram then we should probably do our own CNAME * lookup now in the hope that we won't get a referral again. */ if (cname_here) goto x_restartquery; /* Bloody hell, I thought we asked for recursion ? */ if (!flg_ra) { adns__diag(ads,serv,qu,"server is not willing to do recursive lookups for us"); adns__query_fail(qu,adns_s_norecurse); } else { if (!flg_rd) adns__diag(ads,serv,qu,"server thinks we didn't ask for recursive lookup"); else adns__debug(ads,serv,qu,"server claims to do recursion, but gave us a referral"); adns__query_fail(qu,adns_s_invalidresponse); } return; } /* Now, we have some RRs which we wanted. */ qu->answer->rrs.untyped= adns__alloc_interim(qu,qu->typei->rrsz*wantedrrs); if (!qu->answer->rrs.untyped) { adns__query_fail(qu,adns_s_nomemory); return; } typei= qu->typei; cbyte= anstart; rrsdata= qu->answer->rrs.bytes; pai.ads= qu->ads; pai.qu= qu; pai.serv= serv; pai.dgram= dgram; pai.dglen= dglen; pai.nsstart= nsstart; pai.nscount= nscount; pai.arcount= arcount; pai.now= now; for (rri=0, nrrs=0; rritypei->type & adns__rrt_typemask) || !ownermatched) continue; adns__update_expires(qu,ttl,now); st= typei->parse(&pai, rdstart,rdstart+rdlength, rrsdata+nrrs*typei->rrsz); if (st) { adns__query_fail(qu,st); return; } if (rdstart==-1) goto x_truncated; nrrs++; } assert(nrrs==wantedrrs); qu->answer->nrrs= nrrs; /* This may have generated some child queries ... */ if (qu->children.head) { qu->state= query_childw; ADNS_LIST_LINK_TAIL(ads->childw,qu); return; } adns__query_done(qu); return; x_truncated: if (!flg_tc) { adns__diag(ads,serv,qu,"server sent datagram which points outside itself"); adns__query_fail(qu,adns_s_invalidresponse); return; } qu->flags |= adns_qf_usevc; x_restartquery: if (qu->cname_dgram) { st= adns__mkquery_frdgram(qu->ads,&qu->vb,&qu->id, qu->cname_dgram, qu->cname_dglen, qu->cname_begin, qu->typei->type, qu->flags); if (st) { adns__query_fail(qu,st); return; } newquery= realloc(qu->query_dgram,qu->vb.used); if (!newquery) { adns__query_fail(qu,adns_s_nomemory); return; } qu->query_dgram= newquery; qu->query_dglen= qu->vb.used; memcpy(newquery,qu->vb.buf,qu->vb.used); } if (qu->state == query_tcpw) qu->state= query_tosend; qu->retries= 0; adns__reset_preserved(qu); adns__query_send(qu,now); } lyskom-server-2.1.2/src/libraries/adns/src/setup.c0000664000015100472110000004110407707157070015612 /* * setup.c * - configuration file parsing * - management of global state */ /* * This file is * Copyright (C) 1997-1999 Ian Jackson * * It is part of adns, which is * Copyright (C) 1997-2000 Ian Jackson * Copyright (C) 1999-2000 Tony Finch * * 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 2, 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, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include "internal.h" static void readconfig(adns_state ads, const char *filename, int warnmissing); static void addserver(adns_state ads, struct in_addr addr) { int i; struct server *ss; for (i=0; inservers; i++) { if (ads->servers[i].addr.s_addr == addr.s_addr) { adns__debug(ads,-1,0,"duplicate nameserver %s ignored",inet_ntoa(addr)); return; } } if (ads->nservers>=MAXSERVERS) { adns__diag(ads,-1,0,"too many nameservers, ignoring %s",inet_ntoa(addr)); return; } ss= ads->servers+ads->nservers; ss->addr= addr; ads->nservers++; } static void freesearchlist(adns_state ads) { if (ads->nsearchlist) free(*ads->searchlist); free(ads->searchlist); } static void saveerr(adns_state ads, int en) { if (!ads->configerrno) ads->configerrno= en; } static void configparseerr(adns_state ads, const char *fn, int lno, const char *fmt, ...) { va_list al; saveerr(ads,EINVAL); if (!ads->diagfile || (ads->iflags & adns_if_noerrprint)) return; if (lno==-1) fprintf(ads->diagfile,"adns: %s: ",fn); else fprintf(ads->diagfile,"adns: %s:%d: ",fn,lno); va_start(al,fmt); vfprintf(ads->diagfile,fmt,al); va_end(al); fputc('\n',ads->diagfile); } static int nextword(const char **bufp_io, const char **word_r, int *l_r) { const char *p, *q; p= *bufp_io; while (ctype_whitespace(*p)) p++; if (!*p) return 0; q= p; while (*q && !ctype_whitespace(*q)) q++; *l_r= q-p; *word_r= p; *bufp_io= q; return 1; } static void ccf_nameserver(adns_state ads, const char *fn, int lno, const char *buf) { struct in_addr ia; if (!inet_aton(buf,&ia)) { configparseerr(ads,fn,lno,"invalid nameserver address `%s'",buf); return; } adns__debug(ads,-1,0,"using nameserver %s",inet_ntoa(ia)); addserver(ads,ia); } static void ccf_search(adns_state ads, const char *fn, int lno, const char *buf) { const char *bufp, *word; char *newchars, **newptrs, **pp; int count, tl, l; if (!buf) return; bufp= buf; count= 0; tl= 0; while (nextword(&bufp,&word,&l)) { count++; tl += l+1; } newptrs= malloc(sizeof(char*)*count); if (!newptrs) { saveerr(ads,errno); return; } newchars= malloc(tl); if (!newchars) { saveerr(ads,errno); free(newptrs); return; } bufp= buf; pp= newptrs; while (nextword(&bufp,&word,&l)) { *pp++= newchars; memcpy(newchars,word,l); newchars += l; *newchars++ = 0; } freesearchlist(ads); ads->nsearchlist= count; ads->searchlist= newptrs; } static void ccf_sortlist(adns_state ads, const char *fn, int lno, const char *buf) { const char *word; char tbuf[200], *slash, *ep; struct in_addr base, mask; int l; unsigned long initial, baselocal; if (!buf) return; ads->nsortlist= 0; while (nextword(&buf,&word,&l)) { if (ads->nsortlist >= MAXSORTLIST) { adns__diag(ads,-1,0,"too many sortlist entries, ignoring %.*s onwards",l,word); return; } if (l >= sizeof(tbuf)) { configparseerr(ads,fn,lno,"sortlist entry `%.*s' too long",l,word); continue; } memcpy(tbuf,word,l); tbuf[l]= 0; slash= strchr(tbuf,'/'); if (slash) *slash++= 0; if (!inet_aton(tbuf,&base)) { configparseerr(ads,fn,lno,"invalid address `%s' in sortlist",tbuf); continue; } if (slash) { if (strchr(slash,'.')) { if (!inet_aton(slash,&mask)) { configparseerr(ads,fn,lno,"invalid mask `%s' in sortlist",slash); continue; } if (base.s_addr & ~mask.s_addr) { configparseerr(ads,fn,lno, "mask `%s' in sortlist overlaps address `%s'",slash,tbuf); continue; } } else { initial= strtoul(slash,&ep,10); if (*ep || initial>32) { configparseerr(ads,fn,lno,"mask length `%s' invalid",slash); continue; } mask.s_addr= htonl((0x0ffffffffUL) << (32-initial)); } } else { baselocal= ntohl(base.s_addr); if (!baselocal & 0x080000000UL) /* class A */ mask.s_addr= htonl(0x0ff000000UL); else if ((baselocal & 0x0c0000000UL) == 0x080000000UL) mask.s_addr= htonl(0x0ffff0000UL); /* class B */ else if ((baselocal & 0x0f0000000UL) == 0x0e0000000UL) mask.s_addr= htonl(0x0ff000000UL); /* class C */ else { configparseerr(ads,fn,lno, "network address `%s' in sortlist is not in classed ranges," " must specify mask explicitly", tbuf); continue; } } ads->sortlist[ads->nsortlist].base= base; ads->sortlist[ads->nsortlist].mask= mask; ads->nsortlist++; } } static void ccf_options(adns_state ads, const char *fn, int lno, const char *buf) { const char *word; char *ep; unsigned long v; int l; if (!buf) return; while (nextword(&buf,&word,&l)) { if (l==5 && !memcmp(word,"debug",5)) { ads->iflags |= adns_if_debug; continue; } if (l>=6 && !memcmp(word,"ndots:",6)) { v= strtoul(word+6,&ep,10); if (l==6 || ep != word+l || v > INT_MAX) { configparseerr(ads,fn,lno,"option `%.*s' malformed or has bad value",l,word); continue; } ads->searchndots= v; continue; } if (l>=12 && !memcmp(word,"adns_checkc:",12)) { if (!strcmp(word+12,"none")) { ads->iflags &= ~adns_if_checkc_freq; ads->iflags |= adns_if_checkc_entex; } else if (!strcmp(word+12,"entex")) { ads->iflags &= ~adns_if_checkc_freq; ads->iflags |= adns_if_checkc_entex; } else if (!strcmp(word+12,"freq")) { ads->iflags |= adns_if_checkc_freq; } else { configparseerr(ads,fn,lno, "option adns_checkc has bad value `%s' " "(must be none, entex or freq", word+12); } continue; } adns__diag(ads,-1,0,"%s:%d: unknown option `%.*s'", fn,lno, l,word); } } static void ccf_clearnss(adns_state ads, const char *fn, int lno, const char *buf) { ads->nservers= 0; } static void ccf_include(adns_state ads, const char *fn, int lno, const char *buf) { if (!*buf) { configparseerr(ads,fn,lno,"`include' directive with no filename"); return; } readconfig(ads,buf,1); } static const struct configcommandinfo { const char *name; void (*fn)(adns_state ads, const char *fn, int lno, const char *buf); } configcommandinfos[]= { { "nameserver", ccf_nameserver }, { "domain", ccf_search }, { "search", ccf_search }, { "sortlist", ccf_sortlist }, { "options", ccf_options }, { "clearnameservers", ccf_clearnss }, { "include", ccf_include }, { 0 } }; typedef union { FILE *file; const char *text; } getline_ctx; static int gl_file(adns_state ads, getline_ctx *src_io, const char *filename, int lno, char *buf, int buflen) { FILE *file= src_io->file; int c, i; char *p; p= buf; buflen--; i= 0; for (;;) { /* loop over chars */ if (i == buflen) { adns__diag(ads,-1,0,"%s:%d: line too long, ignored",filename,lno); goto x_badline; } c= getc(file); if (!c) { adns__diag(ads,-1,0,"%s:%d: line contains nul, ignored",filename,lno); goto x_badline; } else if (c == '\n') { break; } else if (c == EOF) { if (ferror(file)) { saveerr(ads,errno); adns__diag(ads,-1,0,"%s:%d: read error: %s",filename,lno,strerror(errno)); return -1; } if (!i) return -1; break; } else { *p++= c; i++; } } *p++= 0; return i; x_badline: saveerr(ads,EINVAL); while ((c= getc(file)) != EOF && c != '\n'); return -2; } static int gl_text(adns_state ads, getline_ctx *src_io, const char *filename, int lno, char *buf, int buflen) { const char *cp= src_io->text; int l; if (!cp || !*cp) return -1; if (*cp == ';' || *cp == '\n') cp++; l= strcspn(cp,";\n"); src_io->text = cp+l; if (l >= buflen) { adns__diag(ads,-1,0,"%s:%d: line too long, ignored",filename,lno); saveerr(ads,EINVAL); return -2; } memcpy(buf,cp,l); buf[l]= 0; return l; } static void readconfiggeneric(adns_state ads, const char *filename, int (*getline)(adns_state ads, getline_ctx*, const char *filename, int lno, char *buf, int buflen), /* Returns >=0 for success, -1 for EOF or error * (error will have been reported), or -2 for * bad line was encountered, try again. */ getline_ctx gl_ctx) { char linebuf[2000], *p, *q; int lno, l, dirl; const struct configcommandinfo *ccip; for (lno=1; (l= getline(ads,&gl_ctx, filename,lno, linebuf,sizeof(linebuf))) != -1; lno++) { if (l == -2) continue; while (l>0 && ctype_whitespace(linebuf[l-1])) l--; linebuf[l]= 0; p= linebuf; while (ctype_whitespace(*p)) p++; if (*p == '#' || !*p) continue; q= p; while (*q && !ctype_whitespace(*q)) q++; dirl= q-p; for (ccip=configcommandinfos; ccip->name && !(strlen(ccip->name)==dirl && !memcmp(ccip->name,p,q-p)); ccip++); if (!ccip->name) { adns__diag(ads,-1,0,"%s:%d: unknown configuration directive `%.*s'", filename,lno,q-p,p); continue; } while (ctype_whitespace(*q)) q++; ccip->fn(ads,filename,lno,q); } } static const char *instrum_getenv(adns_state ads, const char *envvar) { const char *value; value= getenv(envvar); if (!value) adns__debug(ads,-1,0,"environment variable %s not set",envvar); else adns__debug(ads,-1,0,"environment variable %s set to `%s'",envvar,value); return value; } static void readconfig(adns_state ads, const char *filename, int warnmissing) { getline_ctx gl_ctx; gl_ctx.file= fopen(filename,"r"); if (!gl_ctx.file) { if (errno == ENOENT) { if (warnmissing) adns__debug(ads,-1,0,"configuration file `%s' does not exist",filename); return; } saveerr(ads,errno); adns__diag(ads,-1,0,"cannot open configuration file `%s': %s", filename,strerror(errno)); return; } readconfiggeneric(ads,filename,gl_file,gl_ctx); fclose(gl_ctx.file); } static void readconfigtext(adns_state ads, const char *text, const char *showname) { getline_ctx gl_ctx; gl_ctx.text= text; readconfiggeneric(ads,showname,gl_text,gl_ctx); } static void readconfigenv(adns_state ads, const char *envvar) { const char *filename; if (ads->iflags & adns_if_noenv) { adns__debug(ads,-1,0,"not checking environment variable `%s'",envvar); return; } filename= instrum_getenv(ads,envvar); if (filename) readconfig(ads,filename,1); } static void readconfigenvtext(adns_state ads, const char *envvar) { const char *textdata; if (ads->iflags & adns_if_noenv) { adns__debug(ads,-1,0,"not checking environment variable `%s'",envvar); return; } textdata= instrum_getenv(ads,envvar); if (textdata) readconfigtext(ads,textdata,envvar); } int adns__setnonblock(adns_state ads, int fd) { int r; r= fcntl(fd,F_GETFL,0); if (r<0) return errno; r |= O_NONBLOCK; r= fcntl(fd,F_SETFL,r); if (r<0) return errno; return 0; } static int init_begin(adns_state *ads_r, adns_initflags flags, FILE *diagfile) { adns_state ads; ads= malloc(sizeof(*ads)); if (!ads) return errno; ads->iflags= flags; ads->diagfile= diagfile; ads->configerrno= 0; ADNS_LIST_INIT(ads->udpw); ADNS_LIST_INIT(ads->tcpw); ADNS_LIST_INIT(ads->childw); ADNS_LIST_INIT(ads->output); ads->forallnext= 0; ads->nextid= 0x311f; ads->udpsocket= ads->tcpsocket= -1; adns__vbuf_init(&ads->tcpsend); adns__vbuf_init(&ads->tcprecv); ads->tcprecv_skip= 0; ads->nservers= ads->nsortlist= ads->nsearchlist= ads->tcpserver= 0; ads->searchndots= 1; ads->tcpstate= server_disconnected; timerclear(&ads->tcptimeout); ads->searchlist= 0; *ads_r= ads; return 0; } static int init_finish(adns_state ads) { struct in_addr ia; struct protoent *proto; int r; if (!ads->nservers) { if (ads->diagfile && ads->iflags & adns_if_debug) fprintf(ads->diagfile,"adns: no nameservers, using localhost\n"); ia.s_addr= htonl(INADDR_LOOPBACK); addserver(ads,ia); } proto= getprotobyname("udp"); if (!proto) { r= ENOPROTOOPT; goto x_free; } ads->udpsocket= socket(AF_INET,SOCK_DGRAM,proto->p_proto); if (ads->udpsocket<0) { r= errno; goto x_free; } r= adns__setnonblock(ads,ads->udpsocket); if (r) { r= errno; goto x_closeudp; } return 0; x_closeudp: close(ads->udpsocket); x_free: free(ads); return r; } static void init_abort(adns_state ads) { if (ads->nsearchlist) { free(ads->searchlist[0]); free(ads->searchlist); } free(ads); } int adns_init(adns_state *ads_r, adns_initflags flags, FILE *diagfile) { adns_state ads; const char *res_options, *adns_res_options; int r; r= init_begin(&ads, flags, diagfile ? diagfile : stderr); if (r) return r; res_options= instrum_getenv(ads,"RES_OPTIONS"); adns_res_options= instrum_getenv(ads,"ADNS_RES_OPTIONS"); ccf_options(ads,"RES_OPTIONS",-1,res_options); ccf_options(ads,"ADNS_RES_OPTIONS",-1,adns_res_options); readconfig(ads,"/etc/resolv.conf",1); readconfig(ads,"/etc/resolv-adns.conf",0); readconfigenv(ads,"RES_CONF"); readconfigenv(ads,"ADNS_RES_CONF"); readconfigenvtext(ads,"RES_CONF_TEXT"); readconfigenvtext(ads,"ADNS_RES_CONF_TEXT"); ccf_options(ads,"RES_OPTIONS",-1,res_options); ccf_options(ads,"ADNS_RES_OPTIONS",-1,adns_res_options); ccf_search(ads,"LOCALDOMAIN",-1,instrum_getenv(ads,"LOCALDOMAIN")); ccf_search(ads,"ADNS_LOCALDOMAIN",-1,instrum_getenv(ads,"ADNS_LOCALDOMAIN")); if (ads->configerrno && ads->configerrno != EINVAL) { r= ads->configerrno; init_abort(ads); return r; } r= init_finish(ads); if (r) return r; adns__consistency(ads,0,cc_entex); *ads_r= ads; return 0; } int adns_init_strcfg(adns_state *ads_r, adns_initflags flags, FILE *diagfile, const char *configtext) { adns_state ads; int r; r= init_begin(&ads, flags, diagfile); if (r) return r; readconfigtext(ads,configtext,""); if (ads->configerrno) { r= ads->configerrno; init_abort(ads); return r; } r= init_finish(ads); if (r) return r; adns__consistency(ads,0,cc_entex); *ads_r= ads; return 0; } void adns_finish(adns_state ads) { adns__consistency(ads,0,cc_entex); for (;;) { if (ads->udpw.head) adns_cancel(ads->udpw.head); else if (ads->tcpw.head) adns_cancel(ads->tcpw.head); else if (ads->childw.head) adns_cancel(ads->childw.head); else if (ads->output.head) adns_cancel(ads->output.head); else break; } close(ads->udpsocket); if (ads->tcpsocket >= 0) close(ads->tcpsocket); adns__vbuf_free(&ads->tcpsend); adns__vbuf_free(&ads->tcprecv); freesearchlist(ads); free(ads); } void adns_forallqueries_begin(adns_state ads) { adns__consistency(ads,0,cc_entex); ads->forallnext= ads->udpw.head ? ads->udpw.head : ads->tcpw.head ? ads->tcpw.head : ads->childw.head ? ads->childw.head : ads->output.head; } adns_query adns_forallqueries_next(adns_state ads, void **context_r) { adns_query qu, nqu; adns__consistency(ads,0,cc_entex); nqu= ads->forallnext; for (;;) { qu= nqu; if (!qu) return 0; if (qu->next) { nqu= qu->next; } else if (qu == ads->udpw.tail) { nqu= ads->tcpw.head ? ads->tcpw.head : ads->childw.head ? ads->childw.head : ads->output.head; } else if (qu == ads->tcpw.tail) { nqu= ads->childw.head ? ads->childw.head : ads->output.head; } else if (qu == ads->childw.tail) { nqu= ads->output.head; } else { nqu= 0; } if (!qu->parent) break; } ads->forallnext= nqu; if (context_r) *context_r= qu->ctx.ext; return qu; } lyskom-server-2.1.2/src/libraries/adns/src/transmit.c0000664000015100472110000001563207707157070016322 /* * transmit.c * - construct queries * - send queries */ /* * This file is * Copyright (C) 1997-2000 Ian Jackson * * It is part of adns, which is * Copyright (C) 1997-2000 Ian Jackson * Copyright (C) 1999-2000 Tony Finch * * 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 2, 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, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "internal.h" #include "tvarith.h" #define MKQUERY_START(vb) (rqp= (vb)->buf+(vb)->used) #define MKQUERY_ADDB(b) *rqp++= (b) #define MKQUERY_ADDW(w) (MKQUERY_ADDB(((w)>>8)&0x0ff), MKQUERY_ADDB((w)&0x0ff)) #define MKQUERY_STOP(vb) ((vb)->used= rqp-(vb)->buf) static adns_status mkquery_header(adns_state ads, vbuf *vb, int *id_r, int qdlen) { int id; byte *rqp; if (!adns__vbuf_ensure(vb,DNS_HDRSIZE+qdlen+4)) return adns_s_nomemory; vb->used= 0; MKQUERY_START(vb); *id_r= id= (ads->nextid++) & 0x0ffff; MKQUERY_ADDW(id); MKQUERY_ADDB(0x01); /* QR=Q(0), OPCODE=QUERY(0000), !AA, !TC, RD */ MKQUERY_ADDB(0x00); /* !RA, Z=000, RCODE=NOERROR(0000) */ MKQUERY_ADDW(1); /* QDCOUNT=1 */ MKQUERY_ADDW(0); /* ANCOUNT=0 */ MKQUERY_ADDW(0); /* NSCOUNT=0 */ MKQUERY_ADDW(0); /* ARCOUNT=0 */ MKQUERY_STOP(vb); return adns_s_ok; } static adns_status mkquery_footer(vbuf *vb, adns_rrtype type) { byte *rqp; MKQUERY_START(vb); MKQUERY_ADDW(type & adns__rrt_typemask); /* QTYPE */ MKQUERY_ADDW(DNS_CLASS_IN); /* QCLASS=IN */ MKQUERY_STOP(vb); assert(vb->used <= vb->avail); return adns_s_ok; } adns_status adns__mkquery(adns_state ads, vbuf *vb, int *id_r, const char *owner, int ol, const typeinfo *typei, adns_queryflags flags) { int ll, c, nbytes; byte label[255], *rqp; const char *p, *pe; adns_status st; st= mkquery_header(ads,vb,id_r,ol+2); if (st) return st; MKQUERY_START(vb); p= owner; pe= owner+ol; nbytes= 0; while (p!=pe) { ll= 0; while (p!=pe && (c= *p++)!='.') { if (c=='\\') { if (!(flags & adns_qf_quoteok_query)) return adns_s_querydomaininvalid; if (ctype_digit(p[0])) { if (ctype_digit(p[1]) && ctype_digit(p[2])) { c= (*p++ - '0')*100 + (*p++ - '0')*10 + (*p++ - '0'); if (c >= 256) return adns_s_querydomaininvalid; } else { return adns_s_querydomaininvalid; } } else if (!(c= *p++)) { return adns_s_querydomaininvalid; } } if (!(flags & adns_qf_quoteok_query)) { if (c == '-') { if (!ll) return adns_s_querydomaininvalid; } else if (!ctype_alpha(c) && !ctype_digit(c)) { return adns_s_querydomaininvalid; } } if (ll == sizeof(label)) return adns_s_querydomaininvalid; label[ll++]= c; } if (!ll) return adns_s_querydomaininvalid; if (ll > DNS_MAXLABEL) return adns_s_querydomaintoolong; nbytes+= ll+1; if (nbytes >= DNS_MAXDOMAIN) return adns_s_querydomaintoolong; MKQUERY_ADDB(ll); memcpy(rqp,label,ll); rqp+= ll; } MKQUERY_ADDB(0); MKQUERY_STOP(vb); st= mkquery_footer(vb,typei->type); return adns_s_ok; } adns_status adns__mkquery_frdgram(adns_state ads, vbuf *vb, int *id_r, const byte *qd_dgram, int qd_dglen, int qd_begin, adns_rrtype type, adns_queryflags flags) { byte *rqp; findlabel_state fls; int lablen, labstart; adns_status st; st= mkquery_header(ads,vb,id_r,qd_dglen); if (st) return st; MKQUERY_START(vb); adns__findlabel_start(&fls,ads,-1,0,qd_dgram,qd_dglen,qd_dglen,qd_begin,0); for (;;) { st= adns__findlabel_next(&fls,&lablen,&labstart); assert(!st); if (!lablen) break; assert(lablen<255); MKQUERY_ADDB(lablen); memcpy(rqp,qd_dgram+labstart,lablen); rqp+= lablen; } MKQUERY_ADDB(0); MKQUERY_STOP(vb); st= mkquery_footer(vb,type); return adns_s_ok; } void adns__querysend_tcp(adns_query qu, struct timeval now) { byte length[2]; struct iovec iov[2]; int wr, r; adns_state ads; if (qu->ads->tcpstate != server_ok) return; assert(qu->state == query_tcpw); length[0]= (qu->query_dglen&0x0ff00U) >>8; length[1]= (qu->query_dglen&0x0ff); ads= qu->ads; if (!adns__vbuf_ensure(&ads->tcpsend,ads->tcpsend.used+qu->query_dglen+2)) return; qu->retries++; /* Reset idle timeout. */ ads->tcptimeout.tv_sec= ads->tcptimeout.tv_usec= 0; if (ads->tcpsend.used) { wr= 0; } else { iov[0].iov_base= length; iov[0].iov_len= 2; iov[1].iov_base= qu->query_dgram; iov[1].iov_len= qu->query_dglen; adns__sigpipe_protect(qu->ads); wr= writev(qu->ads->tcpsocket,iov,2); adns__sigpipe_unprotect(qu->ads); if (wr < 0) { if (!(errno == EAGAIN || errno == EINTR || errno == ENOSPC || errno == ENOBUFS || errno == ENOMEM)) { adns__tcp_broken(ads,"write",strerror(errno)); return; } wr= 0; } } if (wr<2) { r= adns__vbuf_append(&ads->tcpsend,length,2-wr); assert(r); wr= 0; } else { wr-= 2; } if (wrquery_dglen) { r= adns__vbuf_append(&ads->tcpsend,qu->query_dgram+wr,qu->query_dglen-wr); assert(r); } } static void query_usetcp(adns_query qu, struct timeval now) { qu->state= query_tcpw; qu->timeout= now; timevaladd(&qu->timeout,TCPWAITMS); ADNS_LIST_LINK_TAIL(qu->ads->tcpw,qu); adns__querysend_tcp(qu,now); adns__tcp_tryconnect(qu->ads,now); } void adns__query_send(adns_query qu, struct timeval now) { struct sockaddr_in servaddr; int serv, r; adns_state ads; assert(qu->state == query_tosend); if ((qu->flags & adns_qf_usevc) || (qu->query_dglen > DNS_MAXUDP)) { query_usetcp(qu,now); return; } if (qu->retries >= UDPMAXRETRIES) { adns__query_fail(qu,adns_s_timeout); return; } serv= qu->udpnextserver; memset(&servaddr,0,sizeof(servaddr)); ads= qu->ads; servaddr.sin_family= AF_INET; servaddr.sin_addr= ads->servers[serv].addr; servaddr.sin_port= htons(DNS_PORT); r= sendto(ads->udpsocket,qu->query_dgram,qu->query_dglen,0, (const struct sockaddr*)&servaddr,sizeof(servaddr)); if (r<0 && errno == EMSGSIZE) { qu->retries= 0; query_usetcp(qu,now); return; } if (r<0 && errno != EAGAIN) adns__warn(ads,serv,0,"sendto failed: %s",strerror(errno)); qu->timeout= now; timevaladd(&qu->timeout,UDPRETRYMS); qu->udpsent |= (1<udpnextserver= (serv+1)%ads->nservers; qu->retries++; ADNS_LIST_LINK_TAIL(ads->udpw,qu); } lyskom-server-2.1.2/src/libraries/adns/src/tvarith.h0000664000015100472110000000256407705611251016141 /* * tvarith.h * - static inline functions for doing arithmetic on timevals */ /* * This file is * Copyright (C) 1997-1999 Ian Jackson * * It is part of adns, which is * Copyright (C) 1997-2000 Ian Jackson * Copyright (C) 1999-2000 Tony Finch * * 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 2, 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, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef ADNS_TVARITH_H_INCLUDED #define ADNS_TVARITH_H_INCLUDED static inline void timevaladd(struct timeval *tv_io, long ms) { struct timeval tmp; assert(ms>=0); tmp= *tv_io; tmp.tv_usec += (ms%1000)*1000; tmp.tv_sec += ms/1000; if (tmp.tv_usec >= 1000000) { tmp.tv_sec++; tmp.tv_usec -= 1000000; } *tv_io= tmp; } #endif lyskom-server-2.1.2/src/libraries/adns/src/types.c0000664000015100472110000006517507707157070015634 /* * types.c * - RR-type-specific code, and the machinery to call it */ /* * This file is * Copyright (C) 1997-1999 Ian Jackson * * It is part of adns, which is * Copyright (C) 1997-2000 Ian Jackson * Copyright (C) 1999-2000 Tony Finch * * 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 2, 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, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include "internal.h" #define R_NOMEM return adns_s_nomemory #define CSP_ADDSTR(s) do { if (!adns__vbuf_appendstr(vb,(s))) R_NOMEM; } while (0) /* * order of sections: * * _string (pap) * _textdata, _qstring (csp) * _str (mf,cs) * _intstr (mf,csp,cs) * _manyistr (mf,cs) * _txt (pa) * _inaddr (pa,dip,di) * _addr (pa,di,csp,cs) * _domain (pap) * _host_raw (pa) * _hostaddr (pap,pa,dip,di,mfp,mf,csp,cs +pap_findaddrs) * _mx_raw (pa,di) * _mx (pa,di) * _inthostaddr (mf,cs) * _ptr (pa) * _strpair (mf,cs) * _intstrpair (mf,cs) * _hinfo (pa) * _mailbox (pap +pap_mailbox822) * _rp (pa) * _soa (pa,mf,cs) * _flat (mf) * * within each section: * pap_* * pa_* * dip_* * di_* * mfp_* * mf_* * csp_* * cs_* */ /* * _qstring (pap,csp) */ static adns_status pap_qstring(const parseinfo *pai, int *cbyte_io, int max, int *len_r, char **str_r) { /* Neither len_r nor str_r may be null. * End of datagram (overrun) is indicated by returning adns_s_invaliddata; */ const byte *dgram= pai->dgram; int l, cbyte; char *str; cbyte= *cbyte_io; if (cbyte >= max) return adns_s_invaliddata; GET_B(cbyte,l); if (cbyte+l > max) return adns_s_invaliddata; str= adns__alloc_interim(pai->qu, l+1); if (!str) R_NOMEM; str[l]= 0; memcpy(str,dgram+cbyte,l); *len_r= l; *str_r= str; *cbyte_io= cbyte+l; return adns_s_ok; } static adns_status csp_qstring(vbuf *vb, const char *dp, int len) { unsigned char ch; char buf[10]; int cn; CSP_ADDSTR("\""); for (cn=0; cn= 32 && ch <= 126) { if (!adns__vbuf_append(vb,&ch,1)) R_NOMEM; } else { sprintf(buf,"\\x%02x",ch); CSP_ADDSTR(buf); } } CSP_ADDSTR("\""); return adns_s_ok; } /* * _str (mf) */ static void mf_str(adns_query qu, void *datap) { char **rrp= datap; adns__makefinal_str(qu,rrp); } /* * _intstr (mf) */ static void mf_intstr(adns_query qu, void *datap) { adns_rr_intstr *rrp= datap; adns__makefinal_str(qu,&rrp->str); } /* * _manyistr (mf) */ static void mf_manyistr(adns_query qu, void *datap) { adns_rr_intstr **rrp= datap; adns_rr_intstr *te, *table; void *tablev; int tc; for (tc=0, te= *rrp; te->i >= 0; te++, tc++); tablev= *rrp; adns__makefinal_block(qu,&tablev,sizeof(*te)*(tc+1)); *rrp= table= tablev; for (te= *rrp; te->i >= 0; te++) adns__makefinal_str(qu,&te->str); } /* * _txt (pa,cs) */ static adns_status pa_txt(const parseinfo *pai, int cbyte, int max, void *datap) { adns_rr_intstr **rrp= datap, *table, *te; const byte *dgram= pai->dgram; int ti, tc, l, startbyte; adns_status st; startbyte= cbyte; if (cbyte >= max) return adns_s_invaliddata; tc= 0; while (cbyte < max) { GET_B(cbyte,l); cbyte+= l; tc++; } if (cbyte != max || !tc) return adns_s_invaliddata; table= adns__alloc_interim(pai->qu,sizeof(*table)*(tc+1)); if (!table) R_NOMEM; for (cbyte=startbyte, ti=0, te=table; tii, &te->str); if (st) return st; } assert(cbyte == max); te->i= -1; te->str= 0; *rrp= table; return adns_s_ok; } static adns_status cs_txt(vbuf *vb, const void *datap) { const adns_rr_intstr *const *rrp= datap; const adns_rr_intstr *current; adns_status st; int spc; for (current= *rrp, spc=0; current->i >= 0; current++, spc=1) { if (spc) CSP_ADDSTR(" "); st= csp_qstring(vb,current->str,current->i); if (st) return st; } return adns_s_ok; } /* * _hinfo (cs) */ static adns_status cs_hinfo(vbuf *vb, const void *datap) { const adns_rr_intstrpair *rrp= datap; adns_status st; st= csp_qstring(vb,rrp->array[0].str,rrp->array[0].i); if (st) return st; CSP_ADDSTR(" "); st= csp_qstring(vb,rrp->array[1].str,rrp->array[1].i); if (st) return st; return adns_s_ok; } /* * _inaddr (pa,dip,di) */ static adns_status pa_inaddr(const parseinfo *pai, int cbyte, int max, void *datap) { struct in_addr *storeto= datap; if (max-cbyte != 4) return adns_s_invaliddata; memcpy(storeto, pai->dgram + cbyte, 4); return adns_s_ok; } static int search_sortlist(adns_state ads, struct in_addr ad) { const struct sortlist *slp; int i; for (i=0, slp=ads->sortlist; insortlist && !((ad.s_addr & slp->mask.s_addr) == slp->base.s_addr); i++, slp++); return i; } static int dip_inaddr(adns_state ads, struct in_addr a, struct in_addr b) { int ai, bi; if (!ads->nsortlist) return 0; ai= search_sortlist(ads,a); bi= search_sortlist(ads,b); return bidgram; if (max-cbyte != 4) return adns_s_invaliddata; storeto->len= sizeof(storeto->addr.inet); memset(&storeto->addr,0,sizeof(storeto->addr.inet)); storeto->addr.inet.sin_family= AF_INET; memcpy(&storeto->addr.inet.sin_addr,dgram+cbyte,4); return adns_s_ok; } static int di_addr(adns_state ads, const void *datap_a, const void *datap_b) { const adns_rr_addr *ap= datap_a, *bp= datap_b; assert(ap->addr.sa.sa_family == AF_INET); return dip_inaddr(ads, ap->addr.inet.sin_addr, bp->addr.inet.sin_addr); } static int div_addr(void *context, const void *datap_a, const void *datap_b) { const adns_state ads= context; return di_addr(ads, datap_a, datap_b); } static adns_status csp_addr(vbuf *vb, const adns_rr_addr *rrp) { const char *ia; static char buf[30]; switch (rrp->addr.inet.sin_family) { case AF_INET: CSP_ADDSTR("INET "); ia= inet_ntoa(rrp->addr.inet.sin_addr); assert(ia); CSP_ADDSTR(ia); break; default: sprintf(buf,"AF=%u",rrp->addr.sa.sa_family); CSP_ADDSTR(buf); break; } return adns_s_ok; } static adns_status cs_addr(vbuf *vb, const void *datap) { const adns_rr_addr *rrp= datap; return csp_addr(vb,rrp); } /* * _domain (pap,csp,cs) * _dom_raw (pa) */ static adns_status pap_domain(const parseinfo *pai, int *cbyte_io, int max, char **domain_r, parsedomain_flags flags) { adns_status st; char *dm; st= adns__parse_domain(pai->qu->ads, pai->serv, pai->qu, &pai->qu->vb, flags, pai->dgram,pai->dglen, cbyte_io, max); if (st) return st; if (!pai->qu->vb.used) return adns_s_invaliddata; dm= adns__alloc_interim(pai->qu, pai->qu->vb.used+1); if (!dm) R_NOMEM; dm[pai->qu->vb.used]= 0; memcpy(dm,pai->qu->vb.buf,pai->qu->vb.used); *domain_r= dm; return adns_s_ok; } static adns_status csp_domain(vbuf *vb, const char *domain) { CSP_ADDSTR(domain); if (!*domain) CSP_ADDSTR("."); return adns_s_ok; } static adns_status cs_domain(vbuf *vb, const void *datap) { const char *const *domainp= datap; return csp_domain(vb,*domainp); } static adns_status pa_dom_raw(const parseinfo *pai, int cbyte, int max, void *datap) { char **rrp= datap; adns_status st; st= pap_domain(pai, &cbyte, max, rrp, pdf_quoteok); if (st) return st; if (cbyte != max) return adns_s_invaliddata; return adns_s_ok; } /* * _host_raw (pa) */ static adns_status pa_host_raw(const parseinfo *pai, int cbyte, int max, void *datap) { char **rrp= datap; adns_status st; st= pap_domain(pai, &cbyte, max, rrp, pai->qu->flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0); if (st) return st; if (cbyte != max) return adns_s_invaliddata; return adns_s_ok; } /* * _hostaddr (pap,pa,dip,di,mfp,mf,csp,cs +icb_hostaddr, pap_findaddrs) */ static adns_status pap_findaddrs(const parseinfo *pai, adns_rr_hostaddr *ha, int *cbyte_io, int count, int dmstart) { int rri, naddrs; int type, class, rdlen, rdstart, ownermatched; unsigned long ttl; adns_status st; for (rri=0, naddrs=-1; rriqu, pai->serv, pai->dgram, pai->dglen, cbyte_io, &type, &class, &ttl, &rdlen, &rdstart, pai->dgram, pai->dglen, dmstart, &ownermatched); if (st) return st; if (!ownermatched || class != DNS_CLASS_IN || type != adns_r_a) { if (naddrs>0) break; else continue; } if (naddrs == -1) { naddrs= 0; } if (!adns__vbuf_ensure(&pai->qu->vb, (naddrs+1)*sizeof(adns_rr_addr))) R_NOMEM; adns__update_expires(pai->qu,ttl,pai->now); st= pa_addr(pai, rdstart,rdstart+rdlen, pai->qu->vb.buf + naddrs*sizeof(adns_rr_addr)); if (st) return st; naddrs++; } if (naddrs >= 0) { ha->addrs= adns__alloc_interim(pai->qu, naddrs*sizeof(adns_rr_addr)); if (!ha->addrs) R_NOMEM; memcpy(ha->addrs, pai->qu->vb.buf, naddrs*sizeof(adns_rr_addr)); ha->naddrs= naddrs; ha->astatus= adns_s_ok; adns__isort(ha->addrs, naddrs, sizeof(adns_rr_addr), pai->qu->vb.buf, div_addr, pai->ads); } return adns_s_ok; } static void icb_hostaddr(adns_query parent, adns_query child) { adns_answer *cans= child->answer; adns_rr_hostaddr *rrp= child->ctx.info.hostaddr; adns_state ads= parent->ads; adns_status st; st= cans->status; rrp->astatus= st; rrp->naddrs= (st>0 && st<=adns_s_max_tempfail) ? -1 : cans->nrrs; rrp->addrs= cans->rrs.addr; adns__transfer_interim(child, parent, rrp->addrs, rrp->naddrs*sizeof(adns_rr_addr)); if (parent->children.head) { ADNS_LIST_LINK_TAIL(ads->childw,parent); } else { adns__query_done(parent); } } static adns_status pap_hostaddr(const parseinfo *pai, int *cbyte_io, int max, adns_rr_hostaddr *rrp) { adns_status st; int dmstart, cbyte; qcontext ctx; int id; adns_query nqu; adns_queryflags nflags; dmstart= cbyte= *cbyte_io; st= pap_domain(pai, &cbyte, max, &rrp->host, pai->qu->flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0); if (st) return st; *cbyte_io= cbyte; rrp->astatus= adns_s_ok; rrp->naddrs= -1; rrp->addrs= 0; cbyte= pai->nsstart; st= pap_findaddrs(pai, rrp, &cbyte, pai->nscount, dmstart); if (st) return st; if (rrp->naddrs != -1) return adns_s_ok; st= pap_findaddrs(pai, rrp, &cbyte, pai->arcount, dmstart); if (st) return st; if (rrp->naddrs != -1) return adns_s_ok; st= adns__mkquery_frdgram(pai->ads, &pai->qu->vb, &id, pai->dgram, pai->dglen, dmstart, adns_r_addr, adns_qf_quoteok_query); if (st) return st; ctx.ext= 0; ctx.callback= icb_hostaddr; ctx.info.hostaddr= rrp; nflags= adns_qf_quoteok_query; if (!(pai->qu->flags & adns_qf_cname_loose)) nflags |= adns_qf_cname_forbid; st= adns__internal_submit(pai->ads, &nqu, adns__findtype(adns_r_addr), &pai->qu->vb, id, nflags, pai->now, &ctx); if (st) return st; nqu->parent= pai->qu; ADNS_LIST_LINK_TAIL_PART(pai->qu->children,nqu,siblings.); return adns_s_ok; } static adns_status pa_hostaddr(const parseinfo *pai, int cbyte, int max, void *datap) { adns_rr_hostaddr *rrp= datap; adns_status st; st= pap_hostaddr(pai, &cbyte, max, rrp); if (st) return st; if (cbyte != max) return adns_s_invaliddata; return adns_s_ok; } static int dip_hostaddr(adns_state ads, const adns_rr_hostaddr *ap, const adns_rr_hostaddr *bp) { if (ap->astatus != bp->astatus) return ap->astatus; if (ap->astatus) return 0; assert(ap->addrs[0].addr.sa.sa_family == AF_INET); assert(bp->addrs[0].addr.sa.sa_family == AF_INET); return dip_inaddr(ads, ap->addrs[0].addr.inet.sin_addr, bp->addrs[0].addr.inet.sin_addr); } static int di_hostaddr(adns_state ads, const void *datap_a, const void *datap_b) { const adns_rr_hostaddr *ap= datap_a, *bp= datap_b; return dip_hostaddr(ads, ap,bp); } static void mfp_hostaddr(adns_query qu, adns_rr_hostaddr *rrp) { void *tablev; adns__makefinal_str(qu,&rrp->host); tablev= rrp->addrs; adns__makefinal_block(qu, &tablev, rrp->naddrs*sizeof(*rrp->addrs)); rrp->addrs= tablev; } static void mf_hostaddr(adns_query qu, void *datap) { adns_rr_hostaddr *rrp= datap; mfp_hostaddr(qu,rrp); } static adns_status csp_hostaddr(vbuf *vb, const adns_rr_hostaddr *rrp) { const char *errstr; adns_status st; char buf[20]; int i; st= csp_domain(vb,rrp->host); if (st) return st; CSP_ADDSTR(" "); CSP_ADDSTR(adns_errtypeabbrev(rrp->astatus)); sprintf(buf," %d ",rrp->astatus); CSP_ADDSTR(buf); CSP_ADDSTR(adns_errabbrev(rrp->astatus)); CSP_ADDSTR(" "); errstr= adns_strerror(rrp->astatus); st= csp_qstring(vb,errstr,strlen(errstr)); if (st) return st; if (rrp->naddrs >= 0) { CSP_ADDSTR(" ("); for (i=0; inaddrs; i++) { CSP_ADDSTR(" "); st= csp_addr(vb,&rrp->addrs[i]); } CSP_ADDSTR(" )"); } else { CSP_ADDSTR(" ?"); } return adns_s_ok; } static adns_status cs_hostaddr(vbuf *vb, const void *datap) { const adns_rr_hostaddr *rrp= datap; return csp_hostaddr(vb,rrp); } /* * _mx_raw (pa,di) */ static adns_status pa_mx_raw(const parseinfo *pai, int cbyte, int max, void *datap) { const byte *dgram= pai->dgram; adns_rr_intstr *rrp= datap; adns_status st; int pref; if (cbyte+2 > max) return adns_s_invaliddata; GET_W(cbyte,pref); rrp->i= pref; st= pap_domain(pai, &cbyte, max, &rrp->str, pai->qu->flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0); if (st) return st; if (cbyte != max) return adns_s_invaliddata; return adns_s_ok; } static int di_mx_raw(adns_state ads, const void *datap_a, const void *datap_b) { const adns_rr_intstr *ap= datap_a, *bp= datap_b; if (ap->i < bp->i) return 0; if (ap->i > bp->i) return 1; return 0; } /* * _mx (pa,di) */ static adns_status pa_mx(const parseinfo *pai, int cbyte, int max, void *datap) { const byte *dgram= pai->dgram; adns_rr_inthostaddr *rrp= datap; adns_status st; int pref; if (cbyte+2 > max) return adns_s_invaliddata; GET_W(cbyte,pref); rrp->i= pref; st= pap_hostaddr(pai, &cbyte, max, &rrp->ha); if (st) return st; if (cbyte != max) return adns_s_invaliddata; return adns_s_ok; } static int di_mx(adns_state ads, const void *datap_a, const void *datap_b) { const adns_rr_inthostaddr *ap= datap_a, *bp= datap_b; if (ap->i < bp->i) return 0; if (ap->i > bp->i) return 1; return dip_hostaddr(ads, &ap->ha, &bp->ha); } /* * _inthostaddr (mf,cs) */ static void mf_inthostaddr(adns_query qu, void *datap) { adns_rr_inthostaddr *rrp= datap; mfp_hostaddr(qu,&rrp->ha); } static adns_status cs_inthostaddr(vbuf *vb, const void *datap) { const adns_rr_inthostaddr *rrp= datap; char buf[10]; sprintf(buf,"%u ",rrp->i); CSP_ADDSTR(buf); return csp_hostaddr(vb,&rrp->ha); } /* * _inthost (cs) */ static adns_status cs_inthost(vbuf *vb, const void *datap) { const adns_rr_intstr *rrp= datap; char buf[10]; sprintf(buf,"%u ",rrp->i); CSP_ADDSTR(buf); return csp_domain(vb,rrp->str); } /* * _ptr (pa, +icb_ptr) */ static void icb_ptr(adns_query parent, adns_query child) { adns_answer *cans= child->answer; const adns_rr_addr *queried, *found; adns_state ads= parent->ads; int i; if (cans->status == adns_s_nxdomain || cans->status == adns_s_nodata) { adns__query_fail(parent,adns_s_inconsistent); return; } else if (cans->status) { adns__query_fail(parent,cans->status); return; } queried= &parent->ctx.info.ptr_parent_addr; for (i=0, found=cans->rrs.addr; inrrs; i++, found++) { if (queried->len == found->len && !memcmp(&queried->addr,&found->addr,queried->len)) { if (!parent->children.head) { adns__query_done(parent); return; } else { ADNS_LIST_LINK_TAIL(ads->childw,parent); return; } } } adns__query_fail(parent,adns_s_inconsistent); } static adns_status pa_ptr(const parseinfo *pai, int dmstart, int max, void *datap) { static const char *(expectdomain[])= { DNS_INADDR_ARPA }; char **rrp= datap; adns_status st; adns_rr_addr *ap; findlabel_state fls; char *ep; byte ipv[4]; char labbuf[4]; int cbyte, i, lablen, labstart, l, id; adns_query nqu; qcontext ctx; cbyte= dmstart; st= pap_domain(pai, &cbyte, max, rrp, pai->qu->flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0); if (st) return st; if (cbyte != max) return adns_s_invaliddata; ap= &pai->qu->ctx.info.ptr_parent_addr; if (!ap->len) { adns__findlabel_start(&fls, pai->ads, -1, pai->qu, pai->qu->query_dgram, pai->qu->query_dglen, pai->qu->query_dglen, DNS_HDRSIZE, 0); for (i=0; i<4; i++) { st= adns__findlabel_next(&fls,&lablen,&labstart); assert(!st); if (lablen<=0 || lablen>3) return adns_s_querydomainwrong; memcpy(labbuf, pai->qu->query_dgram + labstart, lablen); labbuf[lablen]= 0; ipv[3-i]= strtoul(labbuf,&ep,10); if (*ep) return adns_s_querydomainwrong; if (lablen>1 && pai->qu->query_dgram[labstart]=='0') return adns_s_querydomainwrong; } for (i=0; iqu->query_dgram + labstart, expectdomain[i], l)) return adns_s_querydomainwrong; } st= adns__findlabel_next(&fls,&lablen,0); assert(!st); if (lablen) return adns_s_querydomainwrong; ap->len= sizeof(struct sockaddr_in); memset(&ap->addr,0,sizeof(ap->addr.inet)); ap->addr.inet.sin_family= AF_INET; ap->addr.inet.sin_addr.s_addr= htonl((ipv[0]<<24) | (ipv[1]<<16) | (ipv[2]<<8) | (ipv[3])); } st= adns__mkquery_frdgram(pai->ads, &pai->qu->vb, &id, pai->dgram, pai->dglen, dmstart, adns_r_addr, adns_qf_quoteok_query); if (st) return st; ctx.ext= 0; ctx.callback= icb_ptr; memset(&ctx.info,0,sizeof(ctx.info)); st= adns__internal_submit(pai->ads, &nqu, adns__findtype(adns_r_addr), &pai->qu->vb, id, adns_qf_quoteok_query, pai->now, &ctx); if (st) return st; nqu->parent= pai->qu; ADNS_LIST_LINK_TAIL_PART(pai->qu->children,nqu,siblings.); return adns_s_ok; } /* * _strpair (mf) */ static void mf_strpair(adns_query qu, void *datap) { adns_rr_strpair *rrp= datap; adns__makefinal_str(qu,&rrp->array[0]); adns__makefinal_str(qu,&rrp->array[1]); } /* * _intstrpair (mf) */ static void mf_intstrpair(adns_query qu, void *datap) { adns_rr_intstrpair *rrp= datap; adns__makefinal_str(qu,&rrp->array[0].str); adns__makefinal_str(qu,&rrp->array[1].str); } /* * _hinfo (pa) */ static adns_status pa_hinfo(const parseinfo *pai, int cbyte, int max, void *datap) { adns_rr_intstrpair *rrp= datap; adns_status st; int i; for (i=0; i<2; i++) { st= pap_qstring(pai, &cbyte, max, &rrp->array[i].i, &rrp->array[i].str); if (st) return st; } if (cbyte != max) return adns_s_invaliddata; return adns_s_ok; } /* * _mailbox (pap,cs) */ static adns_status pap_mailbox822(const parseinfo *pai, int *cbyte_io, int max, char **mb_r) { int lablen, labstart, i, needquote, c, r, neednorm; const unsigned char *p; char *str; findlabel_state fls; adns_status st; vbuf *vb; vb= &pai->qu->vb; vb->used= 0; adns__findlabel_start(&fls, pai->ads, -1, pai->qu, pai->dgram, pai->dglen, max, *cbyte_io, cbyte_io); st= adns__findlabel_next(&fls,&lablen,&labstart); if (!lablen) { adns__vbuf_appendstr(vb,"."); goto x_ok; } neednorm= 1; for (i=0, needquote=0, p= pai->dgram+labstart; i=127 || ctype_822special(c)) needquote++; else neednorm= 0; } if (needquote || neednorm) { r= adns__vbuf_ensure(vb, lablen+needquote+4); if (!r) R_NOMEM; adns__vbuf_appendq(vb,"\"",1); for (i=0, needquote=0, p= pai->dgram+labstart; idgram+labstart, lablen); if (!r) R_NOMEM; } r= adns__vbuf_appendstr(vb,"@"); if (!r) R_NOMEM; st= adns__parse_domain_more(&fls,pai->ads, pai->qu,vb,0, pai->dgram); if (st) return st; x_ok: str= adns__alloc_interim(pai->qu, vb->used+1); if (!str) R_NOMEM; memcpy(str,vb->buf,vb->used); str[vb->used]= 0; *mb_r= str; return adns_s_ok; } static adns_status pap_mailbox(const parseinfo *pai, int *cbyte_io, int max, char **mb_r) { if (pai->qu->typei->type & adns__qtf_mail822) { return pap_mailbox822(pai, cbyte_io, max, mb_r); } else { return pap_domain(pai, cbyte_io, max, mb_r, pdf_quoteok); } } static adns_status csp_mailbox(vbuf *vb, const char *mailbox) { return csp_domain(vb,mailbox); } /* * _rp (pa,cs) */ static adns_status pa_rp(const parseinfo *pai, int cbyte, int max, void *datap) { adns_rr_strpair *rrp= datap; adns_status st; st= pap_mailbox(pai, &cbyte, max, &rrp->array[0]); if (st) return st; st= pap_domain(pai, &cbyte, max, &rrp->array[1], pdf_quoteok); if (st) return st; if (cbyte != max) return adns_s_invaliddata; return adns_s_ok; } static adns_status cs_rp(vbuf *vb, const void *datap) { const adns_rr_strpair *rrp= datap; adns_status st; st= csp_mailbox(vb,rrp->array[0]); if (st) return st; CSP_ADDSTR(" "); st= csp_domain(vb,rrp->array[1]); if (st) return st; return adns_s_ok; } /* * _soa (pa,mf,cs) */ static adns_status pa_soa(const parseinfo *pai, int cbyte, int max, void *datap) { adns_rr_soa *rrp= datap; const byte *dgram= pai->dgram; adns_status st; int msw, lsw, i; st= pap_domain(pai, &cbyte, max, &rrp->mname, pai->qu->flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0); if (st) return st; st= pap_mailbox(pai, &cbyte, max, &rrp->rname); if (st) return st; if (cbyte+20 != max) return adns_s_invaliddata; for (i=0; i<5; i++) { GET_W(cbyte,msw); GET_W(cbyte,lsw); (&rrp->serial)[i]= (msw<<16) | lsw; } return adns_s_ok; } static void mf_soa(adns_query qu, void *datap) { adns_rr_soa *rrp= datap; adns__makefinal_str(qu,&rrp->mname); adns__makefinal_str(qu,&rrp->rname); } static adns_status cs_soa(vbuf *vb, const void *datap) { const adns_rr_soa *rrp= datap; char buf[20]; int i; adns_status st; st= csp_domain(vb,rrp->mname); if (st) return st; CSP_ADDSTR(" "); st= csp_mailbox(vb,rrp->rname); if (st) return st; for (i=0; i<5; i++) { sprintf(buf," %lu",(&rrp->serial)[i]); CSP_ADDSTR(buf); } return adns_s_ok; } /* * _flat (mf) */ static void mf_flat(adns_query qu, void *data) { } /* * Now the table. */ #define TYPESZ_M(member) (sizeof(*((adns_answer*)0)->rrs.member)) #define DEEP_MEMB(memb) TYPESZ_M(memb), mf_##memb, cs_##memb #define FLAT_MEMB(memb) TYPESZ_M(memb), mf_flat, cs_##memb #define DEEP_TYPE(code,rrt,fmt,memb,parser,comparer,printer) \ { adns_r_##code, rrt, fmt, TYPESZ_M(memb), mf_##memb, printer, parser, comparer } #define FLAT_TYPE(code,rrt,fmt,memb,parser,comparer,printer) \ { adns_r_##code, rrt, fmt, TYPESZ_M(memb), mf_flat, printer, parser, comparer } static const typeinfo typeinfos[] = { /* Must be in ascending order of rrtype ! */ /* mem-mgmt code rrt fmt member parser comparer printer */ FLAT_TYPE(a, "A", 0, inaddr, pa_inaddr, di_inaddr, cs_inaddr ), DEEP_TYPE(ns_raw, "NS", "raw", str, pa_host_raw,0, cs_domain ), DEEP_TYPE(cname, "CNAME", 0, str, pa_dom_raw, 0, cs_domain ), DEEP_TYPE(soa_raw,"SOA", "raw", soa, pa_soa, 0, cs_soa ), DEEP_TYPE(ptr_raw,"PTR", "raw", str, pa_host_raw,0, cs_domain ), DEEP_TYPE(hinfo, "HINFO", 0, intstrpair, pa_hinfo, 0, cs_hinfo ), DEEP_TYPE(mx_raw, "MX", "raw", intstr, pa_mx_raw, di_mx_raw, cs_inthost ), DEEP_TYPE(txt, "TXT", 0, manyistr, pa_txt, 0, cs_txt ), DEEP_TYPE(rp_raw, "RP", "raw", strpair, pa_rp, 0, cs_rp ), FLAT_TYPE(addr, "A", "addr", addr, pa_addr, di_addr, cs_addr ), DEEP_TYPE(ns, "NS", "+addr", hostaddr, pa_hostaddr,di_hostaddr,cs_hostaddr ), DEEP_TYPE(ptr, "PTR","checked",str, pa_ptr, 0, cs_domain ), DEEP_TYPE(mx, "MX", "+addr", inthostaddr,pa_mx, di_mx, cs_inthostaddr), DEEP_TYPE(soa, "SOA","822", soa, pa_soa, 0, cs_soa ), DEEP_TYPE(rp, "RP", "822", strpair, pa_rp, 0, cs_rp ), }; const typeinfo *adns__findtype(adns_rrtype type) { const typeinfo *begin, *end, *mid; begin= typeinfos; end= typeinfos+(sizeof(typeinfos)/sizeof(typeinfo)); while (begin < end) { mid= begin + ((end-begin)>>1); if (mid->type == type) return mid; if (type > mid->type) begin= mid+1; else end= mid; } return 0; } lyskom-server-2.1.2/src/libraries/adns/src/.cvsignore0000664000015100472110000000007107705622444016304 .deps Makefile Makefile.in config.h config.h.in stamp-h1 lyskom-server-2.1.2/src/libraries/adns/client/0000777000015100472110000000000007723710277015061 5lyskom-server-2.1.2/src/libraries/adns/client/Makefile.am0000664000015100472110000000036407722446220017027 # adns makefile for the lyskom-server environment. check_PROGRAMS = adnshost adnshost_SOURCES = adh-main.c adh-opts.c adh-query.c adnshost.h client.h adnshost_LDADD = ../src/libadns.a AM_CPPFLAGS = -I$(srcdir)/../src EXTRA_DIST = .cvsignore lyskom-server-2.1.2/src/libraries/adns/client/Makefile.in0000664000015100472110000002571407723707506017056 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # adns makefile for the lyskom-server environment. srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WARNS = @WARNS@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ prefix = @prefix@ program_transform_name = @program_transform_name@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ check_PROGRAMS = adnshost adnshost_SOURCES = adh-main.c adh-opts.c adh-query.c adnshost.h client.h adnshost_LDADD = ../src/libadns.a AM_CPPFLAGS = -I$(srcdir)/../src EXTRA_DIST = .cvsignore subdir = client ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/src/config.h CONFIG_CLEAN_FILES = check_PROGRAMS = adnshost$(EXEEXT) am_adnshost_OBJECTS = adh-main.$(OBJEXT) adh-opts.$(OBJEXT) \ adh-query.$(OBJEXT) adnshost_OBJECTS = $(am_adnshost_OBJECTS) adnshost_DEPENDENCIES = ../src/libadns.a adnshost_LDFLAGS = DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/src depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/adh-main.Po ./$(DEPDIR)/adh-opts.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/adh-query.Po COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ DIST_SOURCES = $(adnshost_SOURCES) DIST_COMMON = Makefile.am Makefile.in SOURCES = $(adnshost_SOURCES) all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu client/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) clean-checkPROGRAMS: -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS) adnshost$(EXEEXT): $(adnshost_OBJECTS) $(adnshost_DEPENDENCIES) @rm -f adnshost$(EXEEXT) $(LINK) $(adnshost_LDFLAGS) $(adnshost_OBJECTS) $(adnshost_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) core *.core distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adh-main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adh-opts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adh-query.Po@am__quote@ distclean-depend: -rm -rf ./$(DEPDIR) .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ @am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ @am__fastdepCC_TRUE@ fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< .c.obj: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ @am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ @am__fastdepCC_TRUE@ fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` uninstall-info-am: ETAGS = etags ETAGSFLAGS = CTAGS = ctags CTAGSFLAGS = tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$tags$$unique" \ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = .. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-checkPROGRAMS clean-generic mostlyclean-am distclean: distclean-am distclean-am: clean-am distclean-compile distclean-depend \ distclean-generic distclean-tags dvi: dvi-am dvi-am: info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-checkPROGRAMS \ clean-generic ctags distclean distclean-compile \ distclean-depend distclean-generic distclean-tags distdir dvi \ dvi-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/src/libraries/adns/client/adh-main.c0000664000015100472110000001506107705611223016613 /* * adh-main.c * - useful general-purpose resolver client program * main program and useful subroutines */ /* * This file is * Copyright (C) 1997-2000 Ian Jackson * * It is part of adns, which is * Copyright (C) 1997-2000 Ian Jackson * Copyright (C) 1999-2000 Tony Finch * * 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 2, 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, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "adnshost.h" int rcode; const char *config_text; static int used, avail; static char *buf; void quitnow(int rc) { if (ads) adns_finish(ads); free(buf); free(ov_id); exit(rc); } void sysfail(const char *what, int errnoval) { fprintf(stderr,"adnshost failed: %s: %s\n",what,strerror(errnoval)); quitnow(10); } void usageerr(const char *fmt, ...) { va_list al; fputs("adnshost usage error: ",stderr); va_start(al,fmt); vfprintf(stderr,fmt,al); va_end(al); putc('\n',stderr); quitnow(11); } void outerr(void) { sysfail("write to stdout",errno); } void *xmalloc(size_t sz) { void *p; p= malloc(sz); if (!p) sysfail("malloc",sz); return p; } char *xstrsave(const char *str) { char *p; p= xmalloc(strlen(str)+1); strcpy(p,str); return p; } void of_config(const struct optioninfo *oi, const char *arg, const char *arg2) { config_text= arg; } void of_type(const struct optioninfo *oi, const char *arg, const char *arg2) { static const struct typename { adns_rrtype type; const char *desc; } typenames[]= { /* enhanced versions */ { adns_r_ns, "ns" }, { adns_r_soa, "soa" }, { adns_r_ptr, "ptr" }, { adns_r_mx, "mx" }, { adns_r_rp, "rp" }, { adns_r_addr, "addr" }, /* types with only one version */ { adns_r_cname, "cname" }, { adns_r_hinfo, "hinfo" }, { adns_r_txt, "txt" }, /* raw versions */ { adns_r_a, "a" }, { adns_r_ns_raw, "ns-" }, { adns_r_soa_raw, "soa-" }, { adns_r_ptr_raw, "ptr-" }, { adns_r_mx_raw, "mx-" }, { adns_r_rp_raw, "rp-" }, { adns_r_none, 0 } }; const struct typename *tnp; for (tnp=typenames; tnp->type && strcmp(arg,tnp->desc); tnp++); if (!tnp->type) usageerr("unknown RR type %s",arg); ov_type= tnp->type; } static void process_optarg(const char *arg, const char *const **argv_p, const char *value) { const struct optioninfo *oip; const char *arg2; int invert; if (arg[0] == '-' || arg[0] == '+') { if (arg[0] == '-' && arg[1] == '-') { if (!strncmp(arg,"--no-",5)) { invert= 1; oip= opt_findl(arg+5); } else { invert= 0; oip= opt_findl(arg+2); } if (oip->type == ot_funcarg) { arg= argv_p ? *++(*argv_p) : value; if (!arg) usageerr("option --%s requires a value argument",oip->lopt); arg2= 0; } else if (oip->type == ot_funcarg2) { assert(argv_p); arg= *++(*argv_p); arg2= arg ? *++(*argv_p) : 0; if (!arg || !arg2) usageerr("option --%s requires two more arguments", oip->lopt); } else { if (value) usageerr("option --%s does not take a value",oip->lopt); arg= 0; arg2= 0; } opt_do(oip,invert,arg,arg2); } else if (arg[0] == '-' && arg[1] == 0) { arg= argv_p ? *++(*argv_p) : value; if (!arg) usageerr("option `-' must be followed by a domain"); query_do(arg); } else { /* arg[1] != '-', != '\0' */ invert= (arg[0] == '+'); ++arg; while (*arg) { oip= opt_finds(&arg); if (oip->type == ot_funcarg) { if (!*arg) { arg= argv_p ? *++(*argv_p) : value; if (!arg) usageerr("option -%s requires a value argument",oip->sopt); } else { if (value) usageerr("two values for option -%s given !",oip->sopt); } opt_do(oip,invert,arg,0); arg= ""; } else { if (value) usageerr("option -%s does not take a value",oip->sopt); opt_do(oip,invert,0,0); } } } } else { /* arg[0] != '-' */ query_do(arg); } } static void read_stdin(void) { int anydone, r; char *newline, *space; anydone= 0; while (!anydone || used) { while (!(newline= memchr(buf,'\n',used))) { if (used == avail) { avail += 20; avail <<= 1; buf= realloc(buf,avail); if (!buf) sysfail("realloc stdin buffer",errno); } do { r= read(0,buf+used,avail-used); } while (r < 0 && errno == EINTR); if (r == 0) { if (used) { /* fake up final newline */ buf[used++]= '\n'; r= 1; } else { ov_pipe= 0; return; } } if (r < 0) sysfail("read stdin",errno); used += r; } *newline++= 0; space= strchr(buf,' '); if (space) *space++= 0; process_optarg(buf,0,space); used -= (newline-buf); memmove(buf,newline,used); anydone= 1; } } int main(int argc, const char *const *argv) { struct timeval *tv, tvbuf; adns_query qu; void *qun_v; adns_answer *answer; int r, maxfd; fd_set readfds, writefds, exceptfds; const char *arg; while ((arg= *++argv)) process_optarg(arg,&argv,0); if (!ov_pipe && !ads) usageerr("no domains given, and -f/--pipe not used; try --help"); ensure_adns_init(); for (;;) { for (;;) { qu= ov_asynch ? 0 : outstanding.head ? outstanding.head->qu : 0; r= adns_check(ads,&qu,&answer,&qun_v); if (r == EAGAIN) break; if (r == ESRCH) { if (!ov_pipe) goto x_quit; else break; } assert(!r); query_done(qun_v,answer); } maxfd= 0; FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); if (ov_pipe) { maxfd= 1; FD_SET(0,&readfds); } tv= 0; adns_beforeselect(ads, &maxfd, &readfds,&writefds,&exceptfds, &tv,&tvbuf,0); r= select(maxfd, &readfds,&writefds,&exceptfds, tv); if (r == -1) { if (errno == EINTR) continue; sysfail("select",errno); } adns_afterselect(ads, maxfd, &readfds,&writefds,&exceptfds, 0); if (ov_pipe && FD_ISSET(0,&readfds)) read_stdin(); } x_quit: if (fclose(stdout)) outerr(); quitnow(rcode); } lyskom-server-2.1.2/src/libraries/adns/client/adh-opts.c0000664000015100472110000003132207705611223016652 /* * adh-opts.c * - useful general-purpose resolver client program * option handling tables etc. */ /* * This file is * Copyright (C) 1997-2000 Ian Jackson * * It is part of adns, which is * Copyright (C) 1997-2000 Ian Jackson * Copyright (C) 1999-2000 Tony Finch * * 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 2, 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, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "adnshost.h" int ov_env=1, ov_pipe=0, ov_asynch=0; int ov_verbose= 0; adns_rrtype ov_type= adns_r_none; int ov_search=0, ov_qc_query=0, ov_qc_anshost=0, ov_qc_cname=1; int ov_tcp=0, ov_cname=0, ov_format=fmt_default; char *ov_id= 0; struct perqueryflags_remember ov_pqfr = { 1,1,1, tm_none }; static const struct optioninfo global_options[]= { { ot_desconly, "global binary options:" }, { ot_flag, "Do not look at environment variables at all", "e", "env", &ov_env, 0 }, { ot_flag, "Read queries on stdin instead of using args", "f", "pipe", &ov_pipe, 1 }, { ot_flag, "Allow answers to be reordered", "a", "asynch", &ov_asynch, 1 }, { ot_desconly, "answer/error output format and destination (see below):" }, { ot_value, "Answers to stdout, errors as messages to stderr (default)", "Fs", "fmt-simple", &ov_format, fmt_simple }, { ot_value, "Answers and errors both to stdout in parseable format", "Fi", "fmt-inline", &ov_format, fmt_inline }, { ot_value, "Fully-parseable output format (default for --asynch)", "Fa", "fmt-asynch", &ov_format, fmt_asynch }, { ot_desconly, "global verbosity level:" }, { ot_value, "Do not print anything to stderr", "Vq", "quiet", &ov_verbose, adns_if_noerrprint }, { ot_value, "Report unexpected kinds of problem only (default)", "Vn", "no-quiet", &ov_verbose, 0 }, { ot_value, "Debugging mode", "Vd", "debug", &ov_verbose, adns_if_debug }, { ot_desconly, "other global options:" }, { ot_funcarg, "Configuration to use instead of /etc/resolv.conf", 0, "config", 0,0, of_config, "" }, { ot_func, "Print version number", 0, "version", 0,0, of_version }, { ot_func, "Print usage information", 0, "help", 0,0, of_help }, { ot_end } }; static const struct optioninfo perquery_options[]= { { ot_desconly, "per-query options:" }, { ot_funcarg, "Query type (see below)", "t", "type", 0,0, &of_type, "type" }, { ot_funcarg, "Do reverse query (address -> name lookup)", "i", "ptr", 0,0, &of_ptr, "addr" }, { ot_funcarg2, "Lookup in in-addr-like `zone' (eg MAPS RBL)", 0, "reverse", 0,0, &of_reverse, "addr","zone" }, { ot_desconly, "per-query binary options:" }, { ot_flag, "Use the search list", "s", "search", &ov_search, 1 }, { ot_flag, "Let query domains contain quote-requiring chars", "Qq", "qc-query", &ov_qc_query, 1 }, { ot_flag, "Let hostnames in answers contain ...", "Qa", "qc-anshost", &ov_qc_anshost, 1 }, { ot_flag, "Prevent CNAME target domains from containing ...", "Qc", "qc-cname", &ov_qc_cname, 0 }, { ot_flag, "Force use of a virtual circuit", "u", "tcp", &ov_tcp, 1 }, { ot_flag, "Do not display owner name in output", "Do", "show-owner", &ov_pqfr.show_owner, 0 }, { ot_flag, "Do not display RR type in output", "Dt", "show-type", &ov_pqfr.show_type, 0 }, { ot_flag, "Do not display CNAME target in output", "Dc", "show-cname", &ov_pqfr.show_cname, 0 }, { ot_desconly, "per-query TTL mode (NB TTL is minimum across all info in reply):" }, { ot_value, "Show the TTL as a TTL", "Tt", "ttl-ttl", &ov_pqfr.ttl, tm_rel }, { ot_value, "Show the TTL as a time_t when the data might expire", "Ta", "ttl-abs", &ov_pqfr.ttl, tm_abs }, { ot_value, "Do not show the TTL (default)", "Tn", "no-ttl", &ov_pqfr.ttl, tm_none }, { ot_desconly, "per-query CNAME handling mode:" }, { ot_value, "Call it an error if a CNAME is found", "Cf", "cname-reject", &ov_cname, adns_qf_cname_forbid }, { ot_value, "Allow references to CNAMEs in other RRs", "Cl", "cname-loose", &ov_cname, adns_qf_cname_loose }, { ot_value, "CNAME ok for query domain, but not in RRs (default)", "Cs", "cname-ok", &ov_cname, 0 }, { ot_desconly, "asynchronous/pipe mode options:" }, { ot_funcarg, "Set , default is decimal sequence starting 0", 0, "asynch-id", 0,0, &of_asynch_id, "id" }, { ot_funcarg, "Cancel the query with id (no error if not found)", 0, "cancel-id", 0,0, &of_cancel_id, "id" }, { ot_end } }; static void printusage(void) { static const struct optioninfo *const all_optiontables[]= { global_options, perquery_options, 0 }; const struct optioninfo *const *oiap, *oip=0; int maxsopt, maxlopt, l; maxsopt= maxlopt= 0; for (oiap=all_optiontables; *oiap; oiap++) { for (oip=*oiap; oip->type != ot_end; oip++) { if (oip->type == ot_funcarg) continue; if (oip->sopt) { l= strlen(oip->sopt); if (l>maxsopt) maxsopt= l; } if (oip->lopt) { l= strlen(oip->lopt); if (oip->type == ot_flag && !oip->value) l+= 3; if (l>maxlopt) maxlopt= l; } } } fputs("usage: adnshost [global-opts] [query-opts] query-domain\n" " [[query-opts] query-domain ...]\n" " adnshost [global-opts] [query-opts] -f|--pipe\n", stdout); for (oiap=all_optiontables; *oiap; oiap++) { putchar('\n'); for (oip=*oiap; oip->type != ot_end; oip++) { switch (oip->type) { case ot_flag: if (!oip->value) { if (oip->sopt) { printf(" +%-*s --no-%-*s %s\n", maxsopt, oip->sopt, maxlopt-2, oip->lopt, oip->desc); } else { printf(" --no-%-*s %s\n", maxlopt+maxsopt+1, oip->lopt, oip->desc); } break; } case ot_value: case ot_func: /* fall through */ if (oip->sopt) { printf(" -%-*s --%-*s %s\n", maxsopt, oip->sopt, maxlopt+1, oip->lopt, oip->desc); } else { printf(" --%-*s %s\n", maxlopt+maxsopt+3, oip->lopt, oip->desc); } break; case ot_funcarg: if (oip->sopt) { l= (maxlopt + maxsopt - 9 - (strlen(oip->sopt) + strlen(oip->lopt) + 2*strlen(oip->argdesc))); printf(" -%s<%s> / --%s <%s>%*s%s\n", oip->sopt, oip->argdesc, oip->lopt, oip->argdesc, l>2 ? l : 2, "", oip->desc); } else { l= (maxlopt + maxsopt + 1 - (strlen(oip->lopt) + strlen(oip->argdesc))); printf(" --%s <%s>%*s%s\n", oip->lopt, oip->argdesc, l>2 ? l : 2, "", oip->desc); } break; case ot_funcarg2: assert(!oip->sopt); l= (maxlopt + maxsopt - 2 - (strlen(oip->lopt) + strlen(oip->argdesc) + strlen(oip->argdesc2))); printf(" --%s <%s> <%s>%*s%s\n", oip->lopt, oip->argdesc, oip->argdesc2, l>2 ? l : 2, "", oip->desc); break; case ot_desconly: printf("%s\n", oip->desc); break; default: abort(); } } } printf("\nEscaping domains which might start with `-':\n" " - %-*s Next argument is a domain, but more options may follow\n", maxlopt+maxsopt+3, ""); fputs("\n" "Query domains should always be quoted according to master file format.\n" "\n" "For binary options, --FOO and --no-FOO are opposites, as are\n" "-X and +X. In each case the default is the one not listed.\n" "Per query options stay set a particular way until they are reset,\n" "whether they appear on the command line or on stdin.\n" "All global options must preceed the first query domain.\n" "\n" "With -f, the input should be lines with either an option, possibly\n" "with a value argument (separated from the option by a space if it's a long\n" "option), or a domain (possibly preceded by a hyphen and a space to\n" "distinguish it from an option).\n" "\n" "Output format is master file format without class or TTL by default:\n" " [] [] [] \n" "or if the domain refers to a CNAME and --show-cname is on\n" " [] [] CNAME \n" " [] [] \n" "When a query fails you get an error message to stderr (with --fmt-simple).\n" "Specify --fmt-inline for lines like this (broken here for readability):\n" " ; failed \\\n" " [] [] [] \"\"\n" "If you use --fmt-asynch, which is the default for --asynch,\n" "each answer (success or failure) is preceded by a line\n" " \\\n" " [] [] [] \"\"\n" "where is the number of RRs that follow and will be `$' or\n" "the CNAME target; the CNAME indirection and error formats above are not used.\n" "\n" "Exit status:\n" " 0 all went well\n" " 1-6 at least one query failed with statustype:\n" " 1 localfail )\n" " 2 remotefail ) temporary errors\n" " 3 tempfail __)_________________\n" " 4 misconfig )\n" " 5 misquery ) permanent errors\n" " 6 permfail )\n" " 10 system trouble\n" " 11 usage problems\n" "\n" "Query types (see adns.h; default is addr):\n" " ns soa ptr mx rp addr - enhanced versions\n" " cname hinfo txt - types with only one version\n" " a ns- soa- ptr- mx- rp- - _raw versions\n" "Default is addr, or ptr for -i/--ptr queries\n", stdout); if (ferror(stdout)) sysfail("write usage message",errno); } void of_version(const struct optioninfo *oi, const char *arg, const char *arg2) { VERSION_PRINT_QUIT("adnshost"); } void of_help(const struct optioninfo *oi, const char *arg, const char *arg2) { printusage(); if (fclose(stdout)) sysfail("finish writing output",errno); quitnow(0); } typedef int comparer_type(const char **optp, const struct optioninfo *entry); static int oc_long(const char **optp, const struct optioninfo *entry) { return entry->lopt && !strcmp(*optp,entry->lopt); } static int oc_short(const char **optp, const struct optioninfo *entry) { const char *sopt; int l; sopt= entry->sopt; if (!sopt) return 0; l= strlen(sopt); if (memcmp(*optp,sopt,l)) return 0; (*optp) += l; return 1; } static const struct optioninfo *find1(const char **optp, const struct optioninfo *table, comparer_type *comparer) { for (;;) { if (table->type == ot_end) return 0; if (comparer(optp,table)) return table; table++; } } static const struct optioninfo *find(const char **optp, const char *prefix, comparer_type *comparer) { const struct optioninfo *oip; const char *opt; opt= *optp; oip= find1(optp,perquery_options,comparer); if (oip) return oip; oip= find1(optp,global_options,comparer); if (!oip) usageerr("unknown option %s%s",prefix,opt); if (ads) usageerr("global option %s%s specified after query domain(s)",prefix,opt); return oip; } const struct optioninfo *opt_findl(const char *opt) { return find(&opt,"--",oc_long); } const struct optioninfo *opt_finds(const char **optp) { return find(optp,"-",oc_short); } static void noninvert(const struct optioninfo *oip) NONRETURNING; static void noninvert(const struct optioninfo *oip) { usageerr("option %s%s%s%s%s may not be inverted", oip->sopt ? "-" : "", oip->sopt ? oip->sopt : "", oip->lopt && oip->sopt ? " / " : "", oip->lopt ? "--" : "", oip->lopt ? oip->lopt : ""); } void opt_do(const struct optioninfo *oip, int invert, const char *arg, const char *arg2) { switch (oip->type) { case ot_flag: assert(!arg); *oip->storep= !invert; return; case ot_value: assert(!arg); if (invert) noninvert(oip); *oip->storep= oip->value; return; case ot_func: case ot_funcarg: case ot_funcarg2: if (invert) noninvert(oip); oip->func(oip,arg,arg2); return; default: abort(); } } lyskom-server-2.1.2/src/libraries/adns/client/adh-query.c0000664000015100472110000002105107707157057017044 /* * adh-query.c * - useful general-purpose resolver client program * make queries and print answers */ /* * This file is * Copyright (C) 1997-2000 Ian Jackson * * It is part of adns, which is * Copyright (C) 1997-2000 Ian Jackson * Copyright (C) 1999-2000 Tony Finch * * 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 2, 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, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "adnshost.h" adns_state ads; struct outstanding_list outstanding; static unsigned long idcounter; void ensure_adns_init(void) { adns_initflags initflags; int r; if (ads) return; if (signal(SIGPIPE,SIG_IGN) == SIG_ERR) sysfail("ignore SIGPIPE",errno); initflags= adns_if_noautosys|adns_if_nosigpipe|ov_verbose; if (!ov_env) initflags |= adns_if_noenv; if (config_text) { r= adns_init_strcfg(&ads, initflags, stderr, config_text); } else { r= adns_init(&ads, initflags, 0); } if (r) sysfail("adns_init",r); if (ov_format == fmt_default) ov_format= ov_asynch ? fmt_asynch : fmt_simple; } static void prep_query(struct query_node **qun_r, int *quflags_r) { struct query_node *qun; char idbuf[20]; if (ov_pipe && !ads) usageerr("-f/--pipe not consistent with domains on command line"); ensure_adns_init(); qun= malloc(sizeof(*qun)); qun->pqfr= ov_pqfr; if (ov_id) { qun->id= xstrsave(ov_id); } else { sprintf(idbuf,"%lu",idcounter++); idcounter &= 0x0fffffffflu; qun->id= xstrsave(idbuf); } *quflags_r= (ov_search ? adns_qf_search : 0) | (ov_tcp ? adns_qf_usevc : 0) | ((ov_pqfr.show_owner || ov_format == fmt_simple) ? adns_qf_owner : 0) | (ov_qc_query ? adns_qf_quoteok_query : 0) | (ov_qc_anshost ? adns_qf_quoteok_anshost : 0) | (ov_qc_cname ? 0 : adns_qf_quoteok_cname) | ov_cname, *qun_r= qun; } void of_ptr(const struct optioninfo *oi, const char *arg, const char *arg2) { struct query_node *qun; int quflags, r; struct sockaddr_in sa; memset(&sa,0,sizeof(sa)); sa.sin_family= AF_INET; if (!inet_aton(arg,&sa.sin_addr)) usageerr("invalid IP address %s",arg); prep_query(&qun,&quflags); qun->owner= xstrsave(arg); r= adns_submit_reverse(ads, (struct sockaddr*)&sa, ov_type == adns_r_none ? adns_r_ptr : ov_type, quflags, qun, &qun->qu); if (r) sysfail("adns_submit_reverse",r); ADNS_LIST_LINK_TAIL(outstanding,qun); } void of_reverse(const struct optioninfo *oi, const char *arg, const char *arg2) { struct query_node *qun; int quflags, r; struct sockaddr_in sa; memset(&sa,0,sizeof(sa)); sa.sin_family= AF_INET; if (!inet_aton(arg,&sa.sin_addr)) usageerr("invalid IP address %s",arg); prep_query(&qun,&quflags); qun->owner= xmalloc(strlen(arg) + strlen(arg2) + 2); sprintf(qun->owner, "%s %s", arg,arg2); r= adns_submit_reverse_any(ads, (struct sockaddr*)&sa, arg2, ov_type == adns_r_none ? adns_r_txt : ov_type, quflags, qun, &qun->qu); if (r) sysfail("adns_submit_reverse",r); ADNS_LIST_LINK_TAIL(outstanding,qun); } void query_do(const char *domain) { struct query_node *qun; int quflags, r; prep_query(&qun,&quflags); qun->owner= xstrsave(domain); r= adns_submit(ads, domain, ov_type == adns_r_none ? adns_r_addr : ov_type, quflags, qun, &qun->qu); if (r) sysfail("adns_submit",r); ADNS_LIST_LINK_TAIL(outstanding,qun); } static void dequeue_query(struct query_node *qun) { ADNS_LIST_UNLINK(outstanding,qun); free(qun->id); free(qun->owner); free(qun); } static void print_withspace(const char *str) { if (printf("%s ", str) == EOF) outerr(); } static void print_ttl(struct query_node *qun, adns_answer *answer) { unsigned long ttl; time_t now; switch (qun->pqfr.ttl) { case tm_none: return; case tm_rel: if (time(&now) == (time_t)-1) sysfail("get current time",errno); ttl= answer->expires < now ? 0 : answer->expires - now; break; case tm_abs: ttl= answer->expires; break; default: abort(); } if (printf("%lu ",ttl) == EOF) outerr(); } static const char *owner_show(struct query_node *qun, adns_answer *answer) { return answer->owner ? answer->owner : qun->owner; } static void print_owner_ttl(struct query_node *qun, adns_answer *answer) { if (qun->pqfr.show_owner) print_withspace(owner_show(qun,answer)); print_ttl(qun,answer); } static void check_status(adns_status st) { static const adns_status statuspoints[]= { adns_s_ok, adns_s_max_localfail, adns_s_max_remotefail, adns_s_max_tempfail, adns_s_max_misconfig, adns_s_max_misquery }; const adns_status *spp; int minrcode; for (minrcode=0, spp=statuspoints; spp < statuspoints + (sizeof(statuspoints)/sizeof(statuspoints[0])); spp++) if (st > *spp) minrcode++; if (rcode < minrcode) rcode= minrcode; } static void print_status(adns_status st, struct query_node *qun, adns_answer *answer) { const char *statustypeabbrev, *statusabbrev, *statusstring; statustypeabbrev= adns_errtypeabbrev(st); statusabbrev= adns_errabbrev(st); statusstring= adns_strerror(st); assert(!strchr(statusstring,'"')); if (printf("%s %d %s ", statustypeabbrev, st, statusabbrev) == EOF) outerr(); print_owner_ttl(qun,answer); if (qun->pqfr.show_cname) print_withspace(answer->cname ? answer->cname : "$"); if (printf("\"%s\"\n", statusstring) == EOF) outerr(); } static void print_dnsfail(adns_status st, struct query_node *qun, adns_answer *answer) { int r; const char *typename, *statusstring; adns_status ist; if (ov_format == fmt_inline) { if (fputs("; failed ",stdout) == EOF) outerr(); print_status(st,qun,answer); return; } assert(ov_format == fmt_simple); if (st == adns_s_nxdomain) { r= fprintf(stderr,"%s does not exist\n", owner_show(qun,answer)); } else { ist= adns_rr_info(answer->type, &typename, 0,0,0,0); if (st == adns_s_nodata) { r= fprintf(stderr,"%s has no %s record\n", owner_show(qun,answer), typename); } else { statusstring= adns_strerror(st); r= fprintf(stderr,"Error during DNS %s lookup for %s: %s\n", typename, owner_show(qun,answer), statusstring); } } if (r == EOF) sysfail("write error message to stderr",errno); } void query_done(struct query_node *qun, adns_answer *answer) { adns_status st, ist; int rrn, nrrs; const char *rrp, *realowner, *typename; char *datastr; st= answer->status; nrrs= answer->nrrs; if (ov_format == fmt_asynch) { check_status(st); if (printf("%s %d ", qun->id, nrrs) == EOF) outerr(); print_status(st,qun,answer); } else { if (qun->pqfr.show_cname && answer->cname) { print_owner_ttl(qun,answer); if (qun->pqfr.show_type) print_withspace("CNAME"); if (printf("%s\n", answer->cname) == EOF) outerr(); } if (st) { check_status(st); print_dnsfail(st,qun,answer); } } if (qun->pqfr.show_owner) { realowner= answer->cname ? answer->cname : owner_show(qun,answer); assert(realowner); } else { realowner= 0; } if (nrrs) { for (rrn=0, rrp = answer->rrs.untyped; rrn < nrrs; rrn++, rrp += answer->rrsz) { if (realowner) print_withspace(realowner); print_ttl(qun,answer); ist= adns_rr_info(answer->type, &typename, 0, 0, rrp, &datastr); if (ist == adns_s_nomemory) sysfail("adns_rr_info failed",ENOMEM); assert(!ist); if (qun->pqfr.show_type) print_withspace(typename); if (printf("%s\n",datastr) == EOF) outerr(); free(datastr); } } if (fflush(stdout)) outerr(); free(answer); dequeue_query(qun); } void of_asynch_id(const struct optioninfo *oi, const char *arg, const char *arg2) { free(ov_id); ov_id= xstrsave(arg); } void of_cancel_id(const struct optioninfo *oi, const char *arg, const char *arg2) { struct query_node *qun; for (qun= outstanding.head; qun && strcmp(qun->id,arg); qun= qun->next); if (!qun) return; adns_cancel(qun->qu); dequeue_query(qun); } lyskom-server-2.1.2/src/libraries/adns/client/adnshost.h0000664000015100472110000000666107705611223016773 /* * adnshost.h * - useful general-purpose resolver client program, header file */ /* * This file is * Copyright (C) 1997-2000 Ian Jackson * * It is part of adns, which is * Copyright (C) 1997-2000 Ian Jackson * Copyright (C) 1999-2000 Tony Finch * * 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 2, 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, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef ADNSHOST_H_INCLUDED #define ADNSHOST_H_INCLUDED #include #include #include #include #include #include #include #include #include #include #include #include #include #include "config.h" #include "adns.h" #include "dlist.h" #include "client.h" #ifdef ADNS_REGRESS_TEST # include "hredirect.h" #endif /* declarations related to option processing */ struct optioninfo; typedef void optfunc(const struct optioninfo *oi, const char *arg, const char *arg2); struct optioninfo { enum oi_type { ot_end, ot_desconly, ot_flag, ot_value, ot_func, ot_funcarg, ot_funcarg2 } type; const char *desc; const char *sopt, *lopt; int *storep, value; optfunc *func; const char *argdesc, *argdesc2; }; enum ttlmode { tm_none, tm_rel, tm_abs }; enum outputformat { fmt_default, fmt_simple, fmt_inline, fmt_asynch }; struct perqueryflags_remember { int show_owner, show_type, show_cname; int ttl; }; extern int ov_env, ov_pipe, ov_asynch; extern int ov_verbose; extern adns_rrtype ov_type; extern int ov_search, ov_qc_query, ov_qc_anshost, ov_qc_cname; extern int ov_tcp, ov_cname, ov_format; extern char *ov_id; extern struct perqueryflags_remember ov_pqfr; extern optfunc of_config, of_version, of_help, of_type, of_ptr, of_reverse; extern optfunc of_asynch_id, of_cancel_id; const struct optioninfo *opt_findl(const char *opt); const struct optioninfo *opt_finds(const char **optp); void opt_do(const struct optioninfo *oip, int invert, const char *arg, const char *arg2); /* declarations related to query processing */ struct query_node { struct query_node *next, *back; struct perqueryflags_remember pqfr; char *id, *owner; adns_query qu; }; extern adns_state ads; extern struct outstanding_list { struct query_node *head, *tail; } outstanding; void ensure_adns_init(void); void query_do(const char *domain); void query_done(struct query_node *qun, adns_answer *answer); /* declarations related to main program and useful utility functions */ void sysfail(const char *what, int errnoval) NONRETURNING; void usageerr(const char *what, ...) NONRETURNPRINTFFORMAT(1,2); void outerr(void) NONRETURNING; void *xmalloc(size_t sz); char *xstrsave(const char *str); extern int rcode; extern const char *config_text; /* 0 => use defaults */ #endif lyskom-server-2.1.2/src/libraries/adns/client/client.h0000664000015100472110000000400307705611223016412 /* * clients.h * - useful declarations and definitions for adns client programs */ /* * This file is * Copyright (C) 1997-2000 Ian Jackson * * It is part of adns, which is * Copyright (C) 1997-2000 Ian Jackson * Copyright (C) 1999-2000 Tony Finch * * 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 2, 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, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef CLIENT_H_INCLUDED #define CLIENT_H_INCLUDED #define ADNS_VERSION_STRING "1.0" #define COPYRIGHT_MESSAGE \ "Copyright (C) 1997-2000 Ian Jackson \n" \ "Copyright (C) 1999-2000 Tony Finch \n" \ "This is free software; see the source for copying conditions. There is NO\n" \ "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" #define VERSION_MESSAGE(program) \ program " (GNU adns) " ADNS_VERSION_STRING "\n\n" COPYRIGHT_MESSAGE #define VERSION_PRINT_QUIT(program) \ if (fputs(VERSION_MESSAGE(program),stdout) == EOF || \ fclose(stdout)) { \ perror(program ": write version message"); \ quitnow(-1); \ } \ quitnow(0); void quitnow(int rc) NONRETURNING; #endif lyskom-server-2.1.2/src/libraries/adns/client/.cvsignore0000664000015100472110000000021507714276235016776 .deps Makefile Makefile.in adnshost adnshost_s adnslogres adnslogres_s adnsresfilter adnsresfilter_s adnstest adnstest_s fanftest fanftest_s lyskom-server-2.1.2/src/libraries/liboop/0000777000015100472110000000000007723710306014133 5lyskom-server-2.1.2/src/libraries/liboop/README0000664000015100472110000000024207703102734014725 This directory contains liboop-0.9, with a few modifications so that it fits in the lyskom-server environment. All changes are documented in ../../../ChangeLog. lyskom-server-2.1.2/src/libraries/liboop/oop.h0000664000015100472110000000762507704236614015035 /* oop.h, liboop, copyright 1999 Dan Egnor This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License, version 2.1 or later. See the file COPYING for details. */ #ifndef OOP_H #define OOP_H #include #include #include /* ------------------------------------------------------------------------- */ typedef struct oop_source oop_source; /* File descriptor action types */ typedef enum { OOP_READ, OOP_WRITE, OOP_EXCEPTION, OOP_NUM_EVENTS } oop_event; /* Pass this to on_time to schedule an event immediately */ static const struct timeval OOP_TIME_NOW = { 0, 0 }; /* Maximum signal number. (The OS may have a stricter limit!) */ #define OOP_NUM_SIGNALS 256 /* Callbacks may return one of these */ extern int _oop_continue,_oop_error; /* internal only */ #define OOP_CONTINUE ((void *) &_oop_continue) #define OOP_ERROR ((void *) &_oop_error) #define OOP_HALT ((void *) NULL) /* (or any other value besides OOP_CONTINUE) */ /* Callback function prototypes */ typedef void *oop_call_fd(oop_source *,int fd,oop_event,void *); typedef void *oop_call_time(oop_source *,struct timeval,void *); typedef void *oop_call_signal(oop_source *,int sig,void *); struct oop_source { void (*on_fd)(oop_source *,int fd,oop_event,oop_call_fd *,void *); void (*cancel_fd)(oop_source *,int fd,oop_event); void (*on_time)(oop_source *,struct timeval,oop_call_time *,void *); void (*cancel_time)(oop_source *,struct timeval,oop_call_time *,void *); void (*on_signal)(oop_source *,int sig,oop_call_signal *,void *); void (*cancel_signal)(oop_source *,int sig,oop_call_signal *,void *); }; /* ------------------------------------------------------------------------- */ /* For recommended use by oop components. */ extern void *(*oop_malloc)(size_t); extern void *(*oop_realloc)(void *,size_t); extern void (*oop_free)(void *); /* ------------------------------------------------------------------------- */ /* System event source. */ typedef struct oop_source_sys oop_source_sys; /* Create a system event source. Returns NULL on failure. */ oop_source_sys *oop_sys_new(void); /* Process events until either of the following two conditions: 1 -- some callback returns anything but OOP_CONTINUE; will return the value in question. 2 -- no callbacks are registered; will return OOP_CONTINUE. 3 -- an error occurs; will return OOP_ERROR (check errno). */ void *oop_sys_run(oop_source_sys *); /* Delete a system event source. No callbacks may be registered. */ void oop_sys_delete(oop_source_sys *); /* Get the event registration interface for a system event source. */ oop_source *oop_sys_source(oop_source_sys *); /* Set SA_RESTART in the sa_flags field of struct sigaction, so that syscalls are restarted. This is a global setting, and the function must be called before the first signal handler is registered. There is no way to undo the setting. */ void oop_sys_use_sa_restart(void); /* ------------------------------------------------------------------------- */ /* Helper for select-style asynchronous interfaces. */ typedef struct oop_adapter_select oop_adapter_select; typedef void *oop_call_select( oop_adapter_select *, int num,fd_set *r,fd_set *w,fd_set *x, struct timeval now,void *); oop_adapter_select *oop_select_new( oop_source *, oop_call_select *, void *); void oop_select_set( oop_adapter_select *,int num_fd, fd_set *rfd,fd_set *wfd,fd_set *xfd,struct timeval *timeout); void oop_select_delete(oop_adapter_select *); /* ------------------------------------------------------------------------- */ /* Helper for event sources without signal handling. */ typedef struct oop_adapter_signal oop_adapter_signal; oop_adapter_signal *oop_signal_new(oop_source *); void oop_signal_delete(oop_adapter_signal *); oop_source *oop_signal_source(oop_adapter_signal *); void oop_signal_use_sa_restart(void); #endif lyskom-server-2.1.2/src/libraries/liboop/oop-adns.h0000664000015100472110000000252307714123666015753 /* oop-adns.h, liboop, copyright 1999 Dan Egnor This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License, version 2.1 or later. See the file COPYING for details. */ #ifndef OOP_ADNS_H #define OOP_ADNS_H #ifndef ADNS_H_INCLUDED #error You must include "adns.h" before "oop-adns.h"! #endif #include "oop.h" typedef struct oop_adapter_adns oop_adapter_adns; typedef struct oop_adns_query oop_adns_query; typedef void *oop_adns_call(oop_adapter_adns *,adns_answer *,void *); /* A liboop adns adapter creates an adns instance tied to a liboop source. oop_adns_new() returns NULL on failure.*/ oop_adapter_adns *oop_adns_new(oop_source *,adns_initflags,FILE *diag); void oop_adns_delete(oop_adapter_adns *); /* Submit an asynchronous DNS query. Returns NULL on system failure. The returned pointer is valid until the callback occurs or the query is cancelled (see below). */ oop_adns_query *oop_adns_submit( oop_adapter_adns *,int *errcode, const char *owner,adns_rrtype type,adns_queryflags flags, oop_adns_call *,void *); oop_adns_query *oop_adns_submit_reverse( oop_adapter_adns *,int *errcode, const struct sockaddr *addr,adns_rrtype type,adns_queryflags flags, oop_adns_call *,void *); /* Cancel a running query. */ void oop_adns_cancel(oop_adns_query *); #endif lyskom-server-2.1.2/src/libraries/liboop/oop-glib.h0000664000015100472110000000124507703073503015733 /* oop-glib.h, liboop, copyright 1999 Dan Egnor This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License, version 2.1 or later. See the file COPYING for details. */ #ifndef OOP_GLIB_H #define OOP_GLIB_H #ifndef __G_LIB_H__ #error You must include "glib.h" before "oop-glib.h"! #endif #include "oop.h" /* Create an event source based on the GLib event loop. */ oop_source *oop_glib_new(void); /* Delete the event source so created. (Uses reference counting.) */ void oop_glib_delete(void); /* Get the value used to terminate the event loop (e.g. OOP_HALT). */ void *oop_glib_return(void); #endif lyskom-server-2.1.2/src/libraries/liboop/oop-tcl.h0000664000015100472110000000075007703073503015600 /* oop-glib.h, liboop, copyright 1999 Dan Egnor This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License, version 2.1 or later. See the file COPYING for details. */ #ifndef OOP_TCL_H #define OOP_TCL_H #include "oop.h" /* Create an event source based on the Tcl event loop. */ oop_source *oop_tcl_new(void); /* Delete the event source so created. (Uses reference counting.) */ void oop_tcl_done(void); #endif lyskom-server-2.1.2/src/libraries/liboop/oop-www.h0000664000015100472110000000156007703073503015642 /* oop-www.h, liboop, copyright 1999 Dan Egnor This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License, version 2.1 or later. See the file COPYING for details. */ #ifndef OOP_WWW_H #define OOP_WWW_H #ifndef HTEVENT_H #error You must include "HTEvent.h" before "oop-www.h"! #endif #include "oop.h" /* Register an event manager with libwww to get events from a liboop source. Because libwww's event loop is global, so is ours. */ void oop_www_register(oop_source *); /* Release any resources associated with the event manager, and unregister it with libwww. This will leave libwww with no event manager. */ void oop_www_cancel(void); /* Use libwww's memory management for liboop. ** If you use this, you must do so before any other liboop function! ** */ void oop_www_memory(void); #endif lyskom-server-2.1.2/src/libraries/liboop/oop-rl.h0000664000015100472110000000116407703073503015433 /* oop-rl.h, liboop, copyright 2000 Dan Egnor This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License, version 2.1 or later. See the file COPYING for details. */ #ifndef OOP_READLINE_H #define OOP_READLINE_H #include "oop.h" /* Use a liboop event source to call rl_callback_read_char(). It is up to you to call rl_callback_handler_install(). Note well that readline uses malloc(), not oop_malloc(). */ void oop_readline_register(oop_source *); /* Stop notifying readline of input characters. */ void oop_readline_cancel(oop_source *); #endif lyskom-server-2.1.2/src/libraries/liboop/oop-read.h0000664000015100472110000002412107703073503015727 /* oop-read.h, liboop, copyright 2000 Ian Jackson This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License, version 2.1 or later. See the file COPYING for details. */ #ifndef OOP_READ_H #define OOP_READ_H #include "oop.h" /* ------------------------------------------------------------------------- */ /* Generic interface for readable bytestreams */ typedef struct oop_readable oop_readable; typedef void *oop_readable_call(oop_source*, oop_readable*, void*); struct oop_readable { int (*on_readable)(struct oop_readable*, oop_readable_call*, void*); /* Calls back as soon as any data available. Only one on_read can * be set for any oop_readable. */ void (*on_cancel)(struct oop_readable*); ssize_t (*try_read)(struct oop_readable*, void *buffer, size_t length); /* Just like read(2), but never gives EINTR, but may give EAGAIN. * Never cancels, never blocks. */ int (*delete_tidy)(struct oop_readable*); /* resets any things done by _new */ void (*delete_kill)(struct oop_readable*); /* just frees etc.; use eg after fork */ }; /* ------------------------------------------------------------------------- */ /* Interpret an fd as a readable bytestream */ /* simple wrapper around fcntl, oop->on_fd and read() */ oop_readable *oop_readable_fd(oop_source*, int fd); /* side-effect on fd is to make it nonblocking. * delete_tidy resets blocking. */ int oop_fd_nonblock(int fd, int nonblock); /* Utility function. Returns 0 if OK, errno value if it fails. */ /* ------------------------------------------------------------------------- */ /* Interpret a block of memory as a readable bytestream */ /* Is always ready for reading, of course. */ oop_readable *oop_readable_mem(oop_source*, const void *data, size_t length); /* Stores a pointer to data, rather than copying it. */ /* ------------------------------------------------------------------------- */ /* Record-structured `cooked' reading from any readable bytestream */ /* * Input stream is treated as series of records. * * If no delimiter is specified (_DELIM_NONE) then the records are * of fixed size (sz arg to oop_rd_read); otherwise file is sequence of * pairs {record data, delimiter string}. * * Records may end early under some circumstances: * - with _SHORTREC_SOONEST, record boundary always `interpreted' * whereever input would block. Note that streams don't usually * guarantee position of blocking boundaries. Use this with * _DELIM_NONE only if record boundaries are not important. * - with _SHORTREC_EOFONLY or _BUFFULL, at end of file a partial * record is always OK, so missing delimiter at EOF, or short last * fixed-length record, is fine; * - with _SHORTREC_BUFFULL, if the sz is exceeded by the record * length - in this case the record is split in two (or more), the * first (strictly: all but last) of which will be passed to ifok * with no delimiter and event type _RD_BUFFULL, the last with the * delimiter attached (if _DELIM_KEEP) and event _RD_OK. * * If, with delimited records, the delimiter doesn't appear within the * sz, and _BUFFULL or _SOONEST are not specified, then iferr is * called with _RD_BUFFULL. Likewise, if the final record is too * short (for fixed-size records) or missing its delimiter (for * delimited ones) then without _SHORTREC_BUFFULL or * _SHORTREC_EOFONLY, iferr is called with _RD_PARTREC. * * Reading will continue until EOF or an error. ifok may be called * any number of times with data!=0, and then there will be either one * further call to ifok with data==0, or alternatively one call to * iferr. * * You can call _rd_cancel at any point (eg in a callback) to prevent * further calls to your callbacks. * * An oop_read may read ahead as much as it likes in the stream any * time after the first call to _rd_read. This can be prevented by * calling _rd_bufcontrol with a non-0 debuf argument; if called * before the first _rd_read then debuf will not be called, and the * oop_read will not read ahead `unnecessarily' (see below). If * called afterwards, then any buffered data will be presented to the * debuf callback, once, and then matters are as above. If * _rd_bufcontrol is called with 0 for debuf then buffering is * (re)-enabled. * * `unnecessary' readahead: with no delimiter, the readahead will * always be less than the record size (sz argument to _rd_read); with * a delimiter, it will be less than the maximum record size if any * except that we won't read past the end of a read(2) return if the * delimiter is in the returned data. If styles and record sizes are * mixed then the readahead point will of course not go backwards, but * apart from that the most recent style and record size will apply. * * Calling _rd_delete will discard any read ahead data ! * * ifok and iferr may be the same function; the sets of arguments * passed to it then will be unambiguous. * * With _NUL_DISCARD, any null bytes in the input still count against * the maximum record size, even though they are not included in the * record size returned. */ typedef struct oop_read oop_read; typedef enum { /* If you change these, also change eventstrings in read.c */ OOP_RD_OK, OOP_RD_EOF, /* EOF; data==0 */ OOP_RD_PARTREC, /* partial record at EOF; data!=0 */ OOP_RD_LONG, /* too much data before delimiter; data==0 if error */ OOP_RD_NUL, /* nul byte in data, with _NUL_FORBID; data==0 */ OOP_RD_SYSTEM /* system error, look in errnoval, data may be !=0 */ } oop_rd_event; typedef enum { OOP_RD_BUFCTL_QUERY, /* return amount of read-ahead data */ OOP_RD_BUFCTL_ENABLE, /* enable, return 0 */ OOP_RD_BUFCTL_DISABLE,/* disable but keep any already read, return that amt */ OOP_RD_BUFCTL_FLUSH /* disable and discard, return amount discarded */ } oop_rd_bufctl_op; size_t oop_rd_bufctl(oop_read*, oop_rd_bufctl_op op); typedef enum { OOP_RD_DELIM_NONE, /* there is no delimiter specified */ OOP_RD_DELIM_STRIP, /* strip the delimiter */ OOP_RD_DELIM_KEEP /* keep the delimiter */ } oop_rd_delim; typedef enum { OOP_RD_NUL_FORBID, /* bad for general-purpose data files ! */ OOP_RD_NUL_DISCARD, /* bad for general-purpose data files ! */ OOP_RD_NUL_PERMIT } oop_rd_nul; typedef enum { /* record may end early without error if: */ OOP_RD_SHORTREC_FORBID, /* never (both conditions above are an error) */ OOP_RD_SHORTREC_EOF, /* EOF */ OOP_RD_SHORTREC_LONG, /* EOF or record too long */ OOP_RD_SHORTREC_SOONEST /* any data read at all */ } oop_rd_shortrec; typedef struct { oop_rd_delim delim_mode; /* if _DELIM_NONE, delim=='\0', */ char delim; /* otherwise delim must be valid */ oop_rd_nul nul_mode; /* applies to data content, not to any in delim */ oop_rd_shortrec shortrec_mode; } oop_rd_style; typedef void *oop_rd_call(oop_source*, oop_read*, oop_rd_event, const char *errmsg, int errnoval, const char *data, size_t recsz, void*); /* * When called as `ifok': * _result indicates why the record ended early (or OK if it didn't); * data is 0 iff no record was read because EOF * errmsg==0, errnoval==0 * * When called as `iferr': * _result indicates the error (and is not _OK); if it is _SYSTEM * then errmsg is strerror(errnoval), otherwise errmsg is from * library and errnoval is 0. Errors in a record do NOT cause any * data to be discarded, though some may be passed to the iferr call; * if data==0 then calling oop_rd_read again with the same style may * produce the same error again. * * data will always be nul-terminated, may also contain nuls unless * _NUL_FORBID specified. recsz does not include the trailing nul; if * _DELIM_STRIP then it doesn't include the (now-stripped) delimiter, * but if _DELIM_KEEP then if there was a delimiter it is included in * recsz. * * Any data allocated by oop_read, and errmsg if set, is valid only * during this call - you must copy it ! (Also invalidated by * _rd_delete, but not by _rd_cancel.) */ const char *oop_rd_errmsg(oop_read *rd, oop_rd_event event, int errnoval, const oop_rd_style *style); /* style is a hint; it may be NUL. The returned value is valid only * until this event call finishes (as if it had come from * oop_call_rd). Will never return NULL. */ oop_read *oop_rd_new(oop_source*, oop_readable *ra, char *buf, size_t bufsz); /* buf may be 0, in which case a buffer will be allocated internally * (and should then not be touched at all while the oop_read exists). * bufsz is the actual size of buf, or 0 if buf==0. */ void oop_rd_delete(oop_read*); oop_read *oop_rd_new_fd(oop_source*, int fd, char *buf, size_t bufsz); /* Uses oop_readable_fd first. */ int oop_rd_delete_tidy(oop_read*); void oop_rd_delete_kill(oop_read*); /* Also call the delete_tidy or delete_kill methods of the underlying * readable. Make sure to use these if you use oop_rd_new_fd. */ /* predefined styles: DELIM NUL SHORTREC */ extern const oop_rd_style OOP_RD_STYLE_GETLINE[1];/*STRIP \n FORBID ATEOF */ extern const oop_rd_style OOP_RD_STYLE_BLOCK[1]; /* NONE ALLOW FIXED */ extern const oop_rd_style OOP_RD_STYLE_IMMED[1]; /* NONE ALLOW SOONEST */ /* these are all 1-element arrays so you don't have to say &... */ int oop_rd_read(oop_read*, const oop_rd_style *style, size_t maxrecsz, oop_rd_call *ifok, void*, oop_rd_call *iferr, void*); /* The data passed to ifok is only valid for that call to ifok (also * invalidated by _rd_delete, but not by _rd_cancel.). maxrecsz is * the maximum value of recsz which will be passed to ifok or iferr, * or 0 for no limit. * * NB that if a caller-supplied buffer is being used then its size * should be at least 1 larger than maxrecsz; otherwise the value of * maxrecsz actually used will be reduced. * * Errors imply _rd_cancel. * * Only one _rd_read at a time per oop_read. */ void oop_rd_cancel(oop_read*); #endif lyskom-server-2.1.2/src/libraries/liboop/COPYING0000664000015100472110000006347507703073501015120 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! lyskom-server-2.1.2/src/libraries/liboop/INSTALL0000664000015100472110000001722707703073502015111 Basic Installation ================== These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, a file `config.cache' that saves the results of its tests to speed up reconfiguring, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.in' is used to create `configure' by a program called `autoconf'. You only need `configure.in' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. You can give `configure' initial values for variables by setting them in the environment. Using a Bourne-compatible shell, you can do that on the command line like this: CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure Or on systems that have the `env' program, you can do it like this: env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not supports the `VPATH' variable, you have to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PATH'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH', the package will use PATH as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=PATH' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' can not figure out automatically, but needs to determine by the type of host the package will run on. Usually `configure' can figure that out, but if it prints a message saying it can not guess the host type, give it the `--host=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name with three fields: CPU-COMPANY-SYSTEM See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the host type. If you are building compiler tools for cross-compiling, you can also use the `--target=TYPE' option to select the type of system they will produce code for and the `--build=TYPE' option to select the type of system on which you are compiling the package. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Operation Controls ================== `configure' recognizes the following options to control how it operates. `--cache-file=FILE' Use and save the results of the tests in FILE instead of `./config.cache'. Set FILE to `/dev/null' to disable caching, for debugging `configure'. `--help' Print a summary of the options to `configure', and exit. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `--version' Print the version of Autoconf used to generate the `configure' script, and exit. `configure' also accepts some other, not widely useful, options. lyskom-server-2.1.2/src/libraries/liboop/Makefile.am0000664000015100472110000000220707722446224016112 ## Process this file with automake to generate Makefile.in # Makefile.am, liboop, copyright 1999 Dan Egnor # # This is free software; you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License, version 2.1 or later. # See the file COPYING for details. AUTOMAKE_OPTIONS = foreign 1.2 AM_CPPFLAGS = -I$(srcdir)/../adns/src noinst_LIBRARIES = liboop.a INCLUDES = $(GLIB_INCLUDES) $(TCL_INCLUDES) $(WWW_INCLUDES) liboop_a_SOURCES = sys.c select.c signal.c alloc.c read.c read-fd.c \ read-mem.c adns.c noinst_HEADERS = oop.h oop-adns.h oop-glib.h oop-tcl.h oop-www.h oop-rl.h oop-read.h check_PROGRAMS = test-oop test_oop_SOURCES = test-oop.c test_oop_LDADD = liboop.a ../adns/src/libadns.a EXTRA_DIST = .cvsignore release: dist gzip -dc $(PACKAGE)-$(VERSION).tar.gz | bzip2 -9 \ > $(PACKAGE)-$(VERSION).tar.bz2 if test -d /ofb/www/download/liboop ; then \ cd /ofb/www/download/liboop && \ mv "$(shell pwd)/$(PACKAGE)-$(VERSION)".* . && \ ln -sf $(PACKAGE)-$(VERSION).tar.gz $(PACKAGE).tar.gz && \ ln -sf $(PACKAGE)-$(VERSION).tar.bz2 $(PACKAGE).tar.bz2 ; \ fi @echo '** NOW TAG THE CVS REPOSITORY! **' lyskom-server-2.1.2/src/libraries/liboop/Makefile.in0000664000015100472110000004163607723707465016144 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # Makefile.am, liboop, copyright 1999 Dan Egnor # # This is free software; you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License, version 2.1 or later. # See the file COPYING for details. srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = . am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : host_triplet = @host@ ACLOCAL = @ACLOCAL@ ADNS_LIBS = @ADNS_LIBS@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ prefix = @prefix@ program_transform_name = @program_transform_name@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ AUTOMAKE_OPTIONS = foreign 1.2 AM_CPPFLAGS = -I$(srcdir)/../adns/src noinst_LIBRARIES = liboop.a INCLUDES = $(GLIB_INCLUDES) $(TCL_INCLUDES) $(WWW_INCLUDES) liboop_a_SOURCES = sys.c select.c signal.c alloc.c read.c read-fd.c \ read-mem.c adns.c noinst_HEADERS = oop.h oop-adns.h oop-glib.h oop-tcl.h oop-www.h oop-rl.h oop-read.h check_PROGRAMS = test-oop test_oop_SOURCES = test-oop.c test_oop_LDADD = liboop.a ../adns/src/libadns.a EXTRA_DIST = .cvsignore subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) liboop_a_AR = $(AR) cru liboop_a_LIBADD = am_liboop_a_OBJECTS = sys.$(OBJEXT) select.$(OBJEXT) signal.$(OBJEXT) \ alloc.$(OBJEXT) read.$(OBJEXT) read-fd.$(OBJEXT) \ read-mem.$(OBJEXT) adns.$(OBJEXT) liboop_a_OBJECTS = $(am_liboop_a_OBJECTS) check_PROGRAMS = test-oop$(EXEEXT) am_test_oop_OBJECTS = test-oop.$(OBJEXT) test_oop_OBJECTS = $(am_test_oop_OBJECTS) test_oop_DEPENDENCIES = liboop.a ../adns/src/libadns.a test_oop_LDFLAGS = DEFAULT_INCLUDES = -I. -I$(srcdir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/adns.Po ./$(DEPDIR)/alloc.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/read-fd.Po ./$(DEPDIR)/read-mem.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/read.Po ./$(DEPDIR)/select.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/signal.Po ./$(DEPDIR)/sys.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/test-oop.Po COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ DIST_SOURCES = $(liboop_a_SOURCES) $(test_oop_SOURCES) HEADERS = $(noinst_HEADERS) DIST_COMMON = README $(noinst_HEADERS) COPYING INSTALL Makefile.am \ Makefile.in aclocal.m4 config.guess config.sub configure \ configure.ac depcomp install-sh ltconfig ltmain.sh missing \ mkinstalldirs SOURCES = $(liboop_a_SOURCES) $(test_oop_SOURCES) all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe) $(top_builddir)/config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(srcdir)/configure: $(srcdir)/configure.ac $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) cd $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): configure.ac cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) liboop.a: $(liboop_a_OBJECTS) $(liboop_a_DEPENDENCIES) -rm -f liboop.a $(liboop_a_AR) liboop.a $(liboop_a_OBJECTS) $(liboop_a_LIBADD) $(RANLIB) liboop.a clean-checkPROGRAMS: -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS) test-oop$(EXEEXT): $(test_oop_OBJECTS) $(test_oop_DEPENDENCIES) @rm -f test-oop$(EXEEXT) $(LINK) $(test_oop_LDFLAGS) $(test_oop_OBJECTS) $(test_oop_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) core *.core distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adns.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alloc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/read-fd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/read-mem.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/read.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/select.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signal.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sys.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-oop.Po@am__quote@ distclean-depend: -rm -rf ./$(DEPDIR) .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ @am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ @am__fastdepCC_TRUE@ fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< .c.obj: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ @am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ @am__fastdepCC_TRUE@ fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` uninstall-info-am: ETAGS = etags ETAGSFLAGS = CTAGS = ctags CTAGSFLAGS = tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$tags$$unique" \ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = . distdir = $(PACKAGE)-$(VERSION) am__remove_distdir = \ { test ! -d $(distdir) \ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr $(distdir); }; } GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print distdir: $(DISTFILES) $(am__remove_distdir) mkdir $(distdir) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r $(distdir) dist-gzip: distdir $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist dist-all: distdir $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist $(am__remove_distdir) GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf - chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && cd $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && $(mkinstalldirs) "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist-gzip \ && rm -f $(distdir).tar.gz \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck $(am__remove_distdir) @echo "$(distdir).tar.gz is ready for distribution" | \ sed 'h;s/./=/g;p;x;p;x' distuninstallcheck: @cd $(distuninstallcheck_dir) \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) check: check-am all-am: Makefile $(LIBRARIES) $(HEADERS) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-checkPROGRAMS clean-generic clean-noinstLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) distclean-am: clean-am distclean-compile distclean-depend \ distclean-generic distclean-tags dvi: dvi-am dvi-am: info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-checkPROGRAMS \ clean-generic clean-noinstLIBRARIES ctags dist dist-all \ dist-gzip distcheck distclean distclean-compile \ distclean-depend distclean-generic distclean-tags \ distcleancheck distdir distuninstallcheck dvi dvi-am info \ info-am install install-am install-data install-data-am \ install-exec install-exec-am install-info install-info-am \ install-man install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ ps ps-am tags uninstall uninstall-am uninstall-info-am release: dist gzip -dc $(PACKAGE)-$(VERSION).tar.gz | bzip2 -9 \ > $(PACKAGE)-$(VERSION).tar.bz2 if test -d /ofb/www/download/liboop ; then \ cd /ofb/www/download/liboop && \ mv "$(shell pwd)/$(PACKAGE)-$(VERSION)".* . && \ ln -sf $(PACKAGE)-$(VERSION).tar.gz $(PACKAGE).tar.gz && \ ln -sf $(PACKAGE)-$(VERSION).tar.bz2 $(PACKAGE).tar.bz2 ; \ fi @echo '** NOW TAG THE CVS REPOSITORY! **' # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/src/libraries/liboop/aclocal.m40000664000015100472110000007436607723707454015743 # generated automatically by aclocal 1.7.6 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 # Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # Do all the work for Automake. -*- Autoconf -*- # This macro actually does too much some checks are only needed if # your package does certain things. But this isn't really a big deal. # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 10 AC_PREREQ([2.54]) # Autoconf 2.50 wants to disallow AM_ names. We explicitly allow # the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl # test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AM_MISSING_PROG(AMTAR, tar) AM_PROG_INSTALL_SH AM_PROG_INSTALL_STRIP # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl ]) ]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $1 | $1:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) # Copyright 2002 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.7"]) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION so it can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.7.6])]) # Helper functions for option handling. -*- Autoconf -*- # Copyright 2001, 2002 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 2 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # ------------------------------ # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ---------------------------------- # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # # Check to make sure that the build environment is sane. # # Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 3 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # -*- Autoconf -*- # Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 3 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # AM_AUX_DIR_EXPAND # Copyright 2001 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. # Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50]) AC_DEFUN([AM_AUX_DIR_EXPAND], [ # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. # Copyright 2001 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl install_sh=${install_sh-"$am_aux_dir/install-sh"} AC_SUBST(install_sh)]) # AM_PROG_INSTALL_STRIP # Copyright 2001 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # -*- Autoconf -*- # Copyright (C) 2003 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 1 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # serial 5 -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "GCJ", or "OBJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c : > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # (even with -Werror). So we grep stderr for any message # that says an option was ignored. if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, [ --disable-dependency-tracking Speeds up one-time builds --enable-dependency-tracking Do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH]) ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. #serial 2 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [for mf in $CONFIG_FILES; do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # So let's grep whole file. if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue # Extract the definition of DEP_FILES from the Makefile without # running `make'. DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"` test -z "$DEPDIR" && continue # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n -e '/^U = / s///p' < "$mf"` test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" # We invoke sed twice because it is the simplest approach to # changing $(DEPDIR) to its actual value in the expansion. for file in `sed -n -e ' /^DEP_FILES = .*\\\\$/ { s/^DEP_FILES = // :loop s/\\\\$// p n /\\\\$/ b loop p } /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each `.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 2 # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright 1997, 2000, 2001 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 5 AC_PREREQ(2.52) # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE]) AC_SUBST([$1_FALSE]) if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]) fi])]) lyskom-server-2.1.2/src/libraries/liboop/config.guess0000775000015100472110000011310607703073502016371 #! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002 Free Software Foundation, Inc. timestamp='2002-03-20' # This file 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 2 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner . # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit build system type. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit 0 ;; --version | -v ) echo "$version" ; exit 0 ;; --help | --h* | -h ) echo "$usage"; exit 0 ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi dummy=dummy-$$ trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int dummy(){}" > $dummy.c ; for c in cc gcc c89 c99 ; do ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ; if test $? = 0 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; rm -f $dummy.c $dummy.o $dummy.rel ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep __ELF__ >/dev/null then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit 0 ;; amiga:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; arc:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; hp300:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mac68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; macppc:OpenBSD:*:*) echo powerpc-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvme68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvme88k:OpenBSD:*:*) echo m88k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvmeppc:OpenBSD:*:*) echo powerpc-unknown-openbsd${UNAME_RELEASE} exit 0 ;; pmax:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; sgi:OpenBSD:*:*) echo mipseb-unknown-openbsd${UNAME_RELEASE} exit 0 ;; sun3:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; wgrisc:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; *:OpenBSD:*:*) echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} exit 0 ;; alpha:OSF1:*:*) if test $UNAME_RELEASE = "V4.0"; then UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` fi # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. cat <$dummy.s .data \$Lformat: .byte 37,100,45,37,120,10,0 # "%d-%x\n" .text .globl main .align 4 .ent main main: .frame \$30,16,\$26,0 ldgp \$29,0(\$27) .prologue 1 .long 0x47e03d80 # implver \$0 lda \$2,-1 .long 0x47e20c21 # amask \$2,\$1 lda \$16,\$Lformat mov \$0,\$17 not \$1,\$18 jsr \$26,printf ldgp \$29,0(\$26) mov 0,\$16 jsr \$26,exit .end main EOF eval $set_cc_for_build $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null if test "$?" = 0 ; then case `./$dummy` in 0-0) UNAME_MACHINE="alpha" ;; 1-0) UNAME_MACHINE="alphaev5" ;; 1-1) UNAME_MACHINE="alphaev56" ;; 1-101) UNAME_MACHINE="alphapca56" ;; 2-303) UNAME_MACHINE="alphaev6" ;; 2-307) UNAME_MACHINE="alphaev67" ;; 2-1307) UNAME_MACHINE="alphaev68" ;; esac fi rm -f $dummy.s $dummy echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit 0 ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit 0 ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit 0 ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit 0;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit 0 ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit 0 ;; *:OS/390:*:*) echo i370-ibm-openedition exit 0 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit 0;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit 0;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit 0 ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit 0 ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; i86pc:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit 0 ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit 0 ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit 0 ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit 0 ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit 0 ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit 0 ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit 0 ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit 0 ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit 0 ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit 0 ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit 0 ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit 0 ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD $dummy.c -o $dummy \ && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ && rm -f $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy echo mips-mips-riscos${UNAME_RELEASE} exit 0 ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit 0 ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit 0 ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit 0 ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit 0 ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit 0 ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit 0 ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit 0 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit 0 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit 0 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit 0 ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit 0 ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit 0 ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit 0 ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy echo rs6000-ibm-aix3.2.5 elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit 0 ;; *:AIX:*:[45]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit 0 ;; *:AIX:*:*) echo rs6000-ibm-aix exit 0 ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit 0 ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit 0 ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit 0 ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit 0 ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit 0 ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit 0 ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`./$dummy` if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi rm -f $dummy.c $dummy fi ;; esac echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit 0 ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit 0 ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy echo unknown-hitachi-hiuxwe2 exit 0 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit 0 ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit 0 ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit 0 ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit 0 ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit 0 ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit 0 ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit 0 ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit 0 ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit 0 ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit 0 ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit 0 ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*T3D:*:*:*) echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit 0 ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit 0 ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:FreeBSD:*:*) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit 0 ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit 0 ;; i*:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit 0 ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit 0 ;; x86:Interix*:3*) echo i386-pc-interix3 exit 0 ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i386-pc-interix exit 0 ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit 0 ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit 0 ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; *:GNU:*:*) echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit 0 ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit 0 ;; arm*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; mips:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips #undef mipsel #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mipsel #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` rm -f $dummy.c test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0 ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit 0 ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit 0 ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit 0 ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit 0 ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit 0 ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit 0 ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit 0 ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. # Set LC_ALL=C to ensure ld outputs messages in English. ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ | sed -ne '/supported targets:/!d s/[ ][ ]*/ /g s/.*supported targets: *// s/ .*// p'` case "$ld_supported_targets" in elf32-i386) TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" ;; a.out-i386-linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" exit 0 ;; coff-i386) echo "${UNAME_MACHINE}-pc-linux-gnucoff" exit 0 ;; "") # Either a pre-BFD a.out linker (linux-gnuoldld) or # one that does not give us useful --help. echo "${UNAME_MACHINE}-pc-linux-gnuoldld" exit 0 ;; esac # Determine whether the default compiler is a.out or elf eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 LIBC=gnu # else LIBC=gnulibc1 # endif # else LIBC=gnulibc1 # endif #else #ifdef __INTEL_COMPILER LIBC=gnu #else LIBC=gnuaout #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` rm -f $dummy.c test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit 0 ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit 0 ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit 0 ;; i*86:*:5:[78]*) case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit 0 ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit 0 ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit 0 ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp exit 0 ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit 0 ;; paragon:*:*:*) echo i860-intel-osf1 exit 0 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit 0 ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit 0 ;; M68*:*:R3V[567]*:*) test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4.3${OS_REL} && exit 0 /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4 && exit 0 ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit 0 ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit 0 ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit 0 ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit 0 ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit 0 ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit 0 ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit 0 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit 0 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit 0 ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit 0 ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit 0 ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit 0 ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit 0 ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit 0 ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit 0 ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit 0 ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit 0 ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit 0 ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit 0 ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit 0 ;; *:Darwin:*:*) echo `uname -p`-apple-darwin${UNAME_RELEASE} exit 0 ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit 0 ;; *:QNX:*:4*) echo i386-pc-qnx exit 0 ;; NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit 0 ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit 0 ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit 0 ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit 0 ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit 0 ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit 0 ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit 0 ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit 0 ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit 0 ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit 0 ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit 0 ;; *:ITS:*:*) echo pdp10-unknown-its exit 0 ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit 0 ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit 0 ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit 0 ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; c34*) echo c34-convex-bsd exit 0 ;; c38*) echo c38-convex-bsd exit 0 ;; c4*) echo c4-convex-bsd exit 0 ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: lyskom-server-2.1.2/src/libraries/liboop/config.sub0000775000015100472110000007054307703073502016043 #! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002 Free Software Foundation, Inc. timestamp='2002-03-07' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file 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 2 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit 0 ;; --version | -v ) echo "$version" ; exit 0 ;; --help | --h* | -h ) echo "$usage"; exit 0 ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit 0;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis) os= basic_machine=$1 ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ | c4x | clipper \ | d10v | d30v | dsp16xx \ | fr30 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | m32r | m68000 | m68k | m88k | mcore \ | mips | mips16 | mips64 | mips64el | mips64orion | mips64orionel \ | mips64vr4100 | mips64vr4100el | mips64vr4300 \ | mips64vr4300el | mips64vr5000 | mips64vr5000el \ | mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \ | mipsisa32 | mipsisa64 \ | mn10200 | mn10300 \ | ns16k | ns32k \ | openrisc | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | sh | sh[34] | sh[34]eb | shbe | shle | sh64 \ | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ | strongarm \ | tahoe | thumb | tic80 | tron \ | v850 | v850e \ | we32k \ | x86 | xscale | xstormy16 | xtensa \ | z8k) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armv*-* \ | avr-* \ | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c54x-* \ | clipper-* | cydra-* \ | d10v-* | d30v-* \ | elxsi-* \ | f30[01]-* | f700-* | fr30-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | m32r-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | mcore-* \ | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \ | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \ | mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* | sh64-* \ | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ | xtensa-* \ | ymp-* \ | z8k-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; c90) basic_machine=c90-cray os=-unicos ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; crds | unos) basic_machine=m68k-crds ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; mmix*) basic_machine=mmix-knuth os=-mmixware ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; or32 | or32-*) basic_machine=or32-unknown os=-coff ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon) basic_machine=i686-pc ;; pentiumii | pentium2) basic_machine=i686-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3d) basic_machine=alpha-cray os=-unicos ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; windows32) basic_machine=i386-pc os=-windows32-msvcrt ;; xps | xps100) basic_machine=xps100-honeywell ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh3 | sh4 | sh3eb | sh4eb) basic_machine=sh-unknown ;; sh64) basic_machine=sh64-unknown ;; sparc | sparcv9 | sparcv9b) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; c4x*) basic_machine=c4x-none os=-coff ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto*) os=-nto-qnx ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-ibm) os=-aix ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -ptx*) vendor=sequent ;; -vxsim* | -vxworks*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: lyskom-server-2.1.2/src/libraries/liboop/configure0000775000015100472110000044320007723707470015773 #! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.57. # # Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 # Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi # Support unset when possible. if (FOO=FOO; unset FOO) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" # Sed expression to map a string onto a valid variable name. as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` exec 6>&1 # # Initializations. # ac_default_prefix=/usr/local ac_config_libobj_dir=. cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. # This variable seems obsolete. It should probably be removed, and # only ac_max_sed_lines should be used. : ${ac_max_here_lines=38} # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= ac_unique_file="INSTALL" # Factoring default headers for most tests. ac_includes_default="\ #include #if HAVE_SYS_TYPES_H # include #endif #if HAVE_SYS_STAT_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_STRING_H # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif # include #endif #if HAVE_STRINGS_H # include #endif #if HAVE_INTTYPES_H # include #else # if HAVE_STDINT_H # include # endif #endif #if HAVE_UNISTD_H # include #endif" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE am__leading_dot build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE RANLIB ac_ct_RANLIB AR CPP EGREP ADNS_LIBS LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_option in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` eval "enable_$ac_feature=no" ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "enable_$ac_feature='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package| sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "with_$ac_package='$ac_optarg'" ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/-/_/g'` eval "with_$ac_package=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` eval "$ac_envvar='$ac_optarg'" export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute paths. for ac_var in exec_prefix prefix do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* | NONE | '' ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # Be sure to have absolute paths. for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ localstatedir libdir includedir oldincludedir infodir mandir do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_confdir=`(dirname "$0") 2>/dev/null || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 { (exit 1); exit 1; }; } else { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi fi (cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 { (exit 1); exit 1; }; } srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` ac_env_build_alias_set=${build_alias+set} ac_env_build_alias_value=$build_alias ac_cv_env_build_alias_set=${build_alias+set} ac_cv_env_build_alias_value=$build_alias ac_env_host_alias_set=${host_alias+set} ac_env_host_alias_value=$host_alias ac_cv_env_host_alias_set=${host_alias+set} ac_cv_env_host_alias_value=$host_alias ac_env_target_alias_set=${target_alias+set} ac_env_target_alias_value=$target_alias ac_cv_env_target_alias_set=${target_alias+set} ac_cv_env_target_alias_value=$target_alias ac_env_CC_set=${CC+set} ac_env_CC_value=$CC ac_cv_env_CC_set=${CC+set} ac_cv_env_CC_value=$CC ac_env_CFLAGS_set=${CFLAGS+set} ac_env_CFLAGS_value=$CFLAGS ac_cv_env_CFLAGS_set=${CFLAGS+set} ac_cv_env_CFLAGS_value=$CFLAGS ac_env_LDFLAGS_set=${LDFLAGS+set} ac_env_LDFLAGS_value=$LDFLAGS ac_cv_env_LDFLAGS_set=${LDFLAGS+set} ac_cv_env_LDFLAGS_value=$LDFLAGS ac_env_CPPFLAGS_set=${CPPFLAGS+set} ac_env_CPPFLAGS_value=$CPPFLAGS ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} ac_cv_env_CPPFLAGS_value=$CPPFLAGS ac_env_AR_set=${AR+set} ac_env_AR_value=$AR ac_cv_env_AR_set=${AR+set} ac_cv_env_AR_value=$AR ac_env_CPP_set=${CPP+set} ac_env_CPP_value=$CPP ac_cv_env_CPP_set=${CPP+set} ac_cv_env_CPP_value=$CPP # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] _ACEOF cat <<_ACEOF Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data [PREFIX/share] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --infodir=DIR info documentation [PREFIX/info] --mandir=DIR man documentation [PREFIX/man] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-dependency-tracking Speeds up one-time builds --enable-dependency-tracking Do not reject slow dependency extractors Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory AR ar program to use CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. _ACEOF fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. ac_popdir=`pwd` for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d $ac_dir || continue ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be # absolute. ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` cd $ac_dir # Check for guested configure; otherwise get Cygnus style configure. if test -f $ac_srcdir/configure.gnu; then echo $SHELL $ac_srcdir/configure.gnu --help=recursive elif test -f $ac_srcdir/configure; then echo $SHELL $ac_srcdir/configure --help=recursive elif test -f $ac_srcdir/configure.ac || test -f $ac_srcdir/configure.in; then echo $ac_configure --help else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi cd $ac_popdir done fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit 0 fi exec 5>config.log cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.57. Invocation command line was $ $0 $@ _ACEOF { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` hostinfo = `(hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_sep= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" # Get rid of the leading space. ac_sep=" " ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Be sure not to use single quotes in there, as some shells, # such as our DU 5.0 friend, will then `close' the trap. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, { (set) 2>&1 | case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in *ac_space=\ *) sed -n \ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" ;; *) sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------- ## ## Output files. ## ## ------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo sed "/^$/d" confdefs.h | sort echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core core.* *.core && rm -rf conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo >confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . $cache_file;; *) . ./$cache_file;; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in `(set) 2>&1 | sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val="\$ac_cv_env_${ac_var}_value" eval ac_new_val="\$ac_env_${ac_var}_value" case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu am__api_version="1.7" ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f $ac_dir/shtool; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} { (exit 1); exit 1; }; } fi ac_config_guess="$SHELL $ac_aux_dir/config.guess" ac_config_sub="$SHELL $ac_aux_dir/config.sub" ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL=$ac_install_sh fi fi echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo "$as_me:$LINENO: checking whether build environment is sane" >&5 echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6 # Just in case sleep 1 echo timestamp > conftest.file # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&5 echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&2;} { (exit 1); exit 1; }; } fi test "$2" = conftest.file ) then # Ok. : else { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! Check your system clock" >&5 echo "$as_me: error: newly created file is older than distributed files! Check your system clock" >&2;} { (exit 1); exit 1; }; } fi echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 test "$program_prefix" != NONE && program_transform_name="s,^,$program_prefix,;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s,\$,$program_suffix,;$program_transform_name" # Double any \ or $. echo might interpret backslashes. # By default was `s,x,x', remove it if useless. cat <<\_ACEOF >conftest.sed s/[\\$]/&&/g;s/;s,x,x,$// _ACEOF program_transform_name=`echo $program_transform_name | sed -f conftest.sed` rm conftest.sed # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_AWK+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then echo "$as_me:$LINENO: result: $AWK" >&5 echo "${ECHO_T}$AWK" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$AWK" && break done echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'` if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.make <<\_ACEOF all: @echo 'ac_maketemp="$(MAKE)"' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` if test -n "$ac_maketemp"; then eval ac_cv_prog_make_${ac_make}_set=yes else eval ac_cv_prog_make_${ac_make}_set=no fi rm -f conftest.make fi if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 SET_MAKE= else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} { (exit 1); exit 1; }; } fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE=liboop VERSION=0.9 cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} AMTAR=${AMTAR-"${am_missing_run}tar"} install_sh=${install_sh-"$am_aux_dir/install-sh"} # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then echo "$as_me:$LINENO: result: $STRIP" >&5 echo "${ECHO_T}$STRIP" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 echo "${ECHO_T}$ac_ct_STRIP" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi STRIP=$ac_ct_STRIP else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Make sure we can run config.sub. $ac_config_sub sun4 >/dev/null 2>&1 || { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 echo "$as_me: error: cannot run $ac_config_sub" >&2;} { (exit 1); exit 1; }; } echo "$as_me:$LINENO: checking build system type" >&5 echo $ECHO_N "checking build system type... $ECHO_C" >&6 if test "${ac_cv_build+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_build_alias=$build_alias test -z "$ac_cv_build_alias" && ac_cv_build_alias=`$ac_config_guess` test -z "$ac_cv_build_alias" && { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 echo "$as_me: error: cannot guess build type; you must specify one" >&2;} { (exit 1); exit 1; }; } ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} { (exit 1); exit 1; }; } fi echo "$as_me:$LINENO: result: $ac_cv_build" >&5 echo "${ECHO_T}$ac_cv_build" >&6 build=$ac_cv_build build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$as_me:$LINENO: checking host system type" >&5 echo $ECHO_N "checking host system type... $ECHO_C" >&6 if test "${ac_cv_host+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_host_alias=$host_alias test -z "$ac_cv_host_alias" && ac_cv_host_alias=$ac_cv_build_alias ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} { (exit 1); exit 1; }; } fi echo "$as_me:$LINENO: result: $ac_cv_host" >&5 echo "${ECHO_T}$ac_cv_host" >&6 host=$ac_cv_host host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$ac_ct_CC" && break done CC=$ac_ct_CC fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO:" \ "checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 (eval $ac_compiler --version &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 (eval $ac_compiler -v &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 (eval $ac_compiler -V &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. echo "$as_me:$LINENO: checking for C compiler default output" >&5 echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6 ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 (eval $ac_link_default) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Find the output, starting from the most likely. This scheme is # not robust to junk in `.', hence go to wildcards (a.*) only as a last # resort. # Be careful to initialize this variable, since it used to be cached. # Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. ac_cv_exeext= # b.out is created by i960 compilers. for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; conftest.$ac_ext ) # This is the source file. ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` # FIXME: I believe we export ac_cv_exeext for Libtool, # but it would be cool to find out if it's true. Does anybody # maintain Libtool? --akim. export ac_cv_exeext break;; * ) break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6 # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether the C compiler works" >&5 echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6 echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` export ac_cv_exeext break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6 rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6 OBJEXT=$ac_cv_objext ac_objext=$OBJEXT echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS CFLAGS="-g" echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_prog_cc_g=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 if test "${ac_cv_prog_cc_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_stdc=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF # Don't try gcc -ansi; that turns off useful extensions and # breaks some systems' header files. # AIX -qlanglvl=ansi # Ultrix and OSF/1 -std1 # HP-UX 10.20 and later -Ae # HP-UX older versions -Aa -D_HPUX_SOURCE # SVR4 -Xc -D__EXTENSIONS__ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_stdc=$ac_arg break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext done rm -f conftest.$ac_ext conftest.$ac_objext CC=$ac_save_CC fi case "x$ac_cv_prog_cc_stdc" in x|xno) echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6 ;; *) echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 CC="$CC $ac_cv_prog_cc_stdc" ;; esac # Some people use a C++ compiler to compile C. Since we use `exit', # in C++ we need to declare it. In case someone uses the same compiler # for both compiling C and C++ we need to have the C++ compiler decide # the declaration of exit, since it's the most demanding environment. cat >conftest.$ac_ext <<_ACEOF #ifndef __cplusplus choke me #endif _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then for ac_declaration in \ ''\ '#include ' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int);' \ 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 continue fi rm -f conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest.$ac_ext done rm -f conftest* if test -n "$ac_declaration"; then echo '#ifdef __cplusplus' >>confdefs.h echo $ac_declaration >>confdefs.h echo '#endif' >>confdefs.h fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6 am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi echo "$as_me:$LINENO: result: $_am_result" >&5 echo "${ECHO_T}$_am_result" >&6 rm -f confinc confmf # Check whether --enable-dependency-tracking or --disable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then enableval="$enable_dependency_tracking" fi; if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c : > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # (even with -Werror). So we grep stderr for any message # that says an option was ignored. if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6 CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL=$ac_install_sh fi fi echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then echo "$as_me:$LINENO: result: $RANLIB" >&5 echo "${ECHO_T}$RANLIB" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 echo "${ECHO_T}$ac_ct_RANLIB" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi RANLIB=$ac_ct_RANLIB else RANLIB="$ac_cv_prog_RANLIB" fi # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_path_AR+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $AR in [\\/]* | ?:[\\/]*) ac_cv_path_AR="$AR" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/ccs/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_AR="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done test -z "$ac_cv_path_AR" && ac_cv_path_AR="notfound" ;; esac fi AR=$ac_cv_path_AR if test -n "$AR"; then echo "$as_me:$LINENO: result: $AR" >&5 echo "${ECHO_T}$AR" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi if test "$AR" = "notfound"; then { { echo "$as_me:$LINENO: error: cannot find \`\`ar''" >&5 echo "$as_me: error: cannot find \`\`ar''" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$CPP" >&6 ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6 if test "${ac_cv_prog_egrep+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | (grep -E '(a|b)') >/dev/null 2>&1 then ac_cv_prog_egrep='grep -E' else ac_cv_prog_egrep='egrep' fi fi echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 echo "${ECHO_T}$ac_cv_prog_egrep" >&6 EGREP=$ac_cv_prog_egrep echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6 if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in poll.h sys/select.h sys/socket.h string.h strings.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc in yes:no ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; no:yes ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done cat >>confdefs.h <<\_ACEOF #define HAVE_ADNS 1 _ACEOF if test -z "$no_wacky_libs" ; then echo "$as_me:$LINENO: checking for res_query in -lresolv" >&5 echo $ECHO_N "checking for res_query in -lresolv... $ECHO_C" >&6 if test "${ac_cv_lib_resolv_res_query+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lresolv $LIBS" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char res_query (); int main () { res_query (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_resolv_res_query=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_resolv_res_query=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_res_query" >&5 echo "${ECHO_T}$ac_cv_lib_resolv_res_query" >&6 if test $ac_cv_lib_resolv_res_query = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBRESOLV 1 _ACEOF LIBS="-lresolv $LIBS" fi echo "$as_me:$LINENO: checking for library containing gethostbyname" >&5 echo $ECHO_N "checking for library containing gethostbyname... $ECHO_C" >&6 if test "${ac_cv_search_gethostbyname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS ac_cv_search_gethostbyname=no cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostbyname (); int main () { gethostbyname (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_gethostbyname="none required" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext if test "$ac_cv_search_gethostbyname" = no; then for ac_lib in nsl; do LIBS="-l$ac_lib $ac_func_search_save_LIBS" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostbyname (); int main () { gethostbyname (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_gethostbyname="-l$ac_lib" break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext done fi LIBS=$ac_func_search_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_search_gethostbyname" >&5 echo "${ECHO_T}$ac_cv_search_gethostbyname" >&6 if test "$ac_cv_search_gethostbyname" != no; then test "$ac_cv_search_gethostbyname" = "none required" || LIBS="$ac_cv_search_gethostbyname $LIBS" fi echo "$as_me:$LINENO: checking for library containing socket" >&5 echo $ECHO_N "checking for library containing socket... $ECHO_C" >&6 if test "${ac_cv_search_socket+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS ac_cv_search_socket=no cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char socket (); int main () { socket (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_socket="none required" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext if test "$ac_cv_search_socket" = no; then for ac_lib in socket; do LIBS="-l$ac_lib $ac_func_search_save_LIBS" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char socket (); int main () { socket (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_socket="-l$ac_lib" break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext done fi LIBS=$ac_func_search_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_search_socket" >&5 echo "${ECHO_T}$ac_cv_search_socket" >&6 if test "$ac_cv_search_socket" != no; then test "$ac_cv_search_socket" = "none required" || LIBS="$ac_cv_search_socket $LIBS" fi fi test yes = "$GCC" && CFLAGS="-Wall -Wno-comment -Wmissing-prototypes -Wstrict-prototypes -Wpointer-arith -Wwrite-strings $CFLAGS"' $(EXTRA_CFLAGS)' ac_config_files="$ac_config_files Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. { (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } | sed ' t clear : clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ : end' >>confcache if diff $cache_file confcache >/dev/null 2>&1; then :; else if test -w $cache_file; then test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" cat confcache >$cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/; s/:*\${srcdir}:*/:/; s/:*@srcdir@:*/:/; s/^\([^=]*=[ ]*\):*/\1/; s/:*$//; s/^[^=]*=[ ]*$//; }' fi # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then we branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. cat >confdef2opt.sed <<\_ACEOF t clear : clear s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g t quote s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g t quote d : quote s,[ `~#$^&*(){}\\|;'"<>?],\\&,g s,\[,\\&,g s,\],\\&,g s,\$,$$,g p _ACEOF # We use echo to avoid assuming a particular line-breaking character. # The extra dot is to prevent the shell from consuming trailing # line-breaks from the sub-command output. A line-break within # single-quotes doesn't work because, if this script is created in a # platform that uses two characters for line-breaks (e.g., DOS), tr # would break. ac_LF_and_DOT=`echo; echo .` DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` rm -f confdef2opt.sed ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_i=`echo "$ac_i" | sed 's/\$U\././;s/\.o$//;s/\.obj$//'` # 2. Add them. ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi # Support unset when possible. if (FOO=FOO; unset FOO) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" # Sed expression to map a string onto a valid variable name. as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH exec 6>&1 # Open the log real soon, to keep \$[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. Logging --version etc. is OK. exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX } >&5 cat >&5 <<_CSEOF This file was extended by $as_me, which was generated by GNU Autoconf 2.57. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ _CSEOF echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 echo >&5 _ACEOF # Files that config.status was made for. if test -n "$ac_config_files"; then echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS fi if test -n "$ac_config_headers"; then echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS fi if test -n "$ac_config_links"; then echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS fi if test -n "$ac_config_commands"; then echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS fi cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.57, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." srcdir=$srcdir INSTALL="$INSTALL" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "x$1" : 'x\([^=]*\)='` ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` ac_shift=: ;; -*) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; *) # This is not an option, so the user has probably given explicit # arguments. ac_option=$1 ac_need_defaults=false;; esac case $ac_option in # Handling of the options. _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --vers* | -V ) echo "$ac_cs_version"; exit 0 ;; --he | --h) # Conflict between --help and --header { { echo "$as_me:$LINENO: error: ambiguous option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; };; --help | --hel | -h ) echo "$ac_cs_usage"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # INIT-COMMANDS section. # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_config_target in $ac_config_targets do case "$ac_config_target" in # Handling of arguments. "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason to put it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Create a temporary directory, and hook for its removal unless debugging. $debug || { trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./confstat$$-$RANDOM (umask 077 && mkdir $tmp) } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "\$CONFIG_FILES"; then # Protect against being on the right side of a sed subst in config.status. sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF s,@SHELL@,$SHELL,;t t s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t s,@exec_prefix@,$exec_prefix,;t t s,@prefix@,$prefix,;t t s,@program_transform_name@,$program_transform_name,;t t s,@bindir@,$bindir,;t t s,@sbindir@,$sbindir,;t t s,@libexecdir@,$libexecdir,;t t s,@datadir@,$datadir,;t t s,@sysconfdir@,$sysconfdir,;t t s,@sharedstatedir@,$sharedstatedir,;t t s,@localstatedir@,$localstatedir,;t t s,@libdir@,$libdir,;t t s,@includedir@,$includedir,;t t s,@oldincludedir@,$oldincludedir,;t t s,@infodir@,$infodir,;t t s,@mandir@,$mandir,;t t s,@build_alias@,$build_alias,;t t s,@host_alias@,$host_alias,;t t s,@target_alias@,$target_alias,;t t s,@DEFS@,$DEFS,;t t s,@ECHO_C@,$ECHO_C,;t t s,@ECHO_N@,$ECHO_N,;t t s,@ECHO_T@,$ECHO_T,;t t s,@LIBS@,$LIBS,;t t s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t s,@INSTALL_DATA@,$INSTALL_DATA,;t t s,@CYGPATH_W@,$CYGPATH_W,;t t s,@PACKAGE@,$PACKAGE,;t t s,@VERSION@,$VERSION,;t t s,@ACLOCAL@,$ACLOCAL,;t t s,@AUTOCONF@,$AUTOCONF,;t t s,@AUTOMAKE@,$AUTOMAKE,;t t s,@AUTOHEADER@,$AUTOHEADER,;t t s,@MAKEINFO@,$MAKEINFO,;t t s,@AMTAR@,$AMTAR,;t t s,@install_sh@,$install_sh,;t t s,@STRIP@,$STRIP,;t t s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t s,@AWK@,$AWK,;t t s,@SET_MAKE@,$SET_MAKE,;t t s,@am__leading_dot@,$am__leading_dot,;t t s,@build@,$build,;t t s,@build_cpu@,$build_cpu,;t t s,@build_vendor@,$build_vendor,;t t s,@build_os@,$build_os,;t t s,@host@,$host,;t t s,@host_cpu@,$host_cpu,;t t s,@host_vendor@,$host_vendor,;t t s,@host_os@,$host_os,;t t s,@CC@,$CC,;t t s,@CFLAGS@,$CFLAGS,;t t s,@LDFLAGS@,$LDFLAGS,;t t s,@CPPFLAGS@,$CPPFLAGS,;t t s,@ac_ct_CC@,$ac_ct_CC,;t t s,@EXEEXT@,$EXEEXT,;t t s,@OBJEXT@,$OBJEXT,;t t s,@DEPDIR@,$DEPDIR,;t t s,@am__include@,$am__include,;t t s,@am__quote@,$am__quote,;t t s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t s,@CCDEPMODE@,$CCDEPMODE,;t t s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t s,@RANLIB@,$RANLIB,;t t s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t s,@AR@,$AR,;t t s,@CPP@,$CPP,;t t s,@EGREP@,$EGREP,;t t s,@ADNS_LIBS@,$ADNS_LIBS,;t t s,@LIBOBJS@,$LIBOBJS,;t t s,@LTLIBOBJS@,$LTLIBOBJS,;t t CEOF _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_lines=48 ac_sed_frag=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_lines # Line after last line for current file. ac_more_lines=: ac_sed_cmds= while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag else sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag fi if test ! -s $tmp/subs.frag; then ac_more_lines=false else # The purpose of the label and of the branching condition is to # speed up the sed processing (if there are no `@' at all, there # is no need to browse any of the substitutions). # These are the two extra sed commands mentioned above. (echo ':t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" else ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" fi ac_sed_frag=`expr $ac_sed_frag + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_lines` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi fi # test -n "$CONFIG_FILES" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case $ac_file in - | *:- | *:-:* ) # input from stdin cat >$tmp/stdin ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; * ) ac_file_in=$ac_file.in ;; esac # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be # absolute. ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_builddir$INSTALL ;; esac if test x"$ac_file" != x-; then { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} rm -f "$ac_file" fi # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ if test x"$ac_file" = x-; then configure_input= else configure_input="$ac_file. " fi configure_input=$configure_input"Generated from `echo $ac_file_in | sed 's,.*/,,'` by configure." # First look for the input files in the build tree, otherwise in the # src tree. ac_file_inputs=`IFS=: for f in $ac_file_in; do case $f in -) echo $tmp/stdin ;; [\\/$]*) # Absolute (can't be DOS-style, as IFS=:) test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } echo $f;; *) # Relative if test -f "$f"; then # Build tree echo $f elif test -f "$srcdir/$f"; then # Source tree echo $srcdir/$f else # /dev/null tree { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } fi;; esac done` || { (exit 1); exit 1; } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s,@configure_input@,$configure_input,;t t s,@srcdir@,$ac_srcdir,;t t s,@abs_srcdir@,$ac_abs_srcdir,;t t s,@top_srcdir@,$ac_top_srcdir,;t t s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t s,@builddir@,$ac_builddir,;t t s,@abs_builddir@,$ac_abs_builddir,;t t s,@top_builddir@,$ac_top_builddir,;t t s,@abs_top_builddir@,$ac_abs_top_builddir,;t t s,@INSTALL@,$ac_INSTALL,;t t " $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out rm -f $tmp/stdin if test x"$ac_file" != x-; then mv $tmp/out $ac_file else cat $tmp/out rm -f $tmp/out fi done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # # CONFIG_COMMANDS section. # for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue ac_dest=`echo "$ac_file" | sed 's,:.*,,'` ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_dir=`(dirname "$ac_dest") 2>/dev/null || $as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_dest" : 'X\(//\)[^/]' \| \ X"$ac_dest" : 'X\(//\)$' \| \ X"$ac_dest" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_dest" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be # absolute. ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 echo "$as_me: executing $ac_dest commands" >&6;} case $ac_dest in depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # So let's grep whole file. if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then dirpart=`(dirname "$mf") 2>/dev/null || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` else continue fi grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue # Extract the definition of DEP_FILES from the Makefile without # running `make'. DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"` test -z "$DEPDIR" && continue # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n -e '/^U = / s///p' < "$mf"` test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" # We invoke sed twice because it is the simplest approach to # changing $(DEPDIR) to its actual value in the expansion. for file in `sed -n -e ' /^DEP_FILES = .*\\\\$/ { s/^DEP_FILES = // :loop s/\\\\$// p n /\\\\$/ b loop p } /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`(dirname "$file") 2>/dev/null || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p $dirpart/$fdir else as_dir=$dirpart/$fdir as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5 echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;} { (exit 1); exit 1; }; }; } # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ;; esac done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi lyskom-server-2.1.2/src/libraries/liboop/configure.ac0000664000015100472110000000153307705623131016340 dnl Process this file with autoconf to produce a configure script. AC_INIT(INSTALL) AM_INIT_AUTOMAKE(liboop,0.9) AC_CANONICAL_HOST dnl Checks for programs. AC_PROG_CC AC_PROG_INSTALL AC_PROG_RANLIB AC_PATH_PROG([AR], [ar], [notfound], [$PATH$PATH_SEPARATOR/usr/ccs/bin]) AC_ARG_VAR([AR], [ar program to use]) [if test "$AR" = "notfound"; then] AC_MSG_ERROR([cannot find ``ar'']) [fi] AC_CHECK_HEADERS(poll.h sys/select.h sys/socket.h string.h strings.h) dnl This is always present in a LysKOM build. AC_DEFINE(HAVE_ADNS) if test -z "$no_wacky_libs" ; then AC_CHECK_LIB(resolv,res_query) AC_SEARCH_LIBS(gethostbyname,nsl) AC_SEARCH_LIBS(socket,socket) fi test yes = "$GCC" && CFLAGS="-Wall -Wno-comment -Wmissing-prototypes -Wstrict-prototypes -Wpointer-arith -Wwrite-strings $CFLAGS"' $(EXTRA_CFLAGS)' AC_SUBST(ADNS_LIBS) AC_OUTPUT(Makefile) lyskom-server-2.1.2/src/libraries/liboop/depcomp0000755000015100000310000003256107716517055015430 #! /bin/sh # depcomp - compile a program generating dependencies as side-effects # Copyright 1999, 2000 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # `libtool' can also be set to `yes' or `no'. if test -z "$depfile"; then base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'` dir=`echo "$object" | sed 's,/.*$,/,'` if test "$dir" = "$object"; then dir= fi # FIXME: should be _deps on DOS. depfile="$dir.deps/$base" fi tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> $depfile echo >> $depfile # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> $depfile else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. This file always lives in the current directory. # Also, the AIX compiler puts `$object:' at the start of each line; # $object doesn't have directory information. stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'` tmpdepfile="$stripped.u" outname="$stripped.o" if test "$libtool" = yes; then "$@" -Wc,-M else "$@" -M fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi if test -f "$tmpdepfile"; then # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; icc) # Intel's C compiler understands `-MD -MF file'. However on # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c # ICC 7.0 will fill foo.d with something like # foo.o: sub/foo.c # foo.o: sub/foo.h # which is wrong. We want: # sub/foo.o: sub/foo.c # sub/foo.o: sub/foo.h # sub/foo.c: # sub/foo.h: # ICC 7.1 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using \ : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1="$dir.libs/$base.lo.d" tmpdepfile2="$dir.libs/$base.d" "$@" -Wc,-MD else tmpdepfile1="$dir$base.o.d" tmpdepfile2="$dir$base.d" "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi if test -f "$tmpdepfile1"; then tmpdepfile="$tmpdepfile1" else tmpdepfile="$tmpdepfile2" fi if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a space and a tab in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for `:' # in the target name. This is to cope with DOS-style filenames: # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. "$@" $dashmflag | sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # X makedepend shift cleared=no for arg in "$@"; do case $cleared in no) set ""; shift cleared=yes ;; esac case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix="`echo $object | sed 's/^.*\././'`" touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E | sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. "$@" || exit $? IFS=" " for arg do case "$arg" in "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 lyskom-server-2.1.2/src/libraries/liboop/install-sh0000755000015100000310000001572207716517054016056 #!/bin/sh # # install - install a program, script, or datafile # # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd=$cpprog shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd=$stripprog shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "$0: no input file specified" >&2 exit 1 else : fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d "$dst" ]; then instcmd=: chmodcmd="" else instcmd=$mkdirprog fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f "$src" ] || [ -d "$src" ] then : else echo "$0: $src does not exist" >&2 exit 1 fi if [ x"$dst" = x ] then echo "$0: no destination specified" >&2 exit 1 else : fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d "$dst" ] then dst=$dst/`basename "$src"` else : fi fi ## this sed command emulates the dirname command dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-$defaultIFS}" oIFS=$IFS # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` IFS=$oIFS pathcomp='' while [ $# -ne 0 ] ; do pathcomp=$pathcomp$1 shift if [ ! -d "$pathcomp" ] ; then $mkdirprog "$pathcomp" else : fi pathcomp=$pathcomp/ done fi if [ x"$dir_arg" != x ] then $doit $instcmd "$dst" && if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename "$dst"` else dstfile=`basename "$dst" $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename "$dst"` else : fi # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up temp files at exit. trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 trap '(exit $?); exit' 1 2 13 15 # Move or copy the file name to the temp name $doit $instcmd "$src" "$dsttmp" && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && # Now remove or move aside any old file at destination location. We try this # two ways since rm can't unlink itself on some systems and the destination # file might be busy for other reasons. In this case, the final cleanup # might fail but the new file should still install successfully. { if [ -f "$dstdir/$dstfile" ] then $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || { echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 (exit 1); exit } else : fi } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" fi && # The final little trick to "correctly" pass the exit status to the exit trap. { (exit 0); exit } lyskom-server-2.1.2/src/libraries/liboop/ltconfig0000775000015100472110000026776507703073502015631 #! /bin/sh # ltconfig - Create a system-specific libtool. # Copyright (C) 1996-1999 Free Software Foundation, Inc. # Originally by Gordon Matzigkeit , 1996 # # This file 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 2 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # A lot of this script is taken from autoconf-2.10. # Check that we are running under the correct shell. SHELL=${CONFIG_SHELL-/bin/sh} echo=echo if test "X$1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X$1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then # Yippee, $echo works! : else # Restart under the correct shell. exec "$SHELL" "$0" --no-reexec ${1+"$@"} fi if test "X$1" = X--fallback-echo; then # used as fallback echo shift cat </dev/null`} case X$UNAME in *-DOS) PATH_SEPARATOR=';' ;; *) PATH_SEPARATOR=':' ;; esac fi # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. if test "${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi if test "X${echo_test_string+set}" != "Xset"; then # find a string as large as possible, as long as the shell can cope with it for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... if (echo_test_string="`eval $cmd`") 2>/dev/null && echo_test_string="`eval $cmd`" && (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null; then break fi done fi if test "X`($echo '\t') 2>/dev/null`" != 'X\t' || test "X`($echo "$echo_test_string") 2>/dev/null`" != X"$echo_test_string"; then # The Solaris, AIX, and Digital Unix default echo programs unquote # backslashes. This makes it impossible to quote backslashes using # echo "$something" | sed 's/\\/\\\\/g' # # So, first we look for a working echo in the user's PATH. IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" for dir in $PATH /usr/ucb; do if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && test "X`($dir/echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then echo="$dir/echo" break fi done IFS="$save_ifs" if test "X$echo" = Xecho; then # We didn't find a better echo, so look for alternatives. if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && test "X`(print -r "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then # This shell has a builtin print -r that does the trick. echo='print -r' elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && test "X$CONFIG_SHELL" != X/bin/ksh; then # If we have ksh, try running ltconfig again with it. ORIGINAL_CONFIG_SHELL="${CONFIG_SHELL-/bin/sh}" export ORIGINAL_CONFIG_SHELL CONFIG_SHELL=/bin/ksh export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" --no-reexec ${1+"$@"} else # Try using printf. echo='printf "%s\n"' if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && test "X`($echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then # Cool, printf works : elif test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' && test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then CONFIG_SHELL="$ORIGINAL_CONFIG_SHELL" export CONFIG_SHELL SHELL="$CONFIG_SHELL" export SHELL echo="$CONFIG_SHELL $0 --fallback-echo" elif test "X`("$CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' && test "X`("$CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then echo="$CONFIG_SHELL $0 --fallback-echo" else # maybe with a smaller string... prev=: for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null; then break fi prev="$cmd" done if test "$prev" != 'sed 50q "$0"'; then echo_test_string=`eval $prev` export echo_test_string exec "${ORIGINAL_CONFIG_SHELL}" "$0" ${1+"$@"} else # Oops. We lost completely, so just stick with echo. echo=echo fi fi fi fi fi # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed='sed -e s/^X//' sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # The name of this program. progname=`$echo "X$0" | $Xsed -e 's%^.*/%%'` # Constants: PROGRAM=ltconfig PACKAGE=libtool VERSION=1.3.3 TIMESTAMP=" (1.385.2.181 1999/07/02 15:49:11)" ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.c 1>&5' ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.c $LIBS 1>&5' rm="rm -f" help="Try \`$progname --help' for more information." # Global variables: default_ofile=libtool can_build_shared=yes enable_shared=yes # All known linkers require a `.a' archive for static linking (except M$VC, # which needs '.lib'). enable_static=yes enable_fast_install=yes enable_dlopen=unknown enable_win32_dll=no ltmain= silent= srcdir= ac_config_guess= ac_config_sub= host= nonopt= ofile="$default_ofile" verify_host=yes with_gcc=no with_gnu_ld=no need_locks=yes ac_ext=c objext=o libext=a exeext= cache_file= old_AR="$AR" old_CC="$CC" old_CFLAGS="$CFLAGS" old_CPPFLAGS="$CPPFLAGS" old_LDFLAGS="$LDFLAGS" old_LD="$LD" old_LN_S="$LN_S" old_LIBS="$LIBS" old_NM="$NM" old_RANLIB="$RANLIB" old_DLLTOOL="$DLLTOOL" old_OBJDUMP="$OBJDUMP" old_AS="$AS" # Parse the command line options. args= prev= for option do case "$option" in -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) optarg= ;; esac # If the previous option needs an argument, assign it. if test -n "$prev"; then eval "$prev=\$option" prev= continue fi case "$option" in --help) cat <&2 echo "$help" 1>&2 exit 1 ;; *) if test -z "$ltmain"; then ltmain="$option" elif test -z "$host"; then # This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1 # if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then # echo "$progname: warning \`$option' is not a valid host type" 1>&2 # fi host="$option" else echo "$progname: too many arguments" 1>&2 echo "$help" 1>&2 exit 1 fi ;; esac done if test -z "$ltmain"; then echo "$progname: you must specify a LTMAIN file" 1>&2 echo "$help" 1>&2 exit 1 fi if test ! -f "$ltmain"; then echo "$progname: \`$ltmain' does not exist" 1>&2 echo "$help" 1>&2 exit 1 fi # Quote any args containing shell metacharacters. ltconfig_args= for arg do case "$arg" in *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ltconfig_args="$ltconfig_args '$arg'" ;; *) ltconfig_args="$ltconfig_args $arg" ;; esac done # A relevant subset of AC_INIT. # File descriptor usage: # 0 standard input # 1 file creation # 2 errors and warnings # 3 some systems may open it to /dev/tty # 4 used on the Kubota Titan # 5 compiler messages saved in config.log # 6 checking for... messages and results if test "$silent" = yes; then exec 6>/dev/null else exec 6>&1 fi exec 5>>./config.log # NLS nuisances. # Only set LANG and LC_ALL to C if already set. # These must not be set unconditionally because not all systems understand # e.g. LANG=C (notably SCO). if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi if test "${LANG+set}" = set; then LANG=C; export LANG; fi if test -n "$cache_file" && test -r "$cache_file"; then echo "loading cache $cache_file within ltconfig" . $cache_file fi if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then ac_n= ac_c=' ' ac_t=' ' else ac_n=-n ac_c= ac_t= fi else ac_n= ac_c='\c' ac_t= fi if test -z "$srcdir"; then # Assume the source directory is the same one as the path to LTMAIN. srcdir=`$echo "X$ltmain" | $Xsed -e 's%/[^/]*$%%'` test "$srcdir" = "$ltmain" && srcdir=. fi trap "$rm conftest*; exit 1" 1 2 15 if test "$verify_host" = yes; then # Check for config.guess and config.sub. ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/config.guess; then ac_aux_dir=$ac_dir break fi done if test -z "$ac_aux_dir"; then echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2 echo "$help" 1>&2 exit 1 fi ac_config_guess=$ac_aux_dir/config.guess ac_config_sub=$ac_aux_dir/config.sub # Make sure we can run config.sub. if $SHELL $ac_config_sub sun4 >/dev/null 2>&1; then : else echo "$progname: cannot run $ac_config_sub" 1>&2 echo "$help" 1>&2 exit 1 fi echo $ac_n "checking host system type""... $ac_c" 1>&6 host_alias=$host case "$host_alias" in "") if host_alias=`$SHELL $ac_config_guess`; then : else echo "$progname: cannot guess host type; you must specify one" 1>&2 echo "$help" 1>&2 exit 1 fi ;; esac host=`$SHELL $ac_config_sub $host_alias` echo "$ac_t$host" 1>&6 # Make sure the host verified. test -z "$host" && exit 1 elif test -z "$host"; then echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2 echo "$help" 1>&2 exit 1 else host_alias=$host fi # Transform linux* to *-*-linux-gnu*, to support old configure scripts. case "$host_os" in linux-gnu*) ;; linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'` esac host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` case "$host_os" in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "${COLLECT_NAMES+set}" != set; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Determine commands to create old-style static archives. old_archive_cmds='$AR cru $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= # Set a sane default for `AR'. test -z "$AR" && AR=ar # Set a sane default for `OBJDUMP'. test -z "$OBJDUMP" && OBJDUMP=objdump # If RANLIB is not set, then run the test. if test "${RANLIB+set}" != "set"; then result=no echo $ac_n "checking for ranlib... $ac_c" 1>&6 IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" for dir in $PATH; do test -z "$dir" && dir=. if test -f $dir/ranlib || test -f $dir/ranlib$ac_exeext; then RANLIB="ranlib" result="ranlib" break fi done IFS="$save_ifs" echo "$ac_t$result" 1>&6 fi if test -n "$RANLIB"; then old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" fi # Set sane defaults for `DLLTOOL', `OBJDUMP', and `AS', used on cygwin. test -z "$DLLTOOL" && DLLTOOL=dlltool test -z "$OBJDUMP" && OBJDUMP=objdump test -z "$AS" && AS=as # Check to see if we are using GCC. if test "$with_gcc" != yes || test -z "$CC"; then # If CC is not set, then try to find GCC or a usable CC. if test -z "$CC"; then echo $ac_n "checking for gcc... $ac_c" 1>&6 IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" for dir in $PATH; do test -z "$dir" && dir=. if test -f $dir/gcc || test -f $dir/gcc$ac_exeext; then CC="gcc" break fi done IFS="$save_ifs" if test -n "$CC"; then echo "$ac_t$CC" 1>&6 else echo "$ac_t"no 1>&6 fi fi # Not "gcc", so try "cc", rejecting "/usr/ucb/cc". if test -z "$CC"; then echo $ac_n "checking for cc... $ac_c" 1>&6 IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" cc_rejected=no for dir in $PATH; do test -z "$dir" && dir=. if test -f $dir/cc || test -f $dir/cc$ac_exeext; then if test "$dir/cc" = "/usr/ucb/cc"; then cc_rejected=yes continue fi CC="cc" break fi done IFS="$save_ifs" if test $cc_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $CC shift if test $# -gt 0; then # We chose a different compiler from the bogus one. # However, it has the same name, so the bogon will be chosen # first if we set CC to just the name; use the full file name. shift set dummy "$dir/cc" "$@" shift CC="$@" fi fi if test -n "$CC"; then echo "$ac_t$CC" 1>&6 else echo "$ac_t"no 1>&6 fi if test -z "$CC"; then echo "$progname: error: no acceptable cc found in \$PATH" 1>&2 exit 1 fi fi # Now see if the compiler is really GCC. with_gcc=no echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6 echo "$progname:581: checking whether we are using GNU C" >&5 $rm conftest.c cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then with_gcc=yes fi $rm conftest.c echo "$ac_t$with_gcc" 1>&6 fi # Allow CC to be a program name with arguments. set dummy $CC compiler="$2" echo $ac_n "checking for object suffix... $ac_c" 1>&6 $rm conftest* echo 'int i = 1;' > conftest.c echo "$progname:603: checking for object suffix" >& 5 if { (eval echo $progname:604: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; }; then # Append any warnings to the config.log. cat conftest.err 1>&5 for ac_file in conftest.*; do case $ac_file in *.c) ;; *) objext=`echo $ac_file | sed -e s/conftest.//` ;; esac done else cat conftest.err 1>&5 echo "$progname: failed program was:" >&5 cat conftest.c >&5 fi $rm conftest* echo "$ac_t$objext" 1>&6 echo $ac_n "checking for executable suffix... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_exeext="no" $rm conftest* echo 'main () { return 0; }' > conftest.c echo "$progname:629: checking for executable suffix" >& 5 if { (eval echo $progname:630: \"$ac_link\") 1>&5; (eval $ac_link) 2>conftest.err; }; then # Append any warnings to the config.log. cat conftest.err 1>&5 for ac_file in conftest.*; do case $ac_file in *.c | *.err | *.$objext ) ;; *) ac_cv_exeext=.`echo $ac_file | sed -e s/conftest.//` ;; esac done else cat conftest.err 1>&5 echo "$progname: failed program was:" >&5 cat conftest.c >&5 fi $rm conftest* fi if test "X$ac_cv_exeext" = Xno; then exeext="" else exeext="$ac_cv_exeext" fi echo "$ac_t$ac_cv_exeext" 1>&6 echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6 pic_flag= special_shlib_compile_flags= wl= link_static_flag= no_builtin_flag= if test "$with_gcc" = yes; then wl='-Wl,' link_static_flag='-static' case "$host_os" in beos* | irix5* | irix6* | osf3* | osf4*) # PIC is the default for these OSes. ;; aix*) # Below there is a dirty hack to force normal static linking with -ldl # The problem is because libdl dynamically linked with both libc and # libC (AIX C++ library), which obviously doesn't included in libraries # list by gcc. This cause undefined symbols with -static flags. # This hack allows C programs to be linked with "-static -ldl", but # we not sure about C++ programs. link_static_flag="$link_static_flag ${wl}-lC" ;; cygwin* | mingw* | os2*) # We can build DLLs from non-PIC. ;; amigaos*) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. pic_flag='-m68020 -resident32 -malways-restore-a4' ;; sysv4*MP*) if test -d /usr/nec; then pic_flag=-Kconform_pic fi ;; *) pic_flag='-fPIC' ;; esac else # PORTME Check for PIC flags for the system compiler. case "$host_os" in aix3* | aix4*) # All AIX code is PIC. link_static_flag='-bnso -bI:/lib/syscalls.exp' ;; hpux9* | hpux10* | hpux11*) # Is there a better link_static_flag that works with the bundled CC? wl='-Wl,' link_static_flag="${wl}-a ${wl}archive" pic_flag='+Z' ;; irix5* | irix6*) wl='-Wl,' link_static_flag='-non_shared' # PIC (with -KPIC) is the default. ;; cygwin* | mingw* | os2*) # We can build DLLs from non-PIC. ;; osf3* | osf4*) # All OSF/1 code is PIC. wl='-Wl,' link_static_flag='-non_shared' ;; sco3.2v5*) pic_flag='-Kpic' link_static_flag='-dn' special_shlib_compile_flags='-belf' ;; solaris*) pic_flag='-KPIC' link_static_flag='-Bstatic' wl='-Wl,' ;; sunos4*) pic_flag='-PIC' link_static_flag='-Bstatic' wl='-Qoption ld ' ;; sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) pic_flag='-KPIC' link_static_flag='-Bstatic' wl='-Wl,' ;; uts4*) pic_flag='-pic' link_static_flag='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then pic_flag='-Kconform_pic' link_static_flag='-Bstatic' fi ;; *) can_build_shared=no ;; esac fi if test -n "$pic_flag"; then echo "$ac_t$pic_flag" 1>&6 # Check to make sure the pic_flag actually works. echo $ac_n "checking if $compiler PIC flag $pic_flag works... $ac_c" 1>&6 $rm conftest* echo "int some_variable = 0;" > conftest.c save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $pic_flag -DPIC" echo "$progname:776: checking if $compiler PIC flag $pic_flag works" >&5 if { (eval echo $progname:777: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.$objext; then # Append any warnings to the config.log. cat conftest.err 1>&5 case "$host_os" in hpux9* | hpux10* | hpux11*) # On HP-UX, both CC and GCC only warn that PIC is supported... then they # create non-PIC objects. So, if there were any warnings, we assume that # PIC is not supported. if test -s conftest.err; then echo "$ac_t"no 1>&6 can_build_shared=no pic_flag= else echo "$ac_t"yes 1>&6 pic_flag=" $pic_flag" fi ;; *) echo "$ac_t"yes 1>&6 pic_flag=" $pic_flag" ;; esac else # Append any errors to the config.log. cat conftest.err 1>&5 can_build_shared=no pic_flag= echo "$ac_t"no 1>&6 fi CFLAGS="$save_CFLAGS" $rm conftest* else echo "$ac_t"none 1>&6 fi # Check to see if options -o and -c are simultaneously supported by compiler echo $ac_n "checking if $compiler supports -c -o file.o... $ac_c" 1>&6 $rm -r conftest 2>/dev/null mkdir conftest cd conftest $rm conftest* echo "int some_variable = 0;" > conftest.c mkdir out # According to Tom Tromey, Ian Lance Taylor reported there are C compilers # that will create temporary files in the current directory regardless of # the output directory. Thus, making CWD read-only will cause this test # to fail, enabling locking or at least warning the user not to do parallel # builds. chmod -w . save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -o out/conftest2.o" echo "$progname:829: checking if $compiler supports -c -o file.o" >&5 if { (eval echo $progname:830: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.o; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings if test -s out/conftest.err; then echo "$ac_t"no 1>&6 compiler_c_o=no else echo "$ac_t"yes 1>&6 compiler_c_o=yes fi else # Append any errors to the config.log. cat out/conftest.err 1>&5 compiler_c_o=no echo "$ac_t"no 1>&6 fi CFLAGS="$save_CFLAGS" chmod u+w . $rm conftest* out/* rmdir out cd .. rmdir conftest $rm -r conftest 2>/dev/null if test x"$compiler_c_o" = x"yes"; then # Check to see if we can write to a .lo echo $ac_n "checking if $compiler supports -c -o file.lo... $ac_c" 1>&6 $rm conftest* echo "int some_variable = 0;" > conftest.c save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -c -o conftest.lo" echo "$progname:862: checking if $compiler supports -c -o file.lo" >&5 if { (eval echo $progname:863: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.lo; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then echo "$ac_t"no 1>&6 compiler_o_lo=no else echo "$ac_t"yes 1>&6 compiler_o_lo=yes fi else # Append any errors to the config.log. cat conftest.err 1>&5 compiler_o_lo=no echo "$ac_t"no 1>&6 fi CFLAGS="$save_CFLAGS" $rm conftest* else compiler_o_lo=no fi # Check to see if we can do hard links to lock some files if needed hard_links="nottested" if test "$compiler_c_o" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user echo $ac_n "checking if we can lock with hard links... $ac_c" 1>&6 hard_links=yes $rm conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no echo "$ac_t$hard_links" 1>&6 $rm conftest* if test "$hard_links" = no; then echo "*** WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2 need_locks=warn fi else need_locks=no fi if test "$with_gcc" = yes; then # Check to see if options -fno-rtti -fno-exceptions are supported by compiler echo $ac_n "checking if $compiler supports -fno-rtti -fno-exceptions ... $ac_c" 1>&6 $rm conftest* echo "int some_variable = 0;" > conftest.c save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.c" echo "$progname:914: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 if { (eval echo $progname:915: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.o; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then echo "$ac_t"no 1>&6 compiler_rtti_exceptions=no else echo "$ac_t"yes 1>&6 compiler_rtti_exceptions=yes fi else # Append any errors to the config.log. cat conftest.err 1>&5 compiler_rtti_exceptions=no echo "$ac_t"no 1>&6 fi CFLAGS="$save_CFLAGS" $rm conftest* if test "$compiler_rtti_exceptions" = "yes"; then no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions' else no_builtin_flag=' -fno-builtin' fi fi # Check for any special shared library compilation flags. if test -n "$special_shlib_compile_flags"; then echo "$progname: warning: \`$CC' requires \`$special_shlib_compile_flags' to build shared libraries" 1>&2 if echo "$old_CC $old_CFLAGS " | egrep -e "[ ]$special_shlib_compile_flags[ ]" >/dev/null; then : else echo "$progname: add \`$special_shlib_compile_flags' to the CC or CFLAGS env variable and reconfigure" 1>&2 can_build_shared=no fi fi echo $ac_n "checking if $compiler static flag $link_static_flag works... $ac_c" 1>&6 $rm conftest* echo 'main(){return(0);}' > conftest.c save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $link_static_flag" echo "$progname:958: checking if $compiler static flag $link_static_flag works" >&5 if { (eval echo $progname:959: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then echo "$ac_t$link_static_flag" 1>&6 else echo "$ac_t"none 1>&6 link_static_flag= fi LDFLAGS="$save_LDFLAGS" $rm conftest* if test -z "$LN_S"; then # Check to see if we can use ln -s, or we need hard links. echo $ac_n "checking whether ln -s works... $ac_c" 1>&6 $rm conftest.dat if ln -s X conftest.dat 2>/dev/null; then $rm conftest.dat LN_S="ln -s" else LN_S=ln fi if test "$LN_S" = "ln -s"; then echo "$ac_t"yes 1>&6 else echo "$ac_t"no 1>&6 fi fi # Make sure LD is an absolute path. if test -z "$LD"; then ac_prog=ld if test "$with_gcc" = yes; then # Check if gcc -print-prog-name=ld gives a path. echo $ac_n "checking for ld used by GCC... $ac_c" 1>&6 echo "$progname:991: checking for ld used by GCC" >&5 ac_prog=`($CC -print-prog-name=ld) 2>&5` case "$ac_prog" in # Accept absolute paths. [\\/]* | [A-Za-z]:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the path of ld ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we are not using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then echo $ac_n "checking for GNU ld... $ac_c" 1>&6 echo "$progname:1015: checking for GNU ld" >&5 else echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6 echo "$progname:1018: checking for non-GNU ld" >&5 fi if test -z "$LD"; then IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some GNU ld's only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. if "$LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then test "$with_gnu_ld" != no && break else test "$with_gnu_ld" != yes && break fi fi done IFS="$ac_save_ifs" fi if test -n "$LD"; then echo "$ac_t$LD" 1>&6 else echo "$ac_t"no 1>&6 fi if test -z "$LD"; then echo "$progname: error: no acceptable ld found in \$PATH" 1>&2 exit 1 fi fi # Check to see if it really is or is not GNU ld. echo $ac_n "checking if the linker ($LD) is GNU ld... $ac_c" 1>&6 # I'd rather use --version here, but apparently some GNU ld's only accept -v. if $LD -v 2>&1 &5; then with_gnu_ld=yes else with_gnu_ld=no fi echo "$ac_t$with_gnu_ld" 1>&6 # See if the linker supports building shared libraries. echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6 allow_undefined_flag= no_undefined_flag= need_lib_prefix=unknown need_version=unknown # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments archive_cmds= archive_expsym_cmds= old_archive_from_new_cmds= export_dynamic_flag_spec= whole_archive_flag_spec= thread_safe_flag_spec= hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_direct=no hardcode_minus_L=no hardcode_shlibpath_var=unsupported runpath_var= always_export_symbols=no export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols' # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an egrep regular expression of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. exclude_expsyms="_GLOBAL_OFFSET_TABLE_" # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. case "$host_os" in cygwin* | mingw*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$with_gcc" != yes; then with_gnu_ld=no fi ;; esac ld_shlibs=yes if test "$with_gnu_ld" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # See if GNU ld supports shared libraries. case "$host_os" in aix3* | aix4*) # On AIX, the GNU linker is very broken ld_shlibs=no cat <&2 *** Warning: the GNU linker, at least up to release 2.9.1, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to modify your PATH *** so that a non-GNU linker is found, and then restart. EOF ;; amigaos*) archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes # Samuel A. Falvo II reports # that the semantics of dynamic libraries on AmigaOS, at least up # to version 4, is to share data among multiple programs linked # with the same dynamic library. Since this doesn't match the # behavior of shared libraries on other platforms, we can use # them. ld_shlibs=no ;; beos*) if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw*) # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' allow_undefined_flag=unsupported always_export_symbols=yes # Extract the symbol export list from an `--export-all' def file, # then regenerate the def file from the symbol export list, so that # the compiled dll only exports the symbol export list. export_symbols_cmds='test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~ test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~ $DLLTOOL --export-all --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --output-def $objdir/$soname-def $objdir/$soname-ltdll.$objext $libobjs $convenience~ sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]* ; *//" < $objdir/$soname-def > $export_symbols' archive_expsym_cmds='echo EXPORTS > $objdir/$soname-def~ _lt_hint=1; for symbol in `cat $export_symbols`; do echo " \$symbol @ \$_lt_hint ; " >> $objdir/$soname-def; _lt_hint=`expr 1 + \$_lt_hint`; done~ test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~ test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~ $CC -Wl,--base-file,$objdir/$soname-base -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~ $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~ $CC -Wl,--base-file,$objdir/$soname-base $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~ $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~ $CC $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts' old_archive_from_new_cmds='$DLLTOOL --as=$AS --dllname $soname --def $objdir/$soname-def --output-lib $objdir/$libname.a' ;; netbsd*) if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else archive_cmds='$LD -Bshareable $libobjs $deplibs $linkopts -o $lib' # can we support soname and/or expsyms with a.out? -oliva fi ;; solaris*) if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. EOF elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linkopts' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = yes; then runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' export_dynamic_flag_spec='${wl}--export-dynamic' case $host_os in cygwin* | mingw*) # dlltool doesn't understand --whole-archive et. al. whole_archive_flag_spec= ;; *) whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' ;; esac fi else # PORTME fill in a description of your system's linker (not GNU ld) case "$host_os" in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $objdir/$soname $libobjs $deplibs $linkopts -bE:$export_symbols -T512 -H512 -bM:SRE~$AR cru $lib $objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$with_gcc" = yes && test -z "$link_static_flag"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix4*) hardcode_libdir_flag_spec='${wl}-b ${wl}nolibpath ${wl}-b ${wl}libpath:$libdir:/usr/lib:/lib' hardcode_libdir_separator=':' if test "$with_gcc" = yes; then collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && \ strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 hardcode_direct=yes else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi shared_flag='-shared' else shared_flag='${wl}-bM:SRE' hardcode_direct=yes fi allow_undefined_flag=' ${wl}-berok' archive_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bexpall ${wl}-bnoentry${allow_undefined_flag}' archive_expsym_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}' case "$host_os" in aix4.[01]|aix4.[01].*) # According to Greg Wooledge, -bexpall is only supported from AIX 4.2 on always_export_symbols=yes ;; esac ;; amigaos*) archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes # see comment about different semantics on the GNU ld section ld_shlibs=no ;; cygwin* | mingw*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $linkopts `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib /OUT:$oldlib$oldobjs' fix_srcfile_path='`cygpath -w $srcfile`' ;; freebsd1*) ld_shlibs=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd*) archive_cmds='$CC -shared -o $lib $libobjs $deplibs $linkopts' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9* | hpux10* | hpux11*) case "$host_os" in hpux9*) archive_cmds='$rm $objdir/$soname~$LD -b +b $install_libdir -o $objdir/$soname $libobjs $deplibs $linkopts~test $objdir/$soname = $lib || mv $objdir/$soname $lib' ;; *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linkopts' ;; esac hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_minus_L=yes # Not in the search PATH, but as the default # location of the library. export_dynamic_flag_spec='${wl}-E' ;; irix5* | irix6*) if test "$with_gcc" = yes; then archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' else archive_cmds='$LD -shared $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' fi hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; netbsd*) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linkopts' # ELF fi hardcode_libdir_flag_spec='${wl}-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; openbsd*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $objdir/$libname.def~$echo DATA >> $objdir/$libname.def~$echo " SINGLE NONSHARED" >> $objdir/$libname.def~$echo EXPORTS >> $objdir/$libname.def~emxexp $libobjs >> $objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $linkopts $objdir/$libname.def' old_archive_from_new_cmds='emximp -o $objdir/$libname.a $objdir/$libname.def' ;; osf3* | osf4*) if test "$with_gcc" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' fi hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; sco3.2v5*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ;; solaris*) no_undefined_flag=' -z text' # $CC -shared without GNU ld will not create a library from C++ # object files and a static libstdc++, better avoid it by now archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts' archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp' hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case "$host_os" in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # Supported since Solaris 2.6 (maybe 2.5.1?) whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linkopts' hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; sysv4*MP*) if test -d /usr/nec ;then # archive_cmds='$LD -G -z text -h $soname -o $lib$libobjs$deplibs' archive_cmds='$LD -G -h $soname -o $lib$libobjs$deplibs' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; *) ld_shlibs=no ;; esac fi echo "$ac_t$ld_shlibs" 1>&6 test "$ld_shlibs" = no && can_build_shared=no if test -z "$NM"; then echo $ac_n "checking for BSD-compatible nm... $ac_c" 1>&6 case "$NM" in [\\/]* | [A-Za-z]:[\\/]*) ;; # Let the user override the test with a path. *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" for ac_dir in $PATH /usr/ucb /usr/ccs/bin /bin; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then NM="$ac_dir/nm -B" break elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then NM="$ac_dir/nm -p" break else NM=${NM="$ac_dir/nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags fi fi done IFS="$ac_save_ifs" test -z "$NM" && NM=nm ;; esac echo "$ac_t$NM" 1>&6 fi # Check for command to grab the raw symbol name followed by C symbol from nm. echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6 # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Transform the above into a raw symbol and a C symbol. symxfrm='\1 \2\3 \3' # Transform an extracted symbol line into a proper C declaration global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'" # Define system-specific variables. case "$host_os" in aix*) symcode='[BCDT]' ;; cygwin* | mingw*) symcode='[ABCDGISTW]' ;; hpux*) # Its linker distinguishes data from code symbols global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'" ;; irix*) symcode='[BCDEGRST]' ;; solaris*) symcode='[BDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then symcode='[ABCDGISTW]' fi # Try without a prefix undercore, then with it. for ac_symprfx in "" "_"; do # Write the raw and C identifiers. global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode\)[ ][ ]*\($ac_symprfx\)$sympat$/$symxfrm/p'" # Check to see that the pipe works correctly. pipe_works=no $rm conftest* cat > conftest.c <&5 if { (eval echo $progname:1593: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.$objext; then # Now try to grab the symbols. nlist=conftest.nm if { echo "$progname:1596: eval \"$NM conftest.$objext | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.$objext | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if egrep ' nm_test_var$' "$nlist" >/dev/null; then if egrep ' nm_test_func$' "$nlist" >/dev/null; then cat < conftest.c #ifdef __cplusplus extern "C" { #endif EOF # Now generate the symbol file. eval "$global_symbol_to_cdecl"' < "$nlist" >> conftest.c' cat <> conftest.c #if defined (__STDC__) && __STDC__ # define lt_ptr_t void * #else # define lt_ptr_t char * # define const #endif /* The mapping between symbol names and symbols. */ const struct { const char *name; lt_ptr_t address; } lt_preloaded_symbols[] = { EOF sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$nlist" >> conftest.c cat <<\EOF >> conftest.c {0, (lt_ptr_t) 0} }; #ifdef __cplusplus } #endif EOF # Now try linking the two files. mv conftest.$objext conftstm.$objext save_LIBS="$LIBS" save_CFLAGS="$CFLAGS" LIBS="conftstm.$objext" CFLAGS="$CFLAGS$no_builtin_flag" if { (eval echo $progname:1648: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then pipe_works=yes else echo "$progname: failed program was:" >&5 cat conftest.c >&5 fi LIBS="$save_LIBS" else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.c >&5 fi $rm conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else global_symbol_pipe= fi done if test "$pipe_works" = yes; then echo "${ac_t}ok" 1>&6 else echo "${ac_t}failed" 1>&6 fi if test -z "$global_symbol_pipe"; then global_symbol_to_cdecl= fi # Check hardcoding attributes. echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6 hardcode_action= if test -n "$hardcode_libdir_flag_spec" || \ test -n "$runpath_var"; then # We can hardcode non-existant directories. if test "$hardcode_direct" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$hardcode_shlibpath_var" != no && test "$hardcode_minus_L" != no; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi echo "$ac_t$hardcode_action" 1>&6 reload_flag= reload_cmds='$LD$reload_flag -o $output$reload_objs' echo $ac_n "checking for $LD option to reload object files... $ac_c" 1>&6 # PORTME Some linkers may need a different reload flag. reload_flag='-r' echo "$ac_t$reload_flag" 1>&6 test -n "$reload_flag" && reload_flag=" $reload_flag" # PORTME Fill in your ld.so characteristics library_names_spec= libname_spec='lib$name' soname_spec= postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" file_magic_cmd= file_magic_test_file= deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # `unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [regex]' -- check by looking for files in library path # which responds to the $file_magic_cmd with a given egrep regex. # If you have `file' or equivalent on your system and you're not sure # whether `pass_all' will *always* work, you probably want this one. echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6 case "$host_os" in aix3*) version_type=linux library_names_spec='${libname}${release}.so$versuffix $libname.a' shlibpath_var=LIBPATH # AIX has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}.so$major' ;; aix4*) version_type=linux # AIX has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. # We preserve .a as extension for shared libraries though AIX4.2 # and later linker supports .so library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.a' shlibpath_var=LIBPATH deplibs_check_method=pass_all ;; amigaos*) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done' ;; beos*) library_names_spec='${libname}.so' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH deplibs_check_method=pass_all lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; bsdi4*) version_type=linux library_names_spec='${libname}.so$major ${libname}.so' soname_spec='${libname}.so' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' file_magic_cmd=/usr/bin/file file_magic_test_file=/shlib/libc.so sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw*) version_type=windows need_version=no need_lib_prefix=no if test "$with_gcc" = yes; then library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.a' else library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib' fi dynamic_linker='Win32 ld.exe' deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' file_magic_cmd='${OBJDUMP} -f' # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; freebsd1*) dynamic_linker=no ;; freebsd*) objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` version_type=freebsd-$objformat case "$version_type" in freebsd-elf*) deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object' file_magic_cmd=/usr/bin/file file_magic_test_file=`echo /usr/lib/libc.so*` library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' need_version=no need_lib_prefix=no ;; freebsd-*) deplibs_check_method=unknown library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix' need_version=yes ;; esac finish_cmds='PATH="\$PATH:/sbin" OBJFORMAT="'"$objformat"'" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH case "$host_os" in freebsd2* | freebsd3.[01]*) shlibpath_overrides_runpath=yes ;; *) # from 3.2 on shlibpath_overrides_runpath=no ;; esac ;; gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so' soname_spec='${libname}${release}.so$major' shlibpath_var=LD_LIBRARY_PATH ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. dynamic_linker="$host_os dld.sl" version_type=sunos need_lib_prefix=no need_version=no shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl' soname_spec='${libname}${release}.sl$major' # HP-UX runs *really* slowly unless shared libraries are mode 555. postinstall_cmds='chmod 555 $lib' ;; irix5* | irix6*) version_type=irix need_lib_prefix=no need_version=no soname_spec='${libname}${release}.so.$major' library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major ${libname}${release}.so $libname.so' case "$host_os" in irix5*) libsuff= shlibsuff= # this will be overridden with pass_all, but let us keep it just in case deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" ;; *) case "$LD" in # libtool.m4 will add one of these switches to LD *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac # this will be overridden with pass_all, but let us keep it just in case deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1" ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" file_magic_cmd=/usr/bin/file file_magic_test_file=`echo /lib${libsuff}/libc.so*` deplibs_check_method='pass_all' ;; # No shared lib support for Linux oldld, aout, or coff. linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*) dynamic_linker=no ;; # This must be Linux ELF. linux-gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' soname_spec='${libname}${release}.so$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' file_magic_cmd=/usr/bin/file file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` if test -f /lib/ld.so.1; then dynamic_linker='GNU ld.so' else # Only the GNU ld.so supports shared libraries on MkLinux. case "$host_cpu" in powerpc*) dynamic_linker=no ;; *) dynamic_linker='Linux ld.so' ;; esac fi ;; netbsd*) version_type=sunos if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so' soname_spec='${libname}${release}.so$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH ;; openbsd*) version_type=sunos if test "$with_gnu_ld" = yes; then need_lib_prefix=no need_version=no fi library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH ;; os2*) libname_spec='$name' need_lib_prefix=no library_names_spec='$libname.dll $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4*) version_type=osf need_version=no soname_spec='${libname}${release}.so' library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' shlibpath_var=LD_LIBRARY_PATH # this will be overridden with pass_all, but let us keep it just in case deplibs_check_method='file_magic COFF format alpha shared library' file_magic_cmd=/usr/bin/file file_magic_test_file=/shlib/libc.so deplibs_check_method='pass_all' sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; sco3.2v5*) version_type=osf soname_spec='${libname}${release}.so$major' library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' shlibpath_var=LD_LIBRARY_PATH ;; solaris*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' soname_spec='${libname}${release}.so$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' deplibs_check_method="file_magic ELF [0-9][0-9]-bit [LM]SB dynamic lib" file_magic_cmd=/usr/bin/file file_magic_test_file=/lib/libc.so ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) version_type=linux library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' soname_spec='${libname}${release}.so$major' shlibpath_var=LD_LIBRARY_PATH case "$host_vendor" in ncr) deplibs_check_method='pass_all' ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' file_magic_cmd=/usr/bin/file file_magic_test_file=`echo /usr/lib/libc.so*` ;; esac ;; uts4*) version_type=linux library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' soname_spec='${libname}${release}.so$major' shlibpath_var=LD_LIBRARY_PATH ;; dgux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' soname_spec='${libname}${release}.so$major' shlibpath_var=LD_LIBRARY_PATH ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so' soname_spec='$libname.so.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; *) dynamic_linker=no ;; esac echo "$ac_t$dynamic_linker" 1>&6 test "$dynamic_linker" = no && can_build_shared=no # Report the final consequences. echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6 # Only try to build win32 dlls if AC_LIBTOOL_WIN32_DLL was used in # configure.in, otherwise build static only libraries. case "$host_os" in cygwin* | mingw* | os2*) if test x$can_build_shared = xyes; then test x$enable_win32_dll = xno && can_build_shared=no echo "checking if package supports dlls... $can_build_shared" 1>&6 fi ;; esac if test -n "$file_magic_test_file" && test -n "$file_magic_cmd"; then case "$deplibs_check_method" in "file_magic "*) file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | egrep "$file_magic_regex" > /dev/null; then : else cat <&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org EOF fi ;; esac fi echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6 test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case "$host_os" in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix4*) test "$enable_shared" = yes && enable_static=no ;; esac echo "$ac_t$enable_shared" 1>&6 # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes echo "checking whether to build static libraries... $enable_static" 1>&6 if test "$hardcode_action" = relink; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi echo $ac_n "checking for objdir... $ac_c" 1>&6 rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. objdir=_libs fi rmdir .libs 2>/dev/null echo "$ac_t$objdir" 1>&6 if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else if eval "test \"`echo '$''{'lt_cv_dlopen'+set}'`\" != set"; then lt_cv_dlopen=no lt_cv_dlopen_libs= echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 echo "$progname:2170: checking for dlopen in -ldl" >&5 ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ldl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else echo "$ac_t""no" 1>&6 echo $ac_n "checking for dlopen""... $ac_c" 1>&6 echo "$progname:2207: checking for dlopen" >&5 if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char dlopen(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_dlopen) || defined (__stub___dlopen) choke me #else dlopen(); #endif ; return 0; } EOF if { (eval echo $progname:2234: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_dlopen=yes" else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_dlopen=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then echo "$ac_t""yes" 1>&6 lt_cv_dlopen="dlopen" else echo "$ac_t""no" 1>&6 echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6 echo "$progname:2251: checking for dld_link in -ldld" >&5 ac_lib_var=`echo dld'_'dld_link | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ldld $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" else echo "$ac_t""no" 1>&6 echo $ac_n "checking for shl_load""... $ac_c" 1>&6 echo "$progname:2288: checking for shl_load" >&5 if eval "test \"`echo '$''{'ac_cv_func_shl_load'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char shl_load(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_shl_load) || defined (__stub___shl_load) choke me #else shl_load(); #endif ; return 0; } EOF if { (eval echo $progname:2315: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_shl_load=yes" else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_shl_load=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'shl_load`\" = yes"; then echo "$ac_t""yes" 1>&6 lt_cv_dlopen="shl_load" else echo "$ac_t""no" 1>&6 echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6 echo "$progname:2333: checking for shl_load in -ldld" >&5 ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ldld $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" else echo "$ac_t""no" 1>&6 fi fi fi fi fi fi if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes fi case "$lt_cv_dlopen" in dlopen) for ac_hdr in dlfcn.h; do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "$progname:2395: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int fnord = 0; EOF ac_try="$ac_compile conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo $progname:2405: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 else echo "$ac_t""no" 1>&6 fi done if test "x$ac_cv_header_dlfcn_h" = xyes; then CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" fi eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" LIBS="$lt_cv_dlopen_libs $LIBS" echo $ac_n "checking whether a program can dlopen itself""... $ac_c" 1>&6 echo "$progname:2433: checking whether a program can dlopen itself" >&5 if test "${lt_cv_dlopen_self+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then lt_cv_dlopen_self=cross else cat > conftest.c < #endif #include #ifdef RTLD_GLOBAL # define LTDL_GLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LTDL_GLOBAL DL_GLOBAL # else # define LTDL_GLOBAL 0 # endif #endif /* We may have to define LTDL_LAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LTDL_LAZY_OR_NOW # ifdef RTLD_LAZY # define LTDL_LAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LTDL_LAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LTDL_LAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LTDL_LAZY_OR_NOW DL_NOW # else # define LTDL_LAZY_OR_NOW 0 # endif # endif # endif # endif #endif fnord() { int i=42;} main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW); if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord"); if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } EOF if { (eval echo $progname:2487: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then lt_cv_dlopen_self=yes else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* lt_cv_dlopen_self=no fi rm -fr conftest* fi fi echo "$ac_t""$lt_cv_dlopen_self" 1>&6 if test "$lt_cv_dlopen_self" = yes; then LDFLAGS="$LDFLAGS $link_static_flag" echo $ac_n "checking whether a statically linked program can dlopen itself""... $ac_c" 1>&6 echo "$progname:2506: checking whether a statically linked program can dlopen itself" >&5 if test "${lt_cv_dlopen_self_static+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then lt_cv_dlopen_self_static=cross else cat > conftest.c < #endif #include #ifdef RTLD_GLOBAL # define LTDL_GLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LTDL_GLOBAL DL_GLOBAL # else # define LTDL_GLOBAL 0 # endif #endif /* We may have to define LTDL_LAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LTDL_LAZY_OR_NOW # ifdef RTLD_LAZY # define LTDL_LAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LTDL_LAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LTDL_LAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LTDL_LAZY_OR_NOW DL_NOW # else # define LTDL_LAZY_OR_NOW 0 # endif # endif # endif # endif #endif fnord() { int i=42;} main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW); if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord"); if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } EOF if { (eval echo $progname:2560: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then lt_cv_dlopen_self_static=yes else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* lt_cv_dlopen_self_static=no fi rm -fr conftest* fi fi echo "$ac_t""$lt_cv_dlopen_self_static" 1>&6 fi ;; esac case "$lt_cv_dlopen_self" in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case "$lt_cv_dlopen_self_static" in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi # Copy echo and quote the copy, instead of the original, because it is # used later. ltecho="$echo" if test "X$ltecho" = "X$CONFIG_SHELL $0 --fallback-echo"; then ltecho="$CONFIG_SHELL \$0 --fallback-echo" fi LTSHELL="$SHELL" LTCONFIG_VERSION="$VERSION" # Only quote variables if we're using ltmain.sh. case "$ltmain" in *.sh) # Now quote all the things that may contain metacharacters. for var in ltecho old_CC old_CFLAGS old_CPPFLAGS \ old_LD old_LDFLAGS old_LIBS \ old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS \ AR CC LD LN_S NM LTSHELL LTCONFIG_VERSION \ reload_flag reload_cmds wl \ pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \ thread_safe_flag_spec whole_archive_flag_spec libname_spec \ library_names_spec soname_spec \ RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \ old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds postuninstall_cmds \ file_magic_cmd export_symbols_cmds deplibs_check_method allow_undefined_flag no_undefined_flag \ finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \ hardcode_libdir_flag_spec hardcode_libdir_separator \ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do case "$var" in reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \ old_postinstall_cmds | old_postuninstall_cmds | \ export_symbols_cmds | archive_cmds | archive_expsym_cmds | \ postinstall_cmds | postuninstall_cmds | \ finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) # Double-quote double-evaled strings. eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" ;; *) eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" ;; esac done case "$ltecho" in *'\$0 --fallback-echo"') ltecho=`$echo "X$ltecho" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` ;; esac trap "$rm \"$ofile\"; exit 1" 1 2 15 echo "creating $ofile" $rm "$ofile" cat < "$ofile" #! $SHELL # `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) # NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh. # # Copyright (C) 1996-1999 Free Software Foundation, Inc. # Gordon Matzigkeit , 1996 # # 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 2 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="sed -e s/^X//" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. if test "\${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi ### BEGIN LIBTOOL CONFIG EOF cfgfile="$ofile" ;; *) # Double-quote the variables that need it (for aesthetics). for var in old_CC old_CFLAGS old_CPPFLAGS \ old_LD old_LDFLAGS old_LIBS \ old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS; do eval "$var=\\\"\$var\\\"" done # Just create a config file. cfgfile="$ofile.cfg" trap "$rm \"$cfgfile\"; exit 1" 1 2 15 echo "creating $cfgfile" $rm "$cfgfile" cat < "$cfgfile" # `$echo "$cfgfile" | sed 's%^.*/%%'` - Libtool configuration file. # Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) EOF ;; esac cat <> "$cfgfile" # Libtool was configured as follows, on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # # CC=$old_CC CFLAGS=$old_CFLAGS CPPFLAGS=$old_CPPFLAGS \\ # LD=$old_LD LDFLAGS=$old_LDFLAGS LIBS=$old_LIBS \\ # NM=$old_NM RANLIB=$old_RANLIB LN_S=$old_LN_S \\ # DLLTOOL=$old_DLLTOOL OBJDUMP=$old_OBJDUMP AS=$old_AS \\ # $0$ltconfig_args # # Compiler and other test output produced by $progname, useful for # debugging $progname, is in ./config.log if it exists. # The version of $progname that generated this script. LTCONFIG_VERSION=$LTCONFIG_VERSION # Shell to use when invoking shell scripts. SHELL=$LTSHELL # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # The host system. host_alias=$host_alias host=$host # An echo program that does not interpret backslashes. echo=$ltecho # The archiver. AR=$AR # The default C compiler. CC=$CC # The linker used to build libraries. LD=$LD # Whether we need hard or soft links. LN_S=$LN_S # A BSD-compatible nm program. NM=$NM # Used on cygwin: DLL creation program. DLLTOOL="$DLLTOOL" # Used on cygwin: object dumper. OBJDUMP="$OBJDUMP" # Used on cygwin: assembler. AS="$AS" # The name of the directory that contains temporary libtool files. objdir=$objdir # How to create reloadable object files. reload_flag=$reload_flag reload_cmds=$reload_cmds # How to pass a linker flag through the compiler. wl=$wl # Object file suffix (normally "o"). objext="$objext" # Old archive suffix (normally "a"). libext="$libext" # Executable file suffix (normally ""). exeext="$exeext" # Additional compiler flags for building library objects. pic_flag=$pic_flag # Does compiler simultaneously support -c and -o options? compiler_c_o=$compiler_c_o # Can we write directly to a .lo ? compiler_o_lo=$compiler_o_lo # Must we lock files when doing compilation ? need_locks=$need_locks # Do we need the lib prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Whether dlopen is supported. dlopen=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Compiler flag to prevent dynamic linking. link_static_flag=$link_static_flag # Compiler flag to turn off builtin functions. no_builtin_flag=$no_builtin_flag # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$whole_archive_flag_spec # Compiler flag to generate thread-safe objects. thread_safe_flag_spec=$thread_safe_flag_spec # Library versioning type. version_type=$version_type # Format of library name prefix. libname_spec=$libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME. library_names_spec=$library_names_spec # The coded name of the library, if different from the real name. soname_spec=$soname_spec # Commands used to build and install an old-style archive. RANLIB=$RANLIB old_archive_cmds=$old_archive_cmds old_postinstall_cmds=$old_postinstall_cmds old_postuninstall_cmds=$old_postuninstall_cmds # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$old_archive_from_new_cmds # Commands used to build and install a shared archive. archive_cmds=$archive_cmds archive_expsym_cmds=$archive_expsym_cmds postinstall_cmds=$postinstall_cmds postuninstall_cmds=$postuninstall_cmds # Method to check whether dependent libraries are shared objects. deplibs_check_method=$deplibs_check_method # Command to use when deplibs_check_method == file_magic. file_magic_cmd=$file_magic_cmd # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$allow_undefined_flag # Flag that forces no undefined symbols. no_undefined_flag=$no_undefined_flag # Commands used to finish a libtool library installation in a directory. finish_cmds=$finish_cmds # Same as above, but a single script fragment to be evaled but not shown. finish_eval=$finish_eval # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$global_symbol_pipe # Transform the output of nm in a proper C declaration global_symbol_to_cdecl=$global_symbol_to_cdecl # This is the shared library runtime path variable. runpath_var=$runpath_var # This is the shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist. hardcode_libdir_flag_spec=$hardcode_libdir_flag_spec # Whether we need a single -rpath flag with a separated argument. hardcode_libdir_separator=$hardcode_libdir_separator # Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the # resulting binary. hardcode_direct=$hardcode_direct # Set to yes if using the -LDIR flag during linking hardcodes DIR into the # resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into # the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Compile-time system search path for libraries sys_lib_search_path_spec=$sys_lib_search_path_spec # Run-time system search path for libraries sys_lib_dlsearch_path_spec=$sys_lib_dlsearch_path_spec # Fix the shell variable \$srcfile for the compiler. fix_srcfile_path="$fix_srcfile_path" # Set to yes if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$exclude_expsyms # Symbols that must always be exported. include_expsyms=$include_expsyms EOF case "$ltmain" in *.sh) echo '### END LIBTOOL CONFIG' >> "$ofile" echo >> "$ofile" case "$host_os" in aix3*) cat <<\EOF >> "$ofile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "${COLLECT_NAMES+set}" != set; then COLLECT_NAMES= export COLLECT_NAMES fi EOF ;; esac # Append the ltmain.sh script. sed '$q' "$ltmain" >> "$ofile" || (rm -f "$ofile"; exit 1) chmod +x "$ofile" ;; *) # Compile the libtool program. echo "FIXME: would compile $ltmain" ;; esac test -n "$cache_file" || exit 0 # AC_CACHE_SAVE trap '' 1 2 15 cat > confcache <<\EOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs. It is not useful on other systems. # If it contains results you don't want to keep, you may remove or edit it. # # By default, configure uses ./config.cache as the cache file, # creating it if it does not exist already. You can give configure # the --cache-file=FILE option to use a different cache file; that is # what configure does when it calls configure scripts in # subdirectories, so they share the cache. # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # EOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote substitution # turns \\\\ into \\, and sed turns \\ into \). sed -n \ -e "s/'/'\\\\''/g" \ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' ;; esac >> confcache if cmp -s $cache_file confcache; then : else if test -w $cache_file; then echo "updating cache $cache_file" cat confcache > $cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache exit 0 # Local Variables: # mode:shell-script # sh-indentation:2 # End: lyskom-server-2.1.2/src/libraries/liboop/ltmain.sh0000664000015100472110000042316607703073502015703 # ltmain.sh - Provide generalized library-building support services. # NOTE: Changing this file will not affect anything until you rerun configure. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 # Free Software Foundation, Inc. # Originally by Gordon Matzigkeit , 1996 # # 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 2 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Check that we have a working $echo. if test "X$1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X$1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then # Yippee, $echo works! : else # Restart under the correct shell, and then maybe $echo will work. exec $SHELL "$0" --no-reexec ${1+"$@"} fi if test "X$1" = X--fallback-echo; then # used as fallback echo shift cat <&2 echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 exit 1 fi # Global variables. mode=$default_mode nonopt= prev= prevopt= run= show="$echo" show_help= execute_dlfiles= lo2o="s/\\.lo\$/.${objext}/" o2lo="s/\\.${objext}\$/.lo/" # Parse our command line options once, thoroughly. while test $# -gt 0 do arg="$1" shift case $arg in -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; *) optarg= ;; esac # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in execute_dlfiles) execute_dlfiles="$execute_dlfiles $arg" ;; *) eval "$prev=\$arg" ;; esac prev= prevopt= continue fi # Have we seen a non-optional argument yet? case $arg in --help) show_help=yes ;; --version) echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" exit 0 ;; --config) sed -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $0 exit 0 ;; --debug) echo "$progname: enabling shell trace mode" set -x ;; --dry-run | -n) run=: ;; --features) echo "host: $host" if test "$build_libtool_libs" = yes; then echo "enable shared libraries" else echo "disable shared libraries" fi if test "$build_old_libs" = yes; then echo "enable static libraries" else echo "disable static libraries" fi exit 0 ;; --finish) mode="finish" ;; --mode) prevopt="--mode" prev=mode ;; --mode=*) mode="$optarg" ;; --preserve-dup-deps) duplicate_deps="yes" ;; --quiet | --silent) show=: ;; -dlopen) prevopt="-dlopen" prev=execute_dlfiles ;; -*) $echo "$modename: unrecognized option \`$arg'" 1>&2 $echo "$help" 1>&2 exit 1 ;; *) nonopt="$arg" break ;; esac done if test -n "$prevopt"; then $echo "$modename: option \`$prevopt' requires an argument" 1>&2 $echo "$help" 1>&2 exit 1 fi # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= if test -z "$show_help"; then # Infer the operation mode. if test -z "$mode"; then case $nonopt in *cc | *++ | gcc* | *-gcc*) mode=link for arg do case $arg in -c) mode=compile break ;; esac done ;; *db | *dbx | *strace | *truss) mode=execute ;; *install*|cp|mv) mode=install ;; *rm) mode=uninstall ;; *) # If we have no mode, but dlfiles were specified, then do execute mode. test -n "$execute_dlfiles" && mode=execute # Just use the default operation mode. if test -z "$mode"; then if test -n "$nonopt"; then $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 else $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 fi fi ;; esac fi # Only execute mode is allowed to have -dlopen flags. if test -n "$execute_dlfiles" && test "$mode" != execute; then $echo "$modename: unrecognized option \`-dlopen'" 1>&2 $echo "$help" 1>&2 exit 1 fi # Change the help message to a mode-specific one. generic_help="$help" help="Try \`$modename --help --mode=$mode' for more information." # These modes are in order of execution frequency so that they run quickly. case $mode in # libtool compile mode compile) modename="$modename: compile" # Get the compilation command and the source file. base_compile= prev= lastarg= srcfile="$nonopt" suppress_output= user_target=no for arg do case $prev in "") ;; xcompiler) # Aesthetically quote the previous argument. prev= lastarg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case $arg in # Double-quote args containing other shell metacharacters. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") arg="\"$arg\"" ;; esac # Add the previous argument to base_compile. if test -z "$base_compile"; then base_compile="$lastarg" else base_compile="$base_compile $lastarg" fi continue ;; esac # Accept any command-line options. case $arg in -o) if test "$user_target" != "no"; then $echo "$modename: you cannot specify \`-o' more than once" 1>&2 exit 1 fi user_target=next ;; -static) build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; -Xcompiler) prev=xcompiler continue ;; -Wc,*) args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` lastarg= save_ifs="$IFS"; IFS=',' for arg in $args; do IFS="$save_ifs" # Double-quote args containing other shell metacharacters. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. case $arg in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") arg="\"$arg\"" ;; esac lastarg="$lastarg $arg" done IFS="$save_ifs" lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` # Add the arguments to base_compile. if test -z "$base_compile"; then base_compile="$lastarg" else base_compile="$base_compile $lastarg" fi continue ;; esac case $user_target in next) # The next one is the -o target name user_target=yes continue ;; yes) # We got the output file user_target=set libobj="$arg" continue ;; esac # Accept the current argument as the source file. lastarg="$srcfile" srcfile="$arg" # Aesthetically quote the previous argument. # Backslashify any backslashes, double quotes, and dollar signs. # These are the only characters that are still specially # interpreted inside of double-quoted scrings. lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` # Double-quote args containing other shell metacharacters. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. case $lastarg in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") lastarg="\"$lastarg\"" ;; esac # Add the previous argument to base_compile. if test -z "$base_compile"; then base_compile="$lastarg" else base_compile="$base_compile $lastarg" fi done case $user_target in set) ;; no) # Get the name of the library object. libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` ;; *) $echo "$modename: you must specify a target with \`-o'" 1>&2 exit 1 ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo xform='[cCFSfmso]' case $libobj in *.ada) xform=ada ;; *.adb) xform=adb ;; *.ads) xform=ads ;; *.asm) xform=asm ;; *.c++) xform=c++ ;; *.cc) xform=cc ;; *.cpp) xform=cpp ;; *.cxx) xform=cxx ;; *.f90) xform=f90 ;; *.for) xform=for ;; esac libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` case $libobj in *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; *) $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 exit 1 ;; esac if test -z "$base_compile"; then $echo "$modename: you must specify a compilation command" 1>&2 $echo "$help" 1>&2 exit 1 fi # Delete any leftover library objects. if test "$build_old_libs" = yes; then removelist="$obj $libobj" else removelist="$libobj" fi $run $rm $removelist trap "$run $rm $removelist; exit 1" 1 2 15 # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2*) pic_mode=default ;; esac if test $pic_mode = no && test "$deplibs_check_method" != pass_all; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test "$compiler_c_o" = no; then output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} lockfile="$output_obj.lock" removelist="$removelist $output_obj $lockfile" trap "$run $rm $removelist; exit 1" 1 2 15 else need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test "$need_locks" = yes; then until $run ln "$0" "$lockfile" 2>/dev/null; do $show "Waiting for $lockfile to be removed" sleep 2 done elif test "$need_locks" = warn; then if test -f "$lockfile"; then echo "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $run $rm $removelist exit 1 fi echo $srcfile > "$lockfile" fi if test -n "$fix_srcfile_path"; then eval srcfile=\"$fix_srcfile_path\" fi # Only build a PIC object if we are building libtool libraries. if test "$build_libtool_libs" = yes; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test "$pic_mode" != no; then # All platforms use -DPIC, to notify preprocessed assembler code. command="$base_compile $srcfile $pic_flag -DPIC" else # Don't build PIC code command="$base_compile $srcfile" fi if test "$build_old_libs" = yes; then lo_libobj="$libobj" dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` if test "X$dir" = "X$libobj"; then dir="$objdir" else dir="$dir/$objdir" fi libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` if test -d "$dir"; then $show "$rm $libobj" $run $rm $libobj else $show "$mkdir $dir" $run $mkdir $dir status=$? if test $status -ne 0 && test ! -d $dir; then exit $status fi fi fi if test "$compiler_o_lo" = yes; then output_obj="$libobj" command="$command -o $output_obj" elif test "$compiler_c_o" = yes; then output_obj="$obj" command="$command -o $output_obj" fi $run $rm "$output_obj" $show "$command" if $run eval "$command"; then : else test -n "$output_obj" && $run $rm $removelist exit 1 fi if test "$need_locks" = warn && test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then echo "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $run $rm $removelist exit 1 fi # Just move the object if needed, then go on to compile the next one if test x"$output_obj" != x"$libobj"; then $show "$mv $output_obj $libobj" if $run $mv $output_obj $libobj; then : else error=$? $run $rm $removelist exit $error fi fi # If we have no pic_flag, then copy the object into place and finish. if (test -z "$pic_flag" || test "$pic_mode" != default) && test "$build_old_libs" = yes; then # Rename the .lo from within objdir to obj if test -f $obj; then $show $rm $obj $run $rm $obj fi $show "$mv $libobj $obj" if $run $mv $libobj $obj; then : else error=$? $run $rm $removelist exit $error fi xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` if test "X$xdir" = "X$obj"; then xdir="." else xdir="$xdir" fi baseobj=`$echo "X$obj" | $Xsed -e "s%.*/%%"` libobj=`$echo "X$baseobj" | $Xsed -e "$o2lo"` # Now arrange that obj and lo_libobj become the same file $show "(cd $xdir && $LN_S $baseobj $libobj)" if $run eval '(cd $xdir && $LN_S $baseobj $libobj)'; then # Unlock the critical section if it was locked if test "$need_locks" != no; then $run $rm "$lockfile" fi exit 0 else error=$? $run $rm $removelist exit $error fi fi # Allow error messages only from the first compilation. suppress_output=' >/dev/null 2>&1' fi # Only build a position-dependent object if we build old libraries. if test "$build_old_libs" = yes; then if test "$pic_mode" != yes; then # Don't build PIC code command="$base_compile $srcfile" else # All platforms use -DPIC, to notify preprocessed assembler code. command="$base_compile $srcfile $pic_flag -DPIC" fi if test "$compiler_c_o" = yes; then command="$command -o $obj" output_obj="$obj" fi # Suppress compiler output if we already did a PIC compilation. command="$command$suppress_output" $run $rm "$output_obj" $show "$command" if $run eval "$command"; then : else $run $rm $removelist exit 1 fi if test "$need_locks" = warn && test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then echo "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $run $rm $removelist exit 1 fi # Just move the object if needed if test x"$output_obj" != x"$obj"; then $show "$mv $output_obj $obj" if $run $mv $output_obj $obj; then : else error=$? $run $rm $removelist exit $error fi fi # Create an invalid libtool object if no PIC, so that we do not # accidentally link it into a program. if test "$build_libtool_libs" != yes; then $show "echo timestamp > $libobj" $run eval "echo timestamp > \$libobj" || exit $? else # Move the .lo from within objdir $show "$mv $libobj $lo_libobj" if $run $mv $libobj $lo_libobj; then : else error=$? $run $rm $removelist exit $error fi fi fi # Unlock the critical section if it was locked if test "$need_locks" != no; then $run $rm "$lockfile" fi exit 0 ;; # libtool link mode link | relink) modename="$modename: link" case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # which system we are compiling for in order to pass an extra # flag for every libtool invokation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll which has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args="$nonopt" compile_command="$nonopt" finalize_command="$nonopt" compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` avoid_version=no dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= prefer_static_libs=no preload=no prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= # We need to know -static, to get the right output filenames. for arg do case $arg in -all-static | -static) if test "X$arg" = "X-all-static"; then if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2 fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi else if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi fi build_libtool_libs=no build_old_libs=yes prefer_static_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test $# -gt 0; do arg="$1" shift case $arg in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test ;; *) qarg=$arg ;; esac libtool_args="$libtool_args $qarg" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) compile_command="$compile_command @OUTPUT@" finalize_command="$finalize_command @OUTPUT@" ;; esac case $prev in dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. compile_command="$compile_command @SYMFILE@" finalize_command="$finalize_command @SYMFILE@" preload=yes fi case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test "$dlself" = no; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test "$prev" = dlprefiles; then dlself=yes elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test "$prev" = dlfiles; then dlfiles="$dlfiles $arg" else dlprefiles="$dlprefiles $arg" fi prev= continue ;; esac ;; expsyms) export_symbols="$arg" if test ! -f "$arg"; then $echo "$modename: symbol file \`$arg' does not exist" exit 1 fi prev= continue ;; expsyms_regex) export_symbols_regex="$arg" prev= continue ;; release) release="-$arg" prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) $echo "$modename: only absolute run-paths are allowed" 1>&2 exit 1 ;; esac if test "$prev" = rpath; then case "$rpath " in *" $arg "*) ;; *) rpath="$rpath $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) xrpath="$xrpath $arg" ;; esac fi prev= continue ;; xcompiler) compiler_flags="$compiler_flags $qarg" prev= compile_command="$compile_command $qarg" finalize_command="$finalize_command $qarg" continue ;; xlinker) linker_flags="$linker_flags $qarg" compiler_flags="$compiler_flags $wl$qarg" prev= compile_command="$compile_command $wl$qarg" finalize_command="$finalize_command $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n $prev prevarg="$arg" case $arg in -all-static) if test -n "$link_static_flag"; then compile_command="$compile_command $link_static_flag" finalize_command="$finalize_command $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 continue ;; -avoid-version) avoid_version=yes continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then $echo "$modename: more than one -exported-symbols argument is not allowed" exit 1 fi if test "X$arg" = "X-export-symbols"; then prev=expsyms else prev=expsyms_regex fi continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | no/*-*-nonstopux*) compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" ;; esac continue ;; -L*) dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 exit 1 fi dir="$absdir" ;; esac case "$deplibs " in *" -L$dir "*) ;; *) deplibs="$deplibs -L$dir" lib_search_path="$lib_search_path $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) case :$dllsearchpath: in *":$dir:"*) ;; *) dllsearchpath="$dllsearchpath:$dir";; esac ;; esac continue ;; -l*) if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then case $host in *-*-cygwin* | *-*-pw32* | *-*-beos*) # These systems don't actually have a C or math library (as such) continue ;; *-*-mingw* | *-*-os2*) # These systems don't actually have a C library (as such) test "X$arg" = "X-lc" && continue ;; *-*-openbsd* | *-*-freebsd*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; esac elif test "X$arg" = "X-lc_r"; then case $host in *-*-openbsd* | *-*-freebsd*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi deplibs="$deplibs $arg" continue ;; -module) module=yes continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) # The PATH hackery in wrapper scripts is required on Windows # in order for the loader to find any dlls it needs. $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -o) prev=output ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) $echo "$modename: only absolute run-paths are allowed" 1>&2 exit 1 ;; esac case "$xrpath " in *" $dir "*) ;; *) xrpath="$xrpath $dir" ;; esac continue ;; -static) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -Wc,*) args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" case $flag in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") flag="\"$flag\"" ;; esac arg="$arg $wl$flag" compiler_flags="$compiler_flags $flag" done IFS="$save_ifs" arg=`$echo "X$arg" | $Xsed -e "s/^ //"` ;; -Wl,*) args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" case $flag in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") flag="\"$flag\"" ;; esac arg="$arg $wl$flag" compiler_flags="$compiler_flags $wl$flag" linker_flags="$linker_flags $flag" done IFS="$save_ifs" arg=`$echo "X$arg" | $Xsed -e "s/^ //"` ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; # Some other compiler flag. -* | +*) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case $arg in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") arg="\"$arg\"" ;; esac ;; *.lo | *.$objext) # A library or standard object. if test "$prev" = dlfiles; then # This file was specified with -dlopen. if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then dlfiles="$dlfiles $arg" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi if test "$prev" = dlprefiles; then # Preload the old-style object. dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"` prev= else case $arg in *.lo) libobjs="$libobjs $arg" ;; *) objs="$objs $arg" ;; esac fi ;; *.$libext) # An archive. deplibs="$deplibs $arg" old_deplibs="$old_deplibs $arg" continue ;; *.la) # A libtool-controlled library. if test "$prev" = dlfiles; then # This library was specified with -dlopen. dlfiles="$dlfiles $arg" prev= elif test "$prev" = dlprefiles; then # The library was specified with -dlpreopen. dlprefiles="$dlprefiles $arg" prev= else deplibs="$deplibs $arg" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case $arg in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") arg="\"$arg\"" ;; esac ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" fi done # argument parsing loop if test -n "$prev"; then $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 $echo "$help" 1>&2 exit 1 fi if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" fi # calculate the name of the file, without its directory outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` libobjs_save="$libobjs" if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` if test "X$output_objdir" = "X$output"; then output_objdir="$objdir" else output_objdir="$output_objdir/$objdir" fi # Create the object directory. if test ! -d $output_objdir; then $show "$mkdir $output_objdir" $run $mkdir $output_objdir status=$? if test $status -ne 0 && test ! -d $output_objdir; then exit $status fi fi # Determine the type of output case $output in "") $echo "$modename: you must specify an output file" 1>&2 $echo "$help" 1>&2 exit 1 ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if test "X$duplicate_deps" = "Xyes" ; then case "$libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi libs="$libs $deplib" done deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 exit 1 ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=no newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do if test $linkmode = prog; then # Determine which files to process case $pass in dlopen) libs="$dlfiles" save_deplibs="$deplibs" # Collect dlpreopened libraries deplibs= ;; dlpreopen) libs="$dlprefiles" ;; link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; esac fi for deplib in $libs; do lib= found=no case $deplib in -l*) if test $linkmode = oldlib && test $linkmode = obj; then $echo "$modename: warning: \`-l' is ignored for archives/objects: $deplib" 1>&2 continue fi if test $pass = conv; then deplibs="$deplib $deplibs" continue fi name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do # Search the libtool library lib="$searchdir/lib${name}.la" if test -f "$lib"; then found=yes break fi done if test "$found" != yes; then # deplib doesn't seem to be a libtool library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test $linkmode = lib && newdependency_libs="$deplib $newdependency_libs" fi continue fi ;; # -l -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test $pass = conv && continue newdependency_libs="$deplib $newdependency_libs" newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` ;; prog) if test $pass = conv; then deplibs="$deplib $deplibs" continue fi if test $pass = scan; then deplibs="$deplib $deplibs" newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi ;; *) $echo "$modename: warning: \`-L' is ignored for archives/objects: $deplib" 1>&2 ;; esac # linkmode continue ;; # -L -R*) if test $pass = link; then dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) xrpath="$xrpath $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) lib="$deplib" ;; *.$libext) if test $pass = conv; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) if test "$deplibs_check_method" != pass_all; then echo echo "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not used here." else echo echo "*** Warning: Linking the shared library $output against the" echo "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" fi continue ;; prog) if test $pass != link; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test $pass = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlopen support or we're linking statically, # we need to preload. newdlprefiles="$newdlprefiles $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else newdlfiles="$newdlfiles $deplib" fi continue ;; %DEPLIBS%) alldeplibs=yes continue ;; esac # case $deplib if test $found = yes || test -f "$lib"; then : else $echo "$modename: cannot find the library \`$lib'" 1>&2 exit 1 fi # Check to see that this really is a libtool archive. if (sed -e '2q' $lib | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : else $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 exit 1 fi ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` test "X$ladir" = "X$lib" && ladir="." dlname= dlopen= dlpreopen= libdir= library_names= old_library= # If the library was installed with an old release of libtool, # it will not redefine variable installed. installed=yes # Read the .la file case $lib in */* | *\\*) . $lib ;; *) . ./$lib ;; esac if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan" || { test $linkmode = oldlib && test $linkmode = obj; }; then # Add dl[pre]opened files of deplib test -n "$dlopen" && dlfiles="$dlfiles $dlopen" test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" fi if test $pass = conv; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 exit 1 fi # It is a libtool convenience library, so add in its objects. convenience="$convenience $ladir/$objdir/$old_library" old_convenience="$old_convenience $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if test "X$duplicate_deps" = "Xyes" ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done elif test $linkmode != prog && test $linkmode != lib; then $echo "$modename: \`$lib' is not a convenience library" 1>&2 exit 1 fi continue fi # $pass = conv # Get the name of the library we link against. linklib= for l in $old_library $library_names; do linklib="$l" done if test -z "$linklib"; then $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 exit 1 fi # This library was specified with -dlopen. if test $pass = dlopen; then if test -z "$libdir"; then $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 exit 1 fi if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. dlprefiles="$dlprefiles $lib" else newdlfiles="$newdlfiles $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 abs_ladir="$ladir" fi ;; esac laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` # Find the relevant object directory and library name. if test "X$installed" = Xyes; then if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then $echo "$modename: warning: library \`$lib' was moved." 1>&2 dir="$ladir" absdir="$abs_ladir" libdir="$abs_ladir" else dir="$libdir" absdir="$libdir" fi else dir="$ladir/$objdir" absdir="$abs_ladir/$objdir" # Remove this search path later notinst_path="$notinst_path $abs_ladir" fi # $installed = yes name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` # This library was specified with -dlpreopen. if test $pass = dlpreopen; then if test -z "$libdir"; then $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 exit 1 fi # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then newdlprefiles="$newdlprefiles $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then newdlprefiles="$newdlprefiles $dir/$dlname" else newdlprefiles="$newdlprefiles $dir/$linklib" fi fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test $linkmode = lib; then deplibs="$dir/$old_library $deplibs" elif test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" fi continue fi if test $linkmode = prog && test $pass != link; then newlib_search_path="$newlib_search_path $ladir" deplibs="$lib $deplibs" linkalldeplibs=no if test "$link_all_deplibs" != no || test -z "$library_names" || test "$build_libtool_libs" = no; then linkalldeplibs=yes fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test esac # Need to link against all dependency_libs? if test $linkalldeplibs = yes; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if test "X$duplicate_deps" = "Xyes" ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done # for deplib continue fi # $linkmode = prog... link_static=no # Whether the deplib will be linked statically if test -n "$library_names" && { test "$prefer_static_libs" = no || test -z "$old_library"; }; then # Link against this shared library if test "$linkmode,$pass" = "prog,link" || { test $linkmode = lib && test $hardcode_into_libs = yes; }; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) compile_rpath="$compile_rpath $absdir" esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" esac ;; esac if test $linkmode = prog; then # We need to hardcode the library path if test -n "$shlibpath_var"; then # Make sure the rpath contains only unique directories. case "$temp_rpath " in *" $dir "*) ;; *" $absdir "*) ;; *) temp_rpath="$temp_rpath $dir" ;; esac fi fi fi # $linkmode,$pass = prog,link... if test "$alldeplibs" = yes && { test "$deplibs_check_method" = pass_all || { test "$build_libtool_libs" = yes && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi if test "$installed" = no; then notinst_deplibs="$notinst_deplibs $lib" need_relink=yes fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names realname="$2" shift; shift libname=`eval \\$echo \"$libname_spec\"` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname="$dlname" elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin*) major=`expr $current - $age` versuffix="-$major" ;; esac eval soname=\"$soname_spec\" else soname="$realname" fi # Make a new name for the extract_expsyms_cmds to use soroot="$soname" soname=`echo $soroot | sed -e 's/^.*\///'` newlib="libimp-`echo $soname | sed 's/^lib//;s/\.dll$//'`.a" # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else $show "extracting exported symbol list from \`$soname'" save_ifs="$IFS"; IFS='~' eval cmds=\"$extract_expsyms_cmds\" for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else $show "generating import library for \`$soname'" save_ifs="$IFS"; IFS='~' eval cmds=\"$old_archive_from_expsyms_cmds\" for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n $old_archive_from_expsyms_cmds if test $linkmode = prog || test "$mode" != relink; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test "$hardcode_direct" = no; then add="$dir/$linklib" elif test "$hardcode_minus_L" = no; then case $host in *-*-sunos*) add_shlibpath="$dir" ;; esac add_dir="-L$dir" add="-l$name" elif test "$hardcode_shlibpath_var" = no; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; relink) if test "$hardcode_direct" = yes; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$dir" add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; *) lib_linked=no ;; esac if test "$lib_linked" != yes; then $echo "$modename: configuration error: unsupported hardcode properties" exit 1 fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; esac fi if test $linkmode = prog; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test "$hardcode_direct" != yes && \ test "$hardcode_minus_L" != yes && \ test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; esac fi fi fi if test $linkmode = prog || test "$mode" = relink; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test "$hardcode_direct" = yes; then add="$libdir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$libdir" add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; esac add="-l$name" else # We cannot seem to hardcode it, guess we'll fake it. add_dir="-L$libdir" add="-l$name" fi if test $linkmode = prog; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test $linkmode = prog; then if test "$alldeplibs" = yes && { test "$deplibs_check_method" = pass_all || { test "$build_libtool_libs" = yes && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi # Try to link the static library # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test "$hardcode_direct" != unsupported; then test -n "$old_library" && linklib="$old_library" compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test "$build_libtool_libs" = yes; then # Not a shared library if test "$deplibs_check_method" != pass_all; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo echo "*** Warning: This system can not link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test "$module" = yes; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else convenience="$convenience $dir/$old_library" old_convenience="$old_convenience $dir/$old_library" deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test $linkmode = lib; then if test -n "$dependency_libs" && { test $hardcode_into_libs != yes || test $build_old_libs = yes || test $link_static = yes; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` case " $xrpath " in *" $temp_xrpath "*) ;; *) xrpath="$xrpath $temp_xrpath";; esac;; *) temp_deplibs="$temp_deplibs $libdir";; esac done dependency_libs="$temp_deplibs" fi newlib_search_path="$newlib_search_path $absdir" # Link against this library test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" if test "X$duplicate_deps" = "Xyes" ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done if test $link_all_deplibs != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do case $deplib in -L*) path="$deplib" ;; *.la) dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` test "X$dir" = "X$deplib" && dir="." # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 absdir="$dir" fi ;; esac if grep "^installed=no" $deplib > /dev/null; then path="-L$absdir/$objdir" else eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` if test -z "$libdir"; then $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 exit 1 fi if test "$absdir" != "$libdir"; then $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 fi path="-L$absdir" fi ;; *) continue ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$deplibs $path" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test $pass = dlpreopen; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test $pass != dlopen; then test $pass != scan && dependency_libs="$newdependency_libs" if test $pass != conv; then # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) lib_search_path="$lib_search_path $dir" ;; esac done newlib_search_path= fi if test "$linkmode,$pass" != "prog,link"; then vars="deplibs" else vars="compile_deplibs finalize_deplibs" fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do case $deplib in -L*) new_libs="$deplib $new_libs" ;; *) case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) tmp_libs="$tmp_libs $deplib" ;; esac ;; *) tmp_libs="$tmp_libs $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi if test "$pass" = "conv" && { test "$linkmode" = "lib" || test "$linkmode" = "prog"; }; then libs="$deplibs" # reset libs deplibs= fi done # for pass if test $linkmode = prog; then dlfiles="$newdlfiles" dlprefiles="$newdlprefiles" fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 fi if test -n "$rpath"; then $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 fi if test -n "$xrpath"; then $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 fi if test -n "$vinfo"; then $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2 fi if test -n "$release"; then $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 fi if test -n "$export_symbols" || test -n "$export_symbols_regex"; then $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 fi # Now set the variables for building old libraries. build_libtool_libs=no oldlibs="$output" objs="$objs$old_deplibs" ;; lib) # Make sure we only generate libraries of the form `libNAME.la'. case $outputname in lib*) name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` eval libname=\"$libname_spec\" ;; *) if test "$module" = no; then $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 $echo "$help" 1>&2 exit 1 fi if test "$need_lib_prefix" != no; then # Add the "lib" prefix for modules if required name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` eval libname=\"$libname_spec\" else libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` fi ;; esac if test -n "$objs"; then if test "$deplibs_check_method" != pass_all; then $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 exit 1 else echo echo "*** Warning: Linking the shared library $output against the non-libtool" echo "*** objects $objs is not portable!" libobjs="$libobjs $objs" fi fi if test "$dlself" != no; then $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 fi set dummy $rpath if test $# -gt 2; then $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 fi install_libdir="$2" oldlibs= if test -z "$rpath"; then if test "$build_libtool_libs" = yes; then # Building a libtool convenience library. libext=al oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi if test -n "$vinfo"; then $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2 fi if test -n "$release"; then $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 fi else # Parse the version information argument. save_ifs="$IFS"; IFS=':' set dummy $vinfo 0 0 0 IFS="$save_ifs" if test -n "$8"; then $echo "$modename: too many parameters to \`-version-info'" 1>&2 $echo "$help" 1>&2 exit 1 fi current="$2" revision="$3" age="$4" # Check that each of the things are valid numbers. case $current in 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; *) $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 exit 1 ;; esac case $revision in 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; *) $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 exit 1 ;; esac case $age in 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; *) $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 exit 1 ;; esac if test $age -gt $current; then $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 exit 1 fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header major=.`expr $current - $age` versuffix="$major.$age.$revision" # Darwin ld doesn't like 0 for these options... minor_current=`expr $current + 1` verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; freebsd-aout) major=".$current" versuffix=".$current.$revision"; ;; freebsd-elf) major=".$current" versuffix=".$current"; ;; irix | nonstopux) case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring="$verstring_prefix$major.$revision" major=`expr $current - $age + 1` # Add in all the interfaces that we are compatible with. loop=$revision while test $loop != 0; do iface=`expr $revision - $loop` loop=`expr $loop - 1` verstring="$verstring_prefix$major.$iface:$verstring" done # Before this point, $major must not contain `.'. major=.$major versuffix="$major.$revision" ;; linux) major=.`expr $current - $age` versuffix="$major.$age.$revision" ;; osf) major=`expr $current - $age` versuffix=".$current.$age.$revision" verstring="$current.$age.$revision" # Add in all the interfaces that we are compatible with. loop=$age while test $loop != 0; do iface=`expr $current - $loop` loop=`expr $loop - 1` verstring="$verstring:${iface}.0" done # Make executables depend on our current version. verstring="$verstring:${current}.0" ;; sunos) major=".$current" versuffix=".$current.$revision" ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 filesystems. major=`expr $current - $age` versuffix="-$major" ;; *) $echo "$modename: unknown library version type \`$version_type'" 1>&2 echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 exit 1 ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= verstring="0.0" case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring="" ;; *) verstring="0.0" ;; esac if test "$need_version" = no; then versuffix= else versuffix=".0.0" fi fi # Remove version info from name if versioning should be avoided if test "$avoid_version" = yes && test "$need_version" = no; then major= versuffix= verstring="" fi # Check to see if the archive will have undefined symbols. if test "$allow_undefined" = yes; then if test "$allow_undefined_flag" = unsupported; then $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 build_libtool_libs=no build_old_libs=yes fi else # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi fi if test "$mode" != relink; then # Remove our outputs. $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*" $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.* fi # Now set the variables for building old libraries. if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then oldlibs="$oldlibs $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` fi # Eliminate all temporary directories. for path in $notinst_path; do lib_search_path=`echo "$lib_search_path " | sed -e 's% $path % %g'` deplibs=`echo "$deplibs " | sed -e 's% -L$path % %g'` dependency_libs=`echo "$dependency_libs " | sed -e 's% -L$path % %g'` done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do temp_xrpath="$temp_xrpath -R$libdir" case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" ;; esac done if test $hardcode_into_libs != yes || test $build_old_libs = yes; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles="$dlfiles" dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) dlfiles="$dlfiles $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles="$dlprefiles" dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) dlprefiles="$dlprefiles $lib" ;; esac done if test "$build_libtool_libs" = yes; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework deplibs="$deplibs -framework System" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd*) # Do not include libc due to us having libc/libc_r. ;; *) # Add libc to deplibs on all other systems if necessary. if test $build_libtool_need_lc = "yes"; then deplibs="$deplibs -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release="" versuffix="" major="" newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behaviour. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $rm conftest.c cat > conftest.c </dev/null` for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null \ | grep " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib="$potent_lib" while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | sed 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ | sed 10q \ | egrep "$file_magic_regex" > /dev/null; then newdeplibs="$newdeplibs $a_deplib" a_deplib="" break 2 fi done done if test -n "$a_deplib" ; then droppeddeps=yes echo echo "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then echo "*** with $libname but no candidates were found. (...for file magic test)" else echo "*** with $libname and none of the candidates passed a file format test" echo "*** using a file magic. Last file checked: $potlib" fi fi else # Add a -L argument. newdeplibs="$newdeplibs $a_deplib" fi done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` for a_deplib in $deplibs; do name="`expr $a_deplib : '-l\(.*\)'`" # If $name is empty we are operating on a -L argument. if test -n "$name" && test "$name" != "0"; then libname=`eval \\$echo \"$libname_spec\"` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib="$potent_lib" # see symlink-check below in file_magic test if eval echo \"$potent_lib\" 2>/dev/null \ | sed 10q \ | egrep "$match_pattern_regex" > /dev/null; then newdeplibs="$newdeplibs $a_deplib" a_deplib="" break 2 fi done done if test -n "$a_deplib" ; then droppeddeps=yes echo echo "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then echo "*** with $libname but no candidates were found. (...for regex pattern test)" else echo "*** with $libname and none of the candidates passed a file format test" echo "*** using a regex pattern. Last file checked: $potlib" fi fi else # Add a -L argument. newdeplibs="$newdeplibs $a_deplib" fi done # Gone through all deplibs. ;; none | unknown | *) newdeplibs="" if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ -e 's/ -[LR][^ ]*//g' -e 's/[ ]//g' | grep . >/dev/null; then echo if test "X$deplibs_check_method" = "Xnone"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes fi ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` ;; esac if test "$droppeddeps" = yes; then if test "$module" = yes; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" echo "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test $allow_undefined = no; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then if test $hardcode_into_libs = yes; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath="$finalize_rpath" test "$mode" != relink && rpath="$compile_rpath$rpath" for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" dep_rpath="$dep_rpath $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) perm_rpath="$perm_rpath $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval dep_rpath=\"$hardcode_libdir_flag_spec\" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do rpath="$rpath$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath="$finalize_shlibpath" test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval library_names=\"$library_names_spec\" set dummy $library_names realname="$2" shift; shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname="$realname" fi test -z "$dlname" && dlname=$soname lib="$output_objdir/$realname" for link do linknames="$linknames $link" done # Ensure that we have .o objects for linkers which dislike .lo # (e.g. aix) in case we are running --disable-static for obj in $libobjs; do xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` if test "X$xdir" = "X$obj"; then xdir="." else xdir="$xdir" fi baseobj=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"` if test ! -f $xdir/$oldobj; then $show "(cd $xdir && ${LN_S} $baseobj $oldobj)" $run eval '(cd $xdir && ${LN_S} $baseobj $oldobj)' || exit $? fi done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` # Prepare the list of exported symbols if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then $show "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $run $rm $export_symbols eval cmds=\"$export_symbols_cmds\" save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" if test -n "$export_symbols_regex"; then $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' $show "$mv \"${export_symbols}T\" \"$export_symbols\"" $run eval '$mv "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' fi if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" else gentop="$output_objdir/${outputname}x" $show "${rm}r $gentop" $run ${rm}r "$gentop" $show "mkdir $gentop" $run mkdir "$gentop" status=$? if test $status -ne 0 && test ! -d "$gentop"; then exit $status fi generated="$generated $gentop" for xlib in $convenience; do # Extract the objects. case $xlib in [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; *) xabs=`pwd`"/$xlib" ;; esac xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` xdir="$gentop/$xlib" $show "${rm}r $xdir" $run ${rm}r "$xdir" $show "mkdir $xdir" $run mkdir "$xdir" status=$? if test $status -ne 0 && test ! -d "$xdir"; then exit $status fi $show "(cd $xdir && $AR x $xabs)" $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` done fi fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" linker_flags="$linker_flags $flag" fi # Make a backup of the uninstalled library when relinking if test "$mode" = relink; then $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval cmds=\"$archive_expsym_cmds\" else eval cmds=\"$archive_cmds\" fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" # Restore the uninstalled library and exit if test "$mode" = relink; then $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? exit 0 fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? fi done # If -module or -export-dynamic was specified, set the dlname. if test "$module" = yes || test "$export_dynamic" = yes; then # On all known operating systems, these are identical. dlname="$soname" fi fi ;; obj) if test -n "$deplibs"; then $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 fi if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 fi if test -n "$rpath"; then $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 fi if test -n "$xrpath"; then $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 fi if test -n "$vinfo"; then $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 fi if test -n "$release"; then $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 fi case $output in *.lo) if test -n "$objs$old_deplibs"; then $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 exit 1 fi libobj="$output" obj=`$echo "X$output" | $Xsed -e "$lo2o"` ;; *) libobj= obj="$output" ;; esac # Delete the old objects. $run $rm $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # reload_cmds runs $LD directly, so let us get rid of # -Wl from whole_archive_flag_spec wl= if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" else gentop="$output_objdir/${obj}x" $show "${rm}r $gentop" $run ${rm}r "$gentop" $show "mkdir $gentop" $run mkdir "$gentop" status=$? if test $status -ne 0 && test ! -d "$gentop"; then exit $status fi generated="$generated $gentop" for xlib in $convenience; do # Extract the objects. case $xlib in [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; *) xabs=`pwd`"/$xlib" ;; esac xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` xdir="$gentop/$xlib" $show "${rm}r $xdir" $run ${rm}r "$xdir" $show "mkdir $xdir" $run mkdir "$xdir" status=$? if test $status -ne 0 && test ! -d "$xdir"; then exit $status fi $show "(cd $xdir && $AR x $xabs)" $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? reload_conv_objs="$reload_objs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` done fi fi # Create the old-style object. reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test output="$obj" eval cmds=\"$reload_cmds\" save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then $show "${rm}r $gentop" $run ${rm}r $gentop fi exit 0 fi if test "$build_libtool_libs" != yes; then if test -n "$gentop"; then $show "${rm}r $gentop" $run ${rm}r $gentop fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. $show "echo timestamp > $libobj" $run eval "echo timestamp > $libobj" || exit $? exit 0 fi if test -n "$pic_flag" || test "$pic_mode" != default; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output="$libobj" eval cmds=\"$reload_cmds\" save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" else # Just create a symlink. $show $rm $libobj $run $rm $libobj xdir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` if test "X$xdir" = "X$libobj"; then xdir="." else xdir="$xdir" fi baseobj=`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"` $show "(cd $xdir && $LN_S $oldobj $baseobj)" $run eval '(cd $xdir && $LN_S $oldobj $baseobj)' || exit $? fi if test -n "$gentop"; then $show "${rm}r $gentop" $run ${rm}r $gentop fi exit 0 ;; prog) case $host in *cygwin*) output=`echo $output | sed -e 's,.exe$,,;s,$,.exe,'` ;; esac if test -n "$vinfo"; then $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 fi if test -n "$release"; then $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 fi if test "$preload" = yes; then if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && test "$dlopen_self_static" = unknown; then $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." fi fi case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` ;; esac compile_command="$compile_command $compile_deplibs" finalize_command="$finalize_command $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" rpath="$rpath $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) perm_rpath="$perm_rpath $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) case :$dllsearchpath: in *":$libdir:"*) ;; *) dllsearchpath="$dllsearchpath:$libdir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath="$rpath" rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" rpath="$rpath $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath="$rpath" if test -n "$libobjs" && test "$build_old_libs" = yes; then # Transform all the library objects into standard objects. compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` fi dlsyms= if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then if test -n "$NM" && test -n "$global_symbol_pipe"; then dlsyms="${outputname}S.c" else $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 fi fi if test -n "$dlsyms"; then case $dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist="$output_objdir/${outputname}.nm" $show "$rm $nlist ${nlist}S ${nlist}T" $run $rm "$nlist" "${nlist}S" "${nlist}T" # Parse the name list into a source file. $show "creating $output_objdir/$dlsyms" test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ /* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ /* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ #ifdef __cplusplus extern \"C\" { #endif /* Prevent the only kind of declaration conflicts we can make. */ #define lt_preloaded_symbols some_other_symbol /* External symbol declarations for the compiler. */\ " if test "$dlself" = yes; then $show "generating symbol list for \`$output'" test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` for arg in $progfiles; do $show "extracting global C symbols from \`$arg'" $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' $run eval '$mv "$nlist"T "$nlist"' fi if test -n "$export_symbols_regex"; then $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T' $run eval '$mv "$nlist"T "$nlist"' fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols="$output_objdir/$output.exp" $run $rm $export_symbols $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' else $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"' $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T' $run eval 'mv "$nlist"T "$nlist"' fi fi for arg in $dlprefiles; do $show "extracting global C symbols from \`$arg'" name=`echo "$arg" | sed -e 's%^.*/%%'` $run eval 'echo ": $name " >> "$nlist"' $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" done if test -z "$run"; then # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $mv "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then : else grep -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' else echo '/* NONE */' >> "$output_objdir/$dlsyms" fi $echo >> "$output_objdir/$dlsyms" "\ #undef lt_preloaded_symbols #if defined (__STDC__) && __STDC__ # define lt_ptr void * #else # define lt_ptr char * # define const #endif /* The mapping between symbol names and symbols. */ const struct { const char *name; lt_ptr address; } lt_preloaded_symbols[] = {\ " eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" $echo >> "$output_objdir/$dlsyms" "\ {0, (lt_ptr) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " fi pic_flag_for_symtable= case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) case "$compile_command " in *" -static "*) ;; *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";; esac;; *-*-hpux*) case "$compile_command " in *" -static "*) ;; *) pic_flag_for_symtable=" $pic_flag -DPIC";; esac esac # Now compile the dynamic symbol file. $show "(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" $run eval '(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? # Clean up the generated files. $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" # Transform the symbol file into the correct name. compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` ;; *) $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 exit 1 ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` fi if test $need_relink = no || test "$build_libtool_libs" != yes; then # Replace the output file specification. compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` link_command="$compile_command$compile_rpath" # We have no uninstalled library dependencies, so finalize right now. $show "$link_command" $run eval "$link_command" status=$? # Delete the generated files. if test -n "$dlsyms"; then $show "$rm $output_objdir/${outputname}S.${objext}" $run $rm "$output_objdir/${outputname}S.${objext}" fi exit $status fi if test -n "$shlibpath_var"; then # We should set the shlibpath_var rpath= for dir in $temp_rpath; do case $dir in [\\/]* | [A-Za-z]:[\\/]*) # Absolute path. rpath="$rpath$dir:" ;; *) # Relative path: add a thisdir entry. rpath="$rpath\$thisdir/$dir:" ;; esac done temp_rpath="$rpath" fi if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do rpath="$rpath$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do rpath="$rpath$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test "$no_install" = yes; then # We don't need to create a wrapper script. link_command="$compile_var$compile_command$compile_rpath" # Replace the output file specification. link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $run $rm $output # Link the executable and exit $show "$link_command" $run eval "$link_command" || exit $? exit 0 fi if test "$hardcode_action" = relink; then # Fast installation is not supported link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 $echo "$modename: \`$output' will be relinked during installation" 1>&2 else if test "$fast_install" != no; then link_command="$finalize_var$compile_command$finalize_rpath" if test "$fast_install" = yes; then relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` else # fast_install is set to needless relink_command= fi else link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" fi fi # Replace the output file specification. link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname $show "$link_command" $run eval "$link_command" || exit $? # Now create the wrapper script. $show "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` relink_command="$var=\"$var_value\"; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` fi # Quote $echo for shipping. if test "X$echo" = "X$SHELL $0 --fallback-echo"; then case $0 in [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";; *) qecho="$SHELL `pwd`/$0 --fallback-echo";; esac qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` else qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` fi # Only actually do things if our run command is non-null. if test -z "$run"; then # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) output=`echo $output|sed 's,.exe$,,'` ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe ;; *) exeext= ;; esac $rm $output trap "$rm $output; exit 1" 1 2 15 $echo > $output "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed='sed -e 1s/^X//' sed_quote_subst='$sed_quote_subst' # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variable: notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$echo are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then echo=\"$qecho\" file=\"\$0\" # Make sure echo works. if test \"X\$1\" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then # Yippee, \$echo works! : else # Restart under the correct shell, and then maybe \$echo will work. exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} fi fi\ " $echo >> $output "\ # Find the directory that this script lives in. thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\` done # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test "$fast_install" = yes; then echo >> $output "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || \\ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $mkdir \"\$progdir\" else $rm \"\$progdir/\$file\" fi" echo >> $output "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else $echo \"\$relink_command_output\" >&2 $rm \"\$progdir/\$file\" exit 1 fi fi $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $rm \"\$progdir/\$program\"; $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } $rm \"\$progdir/\$file\" fi" else echo >> $output "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi echo >> $output "\ if test -f \"\$progdir/\$program\"; then" # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $echo >> $output "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` export $shlibpath_var " fi # fixup the dll searchpath if we need to. if test -n "$dllsearchpath"; then $echo >> $output "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi $echo >> $output "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. " case $host in # win32 systems need to use the prog path for dll # lookup to work *-*-cygwin* | *-*-pw32*) $echo >> $output "\ exec \$progdir/\$program \${1+\"\$@\"} " ;; # Backslashes separate directories on plain windows *-*-mingw | *-*-os2*) $echo >> $output "\ exec \$progdir\\\\\$program \${1+\"\$@\"} " ;; *) $echo >> $output "\ # Export the path to the program. PATH=\"\$progdir:\$PATH\" export PATH exec \$program \${1+\"\$@\"} " ;; esac $echo >> $output "\ \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" exit 1 fi else # The program doesn't exist. \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2 \$echo \"This script is just a wrapper for \$program.\" 1>&2 echo \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " chmod +x $output fi exit 0 ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do if test "$build_libtool_libs" = convenience; then oldobjs="$libobjs_save" addlibs="$convenience" build_libtool_libs=no else if test "$build_libtool_libs" = module; then oldobjs="$libobjs_save" build_libtool_libs=no else oldobjs="$objs$old_deplibs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP` fi addlibs="$old_convenience" fi if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" $show "${rm}r $gentop" $run ${rm}r "$gentop" $show "mkdir $gentop" $run mkdir "$gentop" status=$? if test $status -ne 0 && test ! -d "$gentop"; then exit $status fi generated="$generated $gentop" # Add in members from convenience archives. for xlib in $addlibs; do # Extract the objects. case $xlib in [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; *) xabs=`pwd`"/$xlib" ;; esac xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` xdir="$gentop/$xlib" $show "${rm}r $xdir" $run ${rm}r "$xdir" $show "mkdir $xdir" $run mkdir "$xdir" status=$? if test $status -ne 0 && test ! -d "$xdir"; then exit $status fi $show "(cd $xdir && $AR x $xabs)" $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP` done fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then eval cmds=\"$old_archive_from_new_cmds\" else # Ensure that we have .o objects in place in case we decided # not to build a shared library, and have fallen back to building # static libs even though --disable-static was passed! for oldobj in $oldobjs; do if test ! -f $oldobj; then xdir=`$echo "X$oldobj" | $Xsed -e 's%/[^/]*$%%'` if test "X$xdir" = "X$oldobj"; then xdir="." else xdir="$xdir" fi baseobj=`$echo "X$oldobj" | $Xsed -e 's%^.*/%%'` obj=`$echo "X$baseobj" | $Xsed -e "$o2lo"` $show "(cd $xdir && ${LN_S} $obj $baseobj)" $run eval '(cd $xdir && ${LN_S} $obj $baseobj)' || exit $? fi done eval cmds=\"$old_archive_cmds\" fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" done if test -n "$generated"; then $show "${rm}r$generated" $run ${rm}r$generated fi # Now create the libtool archive. case $output in *.la) old_library= test "$build_old_libs" = yes && old_library="$libname.$libext" $show "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` relink_command="$var=\"$var_value\"; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL $0 --mode=relink $libtool_args)" relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` # Only create the output if not a dry run. if test -z "$run"; then for installed in no yes; do if test "$installed" = yes; then if test -z "$install_libdir"; then break fi output="$output_objdir/$outputname"i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` if test -z "$libdir"; then $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 exit 1 fi newdependency_libs="$newdependency_libs $libdir/$name" ;; *) newdependency_libs="$newdependency_libs $deplib" ;; esac done dependency_libs="$newdependency_libs" newdlfiles= for lib in $dlfiles; do name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $lib` if test -z "$libdir"; then $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 exit 1 fi newdlfiles="$newdlfiles $libdir/$name" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $lib` if test -z "$libdir"; then $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 exit 1 fi newdlprefiles="$newdlprefiles $libdir/$name" done dlprefiles="$newdlprefiles" fi $rm $output # place dlname in correct position for cygwin tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; esac $echo > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test "$installed" = no && test $need_relink = yes; then $echo >> $output "\ relink_command=\"$relink_command\"" fi done fi # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? ;; esac exit 0 ;; # libtool install mode install) modename="$modename: install" # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || # Allow the use of GNU shtool's install command. $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then # Aesthetically quote it. arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` case $arg in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) arg="\"$arg\"" ;; esac install_prog="$arg " arg="$1" shift else install_prog= arg="$nonopt" fi # The real first argument should be the name of the installation program. # Aesthetically quote it. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case $arg in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) arg="\"$arg\"" ;; esac install_prog="$install_prog$arg" # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=no stripme= for arg do if test -n "$dest"; then files="$files $dest" dest="$arg" continue fi case $arg in -d) isdir=yes ;; -f) prev="-f" ;; -g) prev="-g" ;; -m) prev="-m" ;; -o) prev="-o" ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then prev= else dest="$arg" continue fi ;; esac # Aesthetically quote the argument. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case $arg in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) arg="\"$arg\"" ;; esac install_prog="$install_prog $arg" done if test -z "$install_prog"; then $echo "$modename: you must specify an install program" 1>&2 $echo "$help" 1>&2 exit 1 fi if test -n "$prev"; then $echo "$modename: the \`$prev' option requires an argument" 1>&2 $echo "$help" 1>&2 exit 1 fi if test -z "$files"; then if test -z "$dest"; then $echo "$modename: no file or destination specified" 1>&2 else $echo "$modename: you must specify a destination" 1>&2 fi $echo "$help" 1>&2 exit 1 fi # Strip any trailing slash from the destination. dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` # Check to see that the destination is a directory. test -d "$dest" && isdir=yes if test "$isdir" = yes; then destdir="$dest" destname= else destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` test "X$destdir" = "X$dest" && destdir=. destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` # Not a directory, so check to see that there is only one file specified. set dummy $files if test $# -gt 2; then $echo "$modename: \`$dest' is not a directory" 1>&2 $echo "$help" 1>&2 exit 1 fi fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 $echo "$help" 1>&2 exit 1 ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. staticlibs="$staticlibs $file" ;; *.la) # Check to see that this really is a libtool archive. if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : else $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 $echo "$help" 1>&2 exit 1 fi library_names= old_library= relink_command= # If there is no directory component, then add one. case $file in */* | *\\*) . $file ;; *) . ./$file ;; esac # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) current_libdirs="$current_libdirs $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) future_libdirs="$future_libdirs $libdir" ;; esac fi dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ test "X$dir" = "X$file/" && dir= dir="$dir$objdir" if test -n "$relink_command"; then $echo "$modename: warning: relinking \`$file'" 1>&2 $show "$relink_command" if $run eval "$relink_command"; then : else $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 continue fi fi # See the names of the shared library. set dummy $library_names if test -n "$2"; then realname="$2" shift shift srcname="$realname" test -n "$relink_command" && srcname="$realname"T # Install the shared library and build the symlinks. $show "$install_prog $dir/$srcname $destdir/$realname" $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? if test -n "$stripme" && test -n "$striplib"; then $show "$striplib $destdir/$realname" $run eval "$striplib $destdir/$realname" || exit $? fi if test $# -gt 0; then # Delete the old symlinks, and create new ones. for linkname do if test "$linkname" != "$realname"; then $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" fi done fi # Do each command in the postinstall commands. lib="$destdir/$realname" eval cmds=\"$postinstall_cmds\" save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" fi # Install the pseudo-library for information purposes. name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` instname="$dir/$name"i $show "$install_prog $instname $destdir/$name" $run eval "$install_prog $instname $destdir/$name" || exit $? # Maybe install the static library, too. test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` destfile="$destdir/$destfile" fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` ;; *.$objext) staticdest="$destfile" destfile= ;; *) $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 $echo "$help" 1>&2 exit 1 ;; esac # Install the libtool object if requested. if test -n "$destfile"; then $show "$install_prog $file $destfile" $run eval "$install_prog $file $destfile" || exit $? fi # Install the old object if enabled. if test "$build_old_libs" = yes; then # Deduce the name of the old-style object file. staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` $show "$install_prog $staticobj $staticdest" $run eval "$install_prog \$staticobj \$staticdest" || exit $? fi exit 0 ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` destfile="$destdir/$destfile" fi # Do a test to see if this is really a libtool program. case $host in *cygwin*|*mingw*) wrapper=`echo $file | sed -e 's,.exe$,,'` ;; *) wrapper=$file ;; esac if (sed -e '4q' $wrapper | egrep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then notinst_deplibs= relink_command= # If there is no directory component, then add one. case $file in */* | *\\*) . $wrapper ;; *) . ./$wrapper ;; esac # Check the variables that should have been set. if test -z "$notinst_deplibs"; then $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 exit 1 fi finalize=yes for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then # If there is no directory component, then add one. case $lib in */* | *\\*) . $lib ;; *) . ./$lib ;; esac fi libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test if test -n "$libdir" && test ! -f "$libfile"; then $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 finalize=no fi done relink_command= # If there is no directory component, then add one. case $file in */* | *\\*) . $wrapper ;; *) . ./$wrapper ;; esac outputname= if test "$fast_install" = no && test -n "$relink_command"; then if test "$finalize" = yes && test -z "$run"; then tmpdir="/tmp" test -n "$TMPDIR" && tmpdir="$TMPDIR" tmpdir="$tmpdir/libtool-$$" if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then : else $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 continue fi file=`$echo "X$file" | $Xsed -e 's%^.*/%%'` outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` $show "$relink_command" if $run eval "$relink_command"; then : else $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 ${rm}r "$tmpdir" continue fi file="$outputname" else $echo "$modename: warning: cannot relink \`$file'" 1>&2 fi else # Install the binary that we compiled earlier. file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyways case $install_prog,$host in /usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) destfile=`echo $destfile | sed -e 's,.exe$,,'` ;; esac ;; esac $show "$install_prog$stripme $file $destfile" $run eval "$install_prog\$stripme \$file \$destfile" || exit $? test -n "$outputname" && ${rm}r "$tmpdir" ;; esac done for file in $staticlibs; do name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` # Set up the ranlib parameters. oldlib="$destdir/$name" $show "$install_prog $file $oldlib" $run eval "$install_prog \$file \$oldlib" || exit $? if test -n "$stripme" && test -n "$striplib"; then $show "$old_striplib $oldlib" $run eval "$old_striplib $oldlib" || exit $? fi # Do each command in the postinstall commands. eval cmds=\"$old_postinstall_cmds\" save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" done if test -n "$future_libdirs"; then $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 fi if test -n "$current_libdirs"; then # Maybe just do a dry run. test -n "$run" && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL $0 --finish$current_libdirs' else exit 0 fi ;; # libtool finish mode finish) modename="$modename: finish" libdirs="$nonopt" admincmds= if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for dir do libdirs="$libdirs $dir" done for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. eval cmds=\"$finish_cmds\" save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" $run eval "$cmd" || admincmds="$admincmds $cmd" done IFS="$save_ifs" fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $run eval "$cmds" || admincmds="$admincmds $cmds" fi done fi # Exit here if they wanted silent mode. test "$show" = ":" && exit 0 echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do echo " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the \`-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the \`$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the \`$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" echo " - use the \`$flag' linker flag" fi if test -n "$admincmds"; then echo " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" echo "more information, such as the ld(1) and ld.so(8) manual pages." echo "----------------------------------------------------------------------" exit 0 ;; # libtool execute mode execute) modename="$modename: execute" # The first argument is the command name. cmd="$nonopt" if test -z "$cmd"; then $echo "$modename: you must specify a COMMAND" 1>&2 $echo "$help" exit 1 fi # Handle -dlopen flags immediately. for file in $execute_dlfiles; do if test ! -f "$file"; then $echo "$modename: \`$file' is not a file" 1>&2 $echo "$help" 1>&2 exit 1 fi dir= case $file in *.la) # Check to see that this really is a libtool archive. if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : else $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 $echo "$help" 1>&2 exit 1 fi # Read the libtool library. dlname= library_names= # If there is no directory component, then add one. case $file in */* | *\\*) . $file ;; *) . ./$file ;; esac # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" continue fi dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` test "X$dir" = "X$file" && dir=. if test -f "$dir/$objdir/$dlname"; then dir="$dir/$objdir" else $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 exit 1 fi ;; *.lo) # Just add the directory containing the .lo file. dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` test "X$dir" = "X$file" && dir=. ;; *) $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir="$absdir" # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic="$magic" # Check if any of the arguments is a wrapper script. args= for file do case $file in -*) ;; *) # Do a test to see if this is really a libtool program. if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then # If there is no directory component, then add one. case $file in */* | *\\*) . $file ;; *) . ./$file ;; esac # Transform arg to wrapped name. file="$progdir/$program" fi ;; esac # Quote arguments (to preserve shell metacharacters). file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` args="$args \"$file\"" done if test -z "$run"; then if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved enviroment variables if test "${save_LC_ALL+set}" = set; then LC_ALL="$save_LC_ALL"; export LC_ALL fi if test "${save_LANG+set}" = set; then LANG="$save_LANG"; export LANG fi # Now prepare to actually exec the command. exec_cmd="\$cmd$args" else # Display what would be done. if test -n "$shlibpath_var"; then eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" $echo "export $shlibpath_var" fi $echo "$cmd$args" exit 0 fi ;; # libtool clean and uninstall mode clean | uninstall) modename="$modename: $mode" rm="$nonopt" files= rmforce= exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" for arg do case $arg in -f) rm="$rm $arg"; rmforce=yes ;; -*) rm="$rm $arg" ;; *) files="$files $arg" ;; esac done if test -z "$rm"; then $echo "$modename: you must specify an RM program" 1>&2 $echo "$help" 1>&2 exit 1 fi rmdirs= for file in $files; do dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` if test "X$dir" = "X$file"; then dir=. objdir="$objdir" else objdir="$dir/$objdir" fi name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` test $mode = uninstall && objdir="$dir" # Remember objdir for removal later, being careful to avoid duplicates if test $mode = clean; then case " $rmdirs " in *" $objdir "*) ;; *) rmdirs="$rmdirs $objdir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if (test -L "$file") >/dev/null 2>&1 \ || (test -h "$file") >/dev/null 2>&1 \ || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif test "$rmforce" = yes; then continue fi rmfiles="$file" case $name in *.la) # Possibly a libtool archive, so verify it. if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then . $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do rmfiles="$rmfiles $objdir/$n" done test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" test $mode = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" if test $mode = uninstall; then if test -n "$library_names"; then # Do each command in the postuninstall commands. eval cmds=\"$postuninstall_cmds\" save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" $run eval "$cmd" if test $? != 0 && test "$rmforce" != yes; then exit_status=1 fi done IFS="$save_ifs" fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. eval cmds=\"$old_postuninstall_cmds\" save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" $run eval "$cmd" if test $? != 0 && test "$rmforce" != yes; then exit_status=1 fi done IFS="$save_ifs" fi # FIXME: should reinstall the best remaining shared library. fi fi ;; *.lo) if test "$build_old_libs" = yes; then oldobj=`$echo "X$name" | $Xsed -e "$lo2o"` rmfiles="$rmfiles $dir/$oldobj" fi ;; *) # Do a test to see if this is a libtool program. if test $mode = clean && (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then relink_command= . $dir/$file rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" if test "$fast_install" = yes && test -n "$relink_command"; then rmfiles="$rmfiles $objdir/lt-$name" fi fi ;; esac $show "$rm $rmfiles" $run $rm $rmfiles || exit_status=1 done # Try to remove the ${objdir}s in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then $show "rmdir $dir" $run rmdir $dir >/dev/null 2>&1 fi done exit $exit_status ;; "") $echo "$modename: you must specify a MODE" 1>&2 $echo "$generic_help" 1>&2 exit 1 ;; esac if test -z "$exec_cmd"; then $echo "$modename: invalid operation mode \`$mode'" 1>&2 $echo "$generic_help" 1>&2 exit 1 fi fi # test -z "$show_help" if test -n "$exec_cmd"; then eval exec $exec_cmd exit 1 fi # We need to display help for each of the modes. case $mode in "") $echo \ "Usage: $modename [OPTION]... [MODE-ARG]... Provide generalized library-building support services. --config show all configuration variables --debug enable verbose shell tracing -n, --dry-run display commands without modifying any files --features display basic configuration information and exit --finish same as \`--mode=finish' --help display this help message and exit --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] --quiet same as \`--silent' --silent don't print informational messages --version print version information MODE must be one of the following: clean remove files from the build directory compile compile a source file into a libtool object execute automatically set library path, then run a program finish complete the installation of libtool libraries install install libraries or executables link create a library or an executable uninstall remove libraries from an installed directory MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for a more detailed description of MODE." exit 0 ;; clean) $echo \ "Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $echo \ "Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -prefer-pic try to building PIC objects only -prefer-non-pic try to building non-PIC objects only -static always build a \`.o' file suitable for static linking COMPILE-COMMAND is a command to be used in creating a \`standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix \`.c' with the library object suffix, \`.lo'." ;; execute) $echo \ "Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to \`-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $echo \ "Usage: $modename [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the \`--dry-run' option if you just want to see what would be executed." ;; install) $echo \ "Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the \`install' or \`cp' program. The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $echo \ "Usage: $modename [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -static do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] All other options (arguments beginning with \`-') are ignored. Every other argument is treated as a filename. Files ending in \`.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only library objects (\`.lo' files) may be specified, and \`-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created using \`ar' and \`ranlib', or on Windows using \`lib'. If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $echo \ "Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) $echo "$modename: invalid operation mode \`$mode'" 1>&2 $echo "$help" 1>&2 exit 1 ;; esac echo $echo "Try \`$modename --help' for more information about other modes." exit 0 # Local Variables: # mode:shell-script # sh-indentation:2 # End: lyskom-server-2.1.2/src/libraries/liboop/missing0000755000015100000310000002403607716517055015450 #! /bin/sh # Common stub for a few missing GNU programs while installing. # Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi case "$1" in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case "$1" in -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch]" ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing 0.4 - GNU automake" ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; aclocal*) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case "$f" in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. You can get \`$1Help2man' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.h fi ;; esac fi if [ ! -f y.tab.h ]; then echo >y.tab.h fi if [ ! -f y.tab.c ]; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if [ ! -f lex.yy.c ]; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` fi if [ -f "$file" ]; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then # We have makeinfo, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` fi touch $file ;; tar) shift if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 fi # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case "$firstarg" in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case "$firstarg" in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequirements for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 lyskom-server-2.1.2/src/libraries/liboop/mkinstalldirs0000755000015100000310000000370407716517055016656 #! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain errstatus=0 dirmode="" usage="\ Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." # process command line arguments while test $# -gt 0 ; do case $1 in -h | --help | --h*) # -h for help echo "$usage" 1>&2 exit 0 ;; -m) # -m PERM arg shift test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } dirmode=$1 shift ;; --) # stop option processing shift break ;; -*) # unknown option echo "$usage" 1>&2 exit 1 ;; *) # first non-opt arg break ;; esac done for file do if test -d "$file"; then shift else break fi done case $# in 0) exit 0 ;; esac case $dirmode in '') if mkdir -p -- . 2>/dev/null; then echo "mkdir -p -- $*" exec mkdir -p -- "$@" fi ;; *) if mkdir -m "$dirmode" -p -- . 2>/dev/null; then echo "mkdir -m $dirmode -p -- $*" exec mkdir -m "$dirmode" -p -- "$@" fi ;; esac for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case $pathcomp in -*) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr else if test ! -z "$dirmode"; then echo "chmod $dirmode $pathcomp" lasterr="" chmod "$dirmode" "$pathcomp" || lasterr=$? if test ! -z "$lasterr"; then errstatus=$lasterr fi fi fi fi pathcomp="$pathcomp/" done done exit $errstatus # Local Variables: # mode: shell-script # sh-indentation: 2 # End: # mkinstalldirs ends here lyskom-server-2.1.2/src/libraries/liboop/sys.c0000664000015100472110000003014707705102516015036 /* sys.c, liboop, copyright 1999 Dan Egnor This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License, version 2.1 or later. See the file COPYING for details. */ #include "oop.h" #include #include #include #include #include #include #include #include #include #ifdef HAVE_SYS_SELECT_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_STRING_H # include /* Needed on NetBSD1.1/SPARC due to bzero/FD_ZERO. */ #endif #ifdef HAVE_STRINGS_H # include /* Needed on AIX 4.2 due to bzero/FD_ZERO. */ #endif #define MAGIC 0x9643 struct sys_time { struct sys_time *next; struct timeval tv; oop_call_time *f; void *v; }; struct sys_signal_handler { struct sys_signal_handler *next; oop_call_signal *f; void *v; }; struct sys_signal { struct sys_signal_handler *list,*ptr; struct sigaction old; volatile sig_atomic_t active; }; struct sys_file_handler { oop_call_fd *f; void *v; }; typedef struct sys_file_handler sys_file[OOP_NUM_EVENTS]; struct oop_source_sys { oop_source oop; int magic; int in_run; int num_events; /* Timeout queue */ struct sys_time *time_queue,*time_run; /* Signal handling */ struct sys_signal sig[OOP_NUM_SIGNALS]; sigjmp_buf env; int do_jmp,sig_active; /* File descriptors */ int num_files; sys_file *files; }; static struct oop_source_sys *sys_sig_owner[OOP_NUM_SIGNALS]; static int use_sa_restart = 0; static oop_source_sys *verify_source(oop_source *source) { oop_source_sys *sys = (oop_source_sys *) source; assert(MAGIC == sys->magic && "corrupt oop_source structure"); return sys; } static void sys_on_fd(oop_source *source,int fd,oop_event ev, oop_call_fd *f,void *v) { oop_source_sys *sys = verify_source(source); assert(NULL != f && "callback must be non-NULL"); if (fd >= sys->num_files) { int i,j,num_files = 1 + fd; sys_file *files = oop_malloc(num_files * sizeof(sys_file)); if (NULL == files) return; /* ugh */ memcpy(files,sys->files,sizeof(sys_file) * sys->num_files); for (i = sys->num_files; i < num_files; ++i) for (j = 0; j < OOP_NUM_EVENTS; ++j) files[i][j].f = NULL; if (NULL != sys->files) oop_free(sys->files); sys->files = files; sys->num_files = num_files; } assert(NULL == sys->files[fd][ev].f && "multiple handlers registered for a file event"); sys->files[fd][ev].f = f; sys->files[fd][ev].v = v; ++sys->num_events; } static void sys_cancel_fd(oop_source *source,int fd,oop_event ev) { oop_source_sys *sys = verify_source(source); if (fd < sys->num_files && NULL != sys->files[fd][ev].f) { sys->files[fd][ev].f = NULL; sys->files[fd][ev].v = NULL; --sys->num_events; } } static void sys_on_time(oop_source *source,struct timeval tv, oop_call_time *f,void *v) { oop_source_sys *sys = verify_source(source); struct sys_time **p = &sys->time_queue; struct sys_time *time = oop_malloc(sizeof(struct sys_time)); assert(NULL != f && "callback must be non-NULL"); assert(tv.tv_usec >= 0); assert(tv.tv_usec < 1000000); if (NULL == time) return; /* ugh */ time->tv = tv; time->f = f; time->v = v; while (NULL != *p && ((*p)->tv.tv_sec < tv.tv_sec || ((*p)->tv.tv_sec == tv.tv_sec && (*p)->tv.tv_usec <= tv.tv_usec))) p = &(*p)->next; time->next = *p; *p = time; ++sys->num_events; } static int sys_remove_time(oop_source_sys *sys, struct sys_time **p,struct timeval tv, oop_call_time *f,void *v) { while (NULL != *p && ((*p)->tv.tv_sec < tv.tv_sec || ((*p)->tv.tv_sec == tv.tv_sec && (*p)->tv.tv_usec < tv.tv_usec))) p = &(*p)->next; while (NULL != *p && (*p)->tv.tv_sec == tv.tv_sec && (*p)->tv.tv_usec == tv.tv_usec && ((*p)->f != f || (*p)->v != v)) p = &(*p)->next; if (NULL != *p && (*p)->tv.tv_sec == tv.tv_sec && (*p)->tv.tv_usec == tv.tv_usec) { struct sys_time *time = *p; assert(f == time->f); assert(v == time->v); *p = time->next; oop_free(time); --sys->num_events; return 1; } return 0; } static void sys_cancel_time(oop_source *source,struct timeval tv, oop_call_time *f,void *v) { oop_source_sys *sys = verify_source(source); if (!sys_remove_time(sys,&sys->time_run,tv,f,v)) sys_remove_time(sys,&sys->time_queue,tv,f,v); } static void sys_signal_handler(int sig) { oop_source_sys *sys = sys_sig_owner[sig]; struct sigaction act; assert(NULL != sys); /* Reset the handler, in case this is needed. */ sigaction(sig,NULL,&act); act.sa_handler = sys_signal_handler; sigaction(sig,&act,NULL); assert(NULL != sys->sig[sig].list); sys->sig[sig].active = 1; sys->sig_active = 1; /* Break out of select() loop, if necessary. */ if (sys->do_jmp) siglongjmp(sys->env,1); } static void sys_on_signal(oop_source *source,int sig, oop_call_signal *f,void *v) { oop_source_sys *sys = verify_source(source); struct sys_signal_handler *handler = oop_malloc(sizeof(*handler)); assert(NULL != f && "callback must be non-NULL"); if (NULL == handler) return; /* ugh */ assert(sig > 0 && sig < OOP_NUM_SIGNALS && "invalid signal number"); handler->f = f; handler->v = v; handler->next = sys->sig[sig].list; sys->sig[sig].list = handler; ++sys->num_events; if (NULL == handler->next) { struct sigaction act; assert(NULL == sys_sig_owner[sig]); sys_sig_owner[sig] = sys; assert(0 == sys->sig[sig].active); sigaction(sig,NULL,&act); sys->sig[sig].old = act; act.sa_handler = sys_signal_handler; #ifdef SA_NODEFER /* BSD/OS doesn't have this, for one. */ act.sa_flags &= ~SA_NODEFER; #endif if (use_sa_restart) act.sa_flags |= SA_RESTART; sigaction(sig,&act,NULL); } } static void sys_cancel_signal(oop_source *source,int sig, oop_call_signal *f,void *v) { oop_source_sys *sys = verify_source(source); struct sys_signal_handler **pp = &sys->sig[sig].list; assert(sig > 0 && sig < OOP_NUM_SIGNALS && "invalid signal number"); while (NULL != *pp && ((*pp)->f != f || (*pp)->v != v)) pp = &(*pp)->next; if (NULL != *pp) { struct sys_signal_handler *p = *pp; if (NULL == p->next && &sys->sig[sig].list == pp) { sigaction(sig,&sys->sig[sig].old,NULL); sys->sig[sig].active = 0; sys_sig_owner[sig] = NULL; } *pp = p->next; if (sys->sig[sig].ptr == p) sys->sig[sig].ptr = *pp; --sys->num_events; oop_free(p); } } oop_source_sys *oop_sys_new(void) { oop_source_sys *source = oop_malloc(sizeof(oop_source_sys)); int i; if (NULL == source) return NULL; source->oop.on_fd = sys_on_fd; source->oop.cancel_fd = sys_cancel_fd; source->oop.on_time = sys_on_time; source->oop.cancel_time = sys_cancel_time; source->oop.on_signal = sys_on_signal; source->oop.cancel_signal = sys_cancel_signal; source->magic = MAGIC; source->in_run = 0; source->num_events = 0; source->time_queue = source->time_run = NULL; source->do_jmp = 0; source->sig_active = 0; for (i = 0; i < OOP_NUM_SIGNALS; ++i) { source->sig[i].list = NULL; source->sig[i].ptr = NULL; source->sig[i].active = 0; } source->num_files = 0; source->files = NULL; return source; } void oop_sys_use_sa_restart(void) { int i; for (i = 0; i < OOP_NUM_SIGNALS; ++i) assert(NULL == sys_sig_owner[i] && "signal handler already registered"); use_sa_restart = 1; } static void *sys_time_run(oop_source_sys *sys) { void *ret = OOP_CONTINUE; while (OOP_CONTINUE == ret && NULL != sys->time_run) { struct sys_time *p = sys->time_run; sys->time_run = sys->time_run->next; --sys->num_events; ret = p->f(&sys->oop,p->tv,p->v); /* reenter! */ oop_free(p); } return ret; } void *oop_sys_run(oop_source_sys *sys) { void * volatile ret = OOP_CONTINUE; assert(!sys->in_run && "oop_sys_run is not reentrant"); sys->in_run = 1; while (0 != sys->num_events && OOP_CONTINUE == ret) { struct timeval * volatile ptv = NULL; struct timeval tv; fd_set rfd,wfd,xfd; int i,rv; if (NULL != sys->time_run) { /* interrupted, restart */ ptv = &tv; tv.tv_sec = 0; tv.tv_usec = 0; } else if (NULL != sys->time_queue) { ptv = &tv; gettimeofday(ptv,NULL); if (sys->time_queue->tv.tv_usec < tv.tv_usec) { tv.tv_usec -= 1000000; tv.tv_sec ++; } tv.tv_sec = sys->time_queue->tv.tv_sec - tv.tv_sec; tv.tv_usec = sys->time_queue->tv.tv_usec - tv.tv_usec; if (tv.tv_sec < 0) { tv.tv_sec = 0; tv.tv_usec = 0; } assert(tv.tv_usec >= 0); assert(tv.tv_usec < 1000000); } if (!sys->sig_active) sys->do_jmp = !sigsetjmp(sys->env,1); if (sys->sig_active) { /* Still perform select(), but don't block. */ ptv = &tv; tv.tv_sec = 0; tv.tv_usec = 0; } FD_ZERO(&rfd); FD_ZERO(&wfd); FD_ZERO(&xfd); for (i = 0; i < sys->num_files; ++i) { if (NULL != sys->files[i][OOP_READ].f) FD_SET(i,&rfd); if (NULL != sys->files[i][OOP_WRITE].f) FD_SET(i,&wfd); if (NULL != sys->files[i][OOP_EXCEPTION].f) FD_SET(i,&xfd); } assert(ptv == NULL || (ptv->tv_usec >= 0 && ptv->tv_usec < 1000000 && ptv->tv_sec >= 0)); /* FIXME (bug 1065): FreeBSD seems to have problem with too large tv_sec values. It returns EINVAL. Does this fix the problem? */ if (ptv != NULL && ptv->tv_sec > 3600) ptv->tv_sec = 3600; do { assert(ptv == NULL || (ptv->tv_usec >= 0 && ptv->tv_usec < 1000000)); assert(sys->num_files >= 0); rv = select(sys->num_files,&rfd,&wfd,&xfd,ptv); } while (0 > rv && EINTR == errno); sys->do_jmp = 0; if (0 > rv) { /* Error in select(). */ ret = OOP_ERROR; break; } if (sys->sig_active) { sys->sig_active = 0; for (i = 0; OOP_CONTINUE == ret && i < OOP_NUM_SIGNALS; ++i) { if (sys->sig[i].active) { sys->sig[i].active = 0; sys->sig[i].ptr = sys->sig[i].list; } while (OOP_CONTINUE == ret && NULL != sys->sig[i].ptr) { struct sys_signal_handler *h; h = sys->sig[i].ptr; sys->sig[i].ptr = h->next; ret = h->f(&sys->oop,i,h->v); } } if (OOP_CONTINUE != ret) { sys->sig_active = 1; /* come back */ break; } } if (0 < rv) { for (i = 0; OOP_CONTINUE == ret && i < sys->num_files; ++i) if (FD_ISSET(i,&xfd) && NULL != sys->files[i][OOP_EXCEPTION].f) ret = sys->files[i][OOP_EXCEPTION].f(&sys->oop,i,OOP_EXCEPTION, sys->files[i][OOP_EXCEPTION].v); for (i = 0; OOP_CONTINUE == ret && i < sys->num_files; ++i) if (FD_ISSET(i,&wfd) && NULL != sys->files[i][OOP_WRITE].f) ret = sys->files[i][OOP_WRITE].f(&sys->oop,i,OOP_WRITE, sys->files[i][OOP_WRITE].v); for (i = 0; OOP_CONTINUE == ret && i < sys->num_files; ++i) if (FD_ISSET(i,&rfd) && NULL != sys->files[i][OOP_READ].f) ret = sys->files[i][OOP_READ].f(&sys->oop,i,OOP_READ, sys->files[i][OOP_READ].v); if (OOP_CONTINUE != ret) break; } /* Catch any leftover timeout events. */ ret = sys_time_run(sys); if (OOP_CONTINUE != ret) break; if (NULL != sys->time_queue) { struct sys_time *p,**pp = &sys->time_queue; gettimeofday(&tv,NULL); while (NULL != *pp && (tv.tv_sec > (*pp)->tv.tv_sec || (tv.tv_sec == (*pp)->tv.tv_sec && tv.tv_usec >= (*pp)->tv.tv_usec))) pp = &(*pp)->next; p = *pp; *pp = NULL; sys->time_run = sys->time_queue; sys->time_queue = p; } ret = sys_time_run(sys); } sys->in_run = 0; return ret; } void oop_sys_delete(oop_source_sys *sys) { int i,j; assert(!sys->in_run && "cannot delete while in oop_sys_run"); assert(NULL == sys->time_queue && NULL == sys->time_run && "cannot delete with timeout"); for (i = 0; i < OOP_NUM_SIGNALS; ++i) assert(NULL == sys->sig[i].list && "cannot delete with signal handler"); for (i = 0; i < sys->num_files; ++i) for (j = 0; j < OOP_NUM_EVENTS; ++j) assert(NULL == sys->files[i][j].f && "cannot delete with file handler"); assert(0 == sys->num_events); if (NULL != sys->files) oop_free(sys->files); oop_free(sys); } oop_source *oop_sys_source(oop_source_sys *sys) { assert(&sys->oop == (oop_source *) sys); return &sys->oop; } lyskom-server-2.1.2/src/libraries/liboop/select.c0000664000015100472110000001115207705102516015472 /* select.c, liboop, copyright 1999 Dan Egnor This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License, version 2.1 or later. See the file COPYING for details. */ #include "oop.h" #include #ifdef HAVE_STRING_H # include /* Needed on NetBSD1.1/SPARC due to bzero/FD_ZERO. */ #endif #ifdef HAVE_STRINGS_H # include /* Needed on AIX 4.2 due to bzero/FD_ZERO. */ #endif struct select_set { fd_set rfd,wfd,xfd; }; struct oop_adapter_select { oop_source *source; struct select_set watch,active; struct timeval timeout; int num_fd,do_timeout,is_active,num_fd_active; oop_call_select *call; void *data; }; static oop_call_fd on_fd; static oop_call_time on_timeout,on_collect; oop_adapter_select *oop_select_new( oop_source *source, oop_call_select *call,void *data) { oop_adapter_select *s = oop_malloc(sizeof(*s)); if (NULL == s) return s; s->source = source; FD_ZERO(&s->watch.rfd); FD_ZERO(&s->watch.wfd); FD_ZERO(&s->watch.xfd); FD_ZERO(&s->active.rfd); FD_ZERO(&s->active.wfd); FD_ZERO(&s->active.xfd); s->num_fd = 0; s->num_fd_active = 0; s->do_timeout = 0; s->is_active = 0; s->call = call; s->data = data; return s; } static void *activate(oop_adapter_select *s) { if (!s->is_active) { s->is_active = 1; s->source->on_time(s->source,OOP_TIME_NOW,on_collect,s); } return OOP_CONTINUE; } static void deactivate(oop_adapter_select *s) { if (s->is_active) { s->source->cancel_time(s->source,OOP_TIME_NOW,on_collect,s); s->is_active = 0; s->num_fd_active = 0; FD_ZERO(&s->active.rfd); FD_ZERO(&s->active.wfd); FD_ZERO(&s->active.xfd); } } void oop_select_set( oop_adapter_select *s,int num_fd, fd_set *rfd,fd_set *wfd,fd_set *xfd,struct timeval *timeout) { int fd; for (fd = 0; fd < num_fd || fd < s->num_fd; ++fd) { int rfd_set = fd < num_fd && FD_ISSET(fd,rfd); int wfd_set = fd < num_fd && FD_ISSET(fd,wfd); int xfd_set = fd < num_fd && FD_ISSET(fd,xfd); int w_rfd_set = fd < s->num_fd && FD_ISSET(fd,&s->watch.rfd); int w_wfd_set = fd < s->num_fd && FD_ISSET(fd,&s->watch.wfd); int w_xfd_set = fd < s->num_fd && FD_ISSET(fd,&s->watch.xfd); if (rfd_set && !w_rfd_set) { s->source->on_fd(s->source,fd,OOP_READ,on_fd,s); FD_SET(fd,&s->watch.rfd); } if (!rfd_set && w_rfd_set) { s->source->cancel_fd(s->source,fd,OOP_READ); FD_CLR(fd,&s->watch.rfd); } if (wfd_set && !w_wfd_set) { s->source->on_fd(s->source,fd,OOP_WRITE,on_fd,s); FD_SET(fd,&s->watch.wfd); } if (!wfd_set && w_wfd_set) { s->source->cancel_fd(s->source,fd,OOP_WRITE); FD_CLR(fd,&s->watch.wfd); } if (xfd_set && !w_xfd_set) { s->source->on_fd(s->source,fd,OOP_EXCEPTION,on_fd,s); FD_SET(fd,&s->watch.xfd); } if (!xfd_set && w_xfd_set) { s->source->cancel_fd(s->source,fd,OOP_EXCEPTION); FD_CLR(fd,&s->watch.xfd); } } s->num_fd = num_fd; if (s->do_timeout) { s->source->cancel_time(s->source,s->timeout,on_timeout,s); s->do_timeout = 0; } if (NULL != timeout) { gettimeofday(&s->timeout,NULL); s->timeout.tv_sec += timeout->tv_sec; s->timeout.tv_usec += timeout->tv_usec; while (s->timeout.tv_usec >= 1000000) { ++s->timeout.tv_sec; s->timeout.tv_usec -= 1000000; } s->do_timeout = 1; s->source->on_time(s->source,s->timeout,on_timeout,s); } deactivate(s); } void oop_select_delete(oop_adapter_select *s) { fd_set fd; FD_ZERO(&fd); oop_select_set(s,0,&fd,&fd,&fd,NULL); oop_free(s); } static void set_fd(int fd,fd_set *fds,int *num) { if (!FD_ISSET(fd,fds)) { FD_SET(fd,fds); if (fd >= *num) *num = fd + 1; } } static void *on_fd(oop_source *source,int fd,oop_event event,void *data) { oop_adapter_select *s = (oop_adapter_select *) data; switch (event) { case OOP_READ: assert(FD_ISSET(fd,&s->watch.rfd)); set_fd(fd,&s->active.rfd,&s->num_fd_active); break; case OOP_WRITE: assert(FD_ISSET(fd,&s->watch.wfd)); set_fd(fd,&s->active.wfd,&s->num_fd_active); break; case OOP_EXCEPTION: assert(FD_ISSET(fd,&s->watch.xfd)); set_fd(fd,&s->active.xfd,&s->num_fd_active); break; default: assert(0); break; } return activate(s); } static void *on_timeout(oop_source *source,struct timeval when,void *data) { oop_adapter_select *s = (oop_adapter_select *) data; assert(s->do_timeout); return activate(s); } static void *on_collect(oop_source *source,struct timeval when,void *data) { oop_adapter_select *s = (oop_adapter_select *) data; struct select_set set = s->active; int num = s->num_fd_active; struct timeval now; gettimeofday(&now,NULL); deactivate(s); return s->call(s,num,&set.rfd,&set.wfd,&set.xfd,now,s->data); } lyskom-server-2.1.2/src/libraries/liboop/signal.c0000664000015100472110000001403607704460452015501 /* signal.c, liboop, copyright 1999 Dan Egnor This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License, version 2.1 or later. See the file COPYING for details. */ #include "oop.h" #include #include #include #include #include #define MAGIC 5131 struct sig_handler { struct sig_handler *next; oop_call_signal *f; void *v; }; struct sig_signal { struct sig_handler *list,*ptr; struct sigaction old; volatile sig_atomic_t active; }; struct oop_adapter_signal { oop_source oop; int magic,pipefd[2]; oop_source *source; /* backing source */ struct sig_signal sig[OOP_NUM_SIGNALS]; int num_events; }; static struct oop_adapter_signal *sig_owner[OOP_NUM_SIGNALS]; static int use_sa_restart = 0; static oop_adapter_signal *verify_source(oop_source *source) { oop_adapter_signal * const s = (oop_adapter_signal *) source; assert(MAGIC == s->magic); return s; } static void do_pipe(struct oop_adapter_signal *s) { const char ch = '\0'; while (write(s->pipefd[1],&ch,1) < 0 && EINTR == errno) ; } static void on_signal(int sig) { oop_adapter_signal * const s = sig_owner[sig]; struct sigaction act; assert(NULL != s); /* Reset the handler, in case this is needed. */ sigaction(sig,NULL,&act); act.sa_handler = on_signal; sigaction(sig,&act,NULL); assert(NULL != s->sig[sig].list); s->sig[sig].active = 1; do_pipe(s); } static void *on_pipe(oop_source *source,int fd,oop_event event,void *user) { oop_adapter_signal * const s = verify_source((oop_source *) user); int i; char buf[4096]; assert(fd == s->pipefd[0]); assert(OOP_READ == event); while (read(s->pipefd[0],buf,sizeof buf) < 0 && EINTR == errno) ; for (i = 0; i < OOP_NUM_SIGNALS; ++i) { if (s->sig[i].active) { s->sig[i].active = 0; s->sig[i].ptr = s->sig[i].list; } if (NULL != s->sig[i].ptr) { struct sig_handler * const h = s->sig[i].ptr; s->sig[i].ptr = h->next; do_pipe(s); /* come back */ return h->f(&s->oop,i,h->v); } } return OOP_CONTINUE; } static void sig_on_fd(oop_source *source,int fd,oop_event ev, oop_call_fd *call,void *data) { oop_adapter_signal * const s = verify_source(source); s->source->on_fd(s->source,fd,ev,call,data); } static void sig_cancel_fd(oop_source *source,int fd,oop_event ev) { oop_adapter_signal * const s = verify_source(source); s->source->cancel_fd(s->source,fd,ev); } static void sig_on_time(oop_source *source,struct timeval when, oop_call_time *call,void *data) { oop_adapter_signal * const s = verify_source(source); s->source->on_time(s->source,when,call,data); } static void sig_cancel_time(oop_source *source,struct timeval when, oop_call_time *call,void *data) { oop_adapter_signal * const s = verify_source(source); s->source->cancel_time(s->source,when,call,data); } static void sig_on_signal(oop_source *source,int sig, oop_call_signal *f,void *v) { oop_adapter_signal * const s = verify_source(source); struct sig_handler * const handler = oop_malloc(sizeof(*handler)); if (NULL == handler) return; /* ugh */ assert(sig > 0 && sig < OOP_NUM_SIGNALS && "invalid signal number"); handler->f = f; handler->v = v; handler->next = s->sig[sig].list; s->sig[sig].list = handler; ++s->num_events; if (NULL == handler->next) { struct sigaction act; assert(NULL == sig_owner[sig]); sig_owner[sig] = s; assert(0 == s->sig[sig].active); sigaction(sig,NULL,&act); s->sig[sig].old = act; act.sa_handler = on_signal; #ifdef SA_NODEFER act.sa_flags &= ~SA_NODEFER; #endif if (use_sa_restart) act.sa_flags |= SA_RESTART; sigaction(sig,&act,NULL); } } static void sig_cancel_signal(oop_source *source,int sig, oop_call_signal *f,void *v) { oop_adapter_signal * const s = verify_source(source); struct sig_handler **pp = &s->sig[sig].list; assert(sig > 0 && sig < OOP_NUM_SIGNALS && "invalid signal number"); while (NULL != *pp && ((*pp)->f != f || (*pp)->v != v)) pp = &(*pp)->next; if (NULL != *pp) { struct sig_handler * const p = *pp; if (NULL == p->next && &s->sig[sig].list == pp) { sigaction(sig,&s->sig[sig].old,NULL); s->sig[sig].active = 0; sig_owner[sig] = NULL; } *pp = p->next; if (s->sig[sig].ptr == p) s->sig[sig].ptr = *pp; --s->num_events; oop_free(p); } } static int add_flag(int fd, int get_op, int set_op, int val) { int flags; if ((flags = fcntl(fd,get_op,0)) == -1) return -1; if ((fcntl(fd,set_op,flags|val)) == -1) return -1; return 0; } oop_adapter_signal *oop_signal_new(oop_source *source) { int i; oop_adapter_signal * const s = oop_malloc(sizeof(*s)); if (NULL == s) return NULL; assert(NULL != source); if (pipe(s->pipefd)) { oop_free(s); return NULL; } if (add_flag(s->pipefd[0],F_GETFD,F_SETFD,FD_CLOEXEC) || add_flag(s->pipefd[1],F_GETFD,F_SETFD,FD_CLOEXEC) || add_flag(s->pipefd[0],F_GETFL,F_SETFL,O_NONBLOCK) || add_flag(s->pipefd[1],F_GETFL,F_SETFL,O_NONBLOCK)) { oop_free(s); return NULL; } s->oop.on_fd = sig_on_fd; s->oop.cancel_fd = sig_cancel_fd; s->oop.on_time = sig_on_time; s->oop.cancel_time = sig_cancel_time; s->oop.on_signal = sig_on_signal; s->oop.cancel_signal = sig_cancel_signal; s->source = source; s->source->on_fd(s->source,s->pipefd[0],OOP_READ,on_pipe,s); s->num_events = 0; for (i = 0; i < OOP_NUM_SIGNALS; ++i) { s->sig[i].list = NULL; s->sig[i].ptr = NULL; s->sig[i].active = 0; } s->magic = MAGIC; return s; } void oop_signal_delete(oop_adapter_signal *s) { assert(0 == s->num_events && "cannot delete with signal handler"); s->magic = 0; close(s->pipefd[0]); close(s->pipefd[1]); s->source->cancel_fd(s->source,s->pipefd[0],OOP_READ); oop_free(s); } oop_source *oop_signal_source(oop_adapter_signal *s) { return &s->oop; } void oop_signal_use_sa_restart(void) { int i; for (i = 0; i < OOP_NUM_SIGNALS; ++i) assert(NULL == sig_owner[i] && "signal handler already registered"); use_sa_restart = 1; } lyskom-server-2.1.2/src/libraries/liboop/alloc.c0000664000015100472110000000033207703073503015304 #include "oop.h" #include void *(*oop_malloc)(size_t) = malloc; void (*oop_free)(void *) = free; void *(*oop_realloc)(void *,size_t) = realloc; int _oop_continue,_oop_error; /* this has to go somewhere */ lyskom-server-2.1.2/src/libraries/liboop/read.c0000664000015100472110000003075207704773131015143 /* read.c, liboop, copyright 2000 Ian jackson This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License, version 2.1 or later. See the file COPYING for details. */ #include "oop.h" #include "oop-read.h" #include #include #include #include /* HP-UX 11.0 defines MIN. */ #undef MIN #define MIN(a,b) ((a)<(b) ? (a) : (b)) static void *on_time(oop_source*, struct timeval, void*); static void *on_readable(oop_source*, oop_readable*, void*); static void *on_process(oop_source*, oop_read*, int try_read); static int set_time_ifbuf(oop_source *oop, oop_read *rd); static void cancel_time(oop_source *oop, oop_read *rd); const oop_rd_style OOP_RD_STYLE_GETLINE[]= {{ OOP_RD_DELIM_STRIP,'\n', OOP_RD_NUL_FORBID, OOP_RD_SHORTREC_EOF, }}; const oop_rd_style OOP_RD_STYLE_BLOCK[]= {{ OOP_RD_DELIM_NONE, 0, OOP_RD_NUL_PERMIT, OOP_RD_SHORTREC_EOF, }}; const oop_rd_style OOP_RD_STYLE_IMMED[]= {{ OOP_RD_DELIM_NONE, 0, OOP_RD_NUL_PERMIT, OOP_RD_SHORTREC_SOONEST, }}; struct oop_read { /* set at creation time: */ oop_source *oop; oop_readable *ra; char *userbuf; /* persistent state */ oop_rd_bufctl_op readahead; /* _ENABLE or _DISABLE */ char *allocbuf; size_t alloc, used, discard; size_t neednotcheck; /* data we've already searched for delimiter */ int displacedchar; /* >=0, first unused */ /* arguments to oop_rd_read */ oop_rd_style style; size_t maxrecsz; oop_rd_call *call_ok, *call_err; void *data_ok, *data_err; }; /* Buffer is structured like this if displacedchar>=0 and delim found: * * done stuff, displaced readahead - read unused * we've called delimiter| but not yet buffer * back for || returned space * ddddddddddddddddddddddDOaaaaaaaaaaaaaaaaaaa____________ * <------- discard -----> * <----------------------- used ------------> * <------------------------------------- alloc ---------> * * If displacedchar>=0 then the the first character of readahead has * been displaced by a nul byte and is stored in displacedchar. If * _DELIM_STRIP and the delimiter is found then the nul overwrites the * delimiter. * * Buffer when full {this,max} may need * DELIM found? <-recval-> recdata buffer required readahead * NONE n/a ddddddddddOaaa_ recsz recdata+1 == recsz+1 maxrecsz * KEEP Yes dddddddddDOaaa_ recsz recdata+1 == recsz+1 maxrecsz * KEEP No ddddddddddOaaa_ recsz recdata+1 == recsz+1 maxrecsz * STRIP Yes dddddddddd0aaaa recsz+1 recdata == recsz+1 maxrecsz+1 * STRIP No ddddddddddOaaaa recsz recdata+1 == recsz+1 maxrecsz+1 * * Key: d = data to be returned * D = delimiter, being returned * a = readahead, not to be returned * O = readahead character displaced by a nul * 0 = delimiter replaced by a nul * _ = unused */ static const char *const eventstrings_nl[]= { "INTERNAL ERROR (_nl _OK) please report", "End of file", "Missing newline at end of file", "Line too long", "Nul byte", "Nul byte, in line which is also too long", "INTERNAL ERROR (_nl _SYSTEM) please report" }; static const char *const eventstrings_other[]= { "Record read successfully", "End of file", "Incomplete record at end of file", "Record too long", "Nul byte", "Nul byte in record which is also too long", "System error" }; oop_read *oop_rd_new(oop_source *oop, oop_readable *ra, char *buf, size_t bufsz) { oop_read *rd= 0; assert(buf ? bufsz>=2 : !bufsz); rd= oop_malloc(sizeof(*rd)); if (!rd) goto x_fail; rd->oop= oop; rd->ra= ra; rd->userbuf= buf; rd->readahead= OOP_RD_BUFCTL_ENABLE; rd->allocbuf= 0; rd->used= 0; rd->alloc= buf ? bufsz : 0; rd->neednotcheck= 0; rd->displacedchar= -1; rd->style= *OOP_RD_STYLE_IMMED; return rd; x_fail: oop_free(rd); return 0; } static int set_time_ifbuf(oop_source *oop, oop_read *rd) { if (rd->used > rd->discard) return oop->on_time(oop,OOP_TIME_NOW,on_time,rd), 0; /* fixme */ return 0; } static void cancel_time(oop_source *oop, oop_read *rd) { oop->cancel_time(oop,OOP_TIME_NOW,on_time,rd); } static int set_read(oop_source *oop, oop_read *rd) { return rd->ra->on_readable(rd->ra,on_readable,rd), 0; /* fixme */ } static void cancel_read(oop_source *oop, oop_read *rd) { rd->ra->on_cancel(rd->ra); } int oop_rd_read(oop_read *rd, const oop_rd_style *style, size_t maxrecsz, oop_rd_call *ifok, void *data_ok, oop_rd_call *iferr, void *data_err) { oop_source *oop= rd->oop; int er; cancel_time(oop,rd); cancel_read(oop,rd); if (style->delim_mode == OOP_RD_DELIM_NONE || rd->style.delim_mode == OOP_RD_DELIM_NONE || style->delim != rd->style.delim) rd->neednotcheck= 0; rd->style= *style; rd->maxrecsz= maxrecsz; rd->call_ok= ifok; rd->data_ok= data_ok; rd->call_err= iferr; rd->data_err= data_err; er= set_read(oop,rd); if (er) return er; er= set_time_ifbuf(oop,rd); if (er) return er; return 0; } void oop_rd_delete(oop_read *rd) { rd->ra->on_cancel(rd->ra); oop_free(rd->allocbuf); oop_free(rd); } void oop_rd_cancel(oop_read *rd) { cancel_time(rd->oop,rd); cancel_read(rd->oop,rd); } const char *oop_rd_errmsg(oop_read *rd, oop_rd_event event, int errnoval, const oop_rd_style *style) { if (event == OOP_RD_SYSTEM) return strerror(errnoval); else if (style && style->delim_mode != OOP_RD_DELIM_NONE && style->delim == '\n') return eventstrings_nl[event]; else return eventstrings_other[event]; } static void *on_readable(oop_source *oop, oop_readable *ra, void *rd_void) { oop_read *rd= rd_void; assert(oop == rd->oop); assert(ra == rd->ra); return on_process(oop,rd,1); } static void *on_time(oop_source *oop, struct timeval when, void *rd_void) { oop_read *rd= rd_void; assert(oop == rd->oop); return on_process(oop,rd,0); } static size_t calc_dataspace(oop_read *rd) { if (rd->style.delim_mode == OOP_RD_DELIM_STRIP) { return rd->alloc; } else { return rd->alloc ? rd->alloc-1 : 0; } } static void *on_process(oop_source *oop, oop_read *rd, int try_read) { oop_rd_event event; int evkind; /* 0=none, -1=error, 1=something */ int errnoval, nread, cancelnow; oop_rd_call *call; char *buf, *delimp; const char *errmsg; size_t maxrecsz; /* like in arg to oop_rd_read, but 0 -> large val */ size_t maxbufreqd; /* maximum buffer we might possibly want to alloc */ size_t readahead; /* max amount of data we might want to readahead */ size_t want; /* amount we want to allocate or data we want to read */ size_t dataspace; /* amount of buffer we can usefully fill with data */ size_t thisrecsz; /* length of the record we've found */ size_t thisrecdata; /* length of data representing the record */ void *call_data; cancel_time(oop,rd); if (rd->userbuf) { buf= rd->userbuf; } else { buf= rd->allocbuf; } if (rd->discard) { rd->used -= rd->discard; rd->neednotcheck -= rd->discard; memmove(buf, buf + rd->discard, rd->used); rd->discard= 0; } if (rd->displacedchar >= 0) { assert(rd->used > 0); buf[0]= rd->displacedchar; rd->displacedchar= -1; } maxrecsz= rd->maxrecsz ? rd->maxrecsz : INT_MAX / 5 /* allows +20 and *4 */; maxbufreqd= maxrecsz+1; if (rd->userbuf && maxbufreqd > rd->alloc) { maxrecsz -= (maxbufreqd - rd->alloc); maxbufreqd= rd->alloc; } if (rd->style.delim_mode == OOP_RD_DELIM_STRIP) { readahead= maxrecsz+1; } else { readahead= maxrecsz; } for (;;) { evkind= 0; event= -1; thisrecdata= thisrecsz= 0; errnoval= 0; assert(rd->used <= rd->alloc); dataspace= calc_dataspace(rd); if (/* delimiter already in buffer, within max record data ? */ rd->style.delim_mode != OOP_RD_DELIM_NONE && (delimp= memchr(buf + rd->neednotcheck, rd->style.delim, MIN(rd->used, readahead) - rd->neednotcheck))) { thisrecsz= (delimp - buf); thisrecdata= thisrecsz+1; if (rd->style.delim_mode == OOP_RD_DELIM_KEEP) thisrecsz= thisrecdata; event= OOP_RD_OK; evkind= +1; } else if (rd->used >= readahead) { thisrecsz= thisrecdata= maxrecsz; evkind= +1; if (rd->style.delim_mode == OOP_RD_DELIM_NONE) { event= OOP_RD_OK; } else { event= OOP_RD_LONG; if (rd->style.shortrec_mode < OOP_RD_SHORTREC_LONG) { evkind= -1; thisrecsz= thisrecdata= 0; } } } else if (/* want to return ASAP, and we have something ? */ rd->style.shortrec_mode == OOP_RD_SHORTREC_SOONEST && rd->used > 0 && rd->alloc >= 2) { thisrecdata= rd->used; if (thisrecdata == rd->alloc) thisrecdata--; thisrecsz= thisrecdata; event= OOP_RD_OK; evkind= +1; } want= 0; if (evkind && thisrecdata && thisrecsz >= rd->alloc) { /* Need to make space for the trailing nul */ want= rd->alloc+1; } else if (!evkind && !rd->userbuf && rd->used >= dataspace && rd->alloc < maxbufreqd) { /* Need to make space to read more data */ want= rd->alloc + 20; want <<= 2; want= MIN(want, maxbufreqd); } if (want) { assert(!rd->userbuf); assert(want <= maxbufreqd); buf= oop_realloc(rd->allocbuf,want); if (!buf) { event= OOP_RD_SYSTEM; evkind= -1; errnoval= ENOMEM; thisrecsz= thisrecdata= 0; break; } rd->allocbuf= buf; rd->alloc= want; } if (evkind) break; /* OK, process it then */ if (!try_read) return OOP_CONTINUE; /* But we weren't told it was ready. */ dataspace= calc_dataspace(rd); want= MIN(dataspace, readahead); assert(rd->used < want); nread= rd->ra->try_read(rd->ra, buf+rd->used, want-rd->used); if (errno == EAGAIN) return OOP_CONTINUE; if (nread > 0) { rd->neednotcheck= rd->used; rd->used += nread; continue; } if (nread < 0) { /* read error */ event= OOP_RD_SYSTEM; evkind= -1; errnoval= errno; thisrecsz= thisrecdata= rd->used; break; } else { if (rd->used) { event= OOP_RD_PARTREC; evkind= (rd->style.shortrec_mode == OOP_RD_SHORTREC_FORBID) ? -1 : +1; thisrecsz= thisrecdata= rd->used; } else { event= OOP_RD_EOF; evkind= +1; } break; } } /* OK, we have an event of some kind */ /* Nul byte handling */ if (thisrecsz > 0 && rd->style.nul_mode != OOP_RD_NUL_PERMIT) { size_t checked; char *nul, *notnul; for (checked=0; (nul= memchr(buf+checked,0,thisrecsz-checked)); ) { if (rd->style.nul_mode == OOP_RD_NUL_FORBID) { event= OOP_RD_NUL; evkind= -1; thisrecdata= thisrecsz= 0; break; } assert(rd->style.nul_mode == OOP_RD_NUL_DISCARD); for (notnul= nul+1; notnul < buf+thisrecsz && notnul == '\0'; notnul++); thisrecsz-= (notnul-nul); checked= nul-buf; memmove(nul,notnul,thisrecsz-checked); } } /* Checks that all is well */ assert(evkind); assert(thisrecsz <= thisrecdata); assert(!rd->maxrecsz || thisrecsz <= rd->maxrecsz); assert(thisrecdata <= rd->used); rd->discard= thisrecdata; cancelnow= (evkind < 0) || (event == OOP_RD_EOF); if (!cancelnow) { errnoval= set_time_ifbuf(oop,rd); if (errnoval) { event= OOP_RD_SYSTEM; evkind= -1; cancelnow= 1; thisrecsz= thisrecdata= 0; rd->discard= 0; } } if (evkind < 0) { call= rd->call_err; call_data= rd->data_err; errmsg= oop_rd_errmsg(rd,event,errnoval,&rd->style); } else { call= rd->call_ok; call_data= rd->data_ok; errmsg= 0; } if (thisrecdata) { /* We have to fill in a nul byte. */ assert(thisrecsz < rd->alloc); if (thisrecsz == thisrecdata && thisrecsz < rd->used) rd->displacedchar= (unsigned char)buf[thisrecdata]; buf[thisrecsz]= 0; } if (cancelnow) oop_rd_cancel(rd); return call(oop,rd, event,errmsg,errnoval, (thisrecdata ? buf : 0), thisrecsz, call_data); } oop_read *oop_rd_new_fd(oop_source *oop, int fd, char *buf, size_t bufsz) { oop_readable *ra; oop_read *rd; ra= oop_readable_fd(oop,fd); if (!ra) return 0; rd= oop_rd_new(oop,ra,buf,bufsz); if (!rd) { ra->delete_tidy(ra); return 0; } return rd; } int oop_rd_delete_tidy(oop_read *rd) { oop_readable *ra= rd->ra; oop_rd_delete(rd); return ra->delete_tidy(ra); } void oop_rd_delete_kill(oop_read *rd) { oop_readable *ra= rd->ra; oop_rd_delete(rd); ra->delete_kill(ra); } lyskom-server-2.1.2/src/libraries/liboop/read-fd.c0000664000015100472110000000442007703073503015516 /* read-fd.c, liboop, copyright 2000 Ian jackson This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License, version 2.1 or later. See the file COPYING for details. */ #include "oop.h" #include "oop-read.h" #include #include #include #include #include #include typedef struct { oop_readable ra; oop_source *oop; int fd; oop_readable_call *call; void *opaque; } rafd_intern; static void *process(oop_source *oop, int fd, oop_event event, void *rafd_void) { rafd_intern *rafd= rafd_void; assert(event == OOP_READ); assert(fd == rafd->fd); assert(oop == rafd->oop); return rafd->call(oop,&rafd->ra,rafd->opaque); } static void on_cancel(struct oop_readable *ra) { rafd_intern *rafd= (void*)ra; rafd->oop->cancel_fd(rafd->oop,rafd->fd,OOP_READ); } static int on_read(oop_readable *ra, oop_readable_call *call, void *opaque) { rafd_intern *rafd= (void*)ra; rafd->call= call; rafd->opaque= opaque; return rafd->oop->on_fd(rafd->oop,rafd->fd,OOP_READ,process,rafd), 0; /* fixme */ } static ssize_t try_read(oop_readable *ra, void *buffer, size_t length) { rafd_intern *rafd= (void*)ra; ssize_t nread; for (;;) { nread= read(rafd->fd,buffer,length); if (nread != -1) break; if (errno != EINTR) return nread; } assert(nread >= 0); return nread; } static void delete_kill(struct oop_readable *ra) { oop_free(ra); } static int delete_tidy(struct oop_readable *ra) { rafd_intern *rafd= (void*)ra; int err; err= oop_fd_nonblock(rafd->fd,0); delete_kill(ra); return err; } static const oop_readable functions= { on_read, on_cancel, try_read, delete_tidy, delete_kill }; oop_readable *oop_readable_fd(oop_source *oop, int fd) { rafd_intern *rafd; rafd= oop_malloc(sizeof(*rafd)); if (!rafd) return 0; rafd->ra= functions; rafd->oop= oop; rafd->fd= fd; if (oop_fd_nonblock(fd,1)) { oop_free(rafd); return 0; } return (oop_readable*)rafd; } int oop_fd_nonblock(int fd, int nonblock) { int flags; flags= fcntl(fd, F_GETFL); if (flags == -1) return errno; if (nonblock) flags |= O_NONBLOCK; else flags &= ~O_NONBLOCK; return fcntl(fd, F_SETFL, flags) ? errno : 0; } lyskom-server-2.1.2/src/libraries/liboop/read-mem.c0000664000015100472110000000716307703073503015712 /* read-mem.c, liboop, copyright 2000 Ian jackson This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License, version 2.1 or later. See the file COPYING for details. */ #include "oop.h" #include "oop-read.h" #include #include #include #include typedef struct { oop_readable ra; oop_source *oop; int processing; enum { state_cancelled, state_active, state_dying } state; const char *data; size_t remaining; oop_readable_call *call; void *opaque; } ram_intern; static void *process(oop_source *oop, struct timeval when, void *ram_void); static int set_time(ram_intern *ram) { int err; err= (ram->oop->on_time(ram->oop,OOP_TIME_NOW,process,ram), 0); /* fixme */ if (err) return err; ram->processing= 1; return 0; } static void *process(oop_source *oop, struct timeval when, void *ram_void) { ram_intern *ram= ram_void; void *ret; int err; assert(oop == ram->oop); assert(ram->processing); ret= OOP_CONTINUE; while (ram->state == state_active && ret == OOP_CONTINUE) { ret= ram->call(oop,&ram->ra,ram->opaque); } switch (ram->state) { case state_active: err= set_time(ram); if (err) assert(!"must not lose flow of control"); /* AAARGH! No way to avoid this I think. Happens when: * - program calls on_read which works, setting immediate callback; * - process calls the application's function, which returns * OOP_HALT or some such, but without calling on_cancel; * Now we have to set another immediate callback. * If this fails and we were to ignore it then: * - program reenters event loop, expecting to deal with the rest * of the oop_readable_mem data. But we've lost the flow * of control and the callback never happens, so * oop_sys_run or whatever would (lyingly) exit straight * away with OOP_CONTINUE. * Alternatively we could ignore the application's request * to abort the event loop, which seems just as bad. */ break; case state_cancelled: ram->processing= 0; break; case state_dying: oop_free(ram); break; } return ret; } static int on_read(oop_readable *ra, oop_readable_call *call, void *opaque) { ram_intern *ram= (void*)ra; assert(ram->state != state_dying); ram->state= state_active; ram->call= call; ram->opaque= opaque; if (ram->processing) return 0; return set_time(ram); } static void on_cancel(struct oop_readable *ra) { ram_intern *ram= (void*)ra; assert(ram->state != state_dying); ram->state= state_cancelled; } static ssize_t try_read(oop_readable *ra, void *buffer, size_t length) { ram_intern *ram= (void*)ra; if (length > SSIZE_MAX) length= SSIZE_MAX; if (length > ram->remaining) length= ram->remaining; memcpy(buffer,ram->data,length); ram->data += length; ram->remaining -= length; return length; } static void delete_kill(struct oop_readable *ra) { ram_intern *ram= (void*)ra; assert(ram->state != state_dying); ram->state= state_dying; if (!ram->processing) oop_free(ram); } static int delete_tidy(struct oop_readable *ra) { delete_kill(ra); return 0; } static const oop_readable functions= { on_read, on_cancel, try_read, delete_tidy, delete_kill }; oop_readable *oop_readable_mem(oop_source *oop, const void *data, size_t length) { ram_intern *ram; ram= oop_malloc(sizeof(*ram)); if (!ram) return 0; ram->ra= functions; ram->oop= oop; ram->processing= 0; ram->state= state_cancelled; ram->data= data; ram->remaining= length; return (oop_readable*)ram; } lyskom-server-2.1.2/src/libraries/liboop/adns.c0000664000015100472110000000742707714127117015156 /* adns.c, liboop, copyright 1999 Dan Egnor This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License, version 2.1 or later. See the file COPYING for details. */ #ifdef HAVE_ADNS #include "oop.h" #include "adns.h" #include "oop-adns.h" #include #ifdef HAVE_STRING_H # include /* Needed on NetBSD1.1/SPARC due to bzero/FD_ZERO. */ #endif #ifdef HAVE_STRINGS_H # include /* Needed on AIX 4.2 due to bzero/FD_ZERO. */ #endif struct oop_adapter_adns { oop_source *source; oop_adapter_select *select; adns_state state; int count; }; struct oop_adns_query { oop_adapter_adns *a; adns_query query; oop_adns_call *call; void *data; }; static oop_call_select on_select; static oop_call_time on_process; static void set_select(oop_adapter_adns *); oop_adapter_adns *oop_adns_new( oop_source *source, adns_initflags flags,FILE *diag) { oop_adapter_adns *a = oop_malloc(sizeof(*a)); if (NULL == a) return NULL; a->select = NULL; a->state = NULL; if (adns_init(&a->state,flags | adns_if_noautosys,diag) || (NULL == (a->select = oop_select_new(source,on_select,a)))) { if (NULL != a->state) adns_finish(a->state); if (NULL != a->select) oop_select_delete(a->select); oop_free(a); return NULL; } a->source = source; a->count = 0; return a; } void oop_adns_delete(oop_adapter_adns *a) { assert(0 == a->count && "deleting oop_adapter_adns with outstanding queries"); a->source->cancel_time(a->source,OOP_TIME_NOW,on_process,a); oop_select_delete(a->select); adns_finish(a->state); oop_free(a); } oop_adns_query *oop_adns_submit( oop_adapter_adns *a,int *errcode, const char *owner,adns_rrtype type,adns_queryflags flags, oop_adns_call *call,void *data) { oop_adns_query *q = oop_malloc(sizeof(*q)); if (NULL == q) return NULL; if (0 != (*errcode = adns_submit(a->state,owner,type,flags,q,&q->query))) { oop_free(q); return NULL; } q->a = a; q->call = call; q->data = data; ++q->a->count; set_select(a); return q; } oop_adns_query *oop_adns_submit_reverse( oop_adapter_adns *a,int *errcode, const struct sockaddr *addr,adns_rrtype type,adns_queryflags flags, oop_adns_call *call,void *data) { oop_adns_query *q = oop_malloc(sizeof(*q)); if (NULL == q) return NULL; if (0 != (*errcode = adns_submit_reverse(a->state,addr,type,flags,q,&q->query))) { oop_free(q); return NULL; } q->a = a; q->call = call; q->data = data; ++q->a->count; set_select(a); return q; } void oop_adns_cancel(oop_adns_query *q) { adns_cancel(q->query); --q->a->count; set_select(q->a); oop_free(q); } static void set_select(oop_adapter_adns *a) { fd_set rfd,wfd,xfd; struct timeval buf,*out = NULL,now; int maxfd = 0; FD_ZERO(&rfd); FD_ZERO(&wfd); FD_ZERO(&xfd); gettimeofday(&now,NULL); adns_beforeselect(a->state,&maxfd,&rfd,&wfd,&xfd,&out,&buf,&now); oop_select_set(a->select,maxfd,&rfd,&wfd,&xfd,out); } static void *on_process(oop_source *source,struct timeval when,void *data) { oop_adapter_adns *a = (oop_adapter_adns *) data; adns_answer *r; adns_query query; oop_adns_query *q = NULL; void *adns_data; query = NULL; if (0 == adns_check(a->state,&query,&r,&adns_data)) { q = (oop_adns_query *) adns_data; assert(query == q->query); } set_select(a); if (NULL != q) { oop_adns_call *call = q->call; void *data = q->data; assert(a == q->a); --q->a->count; oop_free(q); source->on_time(source,when,on_process,a); return call(a,r,data); } return OOP_CONTINUE; } static void *on_select( oop_adapter_select *select, int num,fd_set *rfd,fd_set *wfd,fd_set *xfd, struct timeval now,void *data) { oop_adapter_adns *a = (oop_adapter_adns *) data; adns_afterselect(a->state,num,rfd,wfd,xfd,&now); return on_process(a->source,OOP_TIME_NOW,a); } #endif lyskom-server-2.1.2/src/libraries/liboop/test-oop.c0000664000015100472110000003724107714132364016000 /* test-oop.c, liboop, copyright 1999 Dan Egnor This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License, version 2.1 or later. See the file COPYING for details. */ #include #include #include #include #include #include #include #include #include #include #include #include "oop.h" #include "oop-read.h" #ifdef HAVE_GLIB #include #include "oop-glib.h" GMainLoop *glib_loop; #endif #ifdef HAVE_TCL #include #include "oop-tcl.h" #endif #ifdef HAVE_WWW /* Yuck: */ #define HAVE_CONFIG_H #undef PACKAGE #undef VERSION #include "oop.h" #include "HTEvent.h" #include "oop-www.h" #include "WWWLib.h" #include "WWWInit.h" #endif #ifdef HAVE_READLINE #include #include "oop-rl.h" #endif struct timer { struct timeval tv; int delay; }; static oop_source_sys *source_sys; static oop_adapter_signal *source_signal; static void usage(void) { fputs( "usage: test-oop [ ...]\n" "sources: sys system event source\n" " signal system event source with signal adapter\n" #ifdef HAVE_GLIB " glib GLib source adapter\n" #endif #ifdef HAVE_TCL " tcl Tcl source adapter\n" #endif "sinks: timer some timers\n" " signal some signal handlers\n" " echo a stdin->stdout copy\n" #ifdef HAVE_READLINE " readline like echo but with line editing\n" #endif #ifdef HAVE_ADNS " adns some asynchronous DNS lookups\n" #endif #ifdef HAVE_WWW " libwww some HTTP GET operations\n" #endif " read:[][,][:]\n" " : n | s | k\n" " : = | n | \n" " : f | d | p\n" " : f | e | l | s\n" ,stderr); exit(1); } /* -- timer ---------------------------------------------------------------- */ static oop_call_time on_timer; static void *on_timer(oop_source *source,struct timeval tv,void *data) { struct timer *timer = (struct timer *) data; timer->tv = tv; timer->tv.tv_sec += timer->delay; source->on_time(source,timer->tv,on_timer,data); printf("timer: once every "); if (1 == timer->delay) printf("second\n"); else printf("%d seconds\n",timer->delay); return OOP_CONTINUE; } static oop_call_signal stop_timer; static void *stop_timer(oop_source *source,int sig,void *data) { struct timer *timer = (struct timer *) data; source->cancel_time(source,timer->tv,on_timer,timer); source->cancel_signal(source,SIGQUIT,stop_timer,timer); return OOP_CONTINUE; } static void add_timer(oop_source *source,int interval) { struct timer *timer = malloc(sizeof(*timer)); gettimeofday(&timer->tv,NULL); timer->delay = interval; source->on_signal(source,SIGQUIT,stop_timer,timer); on_timer(source,timer->tv,timer); } /* -- signal --------------------------------------------------------------- */ static oop_call_signal on_signal; static void *on_signal(oop_source *source,int sig,void *data) { switch (sig) { case SIGINT: puts("signal: SIGINT (control-C) caught. " "(Use SIGQUIT, control-\\, to terminate.)"); break; case SIGQUIT: puts("signal: SIGQUIT (control-\\) caught, terminating."); source->cancel_signal(source,SIGINT,on_signal,NULL); source->cancel_signal(source,SIGQUIT,on_signal,NULL); break; default: assert(0 && "unknown signal?"); } return OOP_CONTINUE; } /* -- echo ----------------------------------------------------------------- */ static oop_call_fd on_data; static void *on_data(oop_source *source,int fd,oop_event event,void *data) { char buf[BUFSIZ]; int r = read(fd,buf,sizeof(buf)); write(1,buf,r); return OOP_CONTINUE; } static oop_call_signal stop_data; static void *stop_data(oop_source *source,int sig,void *data) { source->cancel_fd(source,0,OOP_READ); source->cancel_signal(source,SIGQUIT,stop_data,NULL); return OOP_CONTINUE; } /* -- readline ------------------------------------------------------------- */ #ifdef HAVE_READLINE static void on_readline(const char *input) { if (NULL == input) puts("\rreadline: EOF"); else { fputs("readline: \"",stdout); fputs(input,stdout); puts("\""); } } static void *stop_readline(oop_source *src,int sig,void *data) { oop_readline_cancel(src); src->cancel_signal(src,SIGQUIT,stop_readline,NULL); rl_callback_handler_remove(); return OOP_CONTINUE; } static void add_readline(oop_source *src) { rl_callback_handler_install( (char *) "> ", /* readline isn't const-correct */ (VFunction *) on_readline); oop_readline_register(src); src->on_signal(src,SIGQUIT,stop_readline,NULL); } #else static void add_readline(oop_source *src) { fputs("sorry, readline not available\n",stderr); usage(); } #endif /* -- adns ----------------------------------------------------------------- */ #ifdef HAVE_ADNS #include "adns.h" #include "oop-adns.h" #undef ADNS_CANCEL #define NUM_Q 6 oop_adns_query *q[NUM_Q]; oop_adapter_adns *adns; static void cancel_adns(void) { int i; for (i = 0; i < NUM_Q; ++i) if (NULL != q[i]) { oop_adns_cancel(q[i]); q[i] = NULL; } if (NULL != adns) { oop_adns_delete(adns); adns = NULL; } } static void *stop_lookup(oop_source *src,int sig,void *data) { cancel_adns(); src->cancel_signal(src,SIGQUIT,stop_lookup,NULL); return OOP_CONTINUE; } static void *on_lookup(oop_adapter_adns *adns,adns_answer *reply,void *data) { int i; for (i = 0; i < NUM_Q; ++i) if (data == &q[i]) q[i] = NULL; printf("adns: %s =>",reply->owner); if (adns_s_ok != reply->status) printf(" error: %s\n",adns_strerror(reply->status)); else { if (NULL != reply->cname) printf(" (%s)",reply->cname); assert(adns_r_a == reply->type); for (i = 0; i < reply->nrrs; ++i) printf(" %s",inet_ntoa(reply->rrs.inaddr[i])); printf("\n"); } free(reply); #ifdef ADNS_CANCEL cancel_adns(); #endif return OOP_CONTINUE; } static void get_name(int i,const char *name) { int res; q[i] = oop_adns_submit( adns,&res,name,adns_r_a,adns_qf_owner, on_lookup,&q[i]); } static void add_adns(oop_source *src) { adns = oop_adns_new(src,0,NULL); get_name(0,"g.mp"); get_name(1,"cnn.com"); get_name(2,"slashdot.org"); get_name(3,"love.ugcs.caltech.edu"); get_name(4,"intel.ugcs.caltech.edu"); get_name(5,"ofb.net"); src->on_signal(src,SIGQUIT,stop_lookup,NULL); } #else static void add_adns(oop_source *src) { fputs("sorry, adns not available\n",stderr); usage(); } #endif /* -- libwww --------------------------------------------------------------- */ #ifdef HAVE_WWW static int remaining = 0; static int on_print(const char *fmt,va_list args) { return (vfprintf(stdout,fmt,args)); } static int on_trace (const char *fmt,va_list args) { return (vfprintf(stderr,fmt,args)); } static int on_complete(HTRequest *req,HTResponse *resp,void *x,int status) { HTChunk *chunk = (HTChunk *) HTRequest_context(req); char *address = HTAnchor_address((HTAnchor *) HTRequest_anchor(req)); HTPrint("%d: done with %s\n",status,address); HTMemory_free(address); HTRequest_delete(req); if (NULL != chunk) HTChunk_delete(chunk); if (0 == --remaining) { /* stop ... */ } return HT_OK; } static void get_uri(const char *uri) { HTRequest *req = HTRequest_new(); HTRequest_setOutputFormat(req, WWW_SOURCE); HTRequest_setContext(req,HTLoadToChunk(uri,req)); ++remaining; } static void *stop_www(oop_source *source,int sig,void *x) { oop_www_cancel(); HTProfile_delete(); source->cancel_signal(source,sig,stop_www,x); return OOP_CONTINUE; } static void add_www(oop_source *source) { puts("libwww: known bug: termination (^\\) may abort due to cached " "connections, sorry."); HTProfile_newNoCacheClient("test-www","1.0"); oop_www_register(source); HTPrint_setCallback(on_print); HTTrace_setCallback(on_trace); HTNet_addAfter(on_complete, NULL, NULL, HT_ALL, HT_FILTER_LAST); HTAlert_setInteractive(NO); get_uri("http://ofb.net/~egnor/oop/"); get_uri("http://ofb.net/does.not.exist"); get_uri("http://slashdot.org/"); get_uri("http://www.w3.org/Library/"); get_uri("http://does.not.exist/"); source->on_signal(source,SIGQUIT,stop_www,NULL); } #else static void add_www(oop_source *source) { fputs("sorry, libwww not available\n",stderr); usage(); } #endif typedef void on_read_err_func(oop_source*,oop_read*); static void *on_read(oop_source *source, oop_read *rd, oop_rd_event event, const char *errmsg, int errnoval, const char *data, size_t recsz, void *next_v) { on_read_err_func **next= next_v; size_t off; int c; printf("read %s %s%s%s%s %s ", next ? "error" : "ok", event == OOP_RD_OK ? "OK" : event == OOP_RD_EOF ? "EOF" : event == OOP_RD_PARTREC ? "PARTREC" : event == OOP_RD_LONG ? "LONG" : event == OOP_RD_NUL ? "NUL" : event == OOP_RD_SYSTEM ? "SYSTEM" : (assert(!"event must be valid"), (char*)0), errmsg?" `":"", errmsg?errmsg:"", errmsg?"'":"", errnoval ? strerror(errnoval) : "Zero"); if (data) { printf("%lu:\"", (unsigned long)recsz); for (off=0; offcancel_signal(src,SIGQUIT,stop_read,rd); oop_rd_delete_tidy(rd); return OOP_CONTINUE; } static void on_read_immed_err(oop_source *src, oop_read *rd) { puts("read: terminating"); stop_read(src,0,rd); } static void on_read_std_err(oop_source *src, oop_read *rd) { static on_read_err_func *const next= on_read_immed_err; int r; puts("read: switching to plain immediate mode"); r= oop_rd_read(rd,OOP_RD_STYLE_IMMED,0, on_read,0, on_read,(void*)&next); if (r) { perror("oop_rd_read[2]"); exit(1); } } static void read_bad(const char *errmsg) { fprintf(stderr,"invalid modes for read:...: %s\n",errmsg); usage(); } static void add_read(oop_source *source, const char *modes) { static on_read_err_func *const next= on_read_std_err; oop_readable *ra; oop_read *rd; oop_rd_style style; size_t bufsz, maxrecsz; int r; char delimspec[3]; char *ep; switch (*modes++) { case 'n': style.delim_mode= OOP_RD_DELIM_NONE; break; case 's': style.delim_mode= OOP_RD_DELIM_STRIP; break; case 'k': style.delim_mode= OOP_RD_DELIM_KEEP; break; default: read_bad("invalid delim_mode, must be one of nsk"); } if (style.delim_mode != OOP_RD_DELIM_NONE) { switch ((delimspec[0] = *modes++)) { case '=': style.delim= *modes++; break; case 'n': style.delim= '\n'; break; case '\0': read_bad("missing delimiter"); default: delimspec[1]= *modes++; delimspec[2]= 0; style.delim= strtoul(delimspec,&ep,16); if (ep != modes) read_bad("invalid delimiter"); } } switch (*modes++) { case 'f': style.nul_mode= OOP_RD_NUL_FORBID; break; case 'd': style.nul_mode= OOP_RD_NUL_DISCARD; break; case 'p': style.nul_mode= OOP_RD_NUL_PERMIT; break; default: read_bad("invalid nul_mode, must be one of fdp"); } switch (*modes++) { case 'f': style.shortrec_mode= OOP_RD_SHORTREC_FORBID; break; case 'e': style.shortrec_mode= OOP_RD_SHORTREC_EOF; break; case 'l': style.shortrec_mode= OOP_RD_SHORTREC_LONG; break; case 's': style.shortrec_mode= OOP_RD_SHORTREC_SOONEST; break; default: read_bad("invalid shortrec_mode, must be one of fels"); } maxrecsz= strtoul(modes,&ep,10); if (*ep && *ep != ',' && *ep != ':') read_bad("invalid maxrecsz"); modes= *ep==',' ? ep+1 : ep; bufsz= strtoul(modes,&ep,10); if (*ep && *ep != ':') read_bad("invalid bufsz"); if (*ep != ':') { ra= oop_readable_fd(source,0); if (!ra) { perror("oop_readable_fd"); exit(1); } } else { modes= ep+1; ra= oop_readable_mem(source,modes,strlen(modes)); if (!ra) { perror("oop_readable_fd"); exit(1); } } rd= oop_rd_new(source,ra, bufsz ? malloc(bufsz) : 0, bufsz); r= oop_rd_read(rd,&style,maxrecsz, on_read,0, on_read,(void*)&next); if (r) { perror("oop_rd_read"); exit(1); } source->on_signal(source,SIGQUIT,stop_read,rd); } /* -- core ----------------------------------------------------------------- */ static void *stop_loop_delayed(oop_source *source,struct timeval tv,void *x) { return OOP_HALT; } static void *stop_loop(oop_source *source,int sig,void *x) { /* give everyone else a chance to shut down. */ source->on_time(source,OOP_TIME_NOW,stop_loop_delayed,NULL); source->cancel_signal(source,SIGQUIT,stop_loop,NULL); return OOP_CONTINUE; } static oop_source *create_source(const char *name) { if (!strcmp(name,"sys")) { source_sys = oop_sys_new(); return oop_sys_source(source_sys); } if (!strcmp(name,"signal")) { source_sys = oop_sys_new(); source_signal = oop_signal_new(oop_sys_source(source_sys)); return oop_signal_source(source_signal); } #ifdef HAVE_GLIB if (!strcmp(name,"glib")) { puts("glib: known bug: termination (^\\) won't quit, sorry."); glib_loop = g_main_new(FALSE); return oop_glib_new(); } #endif fprintf(stderr,"unknown source \"%s\"\n",name); usage(); return NULL; } static void run_source(const char *name) { if (!strcmp(name,"sys") || !strcmp(name,"signal")) oop_sys_run(source_sys); #ifdef HAVE_GLIB if (!strcmp(name,"glib")) g_main_run(glib_loop); #endif } static void delete_source(const char *name) { if (!strcmp(name,"sys")) oop_sys_delete(source_sys); if (!strcmp(name,"signal")) { oop_signal_delete(source_signal); oop_sys_delete(source_sys); } #ifdef HAVE_GLIB if (!strcmp(name,"glib")) { oop_glib_delete(); g_main_destroy(glib_loop); } #endif } static void add_sink(oop_source *src,const char *name) { if (!strcmp(name,"timer")) { add_timer(src,1); add_timer(src,2); add_timer(src,3); return; } if (!strcmp(name,"signal")) { src->on_signal(src,SIGINT,on_signal,NULL); src->on_signal(src,SIGQUIT,on_signal,NULL); return; } if (!strcmp(name,"echo")) { src->on_fd(src,0,OOP_READ,on_data,NULL); src->on_signal(src,SIGQUIT,stop_data,NULL); return; } if (!strcmp(name,"readline")) { add_readline(src); return; } if (!strcmp(name,"adns")) { add_adns(src); return; } if (!strcmp(name,"libwww")) { add_www(src); return; } if (!strncmp(name,"read:",5)) { add_read(src,name+5); return; } fprintf(stderr,"unknown sink \"%s\"\n",name); usage(); } static void init(oop_source *source,int count,char *sinks[]) { int i; source->on_signal(source,SIGQUIT,stop_loop,NULL); puts("test-oop: use ^\\ (SIGQUIT) for clean shutdown or " "^C (SIGINT) to stop abruptly."); for (i = 0; i < count; ++i) add_sink(source,sinks[i]); } /* -- tcl source ----------------------------------------------------------- */ #ifdef HAVE_TCL static int tcl_count; static char **tcl_sinks; static int tcl_init(Tcl_Interp *interp) { init(oop_tcl_new(),tcl_count,tcl_sinks); return TCL_OK; } #endif /* -- main ----------------------------------------------------------------- */ int main(int argc,char *argv[]) { if (argc < 3) usage(); #ifdef HAVE_TCL if (!strcmp(argv[1],"tcl")) { /* Tcl is a little ... different. */ tcl_count = argc - 2; tcl_sinks = argv + 2; Tcl_Main(1,argv,tcl_init); } else #endif { oop_source * const source = create_source(argv[1]); init(source,argc - 2,argv + 2); run_source(argv[1]); delete_source(argv[1]); } return 0; } lyskom-server-2.1.2/src/libraries/liboop/.cvsignore0000664000015100472110000000014107703277014016047 .deps Makefile Makefile.in aclocal.m4 autom4te.cache config.log config.status configure test-oop lyskom-server-2.1.2/src/libraries/libisc-new/0000777000015100472110000000000007723710317014705 5lyskom-server-2.1.2/src/libraries/libisc-new/README0000664000015100472110000000116606712622526015510 This package implements a library of functions that was intendend to help creating client-server packages using TCP/IP or other file descriptor based links. Use of this package for development of new software is not currently recommended. Much of the documentation is probably outdated. Be sure to read the file NEWS, and trust it more than the man pages. Trust doc/MANUAL.sv even less than the man pages. Better still: use the source code instead of the documentation. This code is distributed under the GNU Library General Public License. /Peter Eriksson and Per Cederqvist lyskom-server-2.1.2/src/libraries/libisc-new/AUTHORS0000664000015100472110000000033207571503201015662 ISC was initially written and designed by Peter Eriksson . Per Cederqvist has made some improvements and is currently acting as maintainer. Thorild Selén added IPv6 support. lyskom-server-2.1.2/src/libraries/libisc-new/COPYING0000664000015100472110000004312707353345256015672 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. lyskom-server-2.1.2/src/libraries/libisc-new/COPYING.LIB0000664000015100472110000006127306712622531016271 GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! lyskom-server-2.1.2/src/libraries/libisc-new/ChangeLog0000664000015100472110000014143707722446223016410 2003-08-25 Per Cederqvist Don't crash if a write error occurs. * src/isc_event.c (isc_read_data): Don't crash if wr_msg_q is NULL. * src/isc_output.c (isc_oflush): Do nothing in ISC_STATE_CLOSING. Simplified the error-handling code. * src/isc_session.c (isc_check_read_callback): Don't crash if wr_msg_q is NULL. (isc_check_read_callback): Don't setup any callbacks in ISC_STATE_CLOSING. 2003-08-22 Per Cederqvist Don't crash if failing to bind a port. * src/isc_session.c (isc_destroy): Don't chanse a NULL pointer. This could be triggered if the port was already bound. 2003-08-15 Per Cederqvist Get a fresh version of depcomp. * depcomp: Removed. Regenerate this using automake to get a fresh version. 2003-08-11 Per Cederqvist Code cleanup. * src/isc_stdout.c: Fixed a typo in a comment. Don't use memcpy to move overlapping blocks. This could potentially result in the server sending garbage to clients. * src/isc_output.c (isc_oflush): Use memmove, not memcpy, to move memory areas that may overlap. 2003-08-07 Per Cederqvist Removed the useless nlinks field. (Bug 1071). * src/intern.h (struct isc_scb_internal): Removed the nlinks field. (isc_insert): Changed return type to void. * src/isc_session.c (isc_insert): Changed return type to void. Don't manipulate the useless nlinks field. (isc_remove): Don't manipulate the useless nlinks field. (isc_create): Ditto. (isc_destroy): Ditto. 2003-08-06 Per Cederqvist Use ADNS to look up IPv4 addresses. (Bug 627). * src/Makefile.am (AM_CPPFLAGS): Added -I flag for adns. * src/isc.h (enum isc_resolve_status): Added isc_resolve_adns_error. (isc_resolve_remote): Return 0 on success. * src/intern.h (struct isc_mcb): Added adns. (struct isc_scb_internal): Added adns_query. * src/isc_socket.c: Include . (isc_dns_resolve_adns_cb): New function. (isc_resolve_remote): Try to use adns to look up the address. Fall back to the old method if adns returns ENOSYS, which indicates that it doesn't support the addess family. * src/isc_session.c (isc_create): Initialize adns_query. (isc_destroy): Cancel any pending adns query. * src/isc_master.c (isc_initialize): Initialize an oop adns adapter. (isc_shutdown): Delete the oop adns adapter. * src/isc_abort.c: Include "adns.h" and "oop-adns.h". * src/isc_alloc.c: Ditto. * src/isc_compat.c: Ditto. * src/isc_event.c: Ditto. * src/isc_message.c: Ditto. * src/isc_output.c: Ditto. * src/isc_queue.c: Ditto. * src/isc_relocate.c: Ditto. * src/isc_stdout.c: Ditto. * src/isc_tcp.c: Ditto. 2003-08-05 Per Cederqvist Restructure the DNS lookup API in preparation of ADNS integration. The API is now callback-based. The current implementation still uses gethostbyname, though. * src/isc.h (enum isc_resolve_status): New enum. (isc_resolve_done_cb): New callback. (struct isc_scb): Added the field "remote". (isc_gethostname): Removed. (isc_resolve_remotem): New function. * src/intern.h (struct isc_scb_internal): Added resolve_callback. (isc_dns_resolve_cb): New function. * src/isc_socket.c (isc_dns_resolve_cb): New function. (isc_resolve_remote): New function. (isc_gethostname): Removed. * src/isc_session.c (isc_create): Initialize resolve_callback and remote. (isc_destroy): Cancel any pending dns query, and clear remote. 2003-08-04 Per Cederqvist Simplified the API of the callback functions. Pass a pointer to the isc_scb instead of a user-supplied pointer to the callback. * src/isc.h (isc_accept_callback): Removed the cb_mcb argument. (isc_write_error_cb): Removed the cb_mcb and user arguments. (isc_stale_output_cb): Ditto. (isc_set_read_callback): Removed the user argument. Use the udg field of the isc_scb instead. * src/intern.h (struct isc_scb_internal): Removed data_available_user. * src/isc_tcp.c (isc_accept_cb): Adjusted to the new API of the callback functions. * src/isc_session.c (isc_create): Don't set data_available_user, which has been removed. (stale_cb): Adjusted to the new API of the callback functions. (idle_cb): Ditto. (isc_set_read_callback): Removed the user argument. (isc_check_read_callback): Pass the isc_scb object instead of the user-supplied pointer to the on_fd. * src/isc_output.c (isc_oflush): Adjusted to the new API of the callback functions. 2003-08-03 Per Cederqvist Code cleanup. At the same time a micro-optimization was done: get rid of a call to getpeername() and getsockname() per accepted connection. (Bug 916). * src/isc_tcp.c (isc_tcp_accept): Use the address that the accept() call supplies, so that we don't have to do an extra call to getpeername(). Copy the local address from the socket we listen to, so that we don't have to do an extra call to getsockname(). * src/isc_socket.c (isc_getladdress): Function removed. (isc_getraddress): Function removed. (isc_copyaddress): Resurrected the function that was removed 2003-07-12, and changed the type names to the current ones. * src/isc.h (isc_getladdress): Removed. (isc_getraddress): Removed. * src/intern.h (isc_copyaddress): Resurrected the function that was removed 2003-07-12. Removed documentation that was misleading. * man/Makefile.am (EXTRA_DIST): Removed FUNCTIONS. * man/FUNCTIONS: Removed. Almost nothing was true any more. * doc/Makefile.am (EXTRA_DIST): Removed MANUAL.sv. * doc/MANUAL.sv: Removed. Almost nothing was true any more. Fixed an uninitialized variable. * src/isc_session.c (isc_create): Initialize idle_cb_registered. The idle and stalled timeout are now fully orthogonal. Fixes to the idle timeout implementation. * src/isc.h (isc_set_acceptable_idle): It is now acceptable to have a idle timeout that is shorter than the stale timeout. * src/isc_session.c (stale_cb): Return OOP_HALT instead of following a NULL pointer if the user hasn't registered a callback. (idle_cb): Ditto. (isc_set_acceptable_idle): Store the new value inte the proper field. (isc_check_read_callback): Simplified the logic. It is now acceptable to have a idle timeout that is shorter than the stale timeout. 2003-08-02 Per Cederqvist Added the ability to disconnect idle clients. (Bug 11). * src/isc.h (isc_cfg_stale_timeout): New argument: default_idle. (isc_set_read_callback): New argument: idle_cb. (isc_set_acceptable_idle): New function. * src/intern.h (struct isc_scb_internal): Added fields idle_cb, idle_cb_registered, idle_tv and acceptable_idle_time. (struct isc_session_cfg): Added idle_timeout. * src/isc_tcp.c (isc_accept_cb): Forward declaration using the typedef oop_call_fd added. * src/isc_session.c (isc_create): Set acceptable_idle_time to the default idle timeout. (idle_cb): New static function. (isc_cancel_idle_callback): New static function. (isc_set_read_callback): New argument: idle_cb. (isc_check_read_callback): Handle the idle timeout. (isc_destroy): Cancel the idle timeout. * src/isc_master.c (isc_cfg_stale_timeout): New argument: default_idle. Make the message size and output queue configurable again. * src/isc.h (isc_cfg_queue_size): New function. * src/isc_stdout.c (isc_putc): Handle the case when max.msgsize is set to less than ISC_DEFAULT_MAX_MSG_SIZE. (isc_write): Ditto. * src/isc_session.c (isc_check_read_callback): Check the size of the output queue in bytes as well as number of messages. * src/isc_queue.c (isc_newqueue): Initialize bytes. (isc_killqueue): Check bytes. (isc_pushqueue): Update bytes. * src/isc_output.c (isc_oflush): Update the output queue size. * src/isc_master.c (isc_initialize): Initialize queuedsize_bytes. (isc_cfg_queue_size): New function. * src/isc_event.c (isc_read_data): Check for too many bytes in output queue. * src/intern.h (struct isc_scb_internal): Make the sendbuf be ISC_DEFAULT_MAX_MSG_SIZE bytes large, not 2048. (struct isc_msgqueue): New field: bytes. (struct isc_session_cfg): Added queuedsize_bytes. 2003-08-01 Per Cederqvist Added a callback function that reports changes to the size of the output queue. * src/isc.h (isc_write_queue_change_cb): New typedef. (isc_initialize): New argument: the write_change_cb. * src/intern.h (struct isc_mcb): Added write_change_cb. (isc_killqueue): Now returns an int: the number of payload bytes in the killed queue. * src/isc_session.c (isc_destroy): Inform the write change callback function of changes in the pending output queue size. * src/isc_queue.c (isc_killqueue): Now returns an int: the number of payload bytes in the killed queue. * src/isc_output.c (isc_flush): Inform the write change callback function of changes in the pending output queue size. (isc_oflush): Ditto. * src/isc_master.c (isc_initialize): New argument: write_change_cb. Don't fail to unregister the stale timeout during shutdown. * src/isc_session.c (isc_set_read_callback): Call isc_cancel_stale_output_callback(). Removed redundant checks. (isc_destroy): Call isc_cancel_stale_output_callback(). Call a callback function if a client becomes stale. * src/isc.h (isc_stale_output_cb): New typedef. (isc_cfg_stale_timeout): New function. (isc_set_read_callback): New argument: stale_output_cb. * src/isc_session.c (isc_create): Initialize stale_output_cb_registered and stale_output_cb. (stale_cb): New static function. (isc_set_read_callback): New argument: stale_output_cb. (isc_cancel_stale_output_callback): New static function. (isc_check_read_callback): New argument: any_written. All callers updated. Handle a timer callback used to detect if a client has stalled. * src/isc_output.c (isc_oflush): Inform isc_check_read_callback() if anything was written. * src/isc_master.c (isc_initialize): Initialize stale_timeout. (isc_cfg_stale_timeout): New function. * src/intern.h (struct isc_scb_internal): Added stale_output_cb, stale_output_cb_registered and stale_output_tv. (struct isc_session_cfg): Added stale_timeout. (isc_check_read_callback): New argument: any_written. All callers updated. * configure.in: Removed -Waggregate-return, since we use timeval_ctor() from libmisc. 2003-07-31 Per Cederqvist Move struct isc_mcb and large parts of struct isc_scb from isc.h to intern.h. * src/isc.h (isc_msgqueue): Forward declaration removed. (isc_session_cfg): Ditto. (isc_scb_entry): Ditto. (struct isc_scb): Moved a lot of fields to struct isc_scb_internal in intern.h. (struct isc_mcb): Moved to intern.h. (isc_getoopsource): New function. * src/intern.h (struct isc_mcb): Moved here from isc.h. (struct isc_scb_internal): New struct, that contains all the parts of struct isc_scb that the user need not know about. (struct isc_scb_entry): Refer to the internal structure. (isc_oflush): Use the internal structure. (isc_create): Ditto. (isc_insert): Ditto. (isc_remove): Ditto. (isc_createtcp): Ditto. (isc_bindtcp): Ditto. (isc_check_read_callback): Ditto. (isc_cancel_read_callback): Ditto. (isc_cancel_write_callback): Ditto. * src/isc_tcp.c (isc_tcp_accept): Handle struct isc_scb_internal. (isc_createtcp): Handle struct isc_scb_internal. (isc_bindtcp): Handle struct isc_scb_internal. (isc_accept_cb): Handle struct isc_scb_internal. (isc_listentcp): Handle struct isc_scb_internal. * src/isc_stdout.c (isc_putc): Handle struct isc_scb_internal. (isc_write): Handle struct isc_scb_internal. * src/isc_session.c (isc_insert): Handle struct isc_scb_internal. (isc_findsession): Handle struct isc_scb_internal. (isc_remove): Handle struct isc_scb_internal. * src/isc_output.c (isc_flush): Handle struct isc_scb_internal. (write_cb): Handle struct isc_scb_internal. (isc_oflush): Handle struct isc_scb_internal. * src/isc_master.c (isc_shutdown): Handle struct isc_scb_internal. * src/isc_event.c (isc_read_data): Handle struct isc_scb_internal. 2003-07-28 Per Cederqvist Code cleanup. * src/isc_tcp.c (isc_mktcpaddress): Rewrite the code to get rid of a compiler warning and make the code easier to read. Don't use socklen_t in the exported API, since that leads to portability problems. * src/isc_tcp.c, src/isc.h (isc_addressfamily): Changed return type to int. (isc_addresssize): Ditto. Distribute isc_addr.h, which was added yesterday. * src/Makefile.am (libisc_a_SOURCES): Added isc_addr.h. Host name lookup always failed if gethostbyname2() was used. * src/isc_tcp.c (isc_mktcpaddress_internal): The logic for checking the return value from gethostbyname2() was inverted. Export functions for creating and using an isc_address from a host name and port name. * src/isc.h (isc_mktcpaddress): New function. (isc_addressfamily): New function. (isc_addresssize): New function. (isc_addresspointer): New function. * src/isc_tcp.c (isc_mktcpaddress_internal): New name for former isc_mktcpaddress. All callers updated. (isc_mktcpaddress): New function. (isc_addresssize): New function. (isc_addressfamily): New function. (isc_addresspointer): New function. (isc_bindtcp): Use isc_addresspointer() and isc_addresssize() to simplify the code. * src/isc_addr.h (UNUSED_UNLESS_INET6): New macro. (USE_GETIPNODEBYNAME): Moved from intern.h. * src/intern.h: Fixed documentation of FOR_EACH_AF. (USE_GETIPNODEBYNAME): Moved to isc_addr.h. 2003-07-27 Per Cederqvist Clean up some problems in ISC that the IPv6 support added. (Bug 563). * src/isc_addr.h: New file, that contains private structures extracted from isc.h. This file should only be included by files in the isc library. * src/isc_tcp.c: Include isc_addr.h. * src/isc_socket.c: Include isc_addr.h. * src/isc.h: Don't include and from here. The coding standard of lyskomd is to never include files from included files. (SOCKADDR_STORAGE): Moved to isc_addr.h. (union sockaddrs): Ditto. (union isc_address): Ditto, but keep a forward declaration. * src/intern.h (isc_mkipaddress): Moved to isc_addr.h. 2003-07-14 Per Cederqvist Don't read when the output queue is full. * src/isc_event.c (isc_read_data): Return ISC_READ_WOULDBLOCK if the output queue is full. 2003-07-13 Per Cederqvist Ensure that unused parameters are unused. * src/unused.h (UNUSED_H_CONCAT): New macro. (UNUSED): Mangle the name of the supposedly unused argument, so that the compiler will report errors if it actually is used. 2003-07-12 Per Cederqvist Fix new compilation errors. * src/isc_socket.c (isc_getipnum): Fixed compilation errors for IPv6 configurations, which were introduced in the previous commit. (isc_gethostname): Ditto. (isc_getportnum): Ditto. Use liboop as a backend. Only support TCP streams. Removed a lot of stuff that isn't used by lyskom-server. Move much internal stuff from isc.h to intern.h. * src/isc_wait.c: File removed. * src/isc_udp.c: File removed. * src/isc_tcp.c (isc_tcp_accept_fn): Renamed to isc_tcp_accept. Removed the unused hl and msg arguments. (isc_tcp_destroy_fn): Function removed. (isc_connecttcp): Ditto. (isc_opentcp): Ditto. (isc_tcp_funs): Function table removed. (isc_createtcp): Added mcb and initial_state arguments. Removed obsolete bogus setsockopt() calls. (isc_bindtcp): Don't check the type of the session. (isc_accept_cb): New function. (isc_listentcp): Added the cb argument. Don't set the state here; that is now done by isc_create(). Add isc_accept_cb() as a read callback. * src/isc_stdout.c (isc_putc): The ISC_STATE_CONNECTING state no longer exists. (isc_write): Ditto. * src/isc_socket.c (isc_getladdress): Don't check the type of the session. (isc_getraddress): Ditto. (isc_copyaddress): Function removed. (isc_getservice): Ditto. * src/isc_session.c (isc_default_read_fn): Function removed. (isc_default_write_fn): Ditto. (isc_default_close_fn): Ditto. (isc_close): Ditto. (isc_sessions): Ditto. (isc_openfd): Ditto. (isc_file_destroy_fn): Ditto. (isc_openfile): Ditto. (isc_default_fun): Function table removed. (isc_create): Removed the "IscHandler *fun" argument, and added mcb and initial_state arguments. Initialize the currently existing fields. (isc_set_read_callback): New function. (isc_check_read_callback): Ditto. (isc_cancel_read_callback): Ditto. (isc_cancel_write_callback): Ditto. (isc_destroy): Cancel read, write and accept callbacks. Free raddr and laddr instead of calling a destroy handler. (isc_disable): Remove the read callback. (isc_enable): Maybe add the read callback. * src/isc_relocate.c: Include "oop.h" and "s-string.h". * src/isc_queue.c (isc_pollqueue): Removed the external function. The macro is good enough. * src/isc_output.c (isc_flush): There is no longer any read queue. (write_cb): New function. (isc_oflush): Don't close the socket if the output queue is too big. Instead, isc_check_read_callback() refuses to read input from the client until it reads enough of the output queue. Assert that this isn't a listening session, but don't otherwise check the state. Call write instead of using the handler mechanism. Call the write_err_cb callback function if an error occurs. Don't update statistics that nobody uses. Set up a liboop write callback if we cannot send all output at once. Call isc_check_read_callback(). (isc_send): Function removed. (isc_sendto): Ditto. * src/isc_message.c (isc_allocmsg): Don't set the address field, which has been removed. (isc_reallocmsg): Function removed. (isc_copymsg): Ditto. (isc_mkstrmsg): Ditto. * src/isc_master.c (isc_initialize): Removed the cfg argument, and added the oop_source argument. Allocate a cfg struct. (isc_cfg_fd_relocate): New function. (isc_shutdown): Free the cfg struct. * src/isc_handler.c: File removed. * src/isc_event.c (isc_read_data): New function. (isc_getnextevent): Function removed. (isc_dispose): Ditto. * src/isc_compat.c: Include "oop.h" and "s-string.h". * src/isc_alloc.c (isc_strdup): Function removed. * src/isc_abort.c (isc_setabortfn): Place inside #if 0, since it is currently unused. * src/isc.h: Removed several defines for structs and unions. All users updated to use the real names instead: IscSessionConfig => struct isc_session_cfg IscAddress => union isc_address IscMessage => struct isc_msg IscMsgQE => struct isc_msg_q_entry IscMsgQueue => struct isc_msgqueue IscSession => struct isc_scb IscSessionList => struct isc_scb_entry IscMaster => struct isc_mcb (IscMasterConfig): Define and struct removed. (IscConfig): Ditto. (IscHandlerCache): Ditto (IscHandler): Ditto. (IscHandlerList): Ditto. (IscEvent): Ditto. (IscEventType): Define and enum removed. (IscSessionType): Ditto. (IscSessionInfo): Define and union removed. (IscSessionStats): Ditto. (enum isc_session_state): Removed the states ISC_STATE_UNKNOWN, ISC_STATE_CONNECTING and ISC_STATE_CLOSING2. (union isc_address): Don't wrap the saddr field inside a meaningless struct named ip. (isc_initialize): Removed the cfg argument, and added the oop_source argument. (struct isc_scb): Removed the following fields: type, isc_errno, rd_msg_q, info, logintime, idlesince, stats and handlers. Added the following fields: raddr, laddr, master, accept_cb, write_err_cb, data_available_callback, data_available_user, data_available_registered and write_cb_registered. (struct isc_mcb): The scfg field is now a pointer, so that we don't have to expose the struct isc_session_cfg struct in isc.h. Added the event_source field. (isc_listentcp): Added the cb argument. (isc_openfd): Function removed. (isc_openfile): Ditto. (isc_openudp): Ditto. (isc_close): Ditto. (isc_sessions): Ditto. (isc_getnextevent): Ditto. (isc_wait): Ditto. (isc_dispose): Ditto. (isc_send): Ditto. (isc_sendto): Ditto. (isc_reallocmsg): Ditto. (isc_copymsg): Ditto. (isc_mkstrmsg): Ditto. (isc_createudp): Ditto. (isc_bindudp): Ditto. (isc_connecttcp): Ditto. (isc_connectudp): Ditto. (isc_listenudp): Ditto. (isc_copyaddress): Ditto. (isc_getservice): Ditto. (isc_newhandler): Ditto. (isc_freehandler): Ditto. (isc_copyhandler): Ditto. (isc_pushhandler): Ditto. (isc_pophandler): Ditto. (ISC_HCALLFUN1): Macro removed. (ISC_HCALLFUN2): Ditto. (ISC_HCALLFUN3): Ditto. (enum isc_read_result): New enum. (isc_read_data): New function. (isc_cfg_fd_relocate): Ditto. (isc_set_read_callback): Ditto. (isc_accept_callback): New callback function. (isc_write_error_cb): Ditto Moved some constants to intern.h: (ISC_DEFAULT_MAX_MSG_SIZE): Moved. (ISC_DEFAULT_MAX_QUEUED_SIZE): Moved. (ISC_DEFAULT_MAX_DEQUEUE_LEN): Moved. (ISC_DEFAULT_MAX_OPEN_RETRIES): Moved. (ISC_DEFAULT_MAX_BACKLOG): Moved. Moved some structs to intern.h: (struct isc_msg): Was: IscMessage. (struct isc_msg_q_entry): Was: IscMsgQE. (struct isc_msgqueue): Was: IscMsgQueue. (struct isc_session_cfg): Was: IscSessionConfig. (struct isc_scb_entry): Was: IscSessionList. Moved some functions to intern.h: (isc_freemsg): Moved. (isc_create): Moved. (isc_insert): Moved. (isc_remove): Moved. (isc_createtcp): Moved. (isc_bindtcp): Moved. (isc_allocmsg): Moved. Moved some functions from intern.h: (isc_setallocfn): Moved. * src/intern.h: Moved some constants from isc.h and changed their values: ISC_DEFAULT_MAX_MSG_SIZE: 2048 => 8176 ISC_DEFAULT_MAX_QUEUED_SIZE: 600 => 50 ISC_DEFAULT_MAX_DEQUEUE_LEN: 10 => 30 ISC_DEFAULT_MAX_OPEN_RETRIES: 10 => 10 ISC_DEFAULT_MAX_BACKLOG: 5 => 50 Moved some structs from isc.h and stopped using a defined name: (struct isc_msg): Was: IscMessage. (struct isc_msg_q_entry): Was: IscMsgQE. (struct isc_msgqueue): Was: IscMsgQueue. (struct isc_session_cfg): Was: IscSessionConfig. (struct isc_scb_entry): Was: IscSessionList. Moved some functions from isc.h: (isc_freemsg): Moved. (isc_create): Moved. (isc_insert): Moved. (isc_remove): Moved. (isc_createtcp): Moved. (isc_bindtcp): Moved. (isc_allocmsg): Moved. Moved some functions to isc.h: (isc_setallocfn): Moved. Other changes: (struct isc_msg): Removed the address field. (struct isc_session_cfg): Removed the version field. (isc_log): Function removed. (isc_create): Removed the "IscHandler *fun" argument, and added mcb and initial_state arguments. (isc_createtcp): Added mcb and initial_state arguments. (isc_strdup): Function removed. (isc_default_read_fn): Function removed. (isc_default_write_fn): Function removed. (isc_default_close_fn): Function removed. (isc_pollqueue): Removed the external function. Retain the macro. (isc_setabortfn): Place inside #if 0, since it is currently unused. (isc_check_read_callback): New function. (isc_cancel_read_callback): New function. (isc_cancel_write_callback): New function. (ISC_SCALLFUN1): Macro removed. (ISC_SCALLFUN2): Macro removed. (ISC_SCALLFUN3): Macro removed. * src/Makefile.am (libisc_a_SOURCES): Removed isc_handler.c, isc_udp.c and isc_wait.c. (AM_CPPFLAGS): Added -I flags for libmisc (to get the string class), liboop, and the main include library (needed by s-string.h). 2003-01-07 Per Cederqvist Port to IRIX64, where "unsigned long" isn't large enough to avoid alignment problems. * configure.in: Handle --disable-malloc-guards. Check for intptr_t, intmax_t and size_t. * src/isc_alloc.c: Include inttypes.h and stdint.h. Check USE_MALLOC_GUARDS. (union overhead): New union, to fix alignmentproblems. (OVERHEAD): New macro. (isc_malloc): Use union overhead instead of unsigned long. Removed unneeded casts. Handle USE_MALLOC_GUARDS. (isc_realloc): Ditto. (isc_free): Ditto. 2003-01-06 Per Cederqvist Fix IPv4 under Solaris 2.8. (Patch by Thorild Selén.) * src/isc_tcp.c (isc_bindtcp): Pass the proper size to bind() for IPv4 and IPv6. * src/isc_udp.c (isc_bindudp): Pass the proper size to bind() for IPv4 and IPv6. 2002-12-30 Per Cederqvist Autoconf: better check for "attribute unused" support. * configure.in: Use CMOD_C_WORKING_ATTRIBUTE_UNUSED instead of CMOD_C_ATTRIBUTE_UNUSED. * acinclude.m4 (CMOD_C_ATTRIBUTE_UNUSED): Removed. (CMOD_C_WORKING_ATTRIBUTE_UNUSED): New defun. 2002-11-29 Per Cederqvist Fixed more IPv6 portability problems. * configure.in: Check for freehostent. * src/intern.h: Require HAVE_FREEHOSTENT to be defined if we are to use getipnodebyname. * src/isc_udp.c (isc_mkudpaddress): Don't call freehostent() unless hp has been allocated by getipnodebyname(). * src/isc_tcp.c (isc_mktcpaddress): Don't call freehostent() unless hp has been allocated by getipnodebyname(). * src/isc_socket.c (isc_getipnum): Fixed typo: strncpy was spelled "strncopy". 2002-11-28 Per Cederqvist Give credits to Thorild for the IPv6 porting. * AUTHORS: Added Thorild Selén. Fix IPv6 portability problems to various versions of AIX, HP-UX and Solaris. * src/intern.h: Define USE_GETIPNODEBYNAME if both HAVE_GETIPNODEBYNAME and AI_ADDRCONFIG are defined. AIX 4.2 lacks AI_ADDRCONFIG. * src/isc_udp.c (isc_mkudpaddress): Declare error_num if USE_GETIPNODEBYNAME is defined. Test USE_GETIPNODEBYNAME instead of HAVE_GETIPNODEBYNAME to determine if it should be used. Don't access AF_INET6 unless USE_INET6 is true. * src/isc_tcp.c (isc_mktcpaddress): Declare error_num if USE_GETIPNODEBYNAME is defined. Test USE_GETIPNODEBYNAME instead of HAVE_GETIPNODEBYNAME to determine if it should be used. 2002-11-28 Thorild Selén Added IPv6 support with IPv4 compatibility. (ChangeLog entry written by ceder. Some minor coding standard changes by ceder. Three minor problems noted by FIXME comments by ceder.) * configure.in: Added --enable-ipv6 switch. Check for inet_ntop, inet_pton, getipnodebyname, gethostbyname2, and struct sockaddr_storage. * src/isc.h: This commit includes three broken things; see FIXMEs in the code. Include and . (SOCKADDR_STORAGE): Define it to struct sockaddr_storage or struct sockaddr, depending on HAVE_STRUCT_SOCKADDR_STORAGE. (union sockaddrs): New union. (IscAddress): Use union sockaddrs instead of struct sockaddr. * src/intern.h (isc_mkipaddress): Use SOCKADDR_STORAGE as argument, not struct sockaddr. (CHOOSE_IP4OR6): New macro. (FOR_EACH_AF): New macro. (FOR_EACH_PF): New macro. (STORE_ADDR): New macro. * src/isc_udp.c (isc_udp_read_fn): Handle IPv6. (isc_udp_write_fn): Handle IPv6. (isc_mkudpaddress): New argument: address_family. All callers updated. Handle IPv6. Broadcast addresses are not supported. (isc_createudp): Handle IPv6. The first argument of socket() should be PF_INET for IPv4, not AF_INET. (isc_bindudp): Handle IPv6. (isc_connectudp): Handle IPv6. * src/isc_tcp.c (isc_mktcpaddress): New argument: address_family. All callers updated. Handle IPv6. (isc_createtcp): Handle IPv6. The first argument of socket() should be PF_INET for IPv4, not AF_INET. (isc_bindtcp): Handle IPv6. (isc_connecttcp): Handle IPv6. * src/isc_socket.c (cast_to_sockaddr_in): Removed. (isc_mkipaddress): Changed struct sockaddr to SOCKADDR_STORAGE. (isc_getladdress): Ditto. Cast argument of getsockname from SOCKADDR_STORAGE* to struct sockaddr*. (isc_getraddress): Ditto (but for getpeername instead of getsockname). (isc_getipnum): Handle IPv6. (isc_gethostname): Ditto. (isc_getportnum): Ditto. (isc_getservice): Use isc_getportnum to simplify code. 2002-11-25 Per Cederqvist Port to Autoconf 2.56 and Automake 1.7.1. * configure.in: Use autoconf-2.56 and automake-1.7.1: Use AC_COMPILE_IFELSE and AC_LANG_PROGRAM instead of AC_TRY_COMPILE. Fixed broken quoting. 2002-10-09 Per Cederqvist Fixed socklen_t fallback code. * configure.in: The fallback for socklen_t when no compilation worked without a warning was broken. Fix. 2002-10-02 Per Cederqvist Port to the ecc compiler. * acinclude.m4 (CMOD_C_ATTRIBUTE_UNUSED): Improve the test, by checking that __attribute__((unused)) is accepted in a function declaration. The ecc compiler on Linux/ia64 seems to accept it and give a warning when used on a local variable, but chokes on it when used in a function declaration. 2002-09-21 Per Cederqvist Get rid of AIX 4.2 compiler warnings. * src/isc_wait.c: Include strings.h. * src/isc_event.c: Include strings.h. * src/intern.h (socklen_t): Use the type that the configure script has found, instead of always using unsigned int. AIX 4.2 wants an size_t, which is an unsigned long. * configure.in: Check for strings.h. Check for a socklen_t type that produces no warnings. 2002-09-10 Per Cederqvist As expected, uint32_t is not universally available. SunOS 4.1.1_U1 lacks it. * configure.in: Check for uint32_t, and sizeof int and long. * src/intern.h: Typedef uint32_t when needed. 2002-09-10 Per Cederqvist Get rid of more warnings. (This will probably break on several platforms that don't have uint32_t.) * configure.in: Cast INADDR_NONE to uint32_t. 2002-09-09 Per Cederqvist Port to SunOS 5.4. * src/isc_compat.c: Include , needed by SunOS 5.4. 2002-09-08 Per Cederqvist Fix more socklen_t and inet_aton problems. * src/intern.h [!HAVE_INET_ATON]: Declare struct in_addr. [!HAVE_SOCKLEN_T]: Add typedef for socklen_t. * configure.in: Check for socklen_t. Fix include problems with isc_compat.c. * src/isc_compat.c: Include and . Avoid a warning about memset. * src/isc_wait.c: Include if available, to get rid of a warning generated from FD_ZERO on some platforms. Use socklen_t and inet_aton to reduce warnings and increase stability. * src/isc_udp.c (isc_udp_read_fn): Changed type of len from int to socklen_t. (isc_mkudpaddress): Use inet_aton instead of inet_addr. * src/isc_tcp.c (isc_tcp_accept_fn): The third argument of accept() should be pointer to socklen_t, not pointer to int. (isc_mktcpaddress): Use inet_aton instead of inet_addr. * src/isc_socket.c (isc_getladdress): Changed type of len from int to socklen_t. (isc_getraddress): Ditto. Provide a replacement for inet_aton for systems that only have inet_addr. * src/isc_compat.c: New file. (inet_aton): New compatibility function. * src/intern.h (inet_aton): Added a declaration if HAVE_INET_ATON is false. * src/Makefile.am (libisc_a_SOURCES): Added isc_compat.c. * configure.in: Check for -lsockt and -lnsl if needed. Check for inet_aton. Check for INADDR_NONE only if inet_aton isn't available. 2002-09-07 Per Cederqvist Get rid of warnings from casting a struct sockaddr* to a struct sockaddr_in*. * src/isc_socket.c (cast_to_sockaddr_in): New static inline function. (isc_getipnum): Use it, to get rid of a warning. (isc_gethostname): Ditto. (isc_getportnum): Ditto. (isc_getservice): Ditto. * configure.in: Check for inline support. Use INADDR_NONE to get rid of a compiler warning. * src/isc_udp.c (isc_mkudpaddress): Use INADDR_NONE instead of -1. * src/isc_tcp.c (isc_mktcpaddress): Use INADDR_NONE instead of -1. * configure.in: Check for INADDR_NONE. 2002-08-23 Per Cederqvist Waste less bytes. * src/isc_socket.c (isc_getipnum): Use the entire hostname buffer. 2002-08-20 Per Cederqvist Don't include when it isn't available. * configure.in: Check for . * src/isc_event.c: Fix include guards for and . * src/isc_socket.c: Ditto. * src/isc_wait.c: Ditto. 2002-08-10 Per Cederqvist Check for ar. (Bug 523). * configure.in: Check for ar. Look in $PATH:/usr/ccs/bin, and stop with an error if no ar can be found. 2002-04-11 David Byers * configure.in: Added AC_PREREQ(2.53). 2001-09-23 Per Cederqvist * Re-applied a couple of lyskomd modifications. 1999-07-05 Per Cederqvist Delay problems with sessions that are deconnected until we can do a proper fix. * src/isc.h (ISC_DEFAULT_MAX_QUEUED_SIZE): Double to 600. 1999-05-21 Per Cederqvist Remove all gcov files in "make mostlyclean". * src/Makefile.am (MOSTLYCLEANFILES): Added "*.da", "*.bb", "*.gcov" and "*.bbg". 1999-05-17 Per Cederqvist Don't needlessly call time(). * src/isc.h (IscSession): Comment out idlesince. * src/isc_event.c (isc_getnextevent): Don't waste time setting idlesince, which lyskomd doesn't use. 1999-05-01 Per Cederqvist The LysKOM server should not install isc thingies. * src/Makefile.am (noinst_LIBRARIES, noinst_HEADERS): Use instead of lib_LIBRARIES and include_HEADERS so that nothing from isc gets installed by lyskomd. * man/Makefile.am (noinst_MANS): Use noinst_MANS instead of man_MANS so that nothing from isc gets installed by lyskomd. 2001-09-23 Per Cederqvist * Version 1.01 released. Release preparations. * configure.in: Release 1.01. * NEWS: Entry for 1.01 written. Port to Autoconf 2.52 and Automake 1.5. * RELEASING: Updated for automake 1.5. * configure.in: Adjusted to autoconf 2.52: AC_INIT Now takes package name and version as arguments. Use AC_CONFIG_SRCDIR. Use AC_HELP_STRING to format help strings. Use CMOD_CHECK_CC_OPT instead of CMOD_COMPILER_CC_ACCEPTS. Don't use -Wpointer-arith. Use AC_CONFIG_FILES. * acinclude.m4 (CMOD_COMPILER_CC_ACCEPTS): Removed. (CMOD_CHECK_CC_OPT): New macro. * README.DEVO: Updated for autoconf 2.52 and automake 1.5. Removed an unused attribute in IscSession. Handle isc_getraddress() failures properly. * src/isc_tcp.c (isc_tcp_accept_fn): Don't set scb->mode. Fail properly if isc_getraddress() fails. * src/isc.h (IscSession): Delete the "mode" attribute, which was only set in some cases and never used. * src/isc_session.c (isc_openfile): Don't set scb->mode. 1999-05-01 Per Cederqvist * Version 1.00 released. Release preparations. * configure.in: Release 1.00. * TODO: Updated. * README: Updated. * NEWS: Entry for 1.00 written. "make maintainer-clean" shoudl remove everything that can be recreated. * Makefile.am (MAINTAINERCLEANFILES): Added Makefile.in, aclocal.m4, configure, install-sh, mkinstalldirs, missing, INSTALL and COPYING. * src/Makefile.am (MAINTAINERCLEANFILES): Added Makefile.in. * man/Makefile.am (MAINTAINERCLEANFILES): Added Makefile.in. * doc/Makefile.am (MAINTAINERCLEANFILES): Added Makefile.in. * demo/Makefile.am (MAINTAINERCLEANFILES): Added Makefile.in. Removed support for isc_printf and isc_vprintf for license, performance and portability reasons. * configure.in: Removed --enable-isc-printf. * src/isc_stdout.c (isc_printf): Removed. (isc_vprintf): Removed. (send_scb): Removed. (send_putc): Removed. * src/isc.h (isc_printf): Removed. (isc_vprintf): Removed. * src/Makefile.am (libisc_a_LIBADD): Removed. (isc_stdout.o): No longer depend on ../config.status. * src/printf.c: Removed. Merged in all changes made to ISC in the lyskomd code from the isc_merge_1999_04_21 tag to the isc_merge_1999_05_01 tag. Details follows: 1999-04-28 Per Cederqvist Added some output functions. * src/isc_stdout.c (isc_puts): New function. (isc_putul): New function. * src/isc.h (isc_puts): New function. (isc_putul): New function. 1999-04-24 Per Cederqvist Make it easier to compile ISC out-of-the-repository. * README.DEVO: Mention bootstrap.sh. * bootstrap.sh: New file. Fix file inclusions. * src/isc_relocate.c: and must be included before "isc.h". * src/isc_alloc.c: must be included before "isc.h". * src/isc_master.c: Likewise. * src/isc_output.c: Likewise. * src/isc_tcp.c: Likewise. * src/isc_udp.c: Likewise. Update at least one of the man pages. * man/isc_close.3x: Updated. Distribute ISC under LGPL. * README: Changed license to LGPL. * COPYING.LIB: New file, containing LGPL, the license this library is distributed under. * COPYING: No longer under version control. This file is still included in the distribution, even though ISC is licensed under LGPL instead of GPL, for two reasons: LGPL allows you to change the license to GPL, and automake requires the file COPYING. * Makefile.am: Changed license to LGPL. * configure.in: Changed license to LGPL. * demo/Makefile.am: Changed license to LGPL. * man/Makefile.am: Changed license to LGPL. * man/TEMPLATE: Changed license to LGPL. * man/isc.3x: Changed license to LGPL. * man/isc_close.3x: Changed license to LGPL. * man/isc_createtcp.3x: Changed license to LGPL. * man/isc_destroy.3x: Changed license to LGPL. * man/isc_initialize.3x: Changed license to LGPL. * man/isc_listentcp.3x: Changed license to LGPL. * man/isc_openfd.3x: Changed license to LGPL. * man/isc_openfile.3x: Changed license to LGPL. * man/isc_opentcp.3x: Changed license to LGPL. * man/isc_shutdown.3x: Changed license to LGPL. * man/isc_unlisten.3x: Changed license to LGPL. * src/Makefile.am: Changed license to LGPL. * src/intern.h: Changed license to LGPL. * src/isc.h: Changed license to LGPL. * src/isc_abort.c: Changed license to LGPL. * src/isc_alloc.c: Changed license to LGPL. * src/isc_event.c: Changed license to LGPL. * src/isc_handler.c: Changed license to LGPL. * src/isc_master.c: Changed license to LGPL. * src/isc_message.c: Changed license to LGPL. * src/isc_output.c: Changed license to LGPL. * src/isc_queue.c: Changed license to LGPL. * src/isc_relocate.c: Changed license to LGPL. * src/isc_session.c: Changed license to LGPL. * src/isc_socket.c: Changed license to LGPL. * src/isc_stdout.c: Changed license to LGPL. * src/isc_tcp.c: Changed license to LGPL. * src/isc_udp.c: Changed license to LGPL. * src/isc_wait.c: Changed license to LGPL. * src/unused.h: Changed license to LGPL. 1999-04-22 Per Cederqvist Distribute administrative files. * Makefile.am (EXTRA_DIST): Added README.DEVO and RELEASING. Merged in all changes made to ISC in the lyskomd code from ISC 0.99 to the isc_merge_1999_04_21 tag. Details follows: 1999-04-17 Per Cederqvist Added full support for fd relocation. * src/isc_relocate.c (isc_relocate_fd): Implemented for real. * src/isc_event.c (isc_getnextevent): Return ISC_EVENT_LOGIN_UNRELOCATED instead of ISC_EVENT_LOGIN if a file descriptor relocation failed. * src/isc.h (IscEventType): New event: ISC_EVENT_LOGIN_UNRELOCATED. 1999-04-17 Per Cederqvist Added limited support for fd relocation. Error handling still needed. * src/isc_udp.c (isc_createudp): Relocate the fd. * src/isc_tcp.c (isc_tcp_accept_fn): isc_createtcp will close the file descriptor if it fails, so don't re-close it here. isc_createtcp will also set the fd attribute of the session; don't set it again. (isc_createtcp): Relocate the fd. Be careful to always close it if an error occurs. * src/isc_relocate.c (isc_relocate_fd): New file and function. This is still a dummy implementation. * src/isc_master.c (isc_initialize): Expect master config version 1006 and session config 1002. Handle fd_relocate. * src/isc.h (IscSessionConfig): Added fd_relocate. * src/intern.h (isc_relocate_fd): New function. * src/Makefile.am (libisc_a_SOURCES): Added isc_relocate.c. 1999-04-16 Per Cederqvist Simplify the use of IscHandlerList. (This needs more documentation.) * src/isc.h (IscSession): Removed the "IscHandlerCache fun" member. (IscHandlerList): Renamed the "old" member to "current". (ISC_HCALLFUN1): Adapted to IscHandlerList changes. (ISC_HCALLFUN2): Adapted to IscHandlerList changes. (ISC_HCALLFUN3): Adapted to IscHandlerList changes. * src/intern.h (ISC_SCALLFUN1): Use ISC_HCALLFUN1 to simplify code. Adapted to IscHandlerList changes. (ISC_SCALLFUN2): Analogous. (ISC_SCALLFUN3): Analogous. * src/isc_handler.c (isc_pushhandler): Modified so that the members of the member "current" of IscHandlerList objects points to the IscHandler object where the callbacks that should be used exist. Once that changes was done, there is no need for the "scb->fun" member, so it was removed. (isc_pophandler): Adjusted accordingly. * src/isc_session.c (isc_create): Removed the code that initialized scb->fun. (isc_destroy): Use scb->handlers->current instead of scb->fun. * src/isc_event.c (isc_getnextevent): Use scb->handlers->current instead of scb->fun. 1999-04-15 Per Cederqvist Allow disabled sessions to emit data. It is input from the sessions that is disabled. * src/isc_stdout.c (isc_putc): Allow output to sessions that are in state ISC_STATE_DISABLED. (isc_write): Likewise. * src/isc_output.c (isc_flush): Flush pending output even when the session is in ISC_STATE_DISABLED. (isc_oflush): Likewise. * src/isc_event.c (isc_getnextevent): Flush pending output even when the session is in ISC_STATE_DISABLED. 1999-04-11 Per Cederqvist Rebuild more often. * src/Makefile.am (isc_stdout.o): Depend on ../config.status. 1999-04-05 Per Cederqvist Get rid of useless compiler warnings. * configure.in: Don't use -Wtraditional. 1999-02-05 Per Cederqvist Get rid of a compiler warning. * src/isc_alloc.c (ISC_MAGIC_ALLOC): This is an unsigned constant. (ISC_MAGIC_FREE): Likewise. 1999-01-18 David Byers * src/.cvsignore: Added .bbg, .bb, .da and .gcov files. 1999-01-15 David Byers * configure.in: Added --with-checker, --with-gcov and --with-optimization. 1998-10-06 Per Cederqvist Port to glibc2. * src/isc_session.c: Include . 1998-07-09 Per Cederqvist --enable-isc-printf was broken. * src/isc_wait.c: Include . 1999-04-21 Per Cederqvist * demo/Makefile.am: Insert copyright header. Clean up the configure script. * configure.in (AC_PROG_MAKE_SET, AC_PROG_INSTALL): Removed. This is automatically done by AM_INIT_AUTOMAKE. (AM_PROG_CC_STDC): Use it instead of AM_C_PROTOTYPES. 1998-07-06 Per Cederqvist * Version 0.99 released. Release preparations. * NEWS: Updated. * README: Updated. * RELEASING: New file. * README.DEVO: New file. Include isc_wait.o in the built library. * src/Makefile.am (libisc_a_SOURCES): Added isc_wait.c. Improved portability. * src/isc_wait.c: Check TIME_WITH_SYS_TIME. * src/isc_socket.c: Check TIME_WITH_SYS_TIME. * src/isc_event.c: Check TIME_WITH_SYS_TIME. Ported to Solaris 2.7 Beta/gcc 2.8.1. * src/isc_udp.c: Include . (isc_udp_read_fn): Now static. Flag unused arguments. (isc_udp_destroy_fn): Likewise. (isc_udp_write_fn): Now static. (isc_mkudpaddress): Likewise. Don't pass potentially negative characters to isdigit. * src/isc_tcp.c: Include . (isc_tcp_accept_fn): Now static. Flag unused arguments. (isc_tcp_destroy_fn): Likewise. (isc_mktcpaddress): Now static. Don't pass potentially negative characters to isdigit. * src/isc_session.c: Include . (isc_default_read_fn): Flag unused arguments. (isc_default_write_fn): Flag unused arguments. (isc_default_close_fn): Flag unused arguments. (isc_file_destroy_fn): Flag unused arguments. * src/isc_alloc.c (isc_realloc): Code simplified. (isc_free): Code simplified. * src/unused.h: New file (taken from cmod). Added automake/autoconf support. * AUTHORS: New file. * Makefile.am: New file. * NEWS: New file. * acinclude.m4: New file. * configure.in: New file. * demo/Makefile.am: New file. * demo/README: New file. * doc/Makefile.am: New file. * man/Makefile.am: New file. * src/Makefile.am: New file. * man/Makefile: This file is now generated by configure. Don't store it under version control. * src/Makefile: Likewise. * demo/Makefile: Likewise. * build/stddef.h: File removed. * build/gmkdep: File removed. 1998-06-21 Per Cederqvist Incorporated all relevant improvements made to ISC in the committed sources of lyskomd as of 1998-06-21. Edited details follows. Include file improvements. * src/isc_event.c: Include , and for increased portability. * src/printf.c: Check HAVE_STRING_H and HAVE_STDLIB_H before including those files. Don't forward-declare memchr. Ignore attempts to look up the NULL host name. * src/isc_socket.c (isc_gethostname): Return NULL if given a NULL IscAddress. 1998-05-07 Per Cederqvist Incorporated all relevant improvements made to ISC in kom++-0.7.post.2. Edited details follows. Avoid including more files than necessary. * src/isc.h: Don't include any include files. * src/isc_abort.c: Don't declare system functions. Fixed include statements. * src/isc_alloc.c: Likewise. * src/isc_event.c: Likewise. * src/isc_message.c: Likewise. * src/isc_output.c: Likewise. * src/isc_session.c: Likewise. * src/isc_socket.c: Likewise. * src/isc_stdout.c: Likewise. * src/isc_tcp.c: Likewise. * src/isc_udp.c: Likewise. * src/isc_handler.c: Fixed include statements. * src/isc_master: Likewise. * src/isc_queue.c: Likewise. Added the ability to wait until a connection attempt (initiated by this process) either fails or succeeds. * src/isc.h: (isc_wait): Prototype added. * src/isc_wait.c: New file, containing isc_wait. Only support isc_printf and isc_vprintf if ISC_PRINTF_SUPPORT if defined. These functions may lead to bad use of the buffers. * src/isc.h: (isc_vprintf, isc_printf): Only declare if ISC_PRINTF_SUPPORT is defined. Fail to compile if ISC_PRINTF_SUPPORT is defined but HAVE_STDARG_H isn't. * src/isc_stdout.c (send_scb, send_putc, isc_vprintf, isc_printf): Only defined if ISC_PRINTF_SUPPORT is defined. Make sure that isc_getnextevent only returns a single ISC_EVENT_LOGOUT message when a session logs out. * src/isc.h: (IscSessionState): New state: ISC_STATE_CLOSING2. * src/isc_event.c (isc_getnextevent): There is now only one ISC_EVENT_LOGOUT message per session. Set the state to ISC_STATE_CLOSING2 when generating an ISC_EVENT_LOGOUT message. * src/isc_output.c (isc_flush): Treat ISC_STATE_CLOSING2 as ISC_STATE_CLOSING. (isc_oflush): Likewise. Portability fixes. * src/isc_alloc.c (isc_mallocfn, isc_reallocfn, isc_freefn): Removed lame casts. Make sure that isc_malloc returns a block that is aligned on a "long" boundary. * src/isc_alloc.c (isc_malloc, isc_free, isc_realloc): Portablilty fix: Align data on a "long" boundary, not only an "int" boundary. Typo fix. * src/isc_event.c (isc_getnextevent): Fixed a spelling error in a comment. Make sure that errors are reported to the proper session. * src/isc_event.c (isc_getnextevent): event->session was sometimes set erronously if an error occured in select() or if a timeout occured. Use O_NONBLOCK instead of the now obsolete name FNDELAY. * src/isc_session.c (isc_openfd): Use O_NONBLOCK instead of FNDELAY. * src/isc_tcp.c (isc_createtcp): Use O_NONBLOCK instead of FNDELAY. * src/isc_udp.c (isc_createudp): Use O_NONBLOCK instead of FNDELAY. Avoid warnings by adding a dubious cast. * src/isc_socket.c (isc_gethostname): Cast argument to gethostbyaddr to a char* to avoid a warning. Portability fix: Renamed _printf to UCB_printf. * src/isc_stdout.c (isc_printf, isc_vprintf): Call UCB_printf instead of _printf. * src/printf.c (UCB_printf): Renamed _printf to UCB_printf (to avoid conflicts on HPUX). Don't use obsolete setsockopt interfaces. * src/isc_tcp.c (isc_createtcp): Fixed calls to setsockopt with SO_LINGER and SO_REUSEADDR arguments. The old-style style previously used should no longer be necessary on modern operating systems, and in fact it no longer works everywere. * src/isc_udp.c (isc_createudp): Fixed calls to setsockopt with SO_LINGER and SO_REUSEADDR arguments. The old-style style previously used should no longer be necessary on modern operating systems, and in fact it no longer works everywere. If an attempt to bind failed with EADDRINUSE all the retries would automatically fail. * src/isc_tcp.c (isc_listentcp): Clear errno on each loop in the retry loop. Include the licensing conditions used by this package. * COPYING: New file. 1998-04-03 Per Cederqvist Port to glibc 2, where errno is a macro. * isc.h (IscSession::isc_errno): New name for former struct member errno. All users updated. 1996-07-24 Per Cederqvist ISC_EVENT_LOGIN events now return the listening session in the event, so that it can be used to easily determine which kind of connection that was made. 66.7 % of the code was contributed by . * src/isc.h (IscEvent): New field: listen_session. * src/isc_event.c (isc_getnextevent): Fill in listen_session when an ISC_EVENT_LOGIN event is created. Set it to NULL in all other cases. 1996-07-23 Per Cederqvist * Imported ISC version 0.98.3. lyskom-server-2.1.2/src/libraries/libisc-new/INSTALL0000664000015100472110000001722706550175044015664 Basic Installation ================== These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, a file `config.cache' that saves the results of its tests to speed up reconfiguring, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.in' is used to create `configure' by a program called `autoconf'. You only need `configure.in' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. You can give `configure' initial values for variables by setting them in the environment. Using a Bourne-compatible shell, you can do that on the command line like this: CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure Or on systems that have the `env' program, you can do it like this: env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not supports the `VPATH' variable, you have to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PATH'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH', the package will use PATH as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=PATH' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' can not figure out automatically, but needs to determine by the type of host the package will run on. Usually `configure' can figure that out, but if it prints a message saying it can not guess the host type, give it the `--host=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name with three fields: CPU-COMPANY-SYSTEM See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the host type. If you are building compiler tools for cross-compiling, you can also use the `--target=TYPE' option to select the type of system they will produce code for and the `--build=TYPE' option to select the type of system on which you are compiling the package. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Operation Controls ================== `configure' recognizes the following options to control how it operates. `--cache-file=FILE' Use and save the results of the tests in FILE instead of `./config.cache'. Set FILE to `/dev/null' to disable caching, for debugging `configure'. `--help' Print a summary of the options to `configure', and exit. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `--version' Print the version of Autoconf used to generate the `configure' script, and exit. `configure' also accepts some other, not widely useful, options. lyskom-server-2.1.2/src/libraries/libisc-new/Makefile.am0000664000015100472110000000220406712622533016654 # ISC - networking library # Copyright (C) 1998-1999 by Peter Eriksson and Per Cederqvist of the # Lysator Academic Computer Association. # # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library 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 # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the Free # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## Process this file with automake to produce Makefile.in SUBDIRS = src man doc demo AUTOMAKE_OPTIONS = gnu RM = rm -f EXTRA_DIST = .cvsignore README.DEVO RELEASING MAINTAINERCLEANFILES = Makefile.in aclocal.m4 configure \ install-sh mkinstalldirs missing INSTALL COPYING lyskom-server-2.1.2/src/libraries/libisc-new/Makefile.in0000664000015100472110000004067407723707447016715 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # ISC - networking library # Copyright (C) 1998-1999 by Peter Eriksson and Per Cederqvist of the # Lysator Academic Computer Association. # # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library 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 # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the Free # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = . am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ prefix = @prefix@ program_transform_name = @program_transform_name@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ SUBDIRS = src man doc demo AUTOMAKE_OPTIONS = gnu RM = rm -f EXTRA_DIST = .cvsignore README.DEVO RELEASING MAINTAINERCLEANFILES = Makefile.in aclocal.m4 configure \ install-sh mkinstalldirs missing INSTALL COPYING subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = DIST_SOURCES = RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \ ps-recursive install-info-recursive uninstall-info-recursive \ all-recursive install-data-recursive install-exec-recursive \ installdirs-recursive install-recursive uninstall-recursive \ check-recursive installcheck-recursive DIST_COMMON = README AUTHORS COPYING COPYING.LIB ChangeLog INSTALL \ Makefile.am Makefile.in NEWS TODO acinclude.m4 aclocal.m4 \ configure configure.in depcomp install-sh missing mkinstalldirs DIST_SUBDIRS = $(SUBDIRS) all: all-recursive .SUFFIXES: am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe) $(top_builddir)/config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) cd $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): configure.in acinclude.m4 cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) uninstall-info-am: # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ETAGS = etags ETAGSFLAGS = CTAGS = ctags CTAGSFLAGS = tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if (etags --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ else \ include_option=--include; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -f $$subdir/TAGS && \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$tags$$unique" \ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = . distdir = $(PACKAGE)-$(VERSION) am__remove_distdir = \ { test ! -d $(distdir) \ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr $(distdir); }; } GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print distdir: $(DISTFILES) $(am__remove_distdir) mkdir $(distdir) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d $(distdir)/$$subdir \ || mkdir $(distdir)/$$subdir \ || exit 1; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" \ distdir=../$(distdir)/$$subdir \ distdir) \ || exit 1; \ fi; \ done -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r $(distdir) dist-gzip: distdir $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist dist-all: distdir $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist $(am__remove_distdir) GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf - chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && cd $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && $(mkinstalldirs) "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist-gzip \ && rm -f $(distdir).tar.gz \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck $(am__remove_distdir) @echo "$(distdir).tar.gz is ready for distribution" | \ sed 'h;s/./=/g;p;x;p;x' distuninstallcheck: @cd $(distuninstallcheck_dir) \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: info: info-recursive info-am: install-data-am: install-exec-am: install-info: install-info-recursive install-man: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-info-am uninstall-info: uninstall-info-recursive .PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \ clean-generic clean-recursive ctags ctags-recursive dist \ dist-all dist-gzip distcheck distclean distclean-generic \ distclean-recursive distclean-tags distcleancheck distdir \ distuninstallcheck dvi dvi-am dvi-recursive info info-am \ info-recursive install install-am install-data install-data-am \ install-data-recursive install-exec install-exec-am \ install-exec-recursive install-info install-info-am \ install-info-recursive install-man install-recursive \ install-strip installcheck installcheck-am installdirs \ installdirs-am installdirs-recursive maintainer-clean \ maintainer-clean-generic maintainer-clean-recursive mostlyclean \ mostlyclean-generic mostlyclean-recursive pdf pdf-am \ pdf-recursive ps ps-am ps-recursive tags tags-recursive \ uninstall uninstall-am uninstall-info-am \ uninstall-info-recursive uninstall-recursive # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/src/libraries/libisc-new/NEWS0000664000015100472110000000603707353345251015330 News in release 1.01 (release date: 2001-09-23): * An unused attribute in IscSession was removed. * This release was produced with automake 1.5 and autoconf 2.52. News in release 1.00 (release date: 1999-05-01): * All of ISC is now distributed under LGPL. * isc_printf() and isc_vprintf() have been removed. The implementation was unifficient, it used code that could not be distributed under GPL or LGPL, and the implementation was unportable. It was also not needed by the core projects that use ISC. If anybody supplies an efficient implementation that is distributable under LGPL it will be included in a future release. * New functions: isc_puts() and isc_putul(). * New configure options --with-checker, --with-gcov and --without-optimization are useful during debugging. * The distribution is now totally self-contained. * Many implementations of stdio cannot use high file descriptors (typically the file descriptor must be less than 256). You can now tell ISC to leave a few low-numbered file descriptors unused so that they are available for use with stdio. Set the fd_relocate member of the IscSessionConfig structure to the lowest number that ISC is allowed to use. * The new event ISC_EVENT_LOGIN_UNRELOCATED is generated if ISC failed to relocate the file descriptor when it was about to generate an ISC_EVENT_LOGIN session. Applications could destroy the new session, or take care to not open new stdio files as long as the unrelocated session exists. This event is never generated if fd_relocate is set to 0. * The master config version is now 1006. The session config version is now 1002. * IscHandlerList has been simplified. * Some other minor fixes and cleanup. News in release 0.99 (release date: 1998-07-06): * Uses autoconf and automake for easy integration in other packages. * All improvements made to ISC in lyskom-server and kom++ have been merged back in the isc distribution. * When isc_getnextevent returns a ISC_EVENT_LOGIN event, the event now contains a pointer to the listening session in the new field listen_session. * Don't use the symbol "errno" as a struct tag. * Some other bug fixes, style improvements and code conservation (to avoid bit decay). * Ported to architectures where some data must be aligned on a "long" boundary (and "int" is shorter than "long"). * Previously, isc_getnextevent would return repeated ISC_EVENT_LOGOUT events until the corresponding session was destroyed. Now, only a single ISC_EVENT_LOGOUT event will be returned. * The library is normally compiled without the functions isc_printf and isc_vprintf. They are not as portable as the rest of the library, and use of them may result in poor performance. Use the --enable-isc-printf argument to configure to include those functions in the library. * The new function isc_wait makes it possible to wait until an initiated connection attempt (to a remote server) either succeeds or fails. * isc.h no longer includes any header files. News in release 0.98.3 and earlier versions: * Unknown. lyskom-server-2.1.2/src/libraries/libisc-new/TODO0000664000015100472110000000067206712622535015321 * Use an autoconf check for the buggy inet_ntoa (search for __GNU__ in src/isc_socket.c to see what I'm talking about). * Använd ett IscMessage som sendbuffert * Kolla upp så att inte tecken i sendbuf[] sänds förän isc_flush() verkligen har gjorts (manuellt). Vi vill inte ha en-teckens-paket.. * Ta bort isc_setlogfn() et al - ska styras via IscMasterConfig-structen. * IscHandlerCache: Direkta funktionspekare också. * Man-sidorna lyskom-server-2.1.2/src/libraries/libisc-new/acinclude.m40000664000015100472110000000472107606371545017026 dnl ISC - networking library dnl Copyright (C) 1998, 2001 by Peter Eriksson and Per Cederqvist of the dnl Lysator Academic Computer Association. dnl dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 2 of the License, or dnl (at your option) any later version. dnl dnl This program is distributed in the hope that it will be useful, dnl but WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the dnl GNU General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ dnl dnl Check if an option is acceptable to the C compiler in use. dnl (This is taken verbatim from cmod 1.2. Please don't make even a dnl tiny change to it unless you change the name of all variables! dnl See the cmod source code for more information.) dnl AC_DEFUN([CMOD_CHECK_CC_OPT], [AC_MSG_CHECKING([whether ${CC} accepts $1]) AC_CACHE_VAL([cmod_cv_compiler_]$2, [[cmod_oldflags=$CFLAGS CFLAGS="$CFLAGS $1"] AC_TRY_LINK(,, [cmod_cv_compiler_]$2[=yes], [cmod_cv_compiler_]$2[=no]) [CFLAGS=$cmod_oldflags]])dnl AC_MSG_RESULT([$cmod_cv_compiler_]$2) if test [$cmod_cv_compiler_]$2 = yes; then CFLAGS="$CFLAGS $1" fi])dnl dnl dnl Another frozen defun. dnl AC_DEFUN([CMOD_C_WORKING_ATTRIBUTE_UNUSED], [AC_CACHE_CHECK([[whether $CC understands __attribute__((unused))]], [[cmod_cv_c_working_attribute_unused]], [dnl gcc 2.6.3 understands the __attribute__((unused)) syntax dnl enough that it prints a warning and ignores it when the dnl variable "i" is declared inside the function body, but it dnl barfs on the construct when it is used in a dnl parameter-declaration. That is why we have a function dnl definition in the prologue of AC_LANG_PROGRAM part. AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[int cmod_x(int y __attribute__((unused))) { return 7; }]], [[int i __attribute__((unused));]])], [cmod_cv_c_working_attribute_unused=yes], [cmod_cv_c_working_attribute_unused=no])]) [if test $cmod_cv_c_working_attribute_unused = yes ; then] AC_DEFINE([HAVE_ATTRIBUTE_UNUSED], [1], [Define if your compiler supports __attribute__ ((unused)).]) [fi]])dnl lyskom-server-2.1.2/src/libraries/libisc-new/aclocal.m40000664000015100472110000011011407723707433016466 # generated automatically by aclocal 1.7.6 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 # Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. dnl ISC - networking library dnl Copyright (C) 1998, 2001 by Peter Eriksson and Per Cederqvist of the dnl Lysator Academic Computer Association. dnl dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 2 of the License, or dnl (at your option) any later version. dnl dnl This program is distributed in the hope that it will be useful, dnl but WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the dnl GNU General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ dnl dnl Check if an option is acceptable to the C compiler in use. dnl (This is taken verbatim from cmod 1.2. Please don't make even a dnl tiny change to it unless you change the name of all variables! dnl See the cmod source code for more information.) dnl AC_DEFUN([CMOD_CHECK_CC_OPT], [AC_MSG_CHECKING([whether ${CC} accepts $1]) AC_CACHE_VAL([cmod_cv_compiler_]$2, [[cmod_oldflags=$CFLAGS CFLAGS="$CFLAGS $1"] AC_TRY_LINK(,, [cmod_cv_compiler_]$2[=yes], [cmod_cv_compiler_]$2[=no]) [CFLAGS=$cmod_oldflags]])dnl AC_MSG_RESULT([$cmod_cv_compiler_]$2) if test [$cmod_cv_compiler_]$2 = yes; then CFLAGS="$CFLAGS $1" fi])dnl dnl dnl Another frozen defun. dnl AC_DEFUN([CMOD_C_WORKING_ATTRIBUTE_UNUSED], [AC_CACHE_CHECK([[whether $CC understands __attribute__((unused))]], [[cmod_cv_c_working_attribute_unused]], [dnl gcc 2.6.3 understands the __attribute__((unused)) syntax dnl enough that it prints a warning and ignores it when the dnl variable "i" is declared inside the function body, but it dnl barfs on the construct when it is used in a dnl parameter-declaration. That is why we have a function dnl definition in the prologue of AC_LANG_PROGRAM part. AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[int cmod_x(int y __attribute__((unused))) { return 7; }]], [[int i __attribute__((unused));]])], [cmod_cv_c_working_attribute_unused=yes], [cmod_cv_c_working_attribute_unused=no])]) [if test $cmod_cv_c_working_attribute_unused = yes ; then] AC_DEFINE([HAVE_ATTRIBUTE_UNUSED], [1], [Define if your compiler supports __attribute__ ((unused)).]) [fi]])dnl # Do all the work for Automake. -*- Autoconf -*- # This macro actually does too much some checks are only needed if # your package does certain things. But this isn't really a big deal. # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 10 AC_PREREQ([2.54]) # Autoconf 2.50 wants to disallow AM_ names. We explicitly allow # the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl # test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AM_MISSING_PROG(AMTAR, tar) AM_PROG_INSTALL_SH AM_PROG_INSTALL_STRIP # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl ]) ]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $1 | $1:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) # Copyright 2002 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.7"]) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION so it can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.7.6])]) # Helper functions for option handling. -*- Autoconf -*- # Copyright 2001, 2002 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 2 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # ------------------------------ # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ---------------------------------- # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # # Check to make sure that the build environment is sane. # # Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 3 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # -*- Autoconf -*- # Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 3 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # AM_AUX_DIR_EXPAND # Copyright 2001 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. # Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50]) AC_DEFUN([AM_AUX_DIR_EXPAND], [ # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. # Copyright 2001 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl install_sh=${install_sh-"$am_aux_dir/install-sh"} AC_SUBST(install_sh)]) # AM_PROG_INSTALL_STRIP # Copyright 2001 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # -*- Autoconf -*- # Copyright (C) 2003 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 1 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # serial 5 -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "GCJ", or "OBJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c : > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # (even with -Werror). So we grep stderr for any message # that says an option was ignored. if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, [ --disable-dependency-tracking Speeds up one-time builds --enable-dependency-tracking Do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH]) ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. #serial 2 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [for mf in $CONFIG_FILES; do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # So let's grep whole file. if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue # Extract the definition of DEP_FILES from the Makefile without # running `make'. DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"` test -z "$DEPDIR" && continue # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n -e '/^U = / s///p' < "$mf"` test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" # We invoke sed twice because it is the simplest approach to # changing $(DEPDIR) to its actual value in the expansion. for file in `sed -n -e ' /^DEP_FILES = .*\\\\$/ { s/^DEP_FILES = // :loop s/\\\\$// p n /\\\\$/ b loop p } /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each `.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 2 # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright 1997, 2000, 2001 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 5 AC_PREREQ(2.52) # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE]) AC_SUBST([$1_FALSE]) if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]) fi])]) # Copyright 1996, 1997, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # serial 2 # @defmac AC_PROG_CC_STDC # @maindex PROG_CC_STDC # @ovindex CC # If the C compiler in not in ANSI C mode by default, try to add an option # to output variable @code{CC} to make it so. This macro tries various # options that select ANSI C on some system or another. It considers the # compiler to be in ANSI C mode if it handles function prototypes correctly. # # If you use this macro, you should check after calling it whether the C # compiler has been set to accept ANSI C; if not, the shell variable # @code{am_cv_prog_cc_stdc} is set to @samp{no}. If you wrote your source # code in ANSI C, you can make an un-ANSIfied copy of it by using the # program @code{ansi2knr}, which comes with Ghostscript. # @end defmac AC_DEFUN([AM_PROG_CC_STDC], [AC_REQUIRE([AC_PROG_CC]) AC_BEFORE([$0], [AC_C_INLINE]) AC_BEFORE([$0], [AC_C_CONST]) dnl Force this before AC_PROG_CPP. Some cpp's, eg on HPUX, require dnl a magic option to avoid problems with ANSI preprocessor commands dnl like #elif. dnl FIXME: can't do this because then AC_AIX won't work due to a dnl circular dependency. dnl AC_BEFORE([$0], [AC_PROG_CPP]) AC_MSG_CHECKING([for ${CC-cc} option to accept ANSI C]) AC_CACHE_VAL(am_cv_prog_cc_stdc, [am_cv_prog_cc_stdc=no ac_save_CC="$CC" # Don't try gcc -ansi; that turns off useful extensions and # breaks some systems' header files. # AIX -qlanglvl=ansi # Ultrix and OSF/1 -std1 # HP-UX 10.20 and later -Ae # HP-UX older versions -Aa -D_HPUX_SOURCE # SVR4 -Xc -D__EXTENSIONS__ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" AC_TRY_COMPILE( [#include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; ], [ return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ], [am_cv_prog_cc_stdc="$ac_arg"; break]) done CC="$ac_save_CC" ]) if test -z "$am_cv_prog_cc_stdc"; then AC_MSG_RESULT([none needed]) else AC_MSG_RESULT([$am_cv_prog_cc_stdc]) fi case "x$am_cv_prog_cc_stdc" in x|xno) ;; *) CC="$CC $am_cv_prog_cc_stdc" ;; esac ]) AU_DEFUN([fp_PROG_CC_STDC], [AM_PROG_CC_STDC]) lyskom-server-2.1.2/src/libraries/libisc-new/configure0000775000015100472110000070121007723707454016543 #! /bin/sh # From configure.in Revision: 1.24 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.57 for isc 1.01. # # Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 # Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi # Support unset when possible. if (FOO=FOO; unset FOO) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" # Sed expression to map a string onto a valid variable name. as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` exec 6>&1 # # Initializations. # ac_default_prefix=/usr/local ac_config_libobj_dir=. cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. # This variable seems obsolete. It should probably be removed, and # only ac_max_sed_lines should be used. : ${ac_max_here_lines=38} # Identity of this package. PACKAGE_NAME='isc' PACKAGE_TARNAME='isc' PACKAGE_VERSION='1.01' PACKAGE_STRING='isc 1.01' PACKAGE_BUGREPORT='' ac_unique_file="src/isc_master.c" # Factoring default headers for most tests. ac_includes_default="\ #include #if HAVE_SYS_TYPES_H # include #endif #if HAVE_SYS_STAT_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_STRING_H # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif # include #endif #if HAVE_STRINGS_H # include #endif #if HAVE_INTTYPES_H # include #else # if HAVE_STDINT_H # include # endif #endif #if HAVE_UNISTD_H # include #endif" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE am__leading_dot AR CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CPP EGREP RANLIB ac_ct_RANLIB LIBOBJS CHECKER LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_option in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` eval "enable_$ac_feature=no" ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "enable_$ac_feature='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package| sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "with_$ac_package='$ac_optarg'" ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/-/_/g'` eval "with_$ac_package=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` eval "$ac_envvar='$ac_optarg'" export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute paths. for ac_var in exec_prefix prefix do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* | NONE | '' ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # Be sure to have absolute paths. for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ localstatedir libdir includedir oldincludedir infodir mandir do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_confdir=`(dirname "$0") 2>/dev/null || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 { (exit 1); exit 1; }; } else { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi fi (cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 { (exit 1); exit 1; }; } srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` ac_env_build_alias_set=${build_alias+set} ac_env_build_alias_value=$build_alias ac_cv_env_build_alias_set=${build_alias+set} ac_cv_env_build_alias_value=$build_alias ac_env_host_alias_set=${host_alias+set} ac_env_host_alias_value=$host_alias ac_cv_env_host_alias_set=${host_alias+set} ac_cv_env_host_alias_value=$host_alias ac_env_target_alias_set=${target_alias+set} ac_env_target_alias_value=$target_alias ac_cv_env_target_alias_set=${target_alias+set} ac_cv_env_target_alias_value=$target_alias ac_env_AR_set=${AR+set} ac_env_AR_value=$AR ac_cv_env_AR_set=${AR+set} ac_cv_env_AR_value=$AR ac_env_CC_set=${CC+set} ac_env_CC_value=$CC ac_cv_env_CC_set=${CC+set} ac_cv_env_CC_value=$CC ac_env_CFLAGS_set=${CFLAGS+set} ac_env_CFLAGS_value=$CFLAGS ac_cv_env_CFLAGS_set=${CFLAGS+set} ac_cv_env_CFLAGS_value=$CFLAGS ac_env_LDFLAGS_set=${LDFLAGS+set} ac_env_LDFLAGS_value=$LDFLAGS ac_cv_env_LDFLAGS_set=${LDFLAGS+set} ac_cv_env_LDFLAGS_value=$LDFLAGS ac_env_CPPFLAGS_set=${CPPFLAGS+set} ac_env_CPPFLAGS_value=$CPPFLAGS ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} ac_cv_env_CPPFLAGS_value=$CPPFLAGS ac_env_CPP_set=${CPP+set} ac_env_CPP_value=$CPP ac_cv_env_CPP_set=${CPP+set} ac_cv_env_CPP_value=$CPP # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures isc 1.01 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] _ACEOF cat <<_ACEOF Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data [PREFIX/share] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --infodir=DIR info documentation [PREFIX/info] --mandir=DIR man documentation [PREFIX/man] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of isc 1.01:";; esac cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-ipv6 enable IPv6 support --disable-malloc-guards disable defensive guard areas (may crash lyskomd) --disable-dependency-tracking Speeds up one-time builds --enable-dependency-tracking Do not reject slow dependency extractors Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-checker compile with Gnu Checker --with-gcov instrument for gcov (requires gcc) --without-optimization turn off optimization (default on) --with-optimization[=N] specify level of optimization Some influential environment variables: AR ar program to use CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. _ACEOF fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. ac_popdir=`pwd` for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d $ac_dir || continue ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be # absolute. ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` cd $ac_dir # Check for guested configure; otherwise get Cygnus style configure. if test -f $ac_srcdir/configure.gnu; then echo $SHELL $ac_srcdir/configure.gnu --help=recursive elif test -f $ac_srcdir/configure; then echo $SHELL $ac_srcdir/configure --help=recursive elif test -f $ac_srcdir/configure.ac || test -f $ac_srcdir/configure.in; then echo $ac_configure --help else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi cd $ac_popdir done fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF isc configure 1.01 generated by GNU Autoconf 2.57 Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit 0 fi exec 5>config.log cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by isc $as_me 1.01, which was generated by GNU Autoconf 2.57. Invocation command line was $ $0 $@ _ACEOF { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` hostinfo = `(hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_sep= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" # Get rid of the leading space. ac_sep=" " ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Be sure not to use single quotes in there, as some shells, # such as our DU 5.0 friend, will then `close' the trap. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, { (set) 2>&1 | case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in *ac_space=\ *) sed -n \ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" ;; *) sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------- ## ## Output files. ## ## ------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo sed "/^$/d" confdefs.h | sort echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core core.* *.core && rm -rf conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo >confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . $cache_file;; *) . ./$cache_file;; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in `(set) 2>&1 | sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val="\$ac_cv_env_${ac_var}_value" eval ac_new_val="\$ac_env_${ac_var}_value" case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu am__api_version="1.7" ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f $ac_dir/shtool; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} { (exit 1); exit 1; }; } fi ac_config_guess="$SHELL $ac_aux_dir/config.guess" ac_config_sub="$SHELL $ac_aux_dir/config.sub" ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL=$ac_install_sh fi fi echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo "$as_me:$LINENO: checking whether build environment is sane" >&5 echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6 # Just in case sleep 1 echo timestamp > conftest.file # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&5 echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&2;} { (exit 1); exit 1; }; } fi test "$2" = conftest.file ) then # Ok. : else { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! Check your system clock" >&5 echo "$as_me: error: newly created file is older than distributed files! Check your system clock" >&2;} { (exit 1); exit 1; }; } fi echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 test "$program_prefix" != NONE && program_transform_name="s,^,$program_prefix,;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s,\$,$program_suffix,;$program_transform_name" # Double any \ or $. echo might interpret backslashes. # By default was `s,x,x', remove it if useless. cat <<\_ACEOF >conftest.sed s/[\\$]/&&/g;s/;s,x,x,$// _ACEOF program_transform_name=`echo $program_transform_name | sed -f conftest.sed` rm conftest.sed # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_AWK+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then echo "$as_me:$LINENO: result: $AWK" >&5 echo "${ECHO_T}$AWK" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$AWK" && break done echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'` if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.make <<\_ACEOF all: @echo 'ac_maketemp="$(MAKE)"' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` if test -n "$ac_maketemp"; then eval ac_cv_prog_make_${ac_make}_set=yes else eval ac_cv_prog_make_${ac_make}_set=no fi rm -f conftest.make fi if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 SET_MAKE= else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} { (exit 1); exit 1; }; } fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE=isc VERSION=1.01 cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} AMTAR=${AMTAR-"${am_missing_run}tar"} install_sh=${install_sh-"$am_aux_dir/install-sh"} # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then echo "$as_me:$LINENO: result: $STRIP" >&5 echo "${ECHO_T}$STRIP" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 echo "${ECHO_T}$ac_ct_STRIP" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi STRIP=$ac_ct_STRIP else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Check whether --with-checker or --without-checker was given. if test "${with_checker+set}" = set; then withval="$with_checker" use_checker=$withval else use_checker=no fi; # Check whether --with-gcov or --without-gcov was given. if test "${with_gcov+set}" = set; then withval="$with_gcov" use_gcov=$withval else use_gcov=no fi; # Check whether --with-optimization or --without-optimization was given. if test "${with_optimization+set}" = set; then withval="$with_optimization" opt_level=$withval else opt_level="" fi; # Check whether --enable-ipv6 or --disable-ipv6 was given. if test "${enable_ipv6+set}" = set; then enableval="$enable_ipv6" use_inet6=yes else use_inet6=no fi; # Check whether --enable-malloc-guards or --disable-malloc-guards was given. if test "${enable_malloc_guards+set}" = set; then enableval="$enable_malloc_guards" use_malloc_guards=$enableval else use_malloc_guards=yes fi; if test "$use_malloc_guards" = "yes" then cat >>confdefs.h <<\_ACEOF #define USE_MALLOC_GUARDS 1 _ACEOF fi # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_path_AR+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $AR in [\\/]* | ?:[\\/]*) ac_cv_path_AR="$AR" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/ccs/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_AR="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done test -z "$ac_cv_path_AR" && ac_cv_path_AR="notfound" ;; esac fi AR=$ac_cv_path_AR if test -n "$AR"; then echo "$as_me:$LINENO: result: $AR" >&5 echo "${ECHO_T}$AR" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi if test "$AR" = "notfound"; then { { echo "$as_me:$LINENO: error: cannot find \`\`ar''" >&5 echo "$as_me: error: cannot find \`\`ar''" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$ac_ct_CC" && break done CC=$ac_ct_CC fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO:" \ "checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 (eval $ac_compiler --version &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 (eval $ac_compiler -v &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 (eval $ac_compiler -V &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. echo "$as_me:$LINENO: checking for C compiler default output" >&5 echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6 ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 (eval $ac_link_default) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Find the output, starting from the most likely. This scheme is # not robust to junk in `.', hence go to wildcards (a.*) only as a last # resort. # Be careful to initialize this variable, since it used to be cached. # Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. ac_cv_exeext= # b.out is created by i960 compilers. for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; conftest.$ac_ext ) # This is the source file. ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` # FIXME: I believe we export ac_cv_exeext for Libtool, # but it would be cool to find out if it's true. Does anybody # maintain Libtool? --akim. export ac_cv_exeext break;; * ) break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6 # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether the C compiler works" >&5 echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6 echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` export ac_cv_exeext break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6 rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6 OBJEXT=$ac_cv_objext ac_objext=$OBJEXT echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS CFLAGS="-g" echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_prog_cc_g=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 if test "${ac_cv_prog_cc_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_stdc=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF # Don't try gcc -ansi; that turns off useful extensions and # breaks some systems' header files. # AIX -qlanglvl=ansi # Ultrix and OSF/1 -std1 # HP-UX 10.20 and later -Ae # HP-UX older versions -Aa -D_HPUX_SOURCE # SVR4 -Xc -D__EXTENSIONS__ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_stdc=$ac_arg break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext done rm -f conftest.$ac_ext conftest.$ac_objext CC=$ac_save_CC fi case "x$ac_cv_prog_cc_stdc" in x|xno) echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6 ;; *) echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 CC="$CC $ac_cv_prog_cc_stdc" ;; esac # Some people use a C++ compiler to compile C. Since we use `exit', # in C++ we need to declare it. In case someone uses the same compiler # for both compiling C and C++ we need to have the C++ compiler decide # the declaration of exit, since it's the most demanding environment. cat >conftest.$ac_ext <<_ACEOF #ifndef __cplusplus choke me #endif _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then for ac_declaration in \ ''\ '#include ' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int);' \ 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 continue fi rm -f conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest.$ac_ext done rm -f conftest* if test -n "$ac_declaration"; then echo '#ifdef __cplusplus' >>confdefs.h echo $ac_declaration >>confdefs.h echo '#endif' >>confdefs.h fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6 am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi echo "$as_me:$LINENO: result: $_am_result" >&5 echo "${ECHO_T}$_am_result" >&6 rm -f confinc confmf # Check whether --enable-dependency-tracking or --disable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then enableval="$enable_dependency_tracking" fi; if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c : > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # (even with -Werror). So we grep stderr for any message # that says an option was ignored. if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6 CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$CPP" >&6 ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6 if test "${ac_cv_prog_egrep+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | (grep -E '(a|b)') >/dev/null 2>&1 then ac_cv_prog_egrep='grep -E' else ac_cv_prog_egrep='egrep' fi fi echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 echo "${ECHO_T}$ac_cv_prog_egrep" >&6 EGREP=$ac_cv_prog_egrep echo "$as_me:$LINENO: checking for AIX" >&5 echo $ECHO_N "checking for AIX... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef _AIX yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 cat >>confdefs.h <<\_ACEOF #define _ALL_SOURCE 1 _ACEOF else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi rm -f conftest* echo "$as_me:$LINENO: checking for library containing strerror" >&5 echo $ECHO_N "checking for library containing strerror... $ECHO_C" >&6 if test "${ac_cv_search_strerror+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS ac_cv_search_strerror=no cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char strerror (); int main () { strerror (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_strerror="none required" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext if test "$ac_cv_search_strerror" = no; then for ac_lib in cposix; do LIBS="-l$ac_lib $ac_func_search_save_LIBS" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char strerror (); int main () { strerror (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_strerror="-l$ac_lib" break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext done fi LIBS=$ac_func_search_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_search_strerror" >&5 echo "${ECHO_T}$ac_cv_search_strerror" >&6 if test "$ac_cv_search_strerror" != no; then test "$ac_cv_search_strerror" = "none required" || LIBS="$ac_cv_search_strerror $LIBS" fi echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6 if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done if test "${ac_cv_header_minix_config_h+set}" = set; then echo "$as_me:$LINENO: checking for minix/config.h" >&5 echo $ECHO_N "checking for minix/config.h... $ECHO_C" >&6 if test "${ac_cv_header_minix_config_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5 echo "${ECHO_T}$ac_cv_header_minix_config_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking minix/config.h usability" >&5 echo $ECHO_N "checking minix/config.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking minix/config.h presence" >&5 echo $ECHO_N "checking minix/config.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc in yes:no ) { echo "$as_me:$LINENO: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: minix/config.h: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; no:yes ) { echo "$as_me:$LINENO: WARNING: minix/config.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: minix/config.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: minix/config.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: minix/config.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: minix/config.h: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for minix/config.h" >&5 echo $ECHO_N "checking for minix/config.h... $ECHO_C" >&6 if test "${ac_cv_header_minix_config_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_minix_config_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5 echo "${ECHO_T}$ac_cv_header_minix_config_h" >&6 fi if test $ac_cv_header_minix_config_h = yes; then MINIX=yes else MINIX= fi if test "$MINIX" = yes; then cat >>confdefs.h <<\_ACEOF #define _POSIX_SOURCE 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _POSIX_1_SOURCE 2 _ACEOF cat >>confdefs.h <<\_ACEOF #define _MINIX 1 _ACEOF fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then echo "$as_me:$LINENO: result: $RANLIB" >&5 echo "${ECHO_T}$RANLIB" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 echo "${ECHO_T}$ac_ct_RANLIB" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi RANLIB=$ac_ct_RANLIB else RANLIB="$ac_cv_prog_RANLIB" fi echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6 if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi for ac_header in stdlib.h stdarg.h stddef.h string.h sys/select.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc in yes:no ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; no:yes ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in sys/time.h stdint.h strings.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc in yes:no ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; no:yes ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ( cat <<\_ASBOX ## ------------------------------------ ## ## Report this to bug-autoconf@gnu.org. ## ## ------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done echo "$as_me:$LINENO: checking for ${CC-cc} option to accept ANSI C" >&5 echo $ECHO_N "checking for ${CC-cc} option to accept ANSI C... $ECHO_C" >&6 if test "${am_cv_prog_cc_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else am_cv_prog_cc_stdc=no ac_save_CC="$CC" # Don't try gcc -ansi; that turns off useful extensions and # breaks some systems' header files. # AIX -qlanglvl=ansi # Ultrix and OSF/1 -std1 # HP-UX 10.20 and later -Ae # HP-UX older versions -Aa -D_HPUX_SOURCE # SVR4 -Xc -D__EXTENSIONS__ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then am_cv_prog_cc_stdc="$ac_arg"; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest.$ac_ext done CC="$ac_save_CC" fi if test -z "$am_cv_prog_cc_stdc"; then echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6 else echo "$as_me:$LINENO: result: $am_cv_prog_cc_stdc" >&5 echo "${ECHO_T}$am_cv_prog_cc_stdc" >&6 fi case "x$am_cv_prog_cc_stdc" in x|xno) ;; *) CC="$CC $am_cv_prog_cc_stdc" ;; esac echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6 if test "${ac_cv_header_time+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include int main () { if ((struct tm *) 0) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_time=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_time=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 echo "${ECHO_T}$ac_cv_header_time" >&6 if test $ac_cv_header_time = yes; then cat >>confdefs.h <<\_ACEOF #define TIME_WITH_SYS_TIME 1 _ACEOF fi echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6 if test "${ac_cv_c_const+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { /* FIXME: Include the comments suggested by Paul. */ #ifndef __cplusplus /* Ultrix mips cc rejects this. */ typedef int charset[2]; const charset x; /* SunOS 4.1.1 cc rejects this. */ char const *const *ccp; char **p; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; ccp = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++ccp; p = (char**) ccp; ccp = (char const *const *) p; { /* SCO 3.2v4 cc rejects this. */ char *t; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; }; struct s *b; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; } #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_const=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_const=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 echo "${ECHO_T}$ac_cv_c_const" >&6 if test $ac_cv_c_const = no; then cat >>confdefs.h <<\_ACEOF #define const _ACEOF fi echo "$as_me:$LINENO: checking for inline" >&5 echo $ECHO_N "checking for inline... $ECHO_C" >&6 if test "${ac_cv_c_inline+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_inline=$ac_kw; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest.$ac_ext done fi echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 echo "${ECHO_T}$ac_cv_c_inline" >&6 case $ac_cv_c_inline in inline | yes) ;; no) cat >>confdefs.h <<\_ACEOF #define inline _ACEOF ;; *) cat >>confdefs.h <<_ACEOF #define inline $ac_cv_c_inline _ACEOF ;; esac echo "$as_me:$LINENO: checking for size_t" >&5 echo $ECHO_N "checking for size_t... $ECHO_C" >&6 if test "${ac_cv_type_size_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if ((size_t *) 0) return 0; if (sizeof (size_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_size_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_size_t=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 echo "${ECHO_T}$ac_cv_type_size_t" >&6 if test $ac_cv_type_size_t = yes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned _ACEOF fi echo "$as_me:$LINENO: checking for socklen_t" >&5 echo $ECHO_N "checking for socklen_t... $ECHO_C" >&6 if test "${ac_cv_type_socklen_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { if ((socklen_t *) 0) return 0; if (sizeof (socklen_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_socklen_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_socklen_t=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_socklen_t" >&5 echo "${ECHO_T}$ac_cv_type_socklen_t" >&6 if test $ac_cv_type_socklen_t = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_SOCKLEN_T 1 _ACEOF fi echo "$as_me:$LINENO: checking for gethostbyname" >&5 echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6 if test "${ac_cv_func_gethostbyname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* System header to define __stub macros and hopefully few prototypes, which can conflict with char gethostbyname (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostbyname (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_gethostbyname) || defined (__stub___gethostbyname) choke me #else char (*f) () = gethostbyname; #endif #ifdef __cplusplus } #endif int main () { return f != gethostbyname; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_gethostbyname=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_gethostbyname=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5 echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6 if test $ac_cv_func_gethostbyname = no then echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5 echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6 if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostbyname (); int main () { gethostbyname (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_nsl_gethostbyname=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_nsl_gethostbyname=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5 echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6 if test $ac_cv_lib_nsl_gethostbyname = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBNSL 1 _ACEOF LIBS="-lnsl $LIBS" fi fi echo "$as_me:$LINENO: checking for socket" >&5 echo $ECHO_N "checking for socket... $ECHO_C" >&6 if test "${ac_cv_func_socket+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* System header to define __stub macros and hopefully few prototypes, which can conflict with char socket (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char socket (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_socket) || defined (__stub___socket) choke me #else char (*f) () = socket; #endif #ifdef __cplusplus } #endif int main () { return f != socket; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_socket=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_socket=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_socket" >&5 echo "${ECHO_T}$ac_cv_func_socket" >&6 if test $ac_cv_func_socket = no then echo "$as_me:$LINENO: checking for socket in -lsocket" >&5 echo $ECHO_N "checking for socket in -lsocket... $ECHO_C" >&6 if test "${ac_cv_lib_socket_socket+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char socket (); int main () { socket (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_socket_socket=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_socket_socket=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_socket_socket" >&5 echo "${ECHO_T}$ac_cv_lib_socket_socket" >&6 if test $ac_cv_lib_socket_socket = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBSOCKET 1 _ACEOF LIBS="-lsocket $LIBS" fi fi for ac_func in inet_aton do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF else LIBOBJS="$LIBOBJS $ac_func.$ac_objext" fi done if test $ac_cv_func_inet_aton = no then echo "$as_me:$LINENO: checking whether INADDR_NONE is declared" >&5 echo $ECHO_N "checking whether INADDR_NONE is declared... $ECHO_C" >&6 if test "${ac_cv_have_decl_INADDR_NONE+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { #ifndef INADDR_NONE char *p = (char *) INADDR_NONE; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_have_decl_INADDR_NONE=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_have_decl_INADDR_NONE=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_have_decl_INADDR_NONE" >&5 echo "${ECHO_T}$ac_cv_have_decl_INADDR_NONE" >&6 if test $ac_cv_have_decl_INADDR_NONE = yes; then : else cat >>confdefs.h <<\_ACEOF #define INADDR_NONE ((uint32_t)-1) _ACEOF fi fi echo "$as_me:$LINENO: checking for uint32_t" >&5 echo $ECHO_N "checking for uint32_t... $ECHO_C" >&6 if test "${ac_cv_type_uint32_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif int main () { if ((uint32_t *) 0) return 0; if (sizeof (uint32_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_uint32_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_uint32_t=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_uint32_t" >&5 echo "${ECHO_T}$ac_cv_type_uint32_t" >&6 if test $ac_cv_type_uint32_t = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_UINT32_T 1 _ACEOF fi if test $ac_cv_type_uint32_t = no then echo "$as_me:$LINENO: checking for int" >&5 echo $ECHO_N "checking for int... $ECHO_C" >&6 if test "${ac_cv_type_int+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if ((int *) 0) return 0; if (sizeof (int)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_int=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_int=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5 echo "${ECHO_T}$ac_cv_type_int" >&6 echo "$as_me:$LINENO: checking size of int" >&5 echo $ECHO_N "checking size of int... $ECHO_C" >&6 if test "${ac_cv_sizeof_int+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$ac_cv_type_int" = yes; then # The cast to unsigned long works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(((long) (sizeof (int))) >= 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_lo=0 ac_mid=0 while :; do cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr $ac_mid + 1` if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid + 1` fi rm -f conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(((long) (sizeof (int))) < 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=-1 ac_mid=-1 while :; do cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(((long) (sizeof (int))) >= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_lo=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_hi=`expr '(' $ac_mid ')' - 1` if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid` fi rm -f conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo= ac_hi= fi rm -f conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=$ac_mid else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr '(' $ac_mid ')' + 1` fi rm -f conftest.$ac_objext conftest.$ac_ext done case $ac_lo in ?*) ac_cv_sizeof_int=$ac_lo;; '') { { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77 See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (int), 77 See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } ;; esac else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling See \`config.log' for more details." >&5 echo "$as_me: error: cannot run test program while cross compiling See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default long longval () { return (long) (sizeof (int)); } unsigned long ulongval () { return (long) (sizeof (int)); } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) exit (1); if (((long) (sizeof (int))) < 0) { long i = longval (); if (i != ((long) (sizeof (int)))) exit (1); fprintf (f, "%ld\n", i); } else { unsigned long i = ulongval (); if (i != ((long) (sizeof (int)))) exit (1); fprintf (f, "%lu\n", i); } exit (ferror (f) || fclose (f) != 0); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_int=`cat conftest.val` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77 See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (int), 77 See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi rm -f conftest.val else ac_cv_sizeof_int=0 fi fi echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5 echo "${ECHO_T}$ac_cv_sizeof_int" >&6 cat >>confdefs.h <<_ACEOF #define SIZEOF_INT $ac_cv_sizeof_int _ACEOF echo "$as_me:$LINENO: checking for long" >&5 echo $ECHO_N "checking for long... $ECHO_C" >&6 if test "${ac_cv_type_long+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if ((long *) 0) return 0; if (sizeof (long)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_long=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_long=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5 echo "${ECHO_T}$ac_cv_type_long" >&6 echo "$as_me:$LINENO: checking size of long" >&5 echo $ECHO_N "checking size of long... $ECHO_C" >&6 if test "${ac_cv_sizeof_long+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$ac_cv_type_long" = yes; then # The cast to unsigned long works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(((long) (sizeof (long))) >= 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_lo=0 ac_mid=0 while :; do cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr $ac_mid + 1` if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid + 1` fi rm -f conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(((long) (sizeof (long))) < 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=-1 ac_mid=-1 while :; do cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(((long) (sizeof (long))) >= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_lo=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_hi=`expr '(' $ac_mid ')' - 1` if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid` fi rm -f conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo= ac_hi= fi rm -f conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_hi=$ac_mid else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr '(' $ac_mid ')' + 1` fi rm -f conftest.$ac_objext conftest.$ac_ext done case $ac_lo in ?*) ac_cv_sizeof_long=$ac_lo;; '') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77 See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (long), 77 See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } ;; esac else if test "$cross_compiling" = yes; then { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling See \`config.log' for more details." >&5 echo "$as_me: error: cannot run test program while cross compiling See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default long longval () { return (long) (sizeof (long)); } unsigned long ulongval () { return (long) (sizeof (long)); } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) exit (1); if (((long) (sizeof (long))) < 0) { long i = longval (); if (i != ((long) (sizeof (long)))) exit (1); fprintf (f, "%ld\n", i); } else { unsigned long i = ulongval (); if (i != ((long) (sizeof (long)))) exit (1); fprintf (f, "%lu\n", i); } exit (ferror (f) || fclose (f) != 0); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_long=`cat conftest.val` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) { { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77 See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (long), 77 See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi rm -f conftest.val else ac_cv_sizeof_long=0 fi fi echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5 echo "${ECHO_T}$ac_cv_sizeof_long" >&6 cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG $ac_cv_sizeof_long _ACEOF fi echo "$as_me:$LINENO: checking for intptr_t" >&5 echo $ECHO_N "checking for intptr_t... $ECHO_C" >&6 if test "${ac_cv_type_intptr_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if ((intptr_t *) 0) return 0; if (sizeof (intptr_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_intptr_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_intptr_t=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_intptr_t" >&5 echo "${ECHO_T}$ac_cv_type_intptr_t" >&6 echo "$as_me:$LINENO: checking for intmax_t" >&5 echo $ECHO_N "checking for intmax_t... $ECHO_C" >&6 if test "${ac_cv_type_intmax_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if ((intmax_t *) 0) return 0; if (sizeof (intmax_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_intmax_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_intmax_t=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_intmax_t" >&5 echo "${ECHO_T}$ac_cv_type_intmax_t" >&6 echo "$as_me:$LINENO: checking for size_t" >&5 echo $ECHO_N "checking for size_t... $ECHO_C" >&6 if test "${ac_cv_type_size_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if ((size_t *) 0) return 0; if (sizeof (size_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_size_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_size_t=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 echo "${ECHO_T}$ac_cv_type_size_t" >&6 echo "$as_me:$LINENO: checking whether $CC understands __attribute__((unused))" >&5 echo $ECHO_N "checking whether $CC understands __attribute__((unused))... $ECHO_C" >&6 if test "${cmod_cv_c_working_attribute_unused+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int cmod_x(int y __attribute__((unused))) { return 7; } int main () { int i __attribute__((unused)); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cmod_cv_c_working_attribute_unused=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cmod_cv_c_working_attribute_unused=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $cmod_cv_c_working_attribute_unused" >&5 echo "${ECHO_T}$cmod_cv_c_working_attribute_unused" >&6 if test $cmod_cv_c_working_attribute_unused = yes ; then cat >>confdefs.h <<\_ACEOF #define HAVE_ATTRIBUTE_UNUSED 1 _ACEOF fi if test -n "$GCC"; then CFLAGS="$CFLAGS -Wall -W -Wshadow" echo "$as_me:$LINENO: checking whether ${CC} accepts -Wbad-function-cast" >&5 echo $ECHO_N "checking whether ${CC} accepts -Wbad-function-cast... $ECHO_C" >&6 if test "${cmod_cv_compiler_bad_function_cast+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cmod_oldflags=$CFLAGS CFLAGS="$CFLAGS -Wbad-function-cast" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cmod_cv_compiler_bad_function_cast=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cmod_cv_compiler_bad_function_cast=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext CFLAGS=$cmod_oldflags fi echo "$as_me:$LINENO: result: $cmod_cv_compiler_bad_function_cast" >&5 echo "${ECHO_T}$cmod_cv_compiler_bad_function_cast" >&6 if test $cmod_cv_compiler_bad_function_cast = yes; then CFLAGS="$CFLAGS -Wbad-function-cast" fi echo "$as_me:$LINENO: checking whether ${CC} accepts -Wcast-qual" >&5 echo $ECHO_N "checking whether ${CC} accepts -Wcast-qual... $ECHO_C" >&6 if test "${cmod_cv_compiler_cast_qual+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cmod_oldflags=$CFLAGS CFLAGS="$CFLAGS -Wcast-qual" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cmod_cv_compiler_cast_qual=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cmod_cv_compiler_cast_qual=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext CFLAGS=$cmod_oldflags fi echo "$as_me:$LINENO: result: $cmod_cv_compiler_cast_qual" >&5 echo "${ECHO_T}$cmod_cv_compiler_cast_qual" >&6 if test $cmod_cv_compiler_cast_qual = yes; then CFLAGS="$CFLAGS -Wcast-qual" fi echo "$as_me:$LINENO: checking whether ${CC} accepts -Wcast-align" >&5 echo $ECHO_N "checking whether ${CC} accepts -Wcast-align... $ECHO_C" >&6 if test "${cmod_cv_compiler_cast_align+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cmod_oldflags=$CFLAGS CFLAGS="$CFLAGS -Wcast-align" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cmod_cv_compiler_cast_align=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cmod_cv_compiler_cast_align=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext CFLAGS=$cmod_oldflags fi echo "$as_me:$LINENO: result: $cmod_cv_compiler_cast_align" >&5 echo "${ECHO_T}$cmod_cv_compiler_cast_align" >&6 if test $cmod_cv_compiler_cast_align = yes; then CFLAGS="$CFLAGS -Wcast-align" fi echo "$as_me:$LINENO: checking whether ${CC} accepts -Wwrite-strings" >&5 echo $ECHO_N "checking whether ${CC} accepts -Wwrite-strings... $ECHO_C" >&6 if test "${cmod_cv_compiler_write_strings+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cmod_oldflags=$CFLAGS CFLAGS="$CFLAGS -Wwrite-strings" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cmod_cv_compiler_write_strings=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cmod_cv_compiler_write_strings=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext CFLAGS=$cmod_oldflags fi echo "$as_me:$LINENO: result: $cmod_cv_compiler_write_strings" >&5 echo "${ECHO_T}$cmod_cv_compiler_write_strings" >&6 if test $cmod_cv_compiler_write_strings = yes; then CFLAGS="$CFLAGS -Wwrite-strings" fi echo "$as_me:$LINENO: checking whether ${CC} accepts -Wstrict-prototypes" >&5 echo $ECHO_N "checking whether ${CC} accepts -Wstrict-prototypes... $ECHO_C" >&6 if test "${cmod_cv_compiler_strict_prototypes+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cmod_oldflags=$CFLAGS CFLAGS="$CFLAGS -Wstrict-prototypes" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cmod_cv_compiler_strict_prototypes=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cmod_cv_compiler_strict_prototypes=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext CFLAGS=$cmod_oldflags fi echo "$as_me:$LINENO: result: $cmod_cv_compiler_strict_prototypes" >&5 echo "${ECHO_T}$cmod_cv_compiler_strict_prototypes" >&6 if test $cmod_cv_compiler_strict_prototypes = yes; then CFLAGS="$CFLAGS -Wstrict-prototypes" fi echo "$as_me:$LINENO: checking whether ${CC} accepts -Wmissing-prototypes" >&5 echo $ECHO_N "checking whether ${CC} accepts -Wmissing-prototypes... $ECHO_C" >&6 if test "${cmod_cv_compiler_missing_prototypes+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cmod_oldflags=$CFLAGS CFLAGS="$CFLAGS -Wmissing-prototypes" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cmod_cv_compiler_missing_prototypes=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cmod_cv_compiler_missing_prototypes=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext CFLAGS=$cmod_oldflags fi echo "$as_me:$LINENO: result: $cmod_cv_compiler_missing_prototypes" >&5 echo "${ECHO_T}$cmod_cv_compiler_missing_prototypes" >&6 if test $cmod_cv_compiler_missing_prototypes = yes; then CFLAGS="$CFLAGS -Wmissing-prototypes" fi echo "$as_me:$LINENO: checking whether ${CC} accepts -Wmissing-declarations" >&5 echo $ECHO_N "checking whether ${CC} accepts -Wmissing-declarations... $ECHO_C" >&6 if test "${cmod_cv_compiler_missing_declarations+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cmod_oldflags=$CFLAGS CFLAGS="$CFLAGS -Wmissing-declarations" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cmod_cv_compiler_missing_declarations=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cmod_cv_compiler_missing_declarations=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext CFLAGS=$cmod_oldflags fi echo "$as_me:$LINENO: result: $cmod_cv_compiler_missing_declarations" >&5 echo "${ECHO_T}$cmod_cv_compiler_missing_declarations" >&6 if test $cmod_cv_compiler_missing_declarations = yes; then CFLAGS="$CFLAGS -Wmissing-declarations" fi echo "$as_me:$LINENO: checking whether ${CC} accepts -Wnested-externs" >&5 echo $ECHO_N "checking whether ${CC} accepts -Wnested-externs... $ECHO_C" >&6 if test "${cmod_cv_compiler_nested_externs+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cmod_oldflags=$CFLAGS CFLAGS="$CFLAGS -Wnested-externs" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cmod_cv_compiler_nested_externs=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cmod_cv_compiler_nested_externs=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext CFLAGS=$cmod_oldflags fi echo "$as_me:$LINENO: result: $cmod_cv_compiler_nested_externs" >&5 echo "${ECHO_T}$cmod_cv_compiler_nested_externs" >&6 if test $cmod_cv_compiler_nested_externs = yes; then CFLAGS="$CFLAGS -Wnested-externs" fi echo "$as_me:$LINENO: checking whether ${CC} accepts -pipe" >&5 echo $ECHO_N "checking whether ${CC} accepts -pipe... $ECHO_C" >&6 if test "${cmod_cv_compiler_pipe+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cmod_oldflags=$CFLAGS CFLAGS="$CFLAGS -pipe" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cmod_cv_compiler_pipe=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cmod_cv_compiler_pipe=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext CFLAGS=$cmod_oldflags fi echo "$as_me:$LINENO: result: $cmod_cv_compiler_pipe" >&5 echo "${ECHO_T}$cmod_cv_compiler_pipe" >&6 if test $cmod_cv_compiler_pipe = yes; then CFLAGS="$CFLAGS -pipe" fi fi if test $ac_cv_type_socklen_t = no then echo "$as_me:$LINENO: checking for socklen_t replacement type" >&5 echo $ECHO_N "checking for socklen_t replacement type... $ECHO_C" >&6 socklen_found= socklen_fallback= for socklen_type in "unsigned int" "size_t" "unsigned long" do echo lyskomd-socklen-test-$socklen_type >&5 cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { struct sockaddr addr; $socklen_type len; getsockname(0, &addr, &len); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then if sed "1,/lyskomd-socklen-test-$socklen_type/d" config.log | grep -i 'warning.*getsockname' >/dev/null then echo warnings found, not using $socklen_type >&5 if test -z "$socklen_fallback" then echo retaining $socklen_type as fallback >&5 socklen_fallback=$socklen_type fi else socklen_found=$socklen_type break fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 echo compilation failed, not using $socklen_type >&5 fi rm -f conftest.$ac_objext conftest.$ac_ext done if test -z "$socklen_found" then if test -z "$socklen_fallback" then socklen_fallback="unsigned int" fi socklen_found=$socklen_fallback echo "$as_me:$LINENO: result: unknown (using $socklen_found)" >&5 echo "${ECHO_T}unknown (using $socklen_found)" >&6 { echo "$as_me:$LINENO: WARNING: the choosen socklen_t may be wrong" >&5 echo "$as_me: WARNING: the choosen socklen_t may be wrong" >&2;} else echo "$as_me:$LINENO: result: $socklen_found" >&5 echo "${ECHO_T}$socklen_found" >&6 fi cat >>confdefs.h <<_ACEOF #define SOCKLEN_TYPE $socklen_found _ACEOF fi for ac_func in inet_ntop do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF else if test "$use_inet6" = 'yes'; then { echo "$as_me:$LINENO: WARNING: Proper decoding of IPv6 addresses requires inet_ntop" >&5 echo "$as_me: WARNING: Proper decoding of IPv6 addresses requires inet_ntop" >&2;} fi fi done for ac_func in inet_pton do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF else if test "$use_inet6" = 'yes'; then { echo "$as_me:$LINENO: WARNING: Proper encoding of IPv6 addresses requires inet_pton" >&5 echo "$as_me: WARNING: Proper encoding of IPv6 addresses requires inet_pton" >&2;} fi fi done for ac_func in getipnodebyname gethostbyname2 freehostent do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done echo "$as_me:$LINENO: checking for struct sockaddr_storage" >&5 echo $ECHO_N "checking for struct sockaddr_storage... $ECHO_C" >&6 if test "${ac_cv_type_struct_sockaddr_storage+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { if ((struct sockaddr_storage *) 0) return 0; if (sizeof (struct sockaddr_storage)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_struct_sockaddr_storage=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_struct_sockaddr_storage=no fi rm -f conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_struct_sockaddr_storage" >&5 echo "${ECHO_T}$ac_cv_type_struct_sockaddr_storage" >&6 if test $ac_cv_type_struct_sockaddr_storage = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_SOCKADDR_STORAGE 1 _ACEOF if test "$use_inet6" = 'yes'; then cat >>confdefs.h <<\_ACEOF #define USE_INET6 1 _ACEOF { echo "$as_me:$LINENO: IPv6 support is enabled" >&5 echo "$as_me: IPv6 support is enabled" >&6;} else { echo "$as_me:$LINENO: IPv6 support is disabled" >&5 echo "$as_me: IPv6 support is disabled" >&6;} fi else if test "$use_inet6" = 'yes'; then { { echo "$as_me:$LINENO: error: IPv6 support requires struct sockaddr_storage" >&5 echo "$as_me: error: IPv6 support requires struct sockaddr_storage" >&2;} { (exit 1); exit 1; }; } fi fi if test "$use_gcov" = "yes" -a -n "$GCC"; then echo "$as_me:$LINENO: checking whether ${CC} accepts -ftest-coverage" >&5 echo $ECHO_N "checking whether ${CC} accepts -ftest-coverage... $ECHO_C" >&6 if test "${cmod_cv_compiler_test_coverage+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cmod_oldflags=$CFLAGS CFLAGS="$CFLAGS -ftest-coverage" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cmod_cv_compiler_test_coverage=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cmod_cv_compiler_test_coverage=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext CFLAGS=$cmod_oldflags fi echo "$as_me:$LINENO: result: $cmod_cv_compiler_test_coverage" >&5 echo "${ECHO_T}$cmod_cv_compiler_test_coverage" >&6 if test $cmod_cv_compiler_test_coverage = yes; then CFLAGS="$CFLAGS -ftest-coverage" fi echo "$as_me:$LINENO: checking whether ${CC} accepts -fprofile-arcs" >&5 echo $ECHO_N "checking whether ${CC} accepts -fprofile-arcs... $ECHO_C" >&6 if test "${cmod_cv_compiler_profile_arcs+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cmod_oldflags=$CFLAGS CFLAGS="$CFLAGS -fprofile-arcs" cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cmod_cv_compiler_profile_arcs=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cmod_cv_compiler_profile_arcs=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext CFLAGS=$cmod_oldflags fi echo "$as_me:$LINENO: result: $cmod_cv_compiler_profile_arcs" >&5 echo "${ECHO_T}$cmod_cv_compiler_profile_arcs" >&6 if test $cmod_cv_compiler_profile_arcs = yes; then CFLAGS="$CFLAGS -fprofile-arcs" fi fi if test -n "$opt_level" -a "$opt_level" != "yes" ; then CFLAGS=`echo "$CFLAGS" | sed "s/-O[0-9]*//"` if test "$opt_level" != "no" ; then CFLAGS="$CFLAGS -O$opt_level" fi fi # Check for checker if test "$use_checker" = "yes" then for ac_prog in checker do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CHECKER+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CHECKER"; then ac_cv_prog_CHECKER="$CHECKER" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CHECKER="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CHECKER=$ac_cv_prog_CHECKER if test -n "$CHECKER"; then echo "$as_me:$LINENO: result: $CHECKER" >&5 echo "${ECHO_T}$CHECKER" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$CHECKER" && break done CC="checker $CC" LIBS="-lchkr_m $LIBS" fi ac_config_files="$ac_config_files Makefile src/Makefile man/Makefile doc/Makefile demo/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. { (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } | sed ' t clear : clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ : end' >>confcache if diff $cache_file confcache >/dev/null 2>&1; then :; else if test -w $cache_file; then test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" cat confcache >$cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/; s/:*\${srcdir}:*/:/; s/:*@srcdir@:*/:/; s/^\([^=]*=[ ]*\):*/\1/; s/:*$//; s/^[^=]*=[ ]*$//; }' fi # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then we branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. cat >confdef2opt.sed <<\_ACEOF t clear : clear s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g t quote s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g t quote d : quote s,[ `~#$^&*(){}\\|;'"<>?],\\&,g s,\[,\\&,g s,\],\\&,g s,\$,$$,g p _ACEOF # We use echo to avoid assuming a particular line-breaking character. # The extra dot is to prevent the shell from consuming trailing # line-breaks from the sub-command output. A line-break within # single-quotes doesn't work because, if this script is created in a # platform that uses two characters for line-breaks (e.g., DOS), tr # would break. ac_LF_and_DOT=`echo; echo .` DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` rm -f confdef2opt.sed ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_i=`echo "$ac_i" | sed 's/\$U\././;s/\.o$//;s/\.obj$//'` # 2. Add them. ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi # Support unset when possible. if (FOO=FOO; unset FOO) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" # Sed expression to map a string onto a valid variable name. as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH exec 6>&1 # Open the log real soon, to keep \$[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. Logging --version etc. is OK. exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX } >&5 cat >&5 <<_CSEOF This file was extended by isc $as_me 1.01, which was generated by GNU Autoconf 2.57. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ _CSEOF echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 echo >&5 _ACEOF # Files that config.status was made for. if test -n "$ac_config_files"; then echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS fi if test -n "$ac_config_headers"; then echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS fi if test -n "$ac_config_links"; then echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS fi if test -n "$ac_config_commands"; then echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS fi cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ isc config.status 1.01 configured by $0, generated by GNU Autoconf 2.57, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." srcdir=$srcdir INSTALL="$INSTALL" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "x$1" : 'x\([^=]*\)='` ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` ac_shift=: ;; -*) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; *) # This is not an option, so the user has probably given explicit # arguments. ac_option=$1 ac_need_defaults=false;; esac case $ac_option in # Handling of the options. _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --vers* | -V ) echo "$ac_cs_version"; exit 0 ;; --he | --h) # Conflict between --help and --header { { echo "$as_me:$LINENO: error: ambiguous option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; };; --help | --hel | -h ) echo "$ac_cs_usage"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # INIT-COMMANDS section. # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_config_target in $ac_config_targets do case "$ac_config_target" in # Handling of arguments. "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "man/Makefile" ) CONFIG_FILES="$CONFIG_FILES man/Makefile" ;; "doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "demo/Makefile" ) CONFIG_FILES="$CONFIG_FILES demo/Makefile" ;; "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason to put it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Create a temporary directory, and hook for its removal unless debugging. $debug || { trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./confstat$$-$RANDOM (umask 077 && mkdir $tmp) } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "\$CONFIG_FILES"; then # Protect against being on the right side of a sed subst in config.status. sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF s,@SHELL@,$SHELL,;t t s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t s,@exec_prefix@,$exec_prefix,;t t s,@prefix@,$prefix,;t t s,@program_transform_name@,$program_transform_name,;t t s,@bindir@,$bindir,;t t s,@sbindir@,$sbindir,;t t s,@libexecdir@,$libexecdir,;t t s,@datadir@,$datadir,;t t s,@sysconfdir@,$sysconfdir,;t t s,@sharedstatedir@,$sharedstatedir,;t t s,@localstatedir@,$localstatedir,;t t s,@libdir@,$libdir,;t t s,@includedir@,$includedir,;t t s,@oldincludedir@,$oldincludedir,;t t s,@infodir@,$infodir,;t t s,@mandir@,$mandir,;t t s,@build_alias@,$build_alias,;t t s,@host_alias@,$host_alias,;t t s,@target_alias@,$target_alias,;t t s,@DEFS@,$DEFS,;t t s,@ECHO_C@,$ECHO_C,;t t s,@ECHO_N@,$ECHO_N,;t t s,@ECHO_T@,$ECHO_T,;t t s,@LIBS@,$LIBS,;t t s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t s,@INSTALL_DATA@,$INSTALL_DATA,;t t s,@CYGPATH_W@,$CYGPATH_W,;t t s,@PACKAGE@,$PACKAGE,;t t s,@VERSION@,$VERSION,;t t s,@ACLOCAL@,$ACLOCAL,;t t s,@AUTOCONF@,$AUTOCONF,;t t s,@AUTOMAKE@,$AUTOMAKE,;t t s,@AUTOHEADER@,$AUTOHEADER,;t t s,@MAKEINFO@,$MAKEINFO,;t t s,@AMTAR@,$AMTAR,;t t s,@install_sh@,$install_sh,;t t s,@STRIP@,$STRIP,;t t s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t s,@AWK@,$AWK,;t t s,@SET_MAKE@,$SET_MAKE,;t t s,@am__leading_dot@,$am__leading_dot,;t t s,@AR@,$AR,;t t s,@CC@,$CC,;t t s,@CFLAGS@,$CFLAGS,;t t s,@LDFLAGS@,$LDFLAGS,;t t s,@CPPFLAGS@,$CPPFLAGS,;t t s,@ac_ct_CC@,$ac_ct_CC,;t t s,@EXEEXT@,$EXEEXT,;t t s,@OBJEXT@,$OBJEXT,;t t s,@DEPDIR@,$DEPDIR,;t t s,@am__include@,$am__include,;t t s,@am__quote@,$am__quote,;t t s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t s,@CCDEPMODE@,$CCDEPMODE,;t t s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t s,@CPP@,$CPP,;t t s,@EGREP@,$EGREP,;t t s,@RANLIB@,$RANLIB,;t t s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t s,@LIBOBJS@,$LIBOBJS,;t t s,@CHECKER@,$CHECKER,;t t s,@LTLIBOBJS@,$LTLIBOBJS,;t t CEOF _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_lines=48 ac_sed_frag=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_lines # Line after last line for current file. ac_more_lines=: ac_sed_cmds= while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag else sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag fi if test ! -s $tmp/subs.frag; then ac_more_lines=false else # The purpose of the label and of the branching condition is to # speed up the sed processing (if there are no `@' at all, there # is no need to browse any of the substitutions). # These are the two extra sed commands mentioned above. (echo ':t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" else ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" fi ac_sed_frag=`expr $ac_sed_frag + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_lines` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi fi # test -n "$CONFIG_FILES" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case $ac_file in - | *:- | *:-:* ) # input from stdin cat >$tmp/stdin ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; * ) ac_file_in=$ac_file.in ;; esac # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be # absolute. ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_builddir$INSTALL ;; esac if test x"$ac_file" != x-; then { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} rm -f "$ac_file" fi # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ if test x"$ac_file" = x-; then configure_input= else configure_input="$ac_file. " fi configure_input=$configure_input"Generated from `echo $ac_file_in | sed 's,.*/,,'` by configure." # First look for the input files in the build tree, otherwise in the # src tree. ac_file_inputs=`IFS=: for f in $ac_file_in; do case $f in -) echo $tmp/stdin ;; [\\/$]*) # Absolute (can't be DOS-style, as IFS=:) test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } echo $f;; *) # Relative if test -f "$f"; then # Build tree echo $f elif test -f "$srcdir/$f"; then # Source tree echo $srcdir/$f else # /dev/null tree { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } fi;; esac done` || { (exit 1); exit 1; } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s,@configure_input@,$configure_input,;t t s,@srcdir@,$ac_srcdir,;t t s,@abs_srcdir@,$ac_abs_srcdir,;t t s,@top_srcdir@,$ac_top_srcdir,;t t s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t s,@builddir@,$ac_builddir,;t t s,@abs_builddir@,$ac_abs_builddir,;t t s,@top_builddir@,$ac_top_builddir,;t t s,@abs_top_builddir@,$ac_abs_top_builddir,;t t s,@INSTALL@,$ac_INSTALL,;t t " $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out rm -f $tmp/stdin if test x"$ac_file" != x-; then mv $tmp/out $ac_file else cat $tmp/out rm -f $tmp/out fi done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # # CONFIG_COMMANDS section. # for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue ac_dest=`echo "$ac_file" | sed 's,:.*,,'` ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_dir=`(dirname "$ac_dest") 2>/dev/null || $as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_dest" : 'X\(//\)[^/]' \| \ X"$ac_dest" : 'X\(//\)$' \| \ X"$ac_dest" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_dest" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be # absolute. ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 echo "$as_me: executing $ac_dest commands" >&6;} case $ac_dest in depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # So let's grep whole file. if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then dirpart=`(dirname "$mf") 2>/dev/null || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` else continue fi grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue # Extract the definition of DEP_FILES from the Makefile without # running `make'. DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"` test -z "$DEPDIR" && continue # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n -e '/^U = / s///p' < "$mf"` test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" # We invoke sed twice because it is the simplest approach to # changing $(DEPDIR) to its actual value in the expansion. for file in `sed -n -e ' /^DEP_FILES = .*\\\\$/ { s/^DEP_FILES = // :loop s/\\\\$// p n /\\\\$/ b loop p } /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`(dirname "$file") 2>/dev/null || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p $dirpart/$fdir else as_dir=$dirpart/$fdir as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5 echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;} { (exit 1); exit 1; }; }; } # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ;; esac done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi lyskom-server-2.1.2/src/libraries/libisc-new/configure.in0000664000015100472110000001650007712320223017125 dnl ISC - networking library dnl Copyright (C) 1998-1999, 2001 by Peter Eriksson and Per Cederqvist of the dnl Lysator Academic Computer Association. dnl dnl dnl This library is free software; you can redistribute it and/or dnl modify it under the terms of the GNU Library General Public dnl License as published by the Free Software Foundation; either dnl version 2 of the License, or (at your option) any later version. dnl dnl This library is distributed in the hope that it will be useful, dnl but WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU dnl Library General Public License for more details. dnl dnl You should have received a copy of the GNU Library General Public dnl License along with this library; if not, write to the Free dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA dnl Process this file with autoconf to produce a configure script. AC_REVISION($Revision: 1.24 $)dnl AC_PREREQ(2.56) AC_INIT([isc],[1.01]) AC_CONFIG_SRCDIR([src/isc_master.c]) AM_INIT_AUTOMAKE(isc, 1.01) AC_ARG_WITH([checker], AC_HELP_STRING([--with-checker], [compile with Gnu Checker]), [use_checker=$withval], [use_checker=no]) AC_ARG_WITH([gcov], AC_HELP_STRING([--with-gcov], [instrument for gcov (requires gcc)]), [use_gcov=$withval], [use_gcov=no]) AC_ARG_WITH([optimization], AC_HELP_STRING([--without-optimization], [turn off optimization (default on)]) AC_HELP_STRING([--with-optimization@<:@=N@:>@],[specify level of optimization]), [opt_level=$withval], [opt_level=""]) AC_ARG_ENABLE([ipv6], AC_HELP_STRING([--enable-ipv6], [enable IPv6 support]), [use_inet6=yes], [use_inet6=no]) AC_ARG_ENABLE([malloc-guards], AC_HELP_STRING([--disable-malloc-guards], [disable defensive guard areas (may crash lyskomd)]), [use_malloc_guards=$enableval], [use_malloc_guards=yes]) [if test "$use_malloc_guards" = "yes" then] AC_DEFINE([USE_MALLOC_GUARDS], 1, [Insert magic number before and after malloced areas. This can help detect buffer overruns.]) [fi] dnl Checks for programs. AC_PATH_PROG([AR], [ar], [notfound], [$PATH$PATH_SEPARATOR/usr/ccs/bin]) AC_ARG_VAR([AR], [ar program to use]) [if test "$AR" = "notfound"; then] AC_MSG_ERROR([cannot find ``ar'']) [fi] AC_PROG_CC AC_AIX AC_ISC_POSIX AC_MINIX AC_PROG_RANLIB dnl Checks for libraries. dnl Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS(stdlib.h stdarg.h stddef.h string.h sys/select.h unistd.h) AC_CHECK_HEADERS(sys/time.h stdint.h strings.h) dnl Checks for typedefs, structures, and compiler characteristics. AM_PROG_CC_STDC AC_HEADER_TIME AC_C_CONST AC_C_INLINE AC_TYPE_SIZE_T AC_CHECK_TYPE([socklen_t],AC_DEFINE([HAVE_SOCKLEN_T]),,[ #include #include ]) dnl Low-level networking code on Solaris 2. AC_CHECK_FUNC(gethostbyname) [if test $ac_cv_func_gethostbyname = no then] AC_CHECK_LIB(nsl, gethostbyname) [fi] dnl socket() et c on Solaris 2. AC_CHECK_FUNC(socket) [if test $ac_cv_func_socket = no then] AC_CHECK_LIB(socket, socket) [fi] AC_REPLACE_FUNCS(inet_aton) [if test $ac_cv_func_inet_aton = no then] AC_CHECK_DECL([INADDR_NONE],, AC_DEFINE([INADDR_NONE],[((uint32_t)-1)], [Error indicator for inet_addr]), [#include ]) [fi] dnl AC_CHECK_TYPE([uint32_t],AC_DEFINE([HAVE_UINT32_T]),,[ #include #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif ]) [if test $ac_cv_type_uint32_t = no then] AC_CHECK_SIZEOF(int) AC_CHECK_SIZEOF(long) [fi] AC_CHECK_TYPE(intptr_t) AC_CHECK_TYPE(intmax_t) AC_CHECK_TYPE(size_t) CMOD_C_WORKING_ATTRIBUTE_UNUSED [if test -n "$GCC"; then] dnl "-Wtraditional" isn't really useful: we don't support dnl pre-c89-compilers. [CFLAGS="$CFLAGS -Wall -W -Wshadow"] CMOD_CHECK_CC_OPT([-Wbad-function-cast], [bad_function_cast]) CMOD_CHECK_CC_OPT([-Wcast-qual], [cast_qual]) CMOD_CHECK_CC_OPT([-Wcast-align], [cast_align]) CMOD_CHECK_CC_OPT([-Wwrite-strings], [write_strings]) CMOD_CHECK_CC_OPT([-Wstrict-prototypes], [strict_prototypes]) CMOD_CHECK_CC_OPT([-Wmissing-prototypes], [missing_prototypes]) CMOD_CHECK_CC_OPT([-Wmissing-declarations], [missing_declarations]) CMOD_CHECK_CC_OPT([-Wnested-externs], [nested_externs]) CMOD_CHECK_CC_OPT([-pipe], [pipe]) [fi] dnl This test is complex. We want to find a type that can be used dnl as socklen_t and that gives no compiler warnings. There is no dnl builtin support in autoconf for this. So we peek inside the dnl config.log file... dnl FIXME (bug 765): This computation should be cached. [if test $ac_cv_type_socklen_t = no then] AC_MSG_CHECKING([for socklen_t replacement type]) [socklen_found= socklen_fallback= for socklen_type in "unsigned int" "size_t" "unsigned long" do] echo lyskomd-socklen-test-$socklen_type >&5 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include ]], [[ struct sockaddr addr; $socklen_type len; getsockname(0, &addr, &len);]])], [ if sed "1,/lyskomd-socklen-test-$socklen_type/d" config.log | grep -i 'warning.*getsockname' >/dev/null then echo warnings found, not using $socklen_type >&5 if test -z "$socklen_fallback" then echo retaining $socklen_type as fallback >&5 socklen_fallback=$socklen_type fi else socklen_found=$socklen_type break fi], [echo compilation failed, not using $socklen_type >&5]) [done if test -z "$socklen_found" then if test -z "$socklen_fallback" then socklen_fallback="unsigned int" fi] socklen_found=$socklen_fallback AC_MSG_RESULT([unknown (using $socklen_found)]) AC_MSG_WARN([the choosen socklen_t may be wrong]) [else] AC_MSG_RESULT([$socklen_found]) [fi] AC_DEFINE_UNQUOTED([SOCKLEN_TYPE], $socklen_found, [socklen_t-compatible type]) [fi] dnl Checks for IPv6 support AC_CHECK_FUNCS(inet_ntop, , [if test "$use_inet6" = 'yes'; then] AC_MSG_WARN(Proper decoding of IPv6 addresses requires inet_ntop) [fi] ) AC_CHECK_FUNCS(inet_pton, , [if test "$use_inet6" = 'yes'; then] AC_MSG_WARN(Proper encoding of IPv6 addresses requires inet_pton) [fi] ) AC_CHECK_FUNCS(getipnodebyname gethostbyname2 freehostent) AC_CHECK_TYPES(struct sockaddr_storage, [if test "$use_inet6" = 'yes'; then] AC_DEFINE(USE_INET6) AC_MSG_NOTICE([IPv6 support is enabled]) [else] AC_MSG_NOTICE([IPv6 support is disabled]) [fi], [if test "$use_inet6" = 'yes'; then] AC_MSG_ERROR([IPv6 support requires struct sockaddr_storage]) [fi], [#include ]) [if test "$use_gcov" = "yes" -a -n "$GCC"; then] CMOD_CHECK_CC_OPT([-ftest-coverage], [test_coverage]) CMOD_CHECK_CC_OPT([-fprofile-arcs], [profile_arcs]) [fi] [if test -n "$opt_level" -a "$opt_level" != "yes" ; then CFLAGS=`echo "$CFLAGS" | sed "s/-O[0-9]*//"` if test "$opt_level" != "no" ; then CFLAGS="$CFLAGS -O$opt_level" fi fi] # Check for checker [if test "$use_checker" = "yes" then] AC_CHECK_PROGS(CHECKER, checker) [ CC="checker $CC" LIBS="-lchkr_m $LIBS" ] [fi] AC_CONFIG_FILES([ Makefile src/Makefile man/Makefile doc/Makefile demo/Makefile ]) AC_OUTPUT lyskom-server-2.1.2/src/libraries/libisc-new/depcomp0000755000015100000310000003256107716517055016200 #! /bin/sh # depcomp - compile a program generating dependencies as side-effects # Copyright 1999, 2000 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # `libtool' can also be set to `yes' or `no'. if test -z "$depfile"; then base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'` dir=`echo "$object" | sed 's,/.*$,/,'` if test "$dir" = "$object"; then dir= fi # FIXME: should be _deps on DOS. depfile="$dir.deps/$base" fi tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> $depfile echo >> $depfile # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> $depfile else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. This file always lives in the current directory. # Also, the AIX compiler puts `$object:' at the start of each line; # $object doesn't have directory information. stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'` tmpdepfile="$stripped.u" outname="$stripped.o" if test "$libtool" = yes; then "$@" -Wc,-M else "$@" -M fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi if test -f "$tmpdepfile"; then # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; icc) # Intel's C compiler understands `-MD -MF file'. However on # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c # ICC 7.0 will fill foo.d with something like # foo.o: sub/foo.c # foo.o: sub/foo.h # which is wrong. We want: # sub/foo.o: sub/foo.c # sub/foo.o: sub/foo.h # sub/foo.c: # sub/foo.h: # ICC 7.1 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using \ : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1="$dir.libs/$base.lo.d" tmpdepfile2="$dir.libs/$base.d" "$@" -Wc,-MD else tmpdepfile1="$dir$base.o.d" tmpdepfile2="$dir$base.d" "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi if test -f "$tmpdepfile1"; then tmpdepfile="$tmpdepfile1" else tmpdepfile="$tmpdepfile2" fi if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a space and a tab in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for `:' # in the target name. This is to cope with DOS-style filenames: # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. "$@" $dashmflag | sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # X makedepend shift cleared=no for arg in "$@"; do case $cleared in no) set ""; shift cleared=yes ;; esac case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix="`echo $object | sed 's/^.*\././'`" touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E | sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. "$@" || exit $? IFS=" " for arg do case "$arg" in "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 lyskom-server-2.1.2/src/libraries/libisc-new/install-sh0000775000015100472110000001273606712622540016635 #!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: chmodcmd="" else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 lyskom-server-2.1.2/src/libraries/libisc-new/missing0000775000015100472110000002123107353345253016223 #! /bin/sh # Common stub for a few missing GNU programs while installing. # Copyright 1996, 1997, 1999, 2000 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi case "$1" in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case "$1" in -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch]" ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing 0.3 - GNU automake" ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; aclocal) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case "$f" in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.h fi ;; esac fi if [ ! -f y.tab.h ]; then echo >y.tab.h fi if [ ! -f y.tab.c ]; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if [ ! -f lex.yy.c ]; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` fi if [ -f "$file" ]; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then # We have makeinfo, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` fi touch $file ;; tar) shift if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 fi # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar ${1+"$@"} && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar ${1+"$@"} && exit 0 fi firstarg="$1" if shift; then case "$firstarg" in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" ${1+"$@"} && exit 0 ;; esac case "$firstarg" in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" ${1+"$@"} && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequirements for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 lyskom-server-2.1.2/src/libraries/libisc-new/mkinstalldirs0000775000015100472110000000132706712622542017433 #! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain # $Id: mkinstalldirs,v 1.1.1.2 1999/05/01 16:01:38 ceder Exp $ errstatus=0 for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr fi fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here lyskom-server-2.1.2/src/libraries/libisc-new/.cvsignore0000664000015100472110000000015607451137237016627 Makefile Makefile.in aclocal.m4 autom4te.cache config.cache config.log config.status configure gmon.out isc-* lyskom-server-2.1.2/src/libraries/libisc-new/README.DEVO0000664000015100472110000000043707353345254016246 If you got this code by checking it out from the CVS repository of Lysator, you have to perform a few commands before following the instructions in INSTALL: ./bootstrap.sh This requires that the following programs are installed: automake-1.5 (or better) autoconf-2.52 (or better) lyskom-server-2.1.2/src/libraries/libisc-new/RELEASING0000664000015100472110000000217407353345254016066 How to make a release of isc: * Change the version number in the AM_INIT_AUTOMAKE macro in configure.in. * Change the version number in the AC_INIT macro in configure.in. * Update the year in all copyright statements. * Update README.DEVO, especially the versions of the various tools used. * Update NEWS if this is a full release. * Ensure that all documentation is up to date, or that README says that it isn't. * Write a note in ChangeLog. * Commit all code. * Run these commands to ensure that all generated files are up-to-date: ./bootstrap.sh ./configure make distcheck * Test the resulting archive on several architectures. If any problems are found, fix them, and start from the beginning. This step may be skipped if this is a snapshot release, or if there is no test suite written yet. * Set a CVS tag. Full release are tagged like this: cvs tag isc_0_99_final Snapshot releases are tagged like this: cvs tag isc_0_99_post_1 * Move the tar file to ftp://ftp.lysator.liu.se/pub/unix/isc/ aka /lysator/ftp/pub/unix/isc/ * Announce the release in the following forums: - The LysKOM conference "ISC internals". lyskom-server-2.1.2/src/libraries/libisc-new/src/0000777000015100472110000000000007723710313015470 5lyskom-server-2.1.2/src/libraries/libisc-new/src/isc.h0000664000015100472110000001721307714123665016351 /* ** isc.h structures and defines used in a ISC server ** ** Copyright (C) 1991, 1996, 1998-1999, 2001 by Peter Eriksson and ** Per Cederqvist of the Lysator Academic Computer Association. ** ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library 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 ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the Free ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ** ** history: ** 910306 pen major overhaul ** 910307 pen type name changes, changes in structs.. ** 920207 pen updated ** (See ChangeLog for recent history) */ #ifndef __ISC_H__ #define __ISC_H__ /* ** Give the poor user a chance to change it */ #ifndef ISC_UDGTYPE # define ISC_UDGTYPE void #endif /* Forward declarations. */ struct isc_mcb; struct isc_scb; /* * Callback function types. */ /* When a new TCP client conntects. */ typedef void *isc_accept_callback(struct isc_scb *cb_accepting_session, struct isc_scb *cb_new_session); typedef void isc_write_error_cb(struct isc_scb *cb_session, int saved_errno); typedef void isc_stale_output_cb(struct isc_scb *cb_session); typedef void isc_write_queue_change_cb(int delta_bytes); enum isc_resolve_status { isc_resolve_ok, /* Name successfully looked up. */ isc_resolve_h_errno, /* Failed. h_errno value passed in errcode. */ isc_resolve_adns_error, /* Failed. status value passed in errcode. */ isc_resolve_aborted, /* Session is being killed and no reply yet. */ }; /* The errcode is valid when res indicates so. */ typedef void *isc_resolve_done_cb(struct isc_scb *scb, enum isc_resolve_status res, long errcode); /* ** The different session states */ enum isc_session_state { ISC_STATE_RUNNING, ISC_STATE_DISABLED, ISC_STATE_CLOSING, ISC_STATE_LISTENING, }; /* ** Session control structure */ union isc_address; struct isc_scb { int fd; union isc_address *raddr; union isc_address *laddr; String remote; /* See isc_resolve_remote(). */ ISC_UDGTYPE * udg; /* User defined garbage :-) */ struct isc_mcb *master; }; /* ** Setup a set of functions to handle memory allocation */ extern void isc_setallocfn(void * (*mallocfn)(size_t size), void * (*reallocfn)(void * buf, size_t size), void (*freefn)(void * buf)); /* ** This routine will setup the ISC subsystem */ extern struct isc_mcb * isc_initialize(oop_source *, isc_write_queue_change_cb *); extern void isc_cfg_fd_relocate(struct isc_mcb *, int fd_relocate); /* ** Configure timeouts for when a client will be disconnected. If the ** output buffer is full and nothing can be written to the cilent for ** a period longer than STALE the client will be disconnected. If ** nothing is written to it for a period longer than DEFAULT_IDLE, it ** will be disconnected. DEFAULT_IDLE must always be larger than ** STALE. ** ** The client is actually not disconnected by ISC. Instead, one of ** the callback functions stale_output_cb and idle_cb, registered with ** isc_set_read_callback(), will be called when the condition occurs. ** It should make sure that the client is closed (but it need not do ** so right away). */ extern void isc_cfg_stale_timeout(struct isc_mcb *, struct timeval stale, struct timeval default_idle); extern void isc_cfg_queue_size(struct isc_mcb *, int max_queue_size_bytes, int max_msg_size, int max_queue_size_msgs, int max_dequeue_msgs); /* ** Shut down all sessions associated with an ISC Master Control Block ** and deallocate all storage used by the MCB. */ extern void isc_shutdown(struct isc_mcb * mcb); /* ** Establish a TCP port to listen for connections at */ extern struct isc_scb * isc_listentcp(struct isc_mcb * mcb, const char * address, const char * service, isc_accept_callback *cb); /* ** The callback function supplied to isc_listentcp can call this ** function to install a callback that will be called when data is ** available on the new socket. */ extern void isc_set_read_callback(struct isc_scb *session, oop_call_fd *data_available_cb, isc_write_error_cb *write_error_cb, isc_stale_output_cb *stale_output_cb, isc_stale_output_cb *idle_cb); /* ** Dynamically change the acceptable idle timeout of a session. This ** can be used to increase the timeout once the initial handshake is ** complete, or once the user has logged on. (It could even be used ** to lower it if a certain person logs on... -- I'm talking about ** robots whose sessions should be short-lived, of course.) */ extern void isc_set_acceptable_idle(struct isc_scb *session, struct timeval acceptable); extern int isc_destroy(struct isc_mcb * mcb, struct isc_scb * scb); /* ** Read data from a session into the end of a string. The first ** UNUSED bytes of the string are unused, and may be reused. */ enum isc_read_result { ISC_READ_DATA, ISC_READ_LOGOUT, ISC_READ_WOULDBLOCK, ISC_READ_ERROR, /* read() failed unexpectedly -- see errno. */ ISC_READ_NOMEM, /* out of memory. */ }; extern enum isc_read_result isc_read_data(struct isc_scb *scb, String *result, String_size *unused); /* ** Flush the transmit queue for a specific session. ** Unless this function is called, the output might remain in the ** output buffer forever. */ extern void isc_flush(struct isc_scb * scb); /* ** Put a buffer on the transmit queue for a session */ extern int isc_write(struct isc_scb *scb, const void * buffer, size_t length); /* ** Put a single character on the transmit queue */ extern int isc_putc(int chr, struct isc_scb *scb); /* ** Put a NUL-terminated string on the transmit queue (the NUL is not sent). */ extern int isc_puts(const char *str, struct isc_scb *scb); /* ** Put a decimal representation of ``nr'' on the transmit queue. */ extern int isc_putul(unsigned long nr, struct isc_scb *scb); /* ** Enable a previously disabled session */ extern int isc_enable(struct isc_scb *scb); /* ** Disable a session. The session will not generate read events, but ** any enqueued output will still be sent to the remote host. */ extern int isc_disable(struct isc_scb *scb); union isc_address * isc_mktcpaddress(const char *address, const char *service); int isc_addressfamily(union isc_address *); int isc_addresssize(union isc_address *); struct sockaddr * isc_addresspointer(union isc_address *ia); extern void isc_freeaddress(union isc_address *addr); extern char * isc_getipnum(union isc_address *ia, char *address, int len); /* Start to make a reverse DNS lookup on the remote host. Once the lookup completes, store the result in scb->remote and call the callback. If the lookup fails, a printable representation of the IP address will be stored in scb->remote and the callback will be called with res set to something other than isc_resolve_ok. Returns 0 on success, or an error code defined by adns on error. */ extern int isc_resolve_remote(struct isc_scb *scb, isc_resolve_done_cb *callback); extern int isc_getportnum(union isc_address *ia); extern oop_source * isc_getoopsource(struct isc_scb *scb); #endif /* __ISC_H__ */ lyskom-server-2.1.2/src/libraries/libisc-new/src/Makefile.am0000664000015100472110000000266107714127116017452 # ISC - networking library # Copyright (C) 1998-1999 by Peter Eriksson and Per Cederqvist of the # Lysator Academic Computer Association. # # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library 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 # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the Free # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## Process this file with automake to produce Makefile.in noinst_LIBRARIES = libisc.a libisc_a_SOURCES = \ isc_event.c isc_session.c isc_abort.c isc_alloc.c isc_master.c \ isc_output.c isc_queue.c isc_message.c \ isc_stdout.c isc_socket.c isc_tcp.c unused.h intern.h \ isc_relocate.c isc_compat.c isc_addr.h noinst_HEADERS = isc.h EXTRA_DIST = .cvsignore MAINTAINERCLEANFILES = Makefile.in MOSTLYCLEANFILES = *.da *.bb *.gcov *.bbg AM_CPPFLAGS = \ -I$(srcdir)/../../libmisc \ -I$(srcdir)/../../liboop \ -I$(srcdir)/../../adns/src \ -I$(srcdir)/../../../include lyskom-server-2.1.2/src/libraries/libisc-new/src/Makefile.in0000664000015100472110000003271007723707451017467 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # ISC - networking library # Copyright (C) 1998-1999 by Peter Eriksson and Per Cederqvist of the # Lysator Academic Computer Association. # # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library 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 # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the Free # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ prefix = @prefix@ program_transform_name = @program_transform_name@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ noinst_LIBRARIES = libisc.a libisc_a_SOURCES = \ isc_event.c isc_session.c isc_abort.c isc_alloc.c isc_master.c \ isc_output.c isc_queue.c isc_message.c \ isc_stdout.c isc_socket.c isc_tcp.c unused.h intern.h \ isc_relocate.c isc_compat.c isc_addr.h noinst_HEADERS = isc.h EXTRA_DIST = .cvsignore MAINTAINERCLEANFILES = Makefile.in MOSTLYCLEANFILES = *.da *.bb *.gcov *.bbg AM_CPPFLAGS = \ -I$(srcdir)/../../libmisc \ -I$(srcdir)/../../liboop \ -I$(srcdir)/../../adns/src \ -I$(srcdir)/../../../include subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) libisc_a_AR = $(AR) cru libisc_a_LIBADD = am_libisc_a_OBJECTS = isc_event.$(OBJEXT) isc_session.$(OBJEXT) \ isc_abort.$(OBJEXT) isc_alloc.$(OBJEXT) isc_master.$(OBJEXT) \ isc_output.$(OBJEXT) isc_queue.$(OBJEXT) isc_message.$(OBJEXT) \ isc_stdout.$(OBJEXT) isc_socket.$(OBJEXT) isc_tcp.$(OBJEXT) \ isc_relocate.$(OBJEXT) isc_compat.$(OBJEXT) libisc_a_OBJECTS = $(am_libisc_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/isc_abort.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/isc_alloc.Po ./$(DEPDIR)/isc_compat.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/isc_event.Po ./$(DEPDIR)/isc_master.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/isc_message.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/isc_output.Po ./$(DEPDIR)/isc_queue.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/isc_relocate.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/isc_session.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/isc_socket.Po ./$(DEPDIR)/isc_stdout.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/isc_tcp.Po COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ DIST_SOURCES = $(libisc_a_SOURCES) HEADERS = $(noinst_HEADERS) DIST_COMMON = $(noinst_HEADERS) Makefile.am Makefile.in SOURCES = $(libisc_a_SOURCES) all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libisc.a: $(libisc_a_OBJECTS) $(libisc_a_DEPENDENCIES) -rm -f libisc.a $(libisc_a_AR) libisc.a $(libisc_a_OBJECTS) $(libisc_a_LIBADD) $(RANLIB) libisc.a mostlyclean-compile: -rm -f *.$(OBJEXT) core *.core distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isc_abort.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isc_alloc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isc_compat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isc_event.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isc_master.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isc_message.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isc_output.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isc_queue.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isc_relocate.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isc_session.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isc_socket.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isc_stdout.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isc_tcp.Po@am__quote@ distclean-depend: -rm -rf ./$(DEPDIR) .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ @am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ @am__fastdepCC_TRUE@ fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< .c.obj: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ @am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ @am__fastdepCC_TRUE@ fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` uninstall-info-am: ETAGS = etags ETAGSFLAGS = CTAGS = ctags CTAGSFLAGS = tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$tags$$unique" \ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = .. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) $(HEADERS) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am distclean-am: clean-am distclean-compile distclean-depend \ distclean-generic distclean-tags dvi: dvi-am dvi-am: info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags distclean distclean-compile \ distclean-depend distclean-generic distclean-tags distdir dvi \ dvi-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/src/libraries/libisc-new/src/isc_event.c0000664000015100472110000000714707722446224017550 /* ** isc_event.c definitions of ISC subsystem routines ** ** Copyright (C) 1990-1992, 1996, 1998-1999 by Peter Eriksson and ** Per Cederqvist of the Lysator Academic Computer Association. ** ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library 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 ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the Free ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ** ** history: ** 900403 pen initial coding. ** 900612 pen rewrote the message buffering. ** 901102 pen fixed bug in isc_gethostname(). ** 910303 ceder clean up. Removed everything that is lyskom-specific. ** 910304 pen really removed everything lyskom-specific.. :-) ** 920129 pen added support for "lazy" connect ** 920805 pen one unneccessary isc_pollqueue() removed. ** (See ChangeLog for recent history) */ #include #ifdef HAVE_STDARG_H # include #endif #ifdef TIME_WITH_SYS_TIME # include # include #else # ifdef HAVE_SYS_TIME_H # include # else # include # endif #endif #include #include #include #ifdef HAVE_STDDEF_H # include #endif #ifdef HAVE_SYS_SELECT_H # include #endif #ifdef HAVE_UNISTD_H # include /* Needed on NetBSD1.1/SPARC due to select */ #endif #ifdef HAVE_STRING_H # include /* Needed on NetBSD1.1/SPARC due to bzero */ #endif #ifdef HAVE_STRINGS_H # include /* Needed on AIX 4.2 due to bzero */ #endif #include "oop.h" #include "adns.h" #include "oop-adns.h" #include "s-string.h" #include "isc.h" #include "intern.h" enum isc_read_result isc_read_data(struct isc_scb *scb_pub, String *result, String_size *unused) { void *buf; ssize_t status; struct isc_scb_internal *scb = (struct isc_scb_internal *)scb_pub; /* No output queue? This could only happen if trying to read from a connection that has returned an error, but fail safe. */ if (scb->wr_msg_q == NULL) return ISC_READ_WOULDBLOCK; /* Too many queued blocks? Don't read any more data, until the client has read the output we have already produced. */ if (isc_sizequeue(scb->wr_msg_q) >= scb->cfg->max.queuedsize) return ISC_READ_WOULDBLOCK; /* Too many bytes? */ if (scb->wr_msg_q->bytes >= scb->cfg->max.queuedsize_bytes) return ISC_READ_WOULDBLOCK; if (*unused * 2 > s_strlen(*result)) { if (s_trim_left(result, *unused) != OK) return ISC_READ_NOMEM; *unused = 0; } buf = s_reserve(result, scb->pub.master->scfg->max.msgsize); if (buf == NULL) return ISC_READ_NOMEM; do { status = read(scb->pub.fd, buf, scb->pub.master->scfg->max.msgsize); } while (status < 0 && errno == EINTR); if (status == 0) { s_reserve_done(result, 0); return ISC_READ_LOGOUT; } if (status < 0) { s_reserve_done(result, 0); if (errno == EAGAIN || errno == EWOULDBLOCK) return ISC_READ_WOULDBLOCK; return ISC_READ_ERROR; } s_reserve_done(result, status); return ISC_READ_DATA; } lyskom-server-2.1.2/src/libraries/libisc-new/src/isc_session.c0000664000015100472110000002537407722446224020114 /* ** isc_session.c Routines to handle ISC sessions ** ** Copyright (C) 1991-1993, 1998-1999, 2001 by Peter Eriksson and ** Per Cederqvist of the Lysator Academic Computer Association. ** ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library 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 ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the Free ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ** ** history: ** 910305 pen moved into separate file ** 920129 pen added support for "lazy" connect() ** 920209 pen reworked some of the code ** 920209 pen TCP and UDP specific code removed. ** 930117 pen Two memory leak bugs fixed (found by Ceder) ** (See ChangeLog for recent history) */ #include #include #include #include #ifdef HAVE_STDDEF_H # include #endif #ifdef HAVE_STDARG_H # include #endif #include #ifndef NULL # include #endif #ifdef HAVE_UNISTD_H # include #endif #include #include "oop.h" #include "adns.h" #include "oop-adns.h" #include "s-string.h" #include "timeval-util.h" #include "isc.h" #include "intern.h" #include "unused.h" static oop_call_time stale_cb; /* ** Insert a session into a master control structure */ void isc_insert(struct isc_mcb *mcb, struct isc_scb_internal *scb) { struct isc_scb_entry *isl; ISC_XNEW(isl); isl->scb = scb; /* Better check if this is the first session or not */ if (mcb->sessions != NULL) { isl->next = mcb->sessions; isl->prev = mcb->sessions->prev; isl->prev->next = isl; mcb->sessions->prev = isl; } else { isl->next = isl; isl->prev = isl; } mcb->sessions = isl; } /* ** Locate a session list entry in a MCB */ static struct isc_scb_entry * isc_findsession(struct isc_mcb *mcb, struct isc_scb_internal *scb) { struct isc_scb_entry *isl; /* Locate the session in the MCB */ for (isl = mcb->sessions; isl != NULL && isl->scb != scb; isl = isl->next) if (isl->next == mcb->sessions) break; /* Not found? Return -1 */ if (isl == NULL || isl->scb != scb) return NULL; return isl; } /* ** Remove a session from a master control structure */ int isc_remove(struct isc_mcb *mcb, struct isc_scb_internal *scb) { struct isc_scb_entry *isl; isl = isc_findsession(mcb, scb); if (!isl) { errno = ENOENT; return -1; } /* Remove it from the list of sessions if it is still on it */ if (isl->prev != NULL) { if (isl->next != isl) { /* Make sure noone references this session */ if (mcb->sessions == isl) mcb->sessions = isl->next; isl->prev->next = isl->next; isl->next->prev = isl->prev; } else { /* This was the last session on the circular list. */ mcb->sessions = NULL; } isl->prev = NULL; isl->next = NULL; } isc_free(isl); return 0; } /* ** Create a new session structure. */ struct isc_scb_internal * isc_create(struct isc_mcb *mcb, struct isc_session_cfg *cfg, enum isc_session_state initial_state) { struct isc_scb_internal * scb; ISC_XNEW(scb); scb->pub.fd = -1; scb->state = initial_state; scb->wr_msg_q = NULL; scb->accept_cb= NULL; scb->write_cb_registered = 0; scb->stale_output_cb_registered = 0; scb->idle_cb_registered = 0; scb->data_available_registered = 0; scb->data_available_callback = NULL; scb->stale_output_cb = NULL; scb->acceptable_idle_time = cfg->idle_timeout; scb->resolve_callback = NULL; scb->adns_query = NULL; scb->pub.remote = EMPTY_STRING; scb->cfg = cfg; scb->pub.master = mcb; /* Fill in the session structure */ scb->wr_msg_q = isc_newqueue(); scb->sendindex = 0; return scb; } static void * stale_cb(oop_source *UNUSED(src), struct timeval UNUSED(tv), void *user) { struct isc_scb_internal *scb = user; scb->stale_output_cb_registered = 0; if (scb->stale_output_cb == NULL) return OOP_HALT; scb->stale_output_cb(&scb->pub); return OOP_CONTINUE; } static void * idle_cb(oop_source *UNUSED(src), struct timeval UNUSED(tv), void *user) { struct isc_scb_internal *scb = user; scb->idle_cb_registered = 0; if (scb->idle_cb == NULL) return OOP_HALT; scb->idle_cb(&scb->pub); return OOP_CONTINUE; } static void isc_cancel_stale_output_callback(struct isc_scb_internal *session) { oop_source *source = session->pub.master->event_source; if (session->stale_output_cb_registered) { source->cancel_time(source, session->stale_output_tv, stale_cb, session); session->stale_output_cb_registered = 0; } } static void isc_cancel_idle_callback(struct isc_scb_internal *session) { oop_source *source = session->pub.master->event_source; if (session->idle_cb_registered) { source->cancel_time(source, session->idle_tv, idle_cb, session); session->idle_cb_registered = 0; } } void isc_set_read_callback(struct isc_scb *scb, oop_call_fd *data_available_callback, isc_write_error_cb *write_error_cb, isc_stale_output_cb *stale_output_cb, isc_stale_output_cb *idle_output_cb) { struct isc_scb_internal *session = (struct isc_scb_internal*)scb; isc_cancel_read_callback(session); isc_cancel_stale_output_callback(session); isc_cancel_idle_callback(session); session->data_available_callback = data_available_callback; session->write_err_cb = write_error_cb; session->stale_output_cb = stale_output_cb; session->idle_cb = idle_output_cb; isc_check_read_callback(session, 0); } void isc_set_acceptable_idle(struct isc_scb *scb, struct timeval acceptable) { struct isc_scb_internal *session = (struct isc_scb_internal*)scb; isc_cancel_idle_callback(session); session->acceptable_idle_time = acceptable; isc_check_read_callback(session, 0); } void isc_check_read_callback(struct isc_scb_internal *session, int any_written) { oop_source *source = session->pub.master->event_source; int want_read = 1; int want_write_timeout = 0; /* Too many queued blocks or bytes? Don't read any more data, until the client has read the output we have already produced. */ if (session->wr_msg_q != NULL && (isc_sizequeue(session->wr_msg_q) >= session->cfg->max.queuedsize || session->wr_msg_q->bytes >= session->cfg->max.queuedsize_bytes)) { want_read = 0; want_write_timeout = 1; } if (session->state == ISC_STATE_DISABLED) want_read = 0; /* If this session is closing down there is no need for callbacks. */ if (session->state == ISC_STATE_CLOSING) { want_read = 0; want_write_timeout = 0; } if (!want_read) isc_cancel_read_callback(session); else if (!session->data_available_registered && session->data_available_callback != NULL) { source->on_fd(source, session->pub.fd, OOP_READ, session->data_available_callback, &session->pub); session->data_available_registered = 1; } if (any_written || !want_write_timeout) isc_cancel_stale_output_callback(session); if (any_written) isc_cancel_idle_callback(session); if (want_write_timeout && !session->stale_output_cb_registered && session->stale_output_cb != NULL) { setup_timer(&session->stale_output_tv, session->pub.master->scfg->stale_timeout); source->on_time(source, session->stale_output_tv, stale_cb, session); session->stale_output_cb_registered = 1; } if (!session->idle_cb_registered && session->state != ISC_STATE_CLOSING) { setup_timer(&session->idle_tv, session->acceptable_idle_time); source->on_time(source, session->idle_tv, idle_cb, session); session->idle_cb_registered = 1; } } void isc_cancel_read_callback(struct isc_scb_internal *session) { oop_source *source = session->pub.master->event_source; if (session->data_available_registered) { source->cancel_fd(source, session->pub.fd, OOP_READ); session->data_available_registered = 0; } } void isc_cancel_write_callback(struct isc_scb_internal *session) { oop_source *source = session->pub.master->event_source; if (session->write_cb_registered) { source->cancel_fd(source, session->pub.fd, OOP_WRITE); session->write_cb_registered = 0; } } /* ** Destroy the allocated Session structure. Close the ** socket if open and if Master structure specified, remove ** the session from it. */ int isc_destroy(struct isc_mcb *mcb, struct isc_scb *scb) { struct isc_scb_internal *sci = (struct isc_scb_internal*)scb; isc_resolve_done_cb *cb; int code = 0; int size; if (sci->resolve_callback != NULL) { if (sci->adns_query != NULL) oop_adns_cancel(sci->adns_query); else mcb->event_source->cancel_time(mcb->event_source, OOP_TIME_NOW, isc_dns_resolve_cb, scb); cb = sci->resolve_callback; sci->resolve_callback = NULL; cb(scb, isc_resolve_aborted, 0); } isc_cancel_read_callback(sci); isc_cancel_stale_output_callback(sci); isc_cancel_idle_callback(sci); isc_cancel_write_callback(sci); s_clear(&scb->remote); if (mcb) { code = isc_remove(mcb, sci); if (code < 0) return code; if (sci->accept_cb != NULL) { mcb->event_source->cancel_fd(mcb->event_source, scb->fd, OOP_READ); sci->accept_cb = NULL; } } assert(sci->accept_cb == NULL); if (scb->raddr) { isc_freeaddress(scb->raddr); scb->raddr = NULL; } if (scb->laddr) { isc_freeaddress(scb->laddr); scb->laddr = NULL; } if (scb->fd != -1) { close(scb->fd); scb->fd = -1; } if (sci->wr_msg_q) { size = isc_killqueue(sci->wr_msg_q); if (mcb != NULL && mcb->write_change_cb) mcb->write_change_cb(-size); } isc_free(scb); return 0; } int isc_disable(struct isc_scb *scb) { struct isc_scb_internal *sci = (struct isc_scb_internal*)scb; if (sci->state != ISC_STATE_RUNNING) return -1; sci->state = ISC_STATE_DISABLED; isc_check_read_callback(sci, 0); return 0; } int isc_enable(struct isc_scb *scb) { struct isc_scb_internal *sci = (struct isc_scb_internal*)scb; if (sci->state != ISC_STATE_DISABLED) return -1; sci->state = ISC_STATE_RUNNING; isc_check_read_callback(sci, 0); return 0; } oop_source * isc_getoopsource(struct isc_scb *scb) { return scb->master->event_source; } lyskom-server-2.1.2/src/libraries/libisc-new/src/isc_abort.c0000664000015100472110000000331307714124352017521 /* ** isc_abort.c Route to handle fatal errors ** ** Copyright (C) 1991, 1998-1999 by Peter Eriksson and ** Per Cederqvist of the Lysator Academic Computer Association. ** ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library 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 ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the Free ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ** ** history: ** 910305 pen moved into separate file ** (See ChangeLog for recent history) */ #include #ifdef HAVE_STDLIB_H # include #endif #ifdef HAVE_STDDEF_H # include #endif #ifdef HAVE_STDARG_H # include #endif #include #include #include #include "oop.h" #include "adns.h" #include "oop-adns.h" #include "s-string.h" #include "isc.h" #include "intern.h" static void (*isc_abortfn)(const char *msg) = NULL; #if 0 void isc_setabortfn(void (*abortfn)(const char *msg)) { isc_abortfn = abortfn; } #endif void isc_abort(const char *message) { if (isc_abortfn) (*isc_abortfn)(message); else { fprintf(stderr, "\n\r*** ISC SUBSYSTEM FATAL ERROR: %s\n\r", message); abort(); } } lyskom-server-2.1.2/src/libraries/libisc-new/src/isc_alloc.c0000664000015100472110000001014507714124352017505 /* ** isc_alloc.c ISC storage allocation routines ** ** Copyright (C) 1991, 1998-1999 by Peter Eriksson and ** Per Cederqvist of the Lysator Academic Computer Association. ** ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library 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 ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the Free ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ** ** history: ** 910305 pen moved into separate file ** (See ChangeLog for recent history) */ #include #include #ifdef HAVE_STDLIB_H # include #endif #ifdef HAVE_STDDEF_H # include #endif #ifdef HAVE_STDARG_H # include #endif #ifdef HAVE_STRING_H # include #else # include #endif #ifndef NULL # include #endif #include /* The order between inttypes.h and stdint.h is mandated by autoconf-2.57. */ #if HAVE_INTTYPES_H # include #else # if HAVE_STDINT_H # include # endif #endif #include "oop.h" #include "adns.h" #include "oop-adns.h" #include "s-string.h" #include "isc.h" #include "intern.h" /* ** Some magic numbers */ #ifdef USE_MALLOC_GUARDS #define ISC_MAGIC_ALLOC 0x12F54ACEu #define ISC_MAGIC_FREE 0xEE47A37Fu /* A union of "all types", used to get the maximum alignment needed for any type. */ union overhead { /* We prefer to store stuf in a size_t, since we are storing a size. Use an unsigned int if size_t isn't available. */ # ifdef HAVE_SIZE_T size_t val; unsigned int a; # else unsigned int val; # endif void *b; long c; long *d; long long e; long long *f; float g; double h; void (*i)(void); long double j; # ifdef HAVE_INTPTR_T intptr_t k; # endif # ifdef HAVE_INTMAX_T intmax_t l; # endif }; # define OVERHEAD (sizeof(union overhead)) #else union overhead; # define OVERHEAD (0) #endif /* ** Pointers to functions to handle storage allocation */ static void * (*isc_mallocfn)(size_t size) = NULL; static void * (*isc_reallocfn)(void *bufp, size_t size) = NULL; static void (*isc_freefn)(void *bufp) = NULL; /* ** Define functions to handle storage allocation */ void isc_setallocfn(void * (*mallocfn)(size_t size), void * (*reallocfn)(void *buf, size_t size), void (*freefn)(void *buf)) { isc_mallocfn = mallocfn; isc_reallocfn = reallocfn; isc_freefn = freefn; } void * isc_malloc(size_t size) { union overhead *buf; if (isc_mallocfn) buf = (*isc_mallocfn)(size + OVERHEAD); else { buf = malloc(size + OVERHEAD); if (!buf) isc_abort("isc_malloc"); } #ifdef USE_MALLOC_GUARDS buf->val = ISC_MAGIC_ALLOC; buf++; #endif return buf; } void * isc_realloc(void *oldbuf, size_t size) { union overhead *buf; if (!oldbuf) return isc_malloc(size); buf = oldbuf; #ifdef USE_MALLOC_GUARDS buf--; if (buf->val != ISC_MAGIC_ALLOC) isc_abort("isc_realloc"); buf->val = ISC_MAGIC_FREE; #endif if (isc_reallocfn) buf = (*isc_reallocfn)(buf, size + OVERHEAD); else { buf = realloc(buf, size + OVERHEAD); if (!buf) isc_abort("isc_realloc"); } #ifdef USE_MALLOC_GUARDS buf->val = ISC_MAGIC_ALLOC; buf++; #endif return (void *) buf; } void isc_free(void *buf) { union overhead *ibuf; if (!buf) isc_abort("isc_free"); ibuf = buf; #ifdef USE_MALLOC_GUARDS ibuf--; if (ibuf->val != ISC_MAGIC_ALLOC) isc_abort("isc_free"); ibuf->val = ISC_MAGIC_FREE; #endif if (isc_freefn) { (*isc_freefn)(ibuf); return; } else free(ibuf); } lyskom-server-2.1.2/src/libraries/libisc-new/src/isc_master.c0000664000015100472110000000677407714123665017731 /* ** isc_master.c IscMaster control functions ** ** Copyright (C) 1991-1992, 1998-1999 by Peter Eriksson and ** Per Cederqvist of the Lysator Academic Computer Association. ** ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library 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 ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the Free ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ** ** history: ** 910305 pen moved to separate file ** (See ChangeLog for recent history) */ #include #include #ifdef HAVE_STDLIB_H # include #endif #ifdef HAVE_STDDEF_H # include #endif #ifdef HAVE_STDARG_H # include #endif #include #include #include #ifndef NULL # include #endif #include "oop.h" #include "adns.h" #include "oop-adns.h" #include "s-string.h" #include "timeval-util.h" #include "isc.h" #include "intern.h" /* ** This routine will initialize the ISC subsystem */ struct isc_mcb * isc_initialize(oop_source *event_source, isc_write_queue_change_cb *write_change_cb) { struct isc_mcb * mcb; oop_adapter_adns * adns; adns = oop_adns_new(event_source, 0 |adns_if_logpid |adns_if_checkc_entex |adns_if_nosigpipe, stderr); if (adns == NULL) return NULL; ISC_XNEW(mcb); ISC_XNEW(mcb->scfg); mcb->sessions = NULL; mcb->adns = adns; /* Setup default values */ mcb->scfg->max.msgsize = ISC_DEFAULT_MAX_MSG_SIZE; mcb->scfg->max.queuedsize = ISC_DEFAULT_MAX_QUEUED_SIZE; mcb->scfg->max.dequeuelen = ISC_DEFAULT_MAX_DEQUEUE_LEN; mcb->scfg->max.openretries = ISC_DEFAULT_MAX_OPEN_RETRIES; mcb->scfg->max.backlog = ISC_DEFAULT_MAX_BACKLOG; mcb->scfg->fd_relocate = 0; mcb->scfg->stale_timeout = timeval_ctor(3600, 0); /* Default to no byte limit. */ mcb->scfg->max.queuedsize_bytes = (ISC_DEFAULT_MAX_QUEUED_SIZE * ISC_DEFAULT_MAX_MSG_SIZE); mcb->event_source = event_source; mcb->write_change_cb = write_change_cb; return mcb; } void isc_cfg_fd_relocate(struct isc_mcb *mcb, int fd_relocate) { mcb->scfg->fd_relocate = fd_relocate; } void isc_cfg_stale_timeout(struct isc_mcb *mcb, struct timeval stale, struct timeval default_idle) { mcb->scfg->stale_timeout = stale; mcb->scfg->idle_timeout = default_idle; } void isc_cfg_queue_size(struct isc_mcb *mcb, int max_queue_size_bytes, int max_msg_size, int max_queue_size_msgs, int max_dequeue_msgs) { mcb->scfg->max.msgsize = max_msg_size; mcb->scfg->max.queuedsize = max_queue_size_msgs; mcb->scfg->max.queuedsize_bytes = max_queue_size_bytes; mcb->scfg->max.dequeuelen = max_dequeue_msgs; } /* ** Close and destroy all sessions associated with a MCB, then ** destroy the MCB too. */ void isc_shutdown(struct isc_mcb * mcb) { while (mcb->sessions) isc_destroy(mcb, &mcb->sessions->scb->pub); oop_adns_delete(mcb->adns); isc_free(mcb->scfg); isc_free(mcb); } lyskom-server-2.1.2/src/libraries/libisc-new/src/isc_output.c0000664000015100472110000001037207722446224017761 /* ** isc_output.c Isc data output functions ** ** Copyright (C) 1991, 1998-1999 by Peter Eriksson and ** Per Cederqvist of the Lysator Academic Computer Association. ** ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library 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 ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the Free ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ** ** history: ** 910305 pen moved into separate file ** 910310 pen added isc_send() ** (See ChangeLog for recent history) */ #ifdef HAVE_STDDEF_H # include #endif #ifdef HAVE_STDARG_H # include #endif #include #ifdef HAVE_STRING_H # include #endif #include #include #ifndef NULL # include #endif #include #include #include #include #include "oop.h" #include "adns.h" #include "oop-adns.h" #include "s-string.h" #include "isc.h" #include "intern.h" void isc_flush(struct isc_scb *scb) { struct isc_scb_internal *sci = (struct isc_scb_internal*)scb; int size; switch (sci->state) { case ISC_STATE_CLOSING: if (sci->wr_msg_q) { size = isc_killqueue(sci->wr_msg_q); if (sci->pub.master->write_change_cb) sci->pub.master->write_change_cb(-size); sci->wr_msg_q = NULL; } sci->sendindex = 0; return; case ISC_STATE_RUNNING: case ISC_STATE_DISABLED: isc_oflush(sci); return; default: return; } } static void * write_cb(oop_source *src, int fd, oop_event event, void *user) { struct isc_scb_internal *scb = user; assert(scb->pub.fd == fd); assert(scb->pub.master->event_source == src); assert(event == OOP_WRITE); isc_oflush(scb); return OOP_CONTINUE; } void isc_oflush(struct isc_scb_internal *scb) { struct isc_msg * msg; int failed; int any_written; int wlen; int loopcnt; oop_source *src; assert(scb->state != ISC_STATE_LISTENING); if (scb->state == ISC_STATE_CLOSING) return; /* Data in the block buffer? */ if (scb->sendindex > 0) { msg = isc_allocmsg(scb->sendindex); memcpy(msg->buffer, scb->sendbuf, scb->sendindex); msg->length = scb->sendindex; if (scb->pub.master->write_change_cb) scb->pub.master->write_change_cb(msg->length); isc_pushqueue(scb->wr_msg_q, msg); scb->sendindex = 0; } if (scb->pub.fd == -1) return; /* Queued entries? Send as much as possible */ failed = 0; loopcnt = 0; any_written = 0; while ((msg = isc_topqueue(scb->wr_msg_q)) != NULL && !failed && loopcnt < scb->cfg->max.dequeuelen) { wlen = write(scb->pub.fd, msg->buffer, msg->length); if (wlen < 0) { if (errno == EWOULDBLOCK) wlen = 0; else { scb->write_err_cb(&scb->pub, errno); scb->state = ISC_STATE_CLOSING; scb->sendindex = 0; return; } } else { any_written = 1; scb->wr_msg_q->bytes -= wlen; if (scb->pub.master->write_change_cb) scb->pub.master->write_change_cb(-wlen); } msg->length -= wlen; if (msg->length > 0) { /* The write handler could not transmit the whole buffer */ failed = 1; if (wlen > 0) memmove(msg->buffer, msg->buffer + wlen, msg->length); } else { /* Drop the topmost entry */ msg = isc_popqueue(scb->wr_msg_q); isc_freemsg(msg); } loopcnt++; } isc_check_read_callback(scb, any_written); if (isc_pollqueue(scb->wr_msg_q)) { if (!scb->write_cb_registered) { src = scb->pub.master->event_source; src->on_fd(src, scb->pub.fd, OOP_WRITE, write_cb, scb); scb->write_cb_registered = 1; } } else isc_cancel_write_callback(scb); } lyskom-server-2.1.2/src/libraries/libisc-new/src/isc_queue.c0000664000015100472110000000664207714124352017546 /* ** isc_queue.c Handle queues for the ISC subsystem ** ** Copyright (C) 1991, 1998-1999 by Peter Eriksson and ** Per Cederqvist of the Lysator Academic Computer Association. ** ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library 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 ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the Free ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ** ** history: ** 910305 pen moved to separate file ** (See ChangeLog for recent history) */ #ifdef HAVE_STDDEF_H # include #endif #ifdef HAVE_STDARG_H # include #endif #ifndef NULL # include #endif #include #include #include #include #include "oop.h" #include "adns.h" #include "oop-adns.h" #include "s-string.h" #include "isc.h" #include "intern.h" struct isc_msgqueue * isc_newqueue(void) { struct isc_msgqueue * msg_q; msg_q = (struct isc_msgqueue *) isc_malloc(sizeof(struct isc_msgqueue)); msg_q->head = NULL; msg_q->tail = NULL; msg_q->entries = 0; msg_q->bytes = 0; return msg_q; } int isc_killqueue(struct isc_msgqueue * queue) { struct isc_msg_q_entry * mqe; struct isc_msg_q_entry * prev; int size = 0; if (queue == NULL) return 0; if ( queue->head != NULL ) { mqe = queue->head; while ( mqe != NULL ) { prev = mqe; mqe = mqe->next; size += prev->msg->length; isc_freemsg(prev->msg); isc_free(prev); } } assert(size == queue->bytes); isc_free(queue); return size; } /* ** Push a message onto a queue. It is legal to push a message onto the ** the NULL queue and will be equal to freeing that message */ void isc_pushqueue(struct isc_msgqueue * queue, struct isc_msg * msg) { struct isc_msg_q_entry * mqe; if (queue == NULL) { isc_freemsg(msg); return; } mqe = (struct isc_msg_q_entry *) isc_malloc(sizeof(struct isc_msg_q_entry)); mqe->msg = msg; mqe->prev = queue->tail; mqe->next = NULL; if (queue->head == NULL) queue->head = mqe; if (queue->tail) queue->tail->next = mqe; queue->tail = mqe; queue->entries++; queue->bytes += msg->length; } struct isc_msg * isc_topqueue(struct isc_msgqueue * queue) { if (queue != NULL && queue->head != NULL) return queue->head->msg; else return NULL; } int isc_sizequeue(struct isc_msgqueue * queue) { if (queue) return queue->entries; else return -1; } struct isc_msg * isc_popqueue(struct isc_msgqueue * queue) { struct isc_msg_q_entry * mqe; struct isc_msg * msg; if (queue != NULL && queue->head != NULL) { mqe = queue->head; msg = mqe->msg; queue->head = mqe->next; if (queue->head) queue->head->prev = NULL; else queue->tail = NULL; queue->entries--; isc_free(mqe); return msg; } else return NULL; } lyskom-server-2.1.2/src/libraries/libisc-new/src/isc_message.c0000664000015100472110000000336307714124352020043 /* ** isc_message.c Generic "struct isc_msg" handling functions ** ** Copyright (C) 1991-1992, 1998-1999 by Peter Eriksson and ** Per Cederqvist of the Lysator Academic Computer Association. ** ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library 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 ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the Free ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ** ** history: ** 910305 pen moved into separate file ** 920102 pen added isc_copymsg() ** (See ChangeLog for recent history) */ #ifdef HAVE_STDDEF_H # include #endif #ifdef HAVE_STDARG_H # include #endif #ifdef HAVE_STRING_H # include #endif #ifndef NULL # include #endif #include #include #include #include "oop.h" #include "adns.h" #include "oop-adns.h" #include "s-string.h" #include "isc.h" #include "intern.h" struct isc_msg * isc_allocmsg(size_t size) { struct isc_msg * msg; ISC_XNEW(msg); msg->buffer = (char *) isc_malloc(size+1); msg->size = size; msg->length = 0; return msg; } void isc_freemsg(struct isc_msg * msg) { if (msg->buffer) isc_free(msg->buffer); isc_free(msg); } lyskom-server-2.1.2/src/libraries/libisc-new/src/isc_stdout.c0000664000015100472110000000607707715662264017760 /* ** isc_stdout.c Some nice-to-have functions for output. ** ** Copyright (C) 1991, 1998-1999 by Peter Eriksson and ** Per Cederqvist of the Lysator Academic Computer Association. ** ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library 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 ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the Free ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ** ** history: ** 910305 pen moved into separate file ** (See ChangeLog for recent history) */ #include #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_STDARG_H # include #endif #include #include #include #include "oop.h" #include "adns.h" #include "oop-adns.h" #include "s-string.h" #include "isc.h" #include "intern.h" int isc_putc(int chr, struct isc_scb *session) { struct isc_scb_internal *scb = (struct isc_scb_internal*)session; if (scb->state != ISC_STATE_DISABLED && scb->state != ISC_STATE_RUNNING) return EOF; while (scb->sendindex == sizeof(scb->sendbuf) || scb->sendindex >= session->master->scfg->max.msgsize) isc_flush(session); return scb->sendbuf[scb->sendindex++] = chr; } int isc_write(struct isc_scb *session, const void * buffer, size_t length) { const char * bp; int len; int blen; int clen; size_t maxlen; struct isc_scb_internal *scb = (struct isc_scb_internal*)session; if (scb->state != ISC_STATE_DISABLED && scb->state != ISC_STATE_RUNNING) return EOF; bp = (const char *) buffer; clen = length; maxlen = session->master->scfg->max.msgsize; if (sizeof(scb->sendbuf) < maxlen) maxlen = sizeof(scb->sendbuf); while (clen > 0) { blen = maxlen - scb->sendindex; /* Make room in sendbuf */ while (blen == 0) { isc_flush(&scb->pub); blen = maxlen - scb->sendindex; } len = (clen > blen ? blen : clen); memcpy(scb->sendbuf+scb->sendindex, bp, len); scb->sendindex += len; clen -= len; bp += len; } return length; } int isc_puts(const char *str, struct isc_scb *scb) { return isc_write(scb, str, strlen(str)); } int isc_putul(unsigned long nr, struct isc_scb *scb) { static char buf[sizeof(unsigned long) * 3 + 1]; char *cp; if (nr < 10) return isc_putc("0123456789"[nr], scb); else { cp = buf + sizeof(buf); while (nr > 0) { *--cp = (nr % 10) + '0'; nr /= 10; } return isc_write(scb, cp, buf + sizeof(buf) - cp); } } lyskom-server-2.1.2/src/libraries/libisc-new/src/isc_socket.c0000664000015100472110000001537507714136565017726 /* ** isc_socket.c Socket specified code ** ** Copyright (C) 1992, 1998-1999 by Peter Eriksson and ** Per Cederqvist of the Lysator Academic Computer Association. ** ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library 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 ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the Free ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ** ** history: ** 920210 pen initial coding ** (See ChangeLog for recent history) */ #include #ifdef TIME_WITH_SYS_TIME # include # include #else # ifdef HAVE_SYS_TIME_H # include # else # include # endif #endif #include #include #include #include #include #include #include #include #ifdef HAVE_STDDEF_H # include #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_STDARG_H # include #endif #include #include #include #include "oop.h" #include "adns.h" #include "oop-adns.h" #include "s-string.h" #include "isc.h" #include "intern.h" #include "isc_addr.h" #include "unused.h" static oop_adns_call isc_dns_resolve_adns_cb; #if defined(__GNUC__) && defined(__sparc__) /* ** inet_ntoa() is buggy on SPARCs running SunOS 4.1.1, so ** we use our own */ #ifdef inet_ntoa #undef inet_ntoa #endif char *inet_ntoa(ad) struct in_addr ad; { u_long s_ad; int a, b, c, d; static char addr[20]; s_ad = ad.s_addr; d = s_ad % 256; s_ad /= 256; c = s_ad % 256; s_ad /= 256; b = s_ad % 256; a = s_ad / 256; sprintf(addr, "%d.%d.%d.%d", a, b, c, d); return addr; } #endif union isc_address * isc_mkipaddress(SOCKADDR_STORAGE *addr) { union isc_address *ia; ISC_XNEW(ia); memcpy(&ia->saddr, addr, sizeof(ia->saddr)); return ia; } union isc_address * isc_copyaddress(union isc_address *addr) { union isc_address *new_addr; ISC_XNEW(new_addr); *new_addr = *addr; return new_addr; } void isc_freeaddress(union isc_address *addr) { isc_free(addr); } /* isc_getipnum makes a textual representation of the IP address stored in an union isc_address. When an IPv6 socket is connected to an IPv4 socket this will be an IPv6-mapped IPv4 address. To hide this from the user (who might not be used to IPv6), we'll extract the IPv4 address part and present it as an ordinary IPv4 address. RFC2553 suggests no pretty way to do this, but says that we can get the IPv4 address by skipping the first 12 bytes of the in6_addr structure -- so that's what we'll do... If you have a weird IPv6 implementation that doesn't have inet_ntop you simply lose -- RFC2553 requires inet_ntop, and clearly states that inet_ntoa is specific to IPv4. However, it's still possible to handle IPv6-mapped IPv4 addresses with inet_ntoa and the same trickery as above. */ char *isc_getipnum(union isc_address *ia, char *buf, int len) { static char hostname[256]; if (!buf) { buf = hostname; len = sizeof(hostname); } #ifdef HAVE_INET_NTOP CHOOSE_IP4OR6(ia->saddr, inet_ntop(ia->saddr.sa.sa_family, (const void *) &ia->saddr.sa_in.sin_addr, buf, len), IN6_IS_ADDR_V4MAPPED(&ia->saddr.sa_in6.sin6_addr) ? inet_ntop(AF_INET, (const void *) &ia->saddr.sa_in6.sin6_addr.s6_addr[12], buf, len) : inet_ntop(ia->saddr.sa.sa_family, (const void *) &ia->saddr.sa_in6.sin6_addr, buf, len)); #else strncpy(buf, CHOOSE_IP4OR6(ia->saddr, inet_ntoa(ia->saddr.sa_in.sin_addr), IN6_IS_ADDR_V4MAPPED(&ia->saddr.sa_in6.sin6_addr) ? inet_ntoa((struct in_addr *) &ia->saddr.sa_in6.sin6_addr.s6_addr[12]) : ""), len-1); #endif buf[len-1] = '\0'; return buf; } void * isc_dns_resolve_cb(oop_source *UNUSED(src), struct timeval UNUSED(tv), void *user) { struct isc_scb_internal *session = user; struct hostent *hp; isc_resolve_done_cb *cb; union isc_address *ia = session->pub.raddr; hp = CHOOSE_IP4OR6(ia->saddr, gethostbyaddr((char *) &ia->saddr.sa_in.sin_addr, sizeof(ia->saddr.sa_in.sin_addr), ia->saddr.sa.sa_family), gethostbyaddr((char *) &ia->saddr.sa_in6.sin6_addr, sizeof(ia->saddr.sa_in6.sin6_addr), ia->saddr.sa.sa_family)); cb = session->resolve_callback; session->resolve_callback = NULL; if (hp) { s_crea_str(&session->pub.remote, hp->h_name); return cb(&session->pub, isc_resolve_ok, 0); } else { s_crea_str(&session->pub.remote, isc_getipnum(ia, NULL, 0)); return cb(&session->pub, isc_resolve_h_errno, h_errno); } } void * isc_dns_resolve_adns_cb(oop_adapter_adns *UNUSED(adapter), adns_answer *answer, void *user) { struct isc_scb_internal *session = user; isc_resolve_done_cb *cb; void *res = NULL; cb = session->resolve_callback; session->resolve_callback = NULL; if (answer->status == adns_s_ok && answer->nrrs > 0) { s_crea_str(&session->pub.remote, answer->rrs.str[0]); res = cb(&session->pub, isc_resolve_ok, 0); } else { s_crea_str(&session->pub.remote, isc_getipnum(session->pub.raddr, NULL, 0)); res = cb(&session->pub, isc_resolve_adns_error, answer->status); } free(answer); return res; } int isc_resolve_remote(struct isc_scb *scb, isc_resolve_done_cb *callback) { int errcode; struct isc_scb_internal *session = (struct isc_scb_internal*)scb; oop_source *source = session->pub.master->event_source; session->adns_query = oop_adns_submit_reverse( scb->master->adns, &errcode, &scb->raddr->saddr.sa, adns_r_ptr, 0, isc_dns_resolve_adns_cb, session); if (session->adns_query == NULL) { /* adns does not yet support IPv6 addresses, so if this is an IPv6 socket we have to use the old blocking method of host name lookup. */ if (errcode == ENOSYS) source->on_time(source, OOP_TIME_NOW, isc_dns_resolve_cb, session); else { assert(errcode); return errcode; } } session->resolve_callback = callback; return 0; } int isc_getportnum(union isc_address *ia) { return CHOOSE_IP4OR6(ia->saddr, ntohs(ia->saddr.sa_in.sin_port), ntohs(ia->saddr.sa_in6.sin6_port)); } lyskom-server-2.1.2/src/libraries/libisc-new/src/isc_tcp.c0000664000015100472110000002152107714124352017201 /* ** isc_tcp.c Routines to handle TCP ISC sessions ** ** Copyright (C) 1992, 1998-1999, 2001 by Peter Eriksson and ** Per Cederqvist of the Lysator Academic Computer Association. ** ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library 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 ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the Free ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ** ** history: ** 920209 pen code extracted from isc_session.c ** (See ChangeLog for recent history) */ #include #ifdef HAVE_STDLIB_H # include #endif #ifdef HAVE_STDDEF_H # include #endif #ifdef HAVE_STDARG_H # include #endif #include #include #include #include #include #include #include #include #ifdef HAVE_STRING_H # include #endif #include #ifndef NULL # include #endif #ifdef HAVE_UNISTD_H # include #endif #include #include #include "oop.h" #include "adns.h" #include "oop-adns.h" #include "s-string.h" #include "isc.h" #include "intern.h" #include "isc_addr.h" #include "unused.h" static oop_call_fd isc_accept_cb; static struct isc_scb_internal * isc_tcp_accept(struct isc_scb_internal *scb) { struct isc_scb_internal *new_scb; int fd; SOCKADDR_STORAGE addr; socklen_t len; len = sizeof(addr); if ((fd = accept(scb->pub.fd, (struct sockaddr *)&addr, &len)) < 0) { /* FIXME (bug 106): Log a message. */ return NULL; } new_scb = isc_createtcp(scb->pub.master, scb->cfg, fd, ISC_STATE_RUNNING); if (!new_scb) return NULL; /* Fill in the session info structure */ new_scb->pub.raddr = isc_mkipaddress(&addr); new_scb->pub.laddr = isc_copyaddress(scb->pub.laddr); return new_scb; } /* ** Create a TCP Session Address */ static union isc_address * isc_mktcpaddress_internal(const char *address, const char *service, int address_family) { union sockaddrs addr; struct hostent *hp = NULL; struct servent *sp; #ifdef USE_GETIPNODEBYNAME int error_num; #endif memset(&addr, 0, sizeof(addr)); /* Any local address? */ if (address == NULL) { addr.sa.sa_family = address_family; STORE_ADDR(addr, htonl(INADDR_ANY), in6addr_any); } else if (isdigit((int)(unsigned char)address[0]) || (address[0] == ':')) { #ifdef HAVE_INET_PTON if (FOR_EACH_AF(addr.sa.sa_family, (address_family != addr.sa.sa_family) || (inet_pton(address_family, address, CHOOSE_IP4OR6(addr, (void *) &addr.sa_in.sin_addr, (void *) &addr.sa_in6.sin6_addr) ) <= 0))) return NULL; #else /* No inet_pton; we have to do with inet_aton which only handles AF_INET addresses */ if (address_family != AF_INET) return NULL; addr.sa.sa_family = AF_INET; if (!inet_aton(address, &addr.sa_in.sin_addr)) return NULL; #endif } #ifdef USE_GETIPNODEBYNAME else if ((hp = getipnodebyname(address, address_family, /* Use AI_ADDRCONFIG and not AI_DEFAULT, since this address is only used for local addresses of this host. */ AI_ADDRCONFIG, &error_num)) == NULL) return NULL; #elif defined(HAVE_GETHOSTBYNAME2) else if ((hp = gethostbyname2(address, address_family)) == NULL) return NULL; #else else if ((hp = gethostbyname(address)) == NULL) return NULL; #endif else { addr.sa.sa_family = hp->h_addrtype; memcpy(CHOOSE_IP4OR6(addr, (void *) &addr.sa_in.sin_addr, (void *) &addr.sa_in6.sin6_addr), hp->h_addr, hp->h_length); } #ifdef USE_GETIPNODEBYNAME if (hp != NULL) freehostent(hp); #endif if (addr.sa.sa_family != address_family) return NULL; if (isdigit((int)(unsigned char)service[0])) CHOOSE_IP4OR6(addr, addr.sa_in.sin_port = htons(atoi(service)), addr.sa_in6.sin6_port = htons(atoi(service))); else if ((sp = getservbyname(service, "tcp")) == NULL) return NULL; else CHOOSE_IP4OR6(addr, addr.sa_in.sin_port = sp->s_port, addr.sa_in6.sin6_port = sp->s_port); return isc_mkipaddress(&addr.ssa); } union isc_address * isc_mktcpaddress(const char *address, const char *service) { union isc_address *ia; int af; if (FOR_EACH_AF( af, (ia = isc_mktcpaddress_internal(address, service, af)) == NULL)) return NULL; return ia; } int isc_addresssize(union isc_address *UNUSED_UNLESS_INET6(ia)) { return CHOOSE_IP4OR6(ia->saddr, sizeof(struct sockaddr_in), sizeof(struct sockaddr_in6)); } int isc_addressfamily(union isc_address *ia) { return ia->saddr.sa.sa_family; } struct sockaddr * isc_addresspointer(union isc_address *ia) { return (struct sockaddr *) &ia->saddr; } /* ** Create a TCP session. ** Will close fd and return NULL if an error occurs. */ struct isc_scb_internal * isc_createtcp(struct isc_mcb *mcb, struct isc_session_cfg *cfg, int fd, enum isc_session_state initial_state) { struct isc_scb_internal *scb; int res; int flag; struct linger ling; if (fd == -1) { int protocol_family; if (FOR_EACH_PF(protocol_family, (fd = socket(protocol_family, SOCK_STREAM, 0)) < 0)) { /* FIXME (bug 106): Log a message. */ return NULL; } } fd = isc_relocate_fd(fd, cfg->fd_relocate); /* Set non blocking write mode */ if ((res = fcntl(fd, F_GETFL, 0)) == -1) { /* FIXME (bug 106): Log a message. */ close(fd); return NULL; } /* If compilation fails on the next line, please report it as a bug to ceder@lysator.liu.se. I'd like to talk to you so that you can test an autoconf solution to this problem. As a workaround, you can change "O_NONBLOCK" to "FNDELAY". */ if (fcntl(fd, F_SETFL, res | O_NONBLOCK) == -1) { /* FIXME (bug 106): Log a message. */ close(fd); return NULL; } /* This is the modern way to turn off linger and turn on reuseaddr. */ ling.l_onoff = 0; ling.l_linger = 0; setsockopt(fd, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling)); flag = 1; setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)); scb = isc_create(mcb, cfg, initial_state); if (!scb) { /* FIXME (bug 106): Log a message. */ close(fd); return NULL; } scb->pub.fd = fd; scb->pub.raddr = NULL; scb->pub.laddr = NULL; return scb; } /* ** Bind a TCP session to a local port and address */ int isc_bindtcp(struct isc_scb_internal *scb, const char *address, const char *service) { union isc_address *ia; int af; if (FOR_EACH_AF(af, ! (ia = isc_mktcpaddress_internal(address, service, af)) || (bind(scb->pub.fd, isc_addresspointer(ia), isc_addresssize(ia)) < 0))) return -1; scb->pub.laddr = ia; assert(scb->pub.raddr == NULL); return 0; } static void * isc_accept_cb(oop_source *UNUSED(source), int fd, oop_event event, void *user) { struct isc_scb_internal *scb = (struct isc_scb_internal*)user; struct isc_scb_internal *new_scb; assert(event == OOP_READ); assert(scb->state == ISC_STATE_LISTENING); assert(scb->pub.fd == fd); new_scb = isc_tcp_accept(scb); if (new_scb == NULL) return OOP_CONTINUE; isc_insert(scb->pub.master, new_scb); return scb->accept_cb(&scb->pub, &new_scb->pub); } /* ** Establish a port to listen at for new TCP connections */ struct isc_scb * isc_listentcp(struct isc_mcb *mcb, const char *address, const char *service, isc_accept_callback *cb) { struct isc_scb_internal *scb; int retries; int errcode; scb = isc_createtcp(mcb, mcb->scfg, -1, ISC_STATE_LISTENING); if (!scb) return NULL; for (retries = 0; retries < scb->cfg->max.openretries; sleep(1), retries++) { errno = 0; if (isc_bindtcp(scb, address, service) >= 0 || errno != EADDRINUSE) break; } if (retries >= scb->cfg->max.openretries || errno != 0) { errcode = errno; isc_destroy(NULL, &scb->pub); errno = errcode; return NULL; } if (listen(scb->pub.fd, scb->cfg->max.backlog) < 0) { errcode = errno; isc_destroy(NULL, &scb->pub); errno = errcode; return NULL; } (void) isc_insert(mcb, scb); scb->accept_cb = cb; mcb->event_source->on_fd(mcb->event_source, scb->pub.fd, OOP_READ, isc_accept_cb, scb); return &scb->pub; } lyskom-server-2.1.2/src/libraries/libisc-new/src/unused.h0000664000015100472110000000214407704236613017070 /* unused -- compilation macros for unused arguments Copyright (C) 1997-1999 by Per Cederqvist. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef UNUSED_H #define UNUSED_H #define UNUSED_H_CONCAT(a, b) a ## b #ifdef HAVE_ATTRIBUTE_UNUSED # define UNUSED(var) UNUSED_H_CONCAT(qazwsxedc, var) __attribute__((unused)) #else # if defined(__cplusplus) # define UNUSED(var) # else # define UNUSED(var) var # endif #endif #endif lyskom-server-2.1.2/src/libraries/libisc-new/src/intern.h0000664000015100472110000002153607714537565017105 /* ** intern.h Definitions and prototypes used internally ** ** Copyright (C) 1991,1999 by Peter Eriksson and Per Cederqvist of the ** Lysator Academic Computer Association. ** ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library 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 ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the Free ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ** ** history: ** 910305 pen initial coding ** (See ChangeLog for recent history) */ #ifndef __ISC_INTERNALS_H__ #define __ISC_INTERNALS_H__ /* ** Some nice defaults */ #define ISC_DEFAULT_MAX_MSG_SIZE 8176 #define ISC_DEFAULT_MAX_QUEUED_SIZE 50 #define ISC_DEFAULT_MAX_DEQUEUE_LEN 30 #define ISC_DEFAULT_MAX_OPEN_RETRIES 10 #define ISC_DEFAULT_MAX_BACKLOG 50 /* ** The Master Control Block */ struct isc_mcb { struct isc_session_cfg * scfg; struct isc_scb_entry * sessions; oop_source * event_source; oop_adapter_adns * adns; isc_write_queue_change_cb *write_change_cb; }; /* ** The Client Control Block */ struct isc_scb_internal { struct isc_scb pub; enum isc_session_state state; struct isc_msgqueue *wr_msg_q; struct isc_session_cfg * cfg; /* Cheap transmit buffer */ /* Should be dynamically allocated - into an struct isc_msg */ char sendbuf[ISC_DEFAULT_MAX_MSG_SIZE]; int sendindex; isc_accept_callback *accept_cb; isc_write_error_cb *write_err_cb; isc_stale_output_cb *stale_output_cb; isc_stale_output_cb *idle_cb; oop_call_fd *data_available_callback; int data_available_registered; int write_cb_registered; int stale_output_cb_registered; struct timeval stale_output_tv; int idle_cb_registered; struct timeval idle_tv; struct timeval acceptable_idle_time; isc_resolve_done_cb *resolve_callback; /* Non-NULL when lookup pending. */ oop_adns_query *adns_query; }; /* ** Generic message type */ struct isc_msg { int size; /* Maximum buffer size */ int length; /* Length of used buffer */ char * buffer; /* Pointer to buffer */ }; /* ** Entry in a message queue */ struct isc_msg_q_entry { struct isc_msg_q_entry * prev; struct isc_msg_q_entry * next; struct isc_msg * msg; }; /* ** The generic message queue */ struct isc_msgqueue { struct isc_msg_q_entry * head; struct isc_msg_q_entry * tail; int entries; int bytes; }; /* ** Free an allocated struct isc_msg */ extern void isc_freemsg(struct isc_msg * msg); /* ** Configuration structure for sessions */ struct isc_session_cfg { struct { int msgsize; /* Size of a single message. */ int queuedsize; /* Number of messages. */ int queuedsize_bytes; /* Total number of bytes. */ int dequeuelen; /* Number of messages to write at once. */ int openretries; int backlog; } max; int fd_relocate; struct timeval stale_timeout; struct timeval idle_timeout; }; /* ** Session list entry */ struct isc_scb_entry { struct isc_scb_entry * prev; struct isc_scb_entry * next; struct isc_scb_internal * scb; }; /* isc_abort.c */ extern void isc_abort(const char *message); /* isc_alloc.c */ extern void * isc_malloc(size_t length); extern void * isc_realloc(void *buf, size_t length); extern void isc_free(void *buf); /* isc_queue.c */ extern struct isc_msgqueue * isc_newqueue(void); /* Return TRUE if the queue is not empty. */ #define isc_pollqueue(qp) ((qp) != NULL && ((qp)->head != NULL)) extern int isc_killqueue(struct isc_msgqueue *queue); extern void isc_pushqueue(struct isc_msgqueue *queue, struct isc_msg *msg); extern struct isc_msg * isc_topqueue(struct isc_msgqueue *queue); extern int isc_sizequeue(struct isc_msgqueue *queue); extern struct isc_msg * isc_popqueue(struct isc_msgqueue *queue); extern void isc_oflush(struct isc_scb_internal * scb); /* isc_session.c */ extern struct isc_scb_internal * isc_create(struct isc_mcb *mcb, struct isc_session_cfg *cfg, enum isc_session_state initial_state); extern void isc_insert(struct isc_mcb *mcb, struct isc_scb_internal *scb); extern int isc_remove(struct isc_mcb *mcb, struct isc_scb_internal *scb); /* isc_socket.c */ extern union isc_address * isc_copyaddress(union isc_address *addr); extern oop_call_time isc_dns_resolve_cb; /* isc_tcp.c */ extern struct isc_scb_internal * isc_createtcp(struct isc_mcb *mcb, struct isc_session_cfg *cfg, int fd, enum isc_session_state initial_state); extern int isc_bindtcp(struct isc_scb_internal *scb, const char *address, const char *port); /* isc_message.c. */ /* ** Allocate a new struct isc_msg of specified size */ extern struct isc_msg * isc_allocmsg(size_t size); #if 0 /* ** Setup a function to handle fatal abort requests */ extern void isc_setabortfn(void (*abortfn)(const char * msg)); #endif /* * Move a file descriptor FD the first unused file descriptor higher * than or equal to LIMIT. Return the new file descriptor. Close FD. * * On failure, the old FD will be returned, and errno will be set. * * Do nothing (and return FD) if LIMIT is 0. */ extern int isc_relocate_fd(int fd, int limit); extern void isc_check_read_callback(struct isc_scb_internal *session, int any_written); extern void isc_cancel_read_callback(struct isc_scb_internal *session); extern void isc_cancel_write_callback(struct isc_scb_internal *session); #define ISC_XNEW(var) (var = isc_malloc(sizeof(*var))) #if !HAVE_INET_ATON struct in_addr; int inet_aton (const char *, struct in_addr *); #endif #if !HAVE_SOCKLEN_T /* The configure script attempts to find the appropriate socklen_t type to use. This can be size_t, unsigned long or unsigned int. */ typedef SOCKLEN_TYPE socklen_t; #endif #if !HAVE_UINT32_T # if SIZEOF_INT == 4 typedef unsigned int uint32_t; # elif SIZEOF_LONG == 4 typedef unsigned long uint32_t; # else # error Cannot find a 32-bit type on this platform # endif #endif /* IPv4/IPv6 compatibility macros: * * These are used as wrappers around IPv4/IPv6 specific socket * handling code. When USE_INET6 is not defined, IPv6 specific * parts will not be compiled. * * CHOOSE_IP4OR6: Takes 3 args: * evaluates to second arg if first arg (of type * enum sockaddrs) contains an AF_INET address or * IPv6 is not used, otherwise to third arg. * FOR_EACH_AF: Takes 2 args; first is an int lvalue, second * an int expression. For each available address * family (from most preferred to last preferred), * the second arg is evaluated with the address * family assigned to the first arg, until it * evaluates to false (in which case the entire * macro expansion evaluates to false), or until * there are no more address families, in which * case the entire macro expansion evaluates to * true. * FOR_EACH_PF: As FOR_EACH_AF, but for protocol families * instead of address families. * STORE_ADDR: First arg (enum sockaddrs) is checked for * address family (if several address families * are supported), and its address part * assigned the value of the second arg * (of type in_addr) for IPv4, otherwise * the third arg (of type in6_addr). */ #ifdef USE_INET6 #define CHOOSE_IP4OR6(saddrs, ifip4, ifip6) \ ((((saddrs).sa.sa_family) == AF_INET) ? (ifip4) : (ifip6)) #define FOR_EACH_AF(af,expr) \ (((af)=AF_INET6, (expr)) && ((af)=AF_INET, (expr))) #define FOR_EACH_PF(pf,expr) \ (((pf)=PF_INET6, (expr)) && ((pf)=PF_INET, (expr))) #define STORE_ADDR(addr, IPv4addr, IPv6addr) \ CHOOSE_IP4OR6((addr), \ (addr).sa_in.sin_addr.s_addr = (IPv4addr), \ (memcpy(&(addr).sa_in6.sin6_addr, \ &(IPv6addr), \ sizeof((addr).sa_in6.sin6_addr)), 0)) #else #define CHOOSE_IP4OR6(saddrs, ifip4, ifip6) (ifip4) #define FOR_EACH_AF(af,expr) ((af)=AF_INET, (expr)) #define FOR_EACH_PF(pf,expr) ((pf)=PF_INET, (expr)) #define STORE_ADDR(addr, IPv4addr, IPv6addr) \ ((addr).sa_in.sin_addr.s_addr = (IPv4addr)); #endif /* USE_INET6 */ #endif lyskom-server-2.1.2/src/libraries/libisc-new/src/isc_relocate.c0000664000015100472110000000264207714124352020214 /* ** isc_relocate.c Relocate file descriptors ** ** Copyright (C) 1999 by Peter Eriksson and ** Per Cederqvist of the Lysator Academic Computer Association. ** ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library 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 ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the Free ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ** */ #ifdef HAVE_STDDEF_H # include #endif #ifdef HAVE_STDARG_H # include #endif #include #include #include #include #include #include "oop.h" #include "adns.h" #include "oop-adns.h" #include "s-string.h" #include "isc.h" #include "intern.h" int isc_relocate_fd(int fd, int limit) { int high_fd; if (limit <= 0) return fd; high_fd = fcntl(fd, F_DUPFD, limit); if (high_fd < 0) return fd; close(fd); return high_fd; } lyskom-server-2.1.2/src/libraries/libisc-new/src/isc_compat.c0000664000015100472110000000243507714124352017701 /* ** isc_compat.c Portability functions. ** ** Copyright (C) 2002 by Peter Eriksson and ** Per Cederqvist of the Lysator Academic Computer Association. ** ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library 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 ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the Free ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include "oop.h" #include "adns.h" #include "oop-adns.h" #include "s-string.h" #include "isc.h" #include "intern.h" #if !HAVE_INET_ATON int inet_aton(const char *name, struct in_addr *res) { res->s_addr = inet_addr(name); return (res->s_addr != INADDR_NONE); } #endif char isc_neveruse='C'; lyskom-server-2.1.2/src/libraries/libisc-new/src/isc_addr.h0000664000015100472110000000343207711047124017331 /* ** isc_addr.h aggregates and functions that handles IP addresses ** ** Copyright (C) 1991, 1996, 1998-1999, 2001 by Peter Eriksson and ** Per Cederqvist of the Lysator Academic Computer Association. ** ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. ** ** This library 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 ** Library General Public License for more details. ** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the Free ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * For IPv4/IPv6 compatibility: * SOCKADDR_STORAGE: Socket address storage type. * struct sockaddr_storage is used when available (RFC2553) */ #ifdef HAVE_STRUCT_SOCKADDR_STORAGE #define SOCKADDR_STORAGE struct sockaddr_storage #else #define SOCKADDR_STORAGE struct sockaddr #endif /* Socket address */ union sockaddrs { SOCKADDR_STORAGE ssa; struct sockaddr sa; struct sockaddr_in sa_in; #ifdef USE_INET6 struct sockaddr_in6 sa_in6; #endif }; union isc_address { union sockaddrs saddr; }; extern union isc_address * isc_mkipaddress(SOCKADDR_STORAGE *addr); #if (defined(HAVE_GETIPNODEBYNAME) && defined(AI_ADDRCONFIG) \ && defined(HAVE_FREEHOSTENT)) # define USE_GETIPNODEBYNAME 1 #else # undef USE_GETIPNODEBYNAME #endif #ifdef USE_INET6 # define UNUSED_UNLESS_INET6(x) x #else # define UNUSED_UNLESS_INET6(x) UNUSED(x) #endif lyskom-server-2.1.2/src/libraries/libisc-new/src/.cvsignore0000664000015100472110000000006206712627242017411 *.bb *.bbg *.da *.gcov .deps Makefile Makefile.in lyskom-server-2.1.2/src/libraries/libisc-new/man/0000777000015100472110000000000007723710316015457 5lyskom-server-2.1.2/src/libraries/libisc-new/man/Makefile.am0000664000015100472110000000227207713267152017440 # ISC - networking library # Copyright (C) 1998-1999 by Peter Eriksson and Per Cederqvist of the # Lysator Academic Computer Association. # # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library 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 # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the Free # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## Process this file with automake to produce Makefile.in noinst_MANS = isc.3x isc_initialize.3x isc_shutdown.3x isc_openfd.3x \ isc_openfile.3x isc_opentcp.3x isc_close.3x isc_listentcp.3x \ isc_unlisten.3x isc_createtcp.3x isc_destroy.3x EXTRA_DIST = $(noinst_MANS) TEMPLATE .cvsignore MAINTAINERCLEANFILES = Makefile.in lyskom-server-2.1.2/src/libraries/libisc-new/man/Makefile.in0000664000015100472110000001677207723707450017464 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # ISC - networking library # Copyright (C) 1998-1999 by Peter Eriksson and Per Cederqvist of the # Lysator Academic Computer Association. # # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library 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 # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the Free # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ prefix = @prefix@ program_transform_name = @program_transform_name@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ noinst_MANS = isc.3x isc_initialize.3x isc_shutdown.3x isc_openfd.3x \ isc_openfile.3x isc_opentcp.3x isc_close.3x isc_listentcp.3x \ isc_unlisten.3x isc_createtcp.3x isc_destroy.3x EXTRA_DIST = $(noinst_MANS) TEMPLATE .cvsignore MAINTAINERCLEANFILES = Makefile.in subdir = man ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = DIST_SOURCES = DIST_COMMON = Makefile.am Makefile.in all: all-am .SUFFIXES: $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu man/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) uninstall-info-am: tags: TAGS TAGS: ctags: CTAGS CTAGS: DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = .. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am info info-am install \ install-am install-data install-data-am install-exec \ install-exec-am install-info install-info-am install-man \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \ uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/src/libraries/libisc-new/man/isc.3x0000664000015100472110000001354006712622574016437 .\" ISC - networking library .\" Copyright (C) 1991-1992, 1999 by Peter Eriksson and Per Cederqvist of the .\" Lysator Academic Computer Association. .\" .\" .\" 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 2 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, write to the Free Software .\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. .\" .\" .\" @(#)isc.3x 1.0 (Lysator) 2/3/92 .\" .TH ISC 3X "February 3, 1992" "Release 1.0" "ISC LIBRARY" .SH NAME isc_initialize, isc_shutdown, isc_listentcp, isc_unlisten, isc_opentcp, isc_openfile, isc_openfd, isc_close, isc_enable, isc_disable, isc_sessions, isc_getnextevent, isc_dispose, isc_flush, isc_write, isc_putc, isc_printf, isc_allocmsg, isc_reallocmsg, isc_freemsg, isc_mkstrmsg, isc_setmaxmsgsize, isc_setallocfn, isc_setlogfn, isc_setabortfn \- server-client subroutines .SH SYNOPSIS .LP .B "#include " .LP .nf .B IscMaster * .B " isc_initialize (IscConfig *cfg)" .PP .B void .B " isc_shutdown(IscMaster *mcb)" .PP .B int .B " isc_listentcp(IscMaster *mcb, const char *service);" .PP .B void .B " isc_unlisten(IscMaster *mcb, int listen_return_val);" .PP .B "IscSession *" .B " isc_opentcp(IscMaster *mcb, const char *host, const char *service)" .PP .B "IscSession *" .B " isc_openfile(IscMaster *mcb, const char *path, int mode)" .PP .B "IscSession *" .B " isc_openfd(IscMaster *mcb, int fd)" .PP .B "void" .B " isc_close (IscSession *scb)" .PP .B "int" .B " isc_sessions (IscMaster *mcb)" .PP .B "IscEvent *" .B " isc_getnextevent (IscMaster *mcb, long timeout)" .PP .B "void" .B " isc_dispose (IscEvent *ecb)" .PP .B "void" .B " isc_flush (IscSession *scb)" .PP .B "int" .B " isc_write (IscSession *scb, const void *buf, size_t len)" .PP .B "int" .B " isc_printf (IscSession *scb, const char *format, ...)" .PP .B "int" .B " isc_putc (int chr, IscSession *scb)" .PP .B "IscMessage *" .B " isc_allocmsg(size_t size);" .PP .B "IscMessage *" .B " isc_reallocmsg(IscMessage *msg, size_t size);" .PP .B "void" .B " isc_freemsg(IscMessage *msg);" .PP .B "IscMessage *" .B " isc_mkstrmsg(const char *str);" .PP .B "void" .B " isc_setmaxmsgsize (IscMaster *mcb, size_t size)" .PP .B "void" .B " isc_setlogfn (void (*logfnp)(const char *fmt, va_list AP))" .PP .B "void" .B " isc_setallocfn (void * (*mallocfn)(size_t size)," .B " void * (*reallocfn)(void *buf, size_t size)," .B " void (*freefn)(void *buf))" .PP .B "void" .B " isc_setabortfn (void (*abortfn)(const char *msg))" .SH TYPES .nf .B "typedef struct" .B "{" .B " int version; /* Current version is 2 */" .B " struct" .B " {" .B " int msgsize; /* -1 = use defaults */" .B " int queuedsize; /* -1 = use defaults */" .B " int dequeuelen; /* -1 = use defaults */" .B " } max;" .B " struct" .B " {" .B " unsigned inhibit_dns_lookup : 1; /* Do not map IP number -> name */" .B " unsigned late_connect : 1; /* Do non-blocking connect()s */" .B " }" .B "}" .PP .B typedef enum .B { .B " ISC_EVENT_ERROR," .B " ISC_EVENT_TIMEOUT," .B " ISC_EVENT_LOGIN," .B " ISC_EVENT_LOGOUT," .B " ISC_EVENT_MESSAGE," .B "} IscEventType;" .PP .B typedef enum .B { .B " ISC_TYPE_UNKNOWN," .B " ISC_TYPE_TCP," .B " ISC_TYPE_FILE" .B "} IscSessionType;" .PP .B "typedef enum" .B "{" .B " ISC_STATE_UNKNOWN," .B " ISC_STATE_CONNECTING," .B " ISC_STATE_RUNNING," .B " ISC_STATE_DISABLED," .B " ISC_STATE_CLOSING" .B "} IscSessionState;" .PP .B typedef struct isc_msg .B { .B " int size;" .B " int length;" .B " char *buffer;" .B } IscMessage; .PP .B typedef struct isc_mcb .B { .B " int port;" .B " int fd;" .B " int maxmsgsize;" .B " int maxqueuedsize;" .B " int maxdequeuelen;" .B " struct isc_scb *sessions;" .B } IscMaster; .PP .B typedef struct isc_scb .B { .B " struct isc_scb * prev;" .B " struct isc_scb * next;" .B " IscMaster * mcb;" .B " IscSessionType type;" .B " IscSessionState state;" .B " int fd; .B " IscMsgQueue * rd_msg_q;" .B " IscMsgQueue * wr_msg_q;" .B " char sendbuf[2048];" .B " int sendindex;" .B " union" .B " {" .B " struct" .B " {" .B " char * hostname;" .B " int rport;" .B " int lport;" .B " } tcp;" .B " struct" .B " {" .B " char * pathname;" .B " int openmode;" .B " } file;" .B " } info;" .B " time_t logintime;" .B " time_t idlesince;" .B " struct" .B " {" .B " struct" .B " {" .B " long bytes;" .B " long packets;" .B " } rx, tx;" .B " } stats;" .B "" .B " ISC_UDGTYPE * udg; /* Reserved for user defined usage */" .B "} IscSession;" .PP .B typedef struct isc_ecb .B { .B " IscEventType event;" .B " IscSession * session;" .B " IscMessage * msg;" .B } IscEvent; .SH DESCRIPTION These functions implement an interface to the TCP/IP streams facitiliy. The functions are obtained with the loader option .BR \-lisc . (More to come here...) .PP .SH DIAGNOSTICS (And here... :\-) .PP .SH BUGS Hehe... I'm sure they exists... .SH GUILTY Peter Eriksson & Per Cederqvist ISC is Copyright (c) 1991 Lysator Computer Club, Linkoping University, Sweden, in cooperation with the International Syndicate of Computation. All rights reserved. lyskom-server-2.1.2/src/libraries/libisc-new/man/isc_initialize.3x0000664000015100472110000000665606712622575020673 .\" @(#)isc_initialize.3x 1.0 92/02/13 Lysator .\" ISC - networking library .\" Copyright (C) 1992, 1999 by Peter Eriksson and Per Cederqvist of the .\" Lysator Academic Computer Association. .\" .\" .\" 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 2 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, write to the Free Software .\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. .\" .TH ISC_INITIALIZE 3X "13 February 1992" "Release 1.0" "ISC LIBRARY" .SH NAME isc_initialize \- create a master control structure .SH SYNOPSIS .nf .ft B #include .ft .fi .LP .nf .ft B IscMaster *isc_initialize(cfg) IscConfig *cfg; .ft R .fi .SH DESCRIPTION This function initializes an ISC master structure to be ready to handle sessions. It returns a pointer to a master structure that can be used as the argument in subsequent calls to functions that create new sessions to associate a session with a master control structure. It is also used when closing down a master structure or removing sessions from a master structure. .SH ARGUMENTS The .I cfg argument can either be a .SM NULL pointer to force a set of system defaults or point to a structure that should contain various default values to be used by the system. The structure is defined in .BR and includes the following members: .br .ne 6 .LP .RS .nf .ft B .ta +\w'IscSessionConfig\0'u+\w'session;\0'u int version; IscSessionConfig session; .ft R .fi .DT .RE .LP Here .B version should be assigned the current configuration structure version number that for this version is .SM 1004. The .B IscSessionConfig structure is also defined in the same file and has the following members: .br .ne 6 .LP .RS .nf .ft B .ta +\w'struct\0'u+\w'unsigned\0'u+\w'no_host2ip_lookup;\0'u struct { int msgsize; int queuedsize; int dequeuelen; int openretries; int backlog; } max; .ft R .fi .DT .RE .LP Here .B msgsize specifies the maximum number of characters that will be read or written to the underlying file descriptor in any one call. (Ie, the maximum packet size.) .LP The .B queuedsize member specifies the maximum number of packets to queue before closing down the session. This is used both for incoming and outgoing packets. .LP The .B dequeuelen member specifies the maximum number of packets to transmit at any one time. This is so a session with many queued packets wont use up all server resources. .LP The .B openretries member specifies the maximum number of retries that will be made when binding and/or connecting a session to a service. .LP The .B backlog member specifies the maximum number of concurrent outstanding TCP/IP connections as specified by the .BR listen(2) system call. It is possible to assign these members the value .SM -1 to get the system default value. .SH RETURN VALUES The returned value is a pointer to a master control structure, or NULL if an error occurs. .SH ERRORS .TP 10 .SM EINVAL .I cfg is an invalid configuration struct .SH SEE ALSO .BR isc (3x) lyskom-server-2.1.2/src/libraries/libisc-new/man/isc_shutdown.3x0000664000015100472110000000304406712622576020372 .\" @(#)isc_shutdown.3x 1.0 92/02/13 Lysator .\" ISC - networking library .\" Copyright (C) 1992, 1999 by Peter Eriksson and Per Cederqvist of the .\" Lysator Academic Computer Association. .\" .\" .\" 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 2 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, write to the Free Software .\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. .\" .TH ISC_SHUTDOWN 3X "13 February 1992" "Release 1.0" "ISC LIBRARY" .SH NAME isc_shutdown \- close down an ISC master control structure .SH SYNOPSIS .nf .ft B #include .ft .fi .LP .nf .ft B void isc_shutdown(mcb) IscMaster *mcb; .ft R .fi .SH DESCRIPTION .IX "isc_shutdown()" "" "\fLisc_shutdown()\fP function" .LP .B isc_shutdown(\|) closes all active sessions in the master control structure and frees all memory allocated by session under control by that master structure. The sessions are also closed on call to .BR exit(2v). .SH RETURN VALUES .LP .B isc_shutdown (\|) has no return value. .br .ne 6 .SH SEE ALSO .BR isc (3x) .BR exit (2v) lyskom-server-2.1.2/src/libraries/libisc-new/man/isc_openfd.3x0000664000015100472110000000423606712622577017777 .\" @(#)isc_openfd.3x 1.0 92/02/03 Lysator .\" ISC - networking library .\" Copyright (C) 1992, 1999 by Peter Eriksson and Per Cederqvist of the .\" Lysator Academic Computer Association. .\" .\" .\" 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 2 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, write to the Free Software .\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. .\" .TH ISC_OPENFD 3X "3 February 1992" "Release 1.0" "ISC LIBRARY" .SH NAME isc_openfd \- associate a file descriptor with an ISC session .SH SYNOPSIS .nf .ft B #include .ft .fi .LP .nf .ft B IscSession *isc_openfd(IscMaster *mcb, int fd) .ft R .fi .SH DESCRIPTION .IX "isc_openfd()" "" "\fLisc_openfd()\fP function" .LP .B isc_openfd(\|) associates a previously opened file descriptor with a session and inserts it into the master control structure. .LP The .I mcb argument must point to a previously allocated master structure as returned by the .BR isc_initialize(\|) function call. .LP The .I fd argument must be a previously opened file descriptor. .SH RETURN VALUES .B isc_openfd(\|) returns a non-\s-1NULL\s0 pointer to a session value suitable for use with subsequent .SM ISC functions calls. On failure, it returns .SM NULL and no memory is allocated and no connection is initiated. .SH "SEE ALSO" .BR isc (3x) .BR isc_initialize (3x) .BR isc_shutdown (3x) .BR isc_listentcp (3x) .BR isc_unlisten (3x) .BR isc_opentcp (3x) .BR isc_openfile (3x) .BR isc_close (3x) .BR isc_enable (3x) .BR isc_disable (3x) .BR isc_sessions (3x) .BR isc_getnextevent (3x) .BR isc_dispose (3x) .BR isc_flush (3x) .BR isc_write (3x) .BR isc_putc (3x) .BR isc_printf (3x) lyskom-server-2.1.2/src/libraries/libisc-new/man/isc_openfile.3x0000664000015100472110000000462106712622601020307 .\" @(#)isc_openfile.3x 1.0 92/02/03 Lysator .\" ISC - networking library .\" Copyright (C) 1992, 1999 by Peter Eriksson and Per Cederqvist of the .\" Lysator Academic Computer Association. .\" .\" .\" 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 2 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, write to the Free Software .\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. .\" .TH ISC_OPENFILE 3X "3 February 1992" "Release 1.0" "ISC LIBRARY" .SH NAME isc_openfile \- open a file and associate an ISC session with it .SH SYNOPSIS .nf .ft B #include #include .ft .fi .LP .nf .ft B IscSession *isc_openfile(IscMaster *mcb, const char *file, int mode) .ft R .fi .SH DESCRIPTION .IX "isc_openfile()" "" "\fLisc_openfile()\fP function" .LP .B isc_openfile(\|) opens a file using the specified modes and inserts the session into the master control structure. .LP The .I mcb argument must point to a previously allocated master structure as returned by the .BR isc_initialize(\|) function call. .LP The .I file argument is a null terminated string pointing at a file to be opened. .LP The .I mode argument contains the flags used for opening the file. The flags are the sames as those used by the .BR open (2v) system call. .SH RETURN VALUES .B isc_openfile(\|) returns a non-\s-1NULL\s0 pointer to a session value suitable for use with subsequent .SM ISC functions calls. On failure, it returns .SM NULL and no memory is allocated and no connection is initiated. .SH "SEE ALSO" .BR open (2v) .BR isc (3x) .BR isc_initialize (3x) .BR isc_shutdown (3x) .BR isc_listentcp (3x) .BR isc_unlisten (3x) .BR isc_opentcp (3x) .BR isc_openfd (3x) .BR isc_close (3x) .BR isc_enable (3x) .BR isc_disable (3x) .BR isc_sessions (3x) .BR isc_getnextevent (3x) .BR isc_dispose (3x) .BR isc_flush (3x) .BR isc_write (3x) .BR isc_putc (3x) .BR isc_printf (3x) lyskom-server-2.1.2/src/libraries/libisc-new/man/isc_opentcp.3x0000664000015100472110000000506506712622602020162 .\" @(#)isc_opentcp.3x 1.0 92/02/03 Lysator .\" ISC - networking library .\" Copyright (C) 1992, 1999 by Peter Eriksson and Per Cederqvist of the .\" Lysator Academic Computer Association. .\" .\" .\" 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 2 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, write to the Free Software .\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. .\" .TH ISC_OPENTCP 3X "3 February 1992" "Release 1.0" "ISC LIBRARY" .SH NAME isc_opentcp \- open a TCP/IP connection and associate it with an ISC session .SH SYNOPSIS .nf .ft B #include .ft .fi .LP .nf .ft B IscSession *isc_opentcp(IscMaster *mcb, const char *host, const char *service) .ft R .fi .SH DESCRIPTION .IX "isc_opentcp()" "" "\fLisc_opentcp()\fP function" .LP .B isc_opentcp(\|) opens a new TCP/IP connection to a remote service. The session is inserted into the master control structure specified. .LP The .I mcb argument must point to a previously allocated master structure as returned by the .B isc_initialize(\|) function call. .LP The .I host argument can either be NULL for a local connection or a null terminated string containing either a domain name or an IP number in decimal notation. .LP The .I service argument is a null termnated string containing either a port number or a service name as specified by the .BR /etc/services file. .SH RETURN VALUES .LP .B isc_opentcp(\|) returns a non-\s-1NULL\s0 pointer to a session value suitable for use with subsequent .SM ISC functions calls. On failure, it returns .SM NULL and no memory is allocated and no connection is initiated. .br .ne 6 .SH FILES .PD 0 .TP 20 .B /etc/services .TP .B /etc/hosts .PD .SH "SEE ALSO" .BR isc (3x) .BR isc_initialize (3x) .BR isc_shutdown (3x) .BR isc_listentcp (3x) .BR isc_unlisten (3x) .BR isc_openfile (3x) .BR isc_openfd (3x) .BR isc_close (3x) .BR isc_enable (3x) .BR isc_disable (3x) .BR isc_sessions (3x) .BR isc_getnextevent (3x) .BR isc_dispose (3x) .BR isc_flush (3x) .BR isc_write (3x) .BR isc_putc (3x) .BR isc_printf (3x) lyskom-server-2.1.2/src/libraries/libisc-new/man/isc_close.3x0000664000015100472110000000327106712622603017615 .\" @(#)isc_close.3x 1.0 92/02/13 Lysator .\" ISC - networking library .\" Copyright (C) 1992, 1999 by Peter Eriksson and Per Cederqvist of the .\" Lysator Academic Computer Association. .\" .\" .\" 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 2 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, write to the Free Software .\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. .\" .TH ISC_CLOSE 3X "24 April 1999" "Release 1.0" "ISC LIBRARY" .SH NAME isc_close \- close an ISC session .SH SYNOPSIS .nf .ft B #ifdef HAVE_STDDEF_H # include #endif #ifdef HAVE_STDARG_H # include #endif #include #include #include #include .ft .fi .LP .nf .ft B void isc_close(IscSession *scb); .ft R .fi .SH DESCRIPTION This function force the session to go into closing state. You will receive the event .SM ISC_EVENT_CLOSED when all queued data has been read and/or sent. To force an immediate close even if there is pending data you should use the .B isc_destroy(3x) function. .SH ARGUMENTS The .I scb argument must be pointer to a session control structure. .SH RETURN VALUES Does not return any value. .SH SEE ALSO .BR isc (3x) lyskom-server-2.1.2/src/libraries/libisc-new/man/isc_listentcp.3x0000664000015100472110000000417206712622604020517 .\" @(#)isc_listentcp.3x 1.0 92/02/13 Lysator .\" ISC - networking library .\" Copyright (C) 1992, 1999 by Peter Eriksson and Per Cederqvist of the .\" Lysator Academic Computer Association. .\" .\" .\" 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 2 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, write to the Free Software .\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. .\" .TH ISC_LISTENTCP 3X "13 February 1992" "Release 1.0" "ISC LIBRARY" .SH NAME isc_listentcp \- listen on a TCP/IP port .SH SYNOPSIS .nf .ft B #include .ft .fi .LP .nf .ft B IscSession *isc_listentcp(mcb, address, service) IscMaster *mcb; const char *address; const char *service; .ft R .fi .SH DESCRIPTION This function inserts a new TCP/IP connection listening port into the master structure specified. With this you can handle remote network connection attempts. .SH ARGUMENTS The following arguments are passed to the function: .TP 10 .I mcb This argument must point to a master control structure. .TP 10 .I address This argument should either point to a null terminated string containing the local address to bind the session to, or be .SM NULL pointer which will bind the session to all local IP addresses. .TP 10 .I service This argument should point at a null terminated string containing either a port number or a service name as specified in the .BR /etc/services file. .SH RETURN VALUES. This function returns a pointer to a session control structure on success, else returns .SM NULL on failure and sets .B errno to indicate the error. .SH ERRORS (to be done) .SH FILES .PD 0 .TP 20 .B /etc/services .PD .SH SEE ALSO .BR isc (3x) lyskom-server-2.1.2/src/libraries/libisc-new/man/isc_unlisten.3x0000664000015100472110000000413706712622605020355 .\" @(#)isc_unlisten.3x 1.0 92/02/03 Lysator .\" ISC - networking library .\" Copyright (C) 1992, 1999 by Peter Eriksson and Per Cederqvist of the .\" Lysator Academic Computer Association. .\" .\" .\" 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 2 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, write to the Free Software .\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. .\" .TH ISC_UNLISTEN 3X "3 February 1992" "Release 1.0" "ISC LIBRARY" .SH NAME isc_unlisten \- remove a listening port from an ISC master structure .SH SYNOPSIS .nf .ft B #include .ft .fi .LP .nf .ft B int isc_unlisten(IscMaster *mcb, int index) .ft R .fi .SH DESCRIPTION .IX "isc_unlisten()" "" "\fLisc_unlisten()\fP function" .LP .B isc_unlisten(\|) is used to remove listening port from the specified master control structure and close the associated file descriptor. .LP The .I mcb argument must point to a previously allocated master structure as returned by the .I isc_initialize(\|) function call. .LP The .I index argument must be a value previously returned from the .B isc_listentcp(\|) function call. .SH RETURN VALUES .LP .B isc_unlisten(\|) returns 0 on success. On failure it returns \-1 and sets .B errno to indicate the error. .br .ne 6 .SH "SEE ALSO" .BR isc (3x) .BR isc_initialize (3x) .BR isc_shutdown (3x) .BR isc_listentcp (3x) .BR isc_opentcp (3x) .BR isc_openfile (3x) .BR isc_openfd (3x) .BR isc_close (3x) .BR isc_enable (3x) .BR isc_disable (3x) .BR isc_sessions (3x) .BR isc_getnextevent (3x) .BR isc_dispose (3x) .BR isc_flush (3x) .BR isc_write (3x) .BR isc_putc (3x) .BR isc_printf (3x) lyskom-server-2.1.2/src/libraries/libisc-new/man/isc_createtcp.3x0000664000015100472110000000306506712622606020466 .\" @(#)isc_createtcp.3x 1.0 92/02/13 Lysator .\" ISC - networking library .\" Copyright (C) 1992, 1999 by Peter Eriksson and Per Cederqvist of the .\" Lysator Academic Computer Association. .\" .\" .\" 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 2 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, write to the Free Software .\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. .\" .TH ISC_CREATETCP 3X "13 February 1992" "Release 1.0" "ISC LIBRARY" .SH NAME isc_createtcp \- create a TCP/IP session .SH SYNOPSIS .nf .ft B #include .ft .fi .LP .nf .ft B IscSession *isc_createtcp(cfg) IscSessionConfig *scb; .ft R .fi .SH DESCRIPTION This function force the session to go into closing state. You will receive the event .SM ISC_EVENT_CLOSED when all queued data has been read and/or sent. To force a close and flush all queued data you should use the .B isc_destroy(3x) function directly. .SH ARGUMENTS The .I scb argument must be pointer to a session control structure. .SH RETURN VALUES Does not return any value. .SH SEE ALSO .BR isc (3x) lyskom-server-2.1.2/src/libraries/libisc-new/man/isc_destroy.3x0000664000015100472110000000361006712622607020202 .\" @(#)isc_destroy.3x 1.0 92/02/13 Lysator .\" ISC - networking library .\" Copyright (C) 1992, 1999 by Peter Eriksson and Per Cederqvist of the .\" Lysator Academic Computer Association. .\" .\" .\" 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 2 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, write to the Free Software .\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. .\" .TH ISC_DESTROY 3X "13 February 1992" "Release 1.0" "ISC LIBRARY" .SH NAME isc_destroy \- close, remove and destroy an ISC session .SH SYNOPSIS .nf .ft B #include .ft .fi .LP .nf .ft B int isc_destroy(mcb, scb) IscMaster *mcb; IscSession *scb; .ft R .fi .SH DESCRIPTION This function force the session to be closed, and all queued data to be lost. It the deallocates the storage for the session control structure. Also optionally removes the session from the master control structure if the latter is specified. .SH ARGUMENTS The following arguments are passed to the function: .TP 10 .I mcb This argument must either point to a master control structure or be a .SM NULL pointer. .TP 10 .I scb This argument must be pointer to a session control structure. .SH RETURN VALUES This function returns: .TP 10 0 on success, .TP 10 \-1 on failure and sets .B errno to indicate the error. .SH ERRORS .TP 10 .SM ENOENT The session specified did not exist in the master control block. .SH SEE ALSO .BR isc (3x) lyskom-server-2.1.2/src/libraries/libisc-new/man/TEMPLATE0000664000015100472110000000317406712622610016534 .\" @(#)XXXXXX.3x 1.0 92/02/13 Lysator .\" ISC - networking library .\" Copyright (C) 1998 by Peter Eriksson and Per Cederqvist of the .\" Lysator Academic Computer Association. .\" .\" .\" 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 2 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, write to the Free Software .\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. .\" .TH XXXXXX 3X "13 February 1992" "Release 1.0" "ISC LIBRARY" .SH NAME XXXXXX \- close, remove and destroy an ISC session .SH SYNOPSIS .nf .ft B #include .ft .fi .LP .nf .ft B int XXXXXX(mcb, scb) IscMaster *mcb; IscSession *scb; .ft R .fi .SH DESCRIPTION .SH ARGUMENTS The following arguments are passed to the function: .TP 10 .I mcb This argument must either point to a master control structure or be a .SM NULL pointer. .TP 10 .I scb This argument must be pointer to a session control structure. .SH RETURN VALUES This function returns: .TP 10 0 on success, .TP 10 \-1 on failure and sets .B errno to indicate the error. .SH ERRORS .TP 10 .SM ENOENT The session specified did not exist in the master control block. .SH SEE ALSO .BR isc (3x) lyskom-server-2.1.2/src/libraries/libisc-new/man/.cvsignore0000664000015100472110000000002506550775557017411 Makefile Makefile.in lyskom-server-2.1.2/src/libraries/libisc-new/doc/0000777000015100472110000000000007723710317015452 5lyskom-server-2.1.2/src/libraries/libisc-new/doc/Makefile.am0000664000015100472110000000007407713267152017430 EXTRA_DIST = .cvsignore MAINTAINERCLEANFILES = Makefile.in lyskom-server-2.1.2/src/libraries/libisc-new/doc/Makefile.in0000664000015100472110000001466507723707450017455 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ prefix = @prefix@ program_transform_name = @program_transform_name@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ EXTRA_DIST = .cvsignore MAINTAINERCLEANFILES = Makefile.in subdir = doc ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = DIST_SOURCES = DIST_COMMON = Makefile.am Makefile.in all: all-am .SUFFIXES: $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) uninstall-info-am: tags: TAGS TAGS: ctags: CTAGS CTAGS: DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = .. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am info info-am install \ install-am install-data install-data-am install-exec \ install-exec-am install-info install-info-am install-man \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \ uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/src/libraries/libisc-new/doc/.cvsignore0000664000015100472110000000002506550775555017401 Makefile Makefile.in lyskom-server-2.1.2/src/libraries/libisc-new/demo/0000777000015100472110000000000007723710320015623 5lyskom-server-2.1.2/src/libraries/libisc-new/demo/README0000664000015100472110000000021306550175123016420 This directory contains very old demo programs. They probably do not work. Please don't use these as example programs for how to use ISC. lyskom-server-2.1.2/src/libraries/libisc-new/demo/Makefile.am0000664000015100472110000000200106712622614017573 # ISC - networking library # Copyright (C) 1998-1999 by Peter Eriksson and Per Cederqvist of the # Lysator Academic Computer Association. # # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library 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 # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the Free # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## Process this file with automake to produce Makefile.in EXTRA_DIST = mux.c mux.h tcp.c udp.c .cvsignore MAINTAINERCLEANFILES = Makefile.in lyskom-server-2.1.2/src/libraries/libisc-new/demo/Makefile.in0000664000015100472110000001651107723707447017632 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # ISC - networking library # Copyright (C) 1998-1999 by Peter Eriksson and Per Cederqvist of the # Lysator Academic Computer Association. # # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library 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 # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the Free # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ prefix = @prefix@ program_transform_name = @program_transform_name@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ EXTRA_DIST = mux.c mux.h tcp.c udp.c .cvsignore MAINTAINERCLEANFILES = Makefile.in subdir = demo ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = DIST_SOURCES = DIST_COMMON = README Makefile.am Makefile.in all: all-am .SUFFIXES: $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu demo/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) uninstall-info-am: tags: TAGS TAGS: ctags: CTAGS CTAGS: DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = .. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am info info-am install \ install-am install-data install-data-am install-exec \ install-exec-am install-info install-info-am install-man \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \ uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/src/libraries/libisc-new/demo/mux.c0000664000015100472110000000765106550775552016546 /* ** libmux.c A set of functions to implement a multiplexing ** protocol above the ISC library ** ** Copyright (c) 1992 Peter Eriksson and Per Cederqvist of the ** Lysator Academic Computer Association. ** ** history: ** 920210 pen initial coding */ #include #include #include "mux.h" #define MAXSESSIONS 20 typedef struct mux_session { IscSession *scb; int id; } MuxSession; typedef struct mux_control { IscSession *scb[MAXSESSIONS]; } MuxControl; static int mux_session_write_fn(IscHandlerList *hl, IscSession *scb, IscMessage *msg) { /* Here, SCB is a pointer to a MUX simulated session */ MuxSession *msp = scb->udg; isc_printf(msp->scb, "MSG #%d %d:", msp->id, msg->length); isc_write(msp->scb, msg->buffer, msg->length); isc_flush(msp->scb); return msg->length; } static int mux_session_close_fn(IscHandlerList *hl, IscSession *scb) { return 0; } static void mux_session_destroy_fn(IscHandlerList *hl, IscSession *scb) { MuxSession *msp; MuxControl *mcp; msp = scb->udg; /* Remove this MUX session from the MUX controller */ mcp = msp->scb->udg; mcp->scb[msp->id] = NULL; free(msp); } static IscSessionFuns isc_session_funs = { NULL, &mux_session_write_fn, &mux_session_close_fn, NULL, NULL, &mux_session_destroy_fn, NULL }; /* ** Allocate storage for a MUX control structure */ MuxControl * mux_newcontrol(void) { MuxControl *mcp; int i; mcp = malloc(sizeof(MuxControl)); if (!mcp) return NULL; for (i = 0; i < MAXSESSIONS; i++) mcp->scb[i] = NULL; return mcp; } /* ** Create a new MUX session on a MUX control session */ IscSession * mux_newsession(IscSession *scb) { MuxSession *msp; MuxControl *mcp; int i; mcp = scb->udg; for (i = 0; i < MAXSESSIONS; i++) if (mcp->scb[i] == NULL) { msp = malloc(sizeof(MuxSession)); if (!msp) return NULL; mcp->scb[i] = isc_create(scb->cfg, &mux_session_funs); msp->id = i; msp->scb = scb; mcp->scb[i]->udg = msp; return scb; } return NULL; } int mux_control_close_fn(IscHandlerList *hl, IscSession *scb) { MuxControl *mcp; int i; mcp = scb->udg; for (i = 0; i < MAXSESSIONS; i++) if (mcp->scb[i]) { isc_close(mcp->scb[i]); mcp->scb[i] = NULL; } if (!hl) return 0; else return (*hl->hcb->close)(hl->old.close, scb); } void mux_control_destroy_fn(IscSession *scb) { mux_control_close_fn(scb); free(mcp); } IscEvent * mux_control_parse_fn(IscSession *scb, IscMesssage *msg) { MuxControl *mcp; IscEvent *ep; IscMessage *nmsg; int id; /* Here we handle the MUX-to-MUX protocol */ mcp = scb->udg; ep = isc_newevent(); while (parse_msg(msg, &ep->event, &id, &nmsg)) switch (ep->event) { case ISC_EVENT_LOGIN: ep->session = mux_newsession(scb); return ep; case ISC_EVENT_LOGOUT: isc_close(mcp->scb[id]); mcp->scb[id] = NULL; break; case ISC_EVENT_MESSAGE: isc_pushqueue(mcp->scb[id]->rd_msg_q, nmsg); break; default: /* Do something, perhaps */ } return NULL; } /* ** Callback function to accept new sessions */ IscSession * mux_control_accept_fn(IscSession *scb, IscMessage *msg) { IscSession *nscb; nscb = isc_tcp_accept_fn(scb, msg); nscb->fun->close = &mux_control_close_fn; nscb->fun->destroy = &mux_control_destroy_fn; nscb->fun->parse = &mux_control_parse_fn; nscb->udg = mux_newcontrol(); return nscb; } /* ** Establish a TCP/IP port to listen at for new MUX connections */ IscSession * mux_listentcp(IscMaster *mcb, const char *address, const char *service) { IscSession *scb; scb = isc_listentcp(mcb, address, service); if (!scb) return NULL scb->fun->accept = &mux_control_accept_fn; return scb; } lyskom-server-2.1.2/src/libraries/libisc-new/demo/mux.h0000664000015100472110000000055006550775552016542 /* ** mux.h A set of functions to implement a multiplexing ** protocol above the ISC library ** ** Copyright (c) 1992 Peter Eriksson and Per Cederqvist of the ** Lysator Academic Computer Association. ** ** history: ** 920210 pen initial coding */ #ifndef __MUX_H__ #define __MUX_H__ #endif lyskom-server-2.1.2/src/libraries/libisc-new/demo/tcp.c0000664000015100472110000001100605242102756016473 /* ** tcp.c A small ISC TCP/IP subsystem demo program ** ** Copyright (c) 1992 Peter Eriksson and Per Cederqvist of the ** Lysator Academic Computer Association. ** ** history: ** 910306 pen initial coding ** 920211 pen cleaned up */ #include #include /* ** Could do a "#define ISC_UDGTYPE foobar" to change the type of ** the (IscSession) 'udg' member pointer type from "void *" to "foobar *". */ #include extern void abort(void); static IscConfig cfg = { 1005, { 1001, { -1, -1, -1, -1, -1 } }, { 1001, { NULL, NULL, NULL }, NULL } }; #define TIMEOUT 30000 /* 30 seconds */ Perror(char *msg) { perror(msg); exit(1); } void main(void) { IscMaster * mcb; /* ISC master control block */ IscSession * scb; /* ISC session control block */ IscEvent * ecb; /* ISC event control block */ puts("Beginning operation..."); /* ** Initialize the ISC subsystem, create a Master Control Block */ if ((mcb = isc_initialize(&cfg)) == NULL) Perror("isc_initialize"); puts("ISC initialized, connecting to remote service..."); /* ** Establish a TCP session to a remote service (IRC) */ if ((scb = isc_opentcp(mcb, "obel5.ida.liu.se", "2000")) == NULL) Perror("isc_opentcp"); puts("Connection initiated, enabling listening ports..."); /* ** Enable remote connection attempts at port #20000 and #20001 */ if (isc_listentcp(mcb, "localhost", "test-service") == NULL) Perror("isc_listentcp-20000"); if (isc_listentcp(mcb, NULL, "20001") == NULL) Perror("isc_listentcp-20001"); puts("Listening ports installed, entering main event loop..."); /* ** Handle all events */ while (ecb = isc_getnextevent(mcb, TIMEOUT)) { switch (ecb->event) { case ISC_EVENT_CONNECTED: puts("Server connection established."); break; case ISC_EVENT_REJECTED: puts("Server connection rejected."); isc_destroy(mcb, scb); scb = NULL; break; case ISC_EVENT_ERROR: /* ISC subsystem error */ fprintf(stderr, "ISC-ERROR: errno = %d", errno); if (ecb->msg) fprintf(stderr, " (%s)", ecb->msg->buffer); putc('\n', stderr); /* ** Should probably do something more sensible than ** just finishing off the session */ if (ecb->session) isc_destroy(mcb, ecb->session); break; case ISC_EVENT_TIMEOUT: /* Timeout limit reached */ puts("*** Timeout ***"); break; case ISC_EVENT_LOGIN: /* New client requesting connection */ { char laddr[256]; char lserv[256]; char raddr[256]; char rserv[256]; strcpy(raddr, ""); strcpy(rserv, ""); strcpy(laddr, ""); strcpy(lserv, ""); fetch_address(ecb->session->info.tcp.raddr, raddr, sizeof(raddr)-1, rserv, sizeof(rserv)-1); fetch_address(ecb->session->info.tcp.laddr, laddr, sizeof(laddr)-1, lserv, sizeof(lserv)-1); printf("New session #%d on %s/%s connecting from: %s/%s\n", ecb->session, laddr, lserv, raddr, rserv); /* ** Here we could assign the 'ecb->session->udg' member some ** arbitrary value to be used later by our own routines */ } break; case ISC_EVENT_LOGOUT: /* Client closed connection */ if (ecb->session == scb) printf("Server disconnecting\n"); else printf("Client #%d disconnecting\n", ecb->session); /* ** Deallocate the storage reserved for the session */ isc_destroy(mcb, ecb->session); break; case ISC_EVENT_MESSAGE: /* Message from client or server */ if (ecb->session == scb) printf("Message from server: '%s'\n", ecb->msg->buffer); else { printf("Message from client #%d: '%s'\n", ecb->session, ecb->msg->buffer); /* ** Reply with some text to the client */ isc_write(ecb->session, "OK, got it\n\r", 12); isc_flush(ecb->session); } break; default: /* NOTREACHED - OR SHOULDN'T BE ATLEAST :-) */ Perror("NOTREACHED"); } /* ** Finished with the event, lets get rid of it */ isc_dispose(ecb); } /* NOTREACHED - I THINK ... */ Perror("SHUTDOWN"); } const char *strerror(int num) { static char foo[256]; sprintf(foo, "Error #%d", num); return foo; } fetch_address(IscAddress *ia, char *host, int hlen, char *port, int plen) { char *cp; cp = isc_gethostname(ia, host, hlen); if (!cp) isc_getipnum(ia, host, hlen); cp = isc_getservice(ia, port, plen, ISC_TYPE_TCP); if (!cp) sprintf(port, "%d", isc_getportnum(ia)); } lyskom-server-2.1.2/src/libraries/libisc-new/demo/udp.c0000664000015100472110000001156205173076107016507 /* ** udp.c A small ISC subsystem demo program ** ** Copyright (c) 1992 Peter Eriksson and Per Cederqvist of the ** Lysator Academic Computer Association. ** ** history: ** 910306 pen initial coding ** 920211 pen code cleaned up */ #include #include /* ** Could do a "#define ISC_UDGTYPE foobar" to change the type of ** the (IscSession) 'udg' member pointer type from "void *" to "foobar *". */ #include extern void abort(void); static IscConfig cfg = { 1005, { 1001, { -1, -1, -1, -1, -1 } }, { 1001 } }; #define TIMEOUT 30000 /* 30 seconds */ Perror(char *msg) { perror(msg); exit(1); } void main(int argc, char *argv[]) { IscMaster * mcb; /* ISC master control block */ IscSession * scb; /* ISC session control block */ IscSession * tty; /* ISC session control block */ IscEvent * ecb; /* ISC event control block */ if (argc < 2) exit(1); puts("Beginning operation..."); /* ** Initialize the ISC subsystem, create a Master Control Block */ if ((mcb = isc_initialize(&cfg)) == NULL) Perror("isc_initialize"); puts("ISC initialized."); if (argc > 2) { /* Client connection */ /* ** Establish a TCP session to a remote service (IRC) */ if ((scb = isc_openudp(mcb, argv[1], argv[2])) == NULL) Perror("isc_openudp"); if ((tty = isc_openfd(mcb, 0)) == NULL) Perror("isc_openfd(tty)"); puts("Connection initiated."); } else { /* ** Enable remote connection attempts at port "argv[1]" */ if (isc_listenudp(mcb, NULL, argv[1]) == 0) Perror("isc_listenudp"); puts("Listening port installed."); } puts("entering main event loop..."); /* ** Handle all events */ while (ecb = isc_getnextevent(mcb, TIMEOUT)) { switch (ecb->event) { case ISC_EVENT_CONNECTED: puts("Server connection established."); break; case ISC_EVENT_REJECTED: puts("Server connection rejected."); isc_destroy(mcb, scb); exit(0); case ISC_EVENT_ERROR: /* ISC subsystem error */ fprintf(stderr, "ISC-ERROR: errno = %d", errno); if (ecb->msg) fprintf(stderr, " (%s)", ecb->msg->buffer); putc('\n', stderr); /* ** Should probably do something more sensible than ** just finishing off the session */ if (ecb->session) isc_destroy(mcb, ecb->session); break; case ISC_EVENT_TIMEOUT: /* Timeout limit reached */ puts("*** Timeout ***"); break; case ISC_EVENT_LOGIN: /* New client requesting connection */ { /* ** THIS SHOULD NORMALLY NEVER HAPPEN FOR UDP SESSIONS */ char laddr[256]; char lserv[256]; char raddr[256]; char rserv[256]; fetch_address(ecb->session->info.tcp.raddr, raddr, sizeof(raddr)-1, rserv, sizeof(rserv)-1); fetch_address(ecb->session->info.tcp.laddr, laddr, sizeof(laddr)-1, lserv, sizeof(lserv)-1); printf("New session #%d on %s/%s connecting from: %s/%s\n", ecb->session, laddr, lserv, raddr, rserv); /* ** Here we could assign the 'ecb->session->udg' member some ** arbitrary value to be used later by our own routines */ } break; case ISC_EVENT_LOGOUT: /* Client closed connection */ if (ecb->session == scb) { printf("Server disconnecting\n"); exit(0); } else printf("Client #%d disconnecting\n", ecb->session); /* ** Deallocate the storage reserved for the session */ isc_destroy(mcb, ecb->session); break; case ISC_EVENT_MESSAGE: /* Message from client or server */ if (ecb->session == scb) printf("Message from server: '%s'\n", ecb->msg->buffer); else if (ecb->session == tty) isc_send(scb, isc_copymsg(ecb->msg)); else { IscMessage *msg; char raddr[256]; char rserv[256]; fetch_address(ecb->msg->address, raddr, sizeof(raddr)-1, rserv, sizeof(rserv)-1); printf("Message from client #%d (%s/%s):\n%s", ecb->session, raddr, rserv, ecb->msg->buffer); fflush(stdout); /* ** Reply with some text to the client */ msg = isc_mkstrmsg("Ok, got it via UDP\n\r"); isc_sendto(ecb->session, ecb->msg->address, msg); isc_flush(ecb->session); } break; default: /* NOTREACHED - OR SHOULDN'T BE ATLEAST :-) */ Perror("NOTREACHED"); } /* ** Finished with the event, lets get rid of it */ isc_dispose(ecb); } /* NOTREACHED - I THINK ... */ Perror("SHUTDOWN"); } const char *strerror(int num) { static char foo[256]; sprintf(foo, "Error #%d", num); return foo; } fetch_address(IscAddress *ia, char *host, int hlen, char *port, int plen) { char *cp; cp = isc_gethostname(ia, host, hlen); if (!cp) isc_getipnum(ia, host, hlen); cp = isc_getservice(ia, port, plen, ISC_TYPE_TCP); if (!cp) sprintf(port, "%d", isc_getportnum(ia)); } lyskom-server-2.1.2/src/libraries/libisc-new/demo/.cvsignore0000664000015100472110000000002506551006652017542 Makefile Makefile.in lyskom-server-2.1.2/src/libraries/libansi/0000777000015100472110000000000007723710322014266 5lyskom-server-2.1.2/src/libraries/libansi/Makefile.am0000664000015100472110000000253607721716121016247 # $Id: Makefile.am,v 1.11 2003/08/23 16:38:21 ceder Exp $ # Copyright (C) 1998-1999, 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # include $(top_srcdir)/scripts/common.make noinst_LIBRARIES = libansi.a libansi_a_SOURCES = empty.c linkansi.h libansi_a_LIBADD = @LIBOBJS@ # strdup is not currently used. Edit configure.in and remove strdup.c # from EXTRA_DIST if it is ever used again. EXTRA_DIST = .cvsignore strdup.c AM_CPPFLAGS = -I$(srcdir)/../../include MOSTLYCLEANFILES = *.da *.bb *.gcov *.bbg lyskom-server-2.1.2/src/libraries/libansi/Makefile.in0000664000015100472110000003461307723707424016271 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # $Id: Makefile.am,v 1.11 2003/08/23 16:38:21 ceder Exp $ # Copyright (C) 1998-1999, 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEBUG_CALLS = @DEBUG_CALLS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EFENCE = @EFENCE@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FLEX = @FLEX@ HAVE_PYTHON_FALSE = @HAVE_PYTHON_FALSE@ HAVE_PYTHON_TRUE = @HAVE_PYTHON_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSURE = @INSURE@ LANGUAGE_SUFFIX = @LANGUAGE_SUFFIX@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ SED = @SED@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRACED_ALLOCATIONS = @TRACED_ALLOCATIONS@ U = @U@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ YACC = @YACC@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ RM = rm -f dbdir = $(localstatedir)/lyskomd/db exportdir = $(localstatedir)/lyskomd/exportdb noinst_LIBRARIES = libansi.a libansi_a_SOURCES = empty.c linkansi.h libansi_a_LIBADD = @LIBOBJS@ # strdup is not currently used. Edit configure.in and remove strdup.c # from EXTRA_DIST if it is ever used again. EXTRA_DIST = .cvsignore strdup.c AM_CPPFLAGS = -I$(srcdir)/../../include MOSTLYCLEANFILES = *.da *.bb *.gcov *.bbg subdir = src/libraries/libansi ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) libansi_a_AR = $(AR) cru libansi_a_DEPENDENCIES = @LIBOBJS@ am_libansi_a_OBJECTS = empty.$(OBJEXT) libansi_a_OBJECTS = $(am_libansi_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/scripts/depcomp am__depfiles_maybe = depfiles @AMDEP_TRUE@DEP_FILES = $(DEPDIR)/memchr.Po $(DEPDIR)/memcmp.Po \ @AMDEP_TRUE@ $(DEPDIR)/memcpy.Po $(DEPDIR)/memset.Po \ @AMDEP_TRUE@ $(DEPDIR)/remove.Po $(DEPDIR)/setsid.Po \ @AMDEP_TRUE@ $(DEPDIR)/strerror.Po ./$(DEPDIR)/empty.Po COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ DIST_SOURCES = $(libansi_a_SOURCES) DIST_COMMON = $(top_srcdir)/scripts/common.make Makefile.am Makefile.in \ memchr.c memcmp.c memcpy.c memset.c remove.c setsid.c \ strerror.c SOURCES = $(libansi_a_SOURCES) all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/scripts/common.make $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/libraries/libansi/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libansi.a: $(libansi_a_OBJECTS) $(libansi_a_DEPENDENCIES) -rm -f libansi.a $(libansi_a_AR) libansi.a $(libansi_a_OBJECTS) $(libansi_a_LIBADD) $(RANLIB) libansi.a mostlyclean-compile: -rm -f *.$(OBJEXT) core *.core distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/memchr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/memcmp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/memcpy.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/memset.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/remove.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/setsid.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strerror.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/empty.Po@am__quote@ distclean-depend: -rm -rf $(DEPDIR) ./$(DEPDIR) .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ @am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ @am__fastdepCC_TRUE@ fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< .c.obj: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ @am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ @am__fastdepCC_TRUE@ fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` uninstall-info-am: ETAGS = etags ETAGSFLAGS = CTAGS = ctags CTAGSFLAGS = tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$tags$$unique" \ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = ../../.. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) $(mkinstalldirs) $(distdir)/../../../scripts @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am distclean-am: clean-am distclean-compile distclean-depend \ distclean-generic distclean-tags dvi: dvi-am dvi-am: info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags distclean distclean-compile \ distclean-depend distclean-generic distclean-tags distdir dvi \ dvi-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/src/libraries/libansi/memchr.c0000664000015100472110000000250407721716122015626 /* * $Id: memchr.c,v 1.13 2003/08/23 16:38:21 ceder Exp $ * Copyright (C) 1991, 1993-1995, 1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ #ifdef HAVE_CONFIG_H # include #endif #ifdef HAVE_STDDEF_H # include #endif #ifdef HAVE_STRING_H # include #endif void * memchr(void *s, int c, size_t len) { char *p = s; while (len-- > 0) if (*p++ == c) return p-1; return NULL; } lyskom-server-2.1.2/src/libraries/libansi/memcmp.c0000664000015100472110000000256107721716122015634 /* * $Id: memcmp.c,v 1.8 2003/08/23 16:38:20 ceder Exp $ * Copyright (C) 1996, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ #ifdef HAVE_CONFIG_H # include #endif #ifdef HAVE_STDDEF_H # include #endif #include int memcmp (const void * s1, const void * s2, size_t n) { unsigned char *uc1 = s1; unsigned char *uc2 = s2; int diff; for (; n > 0; n--, uc1++, uc2++) { diff = *uc1 - *uc2; if (diff != 0) return diff; } return 0; } lyskom-server-2.1.2/src/libraries/libansi/memcpy.c0000664000015100472110000000260007721716122015642 /* * $Id: memcpy.c,v 1.14 2003/08/23 16:38:20 ceder Exp $ * Copyright (C) 1991, 1993-1995, 1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ #ifdef HAVE_CONFIG_H # include #endif #ifdef HAVE_STRING_H #include #endif #include void * memcpy (void * s1, const void * s2, size_t n) { extern bcopy(const char *b1, char *b2, unsigned int length); /* bcopy takes the parameters the other way round. */ bcopy(s2, s1, n); return s1; /* Since ANSI says so */ } lyskom-server-2.1.2/src/libraries/libansi/memset.c0000664000015100472110000000236607721716122015653 /* * $Id: memset.c,v 1.13 2003/08/23 16:38:20 ceder Exp $ * Copyright (C) 1991, 1993-1995, 1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ #ifdef HAVE_CONFIG_H # include #endif #include void memset(void *s, int c, size_t len) { if (c == 0) bzero(s, len); else { char *p = s; while (len-- > 0) *p++ = c; } } lyskom-server-2.1.2/src/libraries/libansi/remove.c0000664000015100472110000000224607721716122015653 /* * $Id: remove.c,v 1.12 2003/08/23 16:38:20 ceder Exp $ * Copyright (C) 1991, 1993-1995, 1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ #ifdef HAVE_CONFIG_H # include #endif #include #include int remove(const char *filname) { return unlink(filname); } lyskom-server-2.1.2/src/libraries/libansi/setsid.c0000664000015100472110000000241507721716122015647 /* * $Id: setsid.c,v 1.7 2003/08/23 16:38:20 ceder Exp $ * Copyright (C) 1995, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ #ifdef HAVE_CONFIG_H # include #endif #include #include pid_t setsid (void) { /* If the system doesn't have setsid(), it probably doesn't have sessions at all, and we don't need to do any real work. */ return getpid(); } lyskom-server-2.1.2/src/libraries/libansi/strerror.c0000664000015100472110000000261007721716122016233 /* * $Id: strerror.c,v 0.24 2003/08/23 16:38:20 ceder Exp $ * Copyright (C) 1991-1995, 1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* ** strerror.c */ #ifdef HAVE_CONFIG_H # include #endif #include #ifdef HAVE_STRING_H # include #endif extern int sys_nerr; extern const char *sys_errlist[]; char *strerror(int eno) { static char buf[20]; if (eno < 0 || eno >= sys_nerr) { sprintf(buf, "Error %d", eno); return buf; } else return (char*)sys_errlist[eno]; } lyskom-server-2.1.2/src/libraries/libansi/empty.c0000664000015100472110000000324207721716121015510 /* * $Id: empty.c,v 1.13 2003/08/23 16:38:21 ceder Exp $ * Copyright (C) 1993, 1998-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ #ifdef HAVE_CONFIG_H # include #endif #include "linkansi.h" /* Some linkers warn if a library isn't used to resolve any symbol, so we include this useless function in libansi.a and use it from main() of all programs that may need to link with libansi.a. A historic note: Some systems complain if a library is empty. This file was initially created as an empty C file, just so that we always had an object file to include in libansi.a. But then, some system complained when a file contained nothing, so we added an external variable. Then we found the warnings from the linker, and added linkansi(). */ void link_ansi(void) { } lyskom-server-2.1.2/src/libraries/libansi/linkansi.h0000664000015100472110000000201307721716121016162 /* * $Id: linkansi.h,v 1.3 2003/08/23 16:38:21 ceder Exp $ * Copyright (C) 2002-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ void link_ansi(void); lyskom-server-2.1.2/src/libraries/libansi/.cvsignore0000664000015100472110000000006206650620443016204 .deps Makefile Makefile.in *.da *.bb *.bbg *.gcov lyskom-server-2.1.2/src/libraries/libansi/strdup.c0000664000015100472110000000226107721716122015674 /* * Copyright (C) 1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ #ifdef HAVE_CONFIG_H # include #endif #include #include char * strdup(const char *s) { char *copy = malloc(strlen(s) + 1); if (copy == NULL) return NULL; strcpy(copy, s); return copy; } lyskom-server-2.1.2/src/libraries/regex/0000777000015100472110000000000007723710331013757 5lyskom-server-2.1.2/src/libraries/regex/README0000664000015100472110000000433705533104324014560 This directory contains the GNU regex library. It is compliant with POSIX.2, except for internationalization features. See the file NEWS for a list of major changes in the current release. See the file INSTALL for compilation instructions. (The only thing installed is the documentation; regex.c is compiled into regex.o, but not installed anywhere.) The subdirectory `doc' contains a (programmers') manual for the library. It's probably out-of-date. Improvements are welcome. The subdirectory `test' contains the various tests we've written. We know this code is not as fast as it might be. If you have specific suggestions, profiling results, or other such useful information to report, please do. Emacs 18 is not going use this revised regex (but Emacs 19 will). If you want to try it with Emacs 18, apply the patch at the end of this file first. Mail bug reports to bug-gnu-utils@prep.ai.mit.edu. Please include an actual regular expression that fails (and the syntax used to compile it); without that, there's no way to reproduce the bug, so there's no way we can fix it. Even if you include a patch, also include the regular expression in error; otherwise, we can't know for sure what you're trying to fix. Here is the patch to make this version of regex work with Emacs 18. *** ORIG/search.c Tue Jan 8 13:04:55 1991 --- search.c Sun Jan 5 10:57:00 1992 *************** *** 25,26 **** --- 25,28 ---- #include "commands.h" + + #include #include "regex.h" *************** *** 477,479 **** /* really needed. */ ! && *(searchbuf.buffer) == (char) exactn /* first item is "exact match" */ && searchbuf.buffer[1] + 2 == searchbuf.used) /*first is ONLY item */ --- 479,482 ---- /* really needed. */ ! /* first item is "exact match" */ ! && *(searchbuf.buffer) == (char) RE_EXACTN_VALUE && searchbuf.buffer[1] + 2 == searchbuf.used) /*first is ONLY item */ *************** *** 1273,1275 **** searchbuf.allocated = 100; ! searchbuf.buffer = (char *) malloc (searchbuf.allocated); searchbuf.fastmap = search_fastmap; --- 1276,1278 ---- searchbuf.allocated = 100; ! searchbuf.buffer = (unsigned char *) malloc (searchbuf.allocated); searchbuf.fastmap = search_fastmap; lyskom-server-2.1.2/src/libraries/regex/AUTHORS0000664000015100472110000000063005314452674014753 Richard Stallman -- original version and continuing revisions of regex.c and regex.h, and original version of the documentation. Karl Berry and Kathryn Hargreaves -- extensive modifications to above, and all test files. Jim Blandy -- original version of re_set_registers, revisions to regex.c. Joe Arceneaux, David MacKenzie, Mike Haertel, Charles Hannum, and probably others -- revisions to regex.c. lyskom-server-2.1.2/src/libraries/regex/COPYING0000664000015100472110000004307605314452676014753 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy 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 2 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, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. lyskom-server-2.1.2/src/libraries/regex/ChangeLog0000664000015100472110000042321106721264633015460 1999-05-21 Per Cederqvist Remove all gcov files in "make mostlyclean". * Makefile.am (MOSTLYCLEANFILES): Added *.da, *.bb, *.gcov and *.bbg. 1999-04-03 Per Cederqvist Distribute the subdirectories. * Makefile.am (SUBDIRS): New variable. Added doc and test. * doc/Makefile.am: New file. 1999-01-18 David Byers * .cvsignore: Added .da, .bb, .bbg and .gcov files. 1998-07-09 Per Cederqvist * Makefile.in: No longer kept under version control. 1998-07-08 Per Cederqvist * Makefile.am: New file. Tue Sep 5 20:32:00 1995 Per Cederqvist (ceder@lysator.liu.se) * regex.c: Don't define _GNU_SOURCE if it is already defined. Sat Feb 19 05:47:32 1994 Per Cederqvist (ceder@lysator.liu.se) * Makefile.in (clean et c): Fixed the clean rules. Wed Oct 13 00:58:41 1993 Per Cederqvist (ceder@lysator.liu.se) * Makefile.in (clean et c): Copy clean rules from the LysKOM project. * Makefile.in (SUBDIRS): Renamed subdirs to SUBDIRS. Sun Oct 10 12:36:44 1993 Per Cederqvist (ceder@lysator.liu.se) * doc/Makefile.in hacked to fit the LysKOM project. Fri Oct 8 00:37:52 1993 Per Cederqvist (ceder@lysator.liu.se) * Makefile.in hacked to fit the LysKOM project. Fri Apr 2 17:31:59 1993 Jim Blandy (jimb@totoro.cs.oberlin.edu) * Released version 0.12. * regex.c (regerror): If errcode is zero, that's not a valid error code, according to POSIX, but return "Success." * regex.c (regerror): Remember to actually fetch the message from re_error_msg. * regex.c (regex_compile): Don't use the trick for ".*\n" on ".+\n". Since the latter involves laying an extra choice point, the backward jump isn't adjusted properly. Thu Mar 25 21:35:18 1993 Jim Blandy (jimb@totoro.cs.oberlin.edu) * regex.c (regex_compile): In the handle_open and handle_close sections, clear pending_exact to zero. Tue Mar 9 12:03:07 1993 Jim Blandy (jimb@wookumz.gnu.ai.mit.edu) * regex.c (re_search_2): In the loop which searches forward using fastmap, don't forget to cast the character from the string to an unsigned before using it as an index into the translate map. Thu Jan 14 15:41:46 1993 David J. MacKenzie (djm@kropotkin.gnu.ai.mit.edu) * regex.h: Never define const; let the callers do it. configure.in: Don't define USING_AUTOCONF. Wed Jan 6 20:49:29 1993 Jim Blandy (jimb@geech.gnu.ai.mit.edu) * regex.c (regerror): Abort if ERRCODE is out of range. Sun Dec 20 16:19:10 1992 Jim Blandy (jimb@totoro.cs.oberlin.edu) * configure.in: Arrange to #define USING_AUTOCONF. * regex.h: If USING_AUTOCONF is #defined, don't mess with `const' at all; autoconf has taken care of it. Mon Dec 14 21:40:39 1992 David J. MacKenzie (djm@kropotkin.gnu.ai.mit.edu) * regex.h (RE_SYNTAX_AWK): Fix typo. From Arnold Robbins. Sun Dec 13 20:35:39 1992 Jim Blandy (jimb@totoro.cs.oberlin.edu) * regex.c (compile_range): Fetch the range start and end by casting the pattern pointer to an `unsigned char *' before fetching through it. Sat Dec 12 09:41:01 1992 Jim Blandy (jimb@totoro.cs.oberlin.edu) * regex.c: Undo change of 12/7/92; it's better for Emacs to #define HAVE_CONFIG_H. Fri Dec 11 22:00:34 1992 Jim Meyering (meyering@hal.gnu.ai.mit.edu) * regex.c: Define and use isascii-protected ctype.h macros. Fri Dec 11 05:10:38 1992 Jim Blandy (jimb@totoro.cs.oberlin.edu) * regex.c (re_match_2): Undo Karl's November 10th change; it keeps the group in :\(.*\) from matching :/ properly. Mon Dec 7 19:44:56 1992 Jim Blandy (jimb@wookumz.gnu.ai.mit.edu) * regex.c: #include config.h if either HAVE_CONFIG_H or emacs is #defined. Tue Dec 1 13:33:17 1992 David J. MacKenzie (djm@goldman.gnu.ai.mit.edu) * regex.c [HAVE_CONFIG_H]: Include config.h. Wed Nov 25 23:46:02 1992 David J. MacKenzie (djm@goldman.gnu.ai.mit.edu) * regex.c (regcomp): Add parens around bitwise & for clarity. Initialize preg->allocated to prevent segv. Tue Nov 24 09:22:29 1992 David J. MacKenzie (djm@goldman.gnu.ai.mit.edu) * regex.c: Use HAVE_STRING_H, not USG. * configure.in: Check for string.h, not USG. Fri Nov 20 06:33:24 1992 Karl Berry (karl@cs.umb.edu) * regex.c (SIGN_EXTEND_CHAR) [VMS]: Back out of this change, since Roland Roberts now says it was a localism. Mon Nov 16 07:01:36 1992 Karl Berry (karl@cs.umb.edu) * regex.h (const) [!HAVE_CONST]: Test another cpp symbol (from Autoconf) before zapping const. Sun Nov 15 05:36:42 1992 Jim Blandy (jimb@wookumz.gnu.ai.mit.edu) * regex.c, regex.h: Changes for VMS from Roland B Roberts . Thu Nov 12 11:31:15 1992 Karl Berry (karl@cs.umb.edu) * Makefile.in (distfiles): Include INSTALL. Tue Nov 10 09:29:23 1992 Karl Berry (karl@cs.umb.edu) * regex.c (re_match_2): At maybe_pop_jump, if at end of string and pattern, just quit the matching loop. * regex.c (LETTER_P): Rename to `WORDCHAR_P'. * regex.c (AT_STRINGS_{BEG,END}): Take `d' as an arg; change callers. * regex.c (re_match_2) [!emacs]: In wordchar and notwordchar cases, advance d. Wed Nov 4 15:43:58 1992 Karl Berry (karl@hal.gnu.ai.mit.edu) * regex.h (const) [!__STDC__]: Don't define if it's already defined. Sat Oct 17 19:28:19 1992 Karl Berry (karl@cs.umb.edu) * regex.c (bcmp, bcopy, bzero): Only #define if they are not already #defined. * configure.in: Use AC_CONST. Thu Oct 15 08:39:06 1992 Karl Berry (karl@cs.umb.edu) * regex.h (const) [!const]: Conditionalize. Fri Oct 2 13:31:42 1992 Karl Berry (karl@cs.umb.edu) * regex.h (RE_SYNTAX_ED): New definition. Sun Sep 20 12:53:39 1992 Karl Berry (karl@cs.umb.edu) * regex.[ch]: remove traces of `longest_p' -- dumb idea to put this into the pattern buffer, as it means parallelism loses. * Makefile.in (config.status): use sh to run configure --no-create. * Makefile.in (realclean): OK, don't remove configure. Sat Sep 19 09:05:08 1992 Karl Berry (karl@hayley) * regex.c (PUSH_FAILURE_POINT, POP_FAILURE_POINT) [DEBUG]: keep track of how many failure points we push and pop. (re_match_2) [DEBUG]: declare variables for that, and print results. (DEBUG_PRINT4): new macro. * regex.h (re_pattern_buffer): new field `longest_p' (to eliminate backtracking if the user doesn't need it). * regex.c (re_compile_pattern): initialize it (to 1). (re_search_2): set it to zero if register information is not needed. (re_match_2): if it's set, don't backtrack. * regex.c (re_search_2): update fastmap only after checking that the pattern is anchored. * regex.c (re_match_2): do more debugging at maybe_pop_jump. * regex.c (re_search_2): cast result of TRANSLATE for use in array subscript. Thu Sep 17 19:47:16 1992 Karl Berry (karl@geech.gnu.ai.mit.edu) * Version 0.11. Wed Sep 16 08:17:10 1992 Karl Berry (karl@hayley) * regex.c (INIT_FAIL_STACK): rewrite as statements instead of a complicated comma expr, to avoid compiler warnings (and also simplify). (re_compile_fastmap, re_match_2): change callers. * regex.c (POP_FAILURE_POINT): cast pop of regstart and regend to avoid compiler warnings. * regex.h (RE_NEWLINE_ORDINARY): remove this syntax bit, and remove uses. * regex.c (at_{beg,end}line_loc_p): go the last mile: remove the RE_NEWLINE_ORDINARY case which made the ^ in \n^ be an anchor. Tue Sep 15 09:55:29 1992 Karl Berry (karl@hayley) * regex.c (at_begline_loc_p): new fn. (at_endline_loc_p): simplify at_endline_op_p. (regex_compile): in ^/$ cases, call the above. * regex.c (POP_FAILURE_POINT): rewrite the fn as a macro again, as lord's profiling indicates the function is 20% of the time. (re_match_2): callers changed. * configure.in (AC_MEMORY_H): remove, since we never use memcpy et al. Mon Sep 14 17:49:27 1992 Karl Berry (karl@hayley) * Makefile.in (makeargs): include MFLAGS. Sun Sep 13 07:41:45 1992 Karl Berry (karl@hayley) * regex.c (regex_compile): in \1..\9 case, make it always invalid to use \ if there is no preceding th subexpr. * regex.h (RE_NO_MISSING_BK_REF): remove this syntax bit. * regex.c (regex_compile): remove support for invalid empty groups. * regex.h (RE_NO_EMPTY_GROUPS): remove this syntax bit. * regex.c (FREE_VARIABLES) [!REGEX_MALLOC]: define as alloca (0), to reclaim memory. * regex.h (RE_SYNTAX_POSIX_SED): don't bother with this. Sat Sep 12 13:37:21 1992 Karl Berry (karl@hayley) * README: incorporate emacs.diff. * regex.h (_RE_ARGS) [!__STDC__]: define as empty parens. * configure.in: add AC_ALLOCA. * Put test files in subdir test, documentation in subdir doc. Adjust Makefile.in and configure.in accordingly. Thu Sep 10 10:29:11 1992 Karl Berry (karl@hayley) * regex.h (RE_SYNTAX_{POSIX_,}SED): new definitions. Wed Sep 9 06:27:09 1992 Karl Berry (karl@hayley) * Version 0.10. Tue Sep 8 07:32:30 1992 Karl Berry (karl@hayley) * xregex.texinfo: put the day of month into the date. * Makefile.in (realclean): remove Texinfo-generated files. (distclean): remove empty sorted index files. (clean): remove dvi files, etc. * configure.in: test for more Unix variants. * fileregex.c: new file. Makefile.in (fileregex): new target. * iregex.c (main): move variable decls to smallest scope. * regex.c (FREE_VARIABLES): free reg_{,info_}dummy. (re_match_2): check that the allocation for those two succeeded. * regex.c (FREE_VAR): replace FREE_NONNULL with this. (FREE_VARIABLES): call it. (re_match_2) [REGEX_MALLOC]: initialize all our vars to NULL. * tregress.c (do_match): generalize simple_match. (SIMPLE_NONMATCH): new macro. (SIMPLE_MATCH): change from routine. * Makefile.in (regex.texinfo): make file readonly, so we don't edit it by mistake. * many files (re_default_syntax): rename to `re_syntax_options'; call re_set_syntax instead of assigning to the variable where possible. Mon Sep 7 10:12:16 1992 Karl Berry (karl@hayley) * syntax.skel: don't use prototypes. * {configure,Makefile}.in: new files. * regex.c: include `#if USG || STDC_HEADERS'; remove obsolete test for `POSIX', and test for BSRTING. Include if we are not USG or STDC_HEADERS. Do not include . What did we ever need that for? * regex.h (RE_NO_EMPTY_ALTS): remove this. (RE_SYNTAX_AWK): remove from here, too. * regex.c (regex_compile): remove the check. * xregex.texinfo (Alternation Operator): update. * other.c (test_others): remove tests for this. * regex.h (RE_DUP_MAX): undefine if already defined. * regex.h: (RE_SYNTAX_POSIX*): redo to allow more operators, and define new syntaxes with the minimal set. * syntax.skel (main): used sscanf instead of scanf. * regex.h (RE_SYNTAX_*GREP): new definitions from mike. * regex.c (regex_compile): initialize the upper bound of intervals at the beginning of the interval, not the end. (From pclink@qld.tne.oz.au.) * regex.c (handle_bar): rename to `handle_alt', for consistency. * regex.c ({store,insert}_{op1,op2}): new routines (except the last). ({STORE,INSERT}_JUMP{,2}): macros to replace the old routines, which took arguments in different orders, and were generally weird. * regex.c (PAT_PUSH*): rename to `BUF_PUSH*' -- we're not appending info to the pattern! Sun Sep 6 11:26:49 1992 Karl Berry (karl@hayley) * regex.c (regex_compile): delete the variable `following_left_brace', since we never use it. * regex.c (print_compiled_pattern): don't print the fastmap if it's null. * regex.c (re_compile_fastmap): handle `on_failure_keep_string_jump' like `on_failure_jump'. * regex.c (re_match_2): in `charset{,_not' case, cast the bit count to unsigned, not unsigned char, in case we have a full 32-byte bit list. * tregress.c (simple_match): remove. (simple_test): rename as `simple_match'. (simple_compile): print the error string if the compile failed. * regex.c (DO_RANGE): rewrite as a function, `compile_range', so we can debug it. Change pattern characters to unsigned char *'s, and change the range variable to an unsigned. (regex_compile): change calls. Sat Sep 5 17:40:49 1992 Karl Berry (karl@hayley) * regex.h (_RE_ARGS): new macro to put in argument lists (if ANSI) or omit them (if K&R); don't declare routines twice. * many files (obscure_syntax): rename to `re_default_syntax'. Fri Sep 4 09:06:53 1992 Karl Berry (karl@hayley) * GNUmakefile (extraclean): new target. (realclean): delete the info files. Wed Sep 2 08:14:42 1992 Karl Berry (karl@hayley) * regex.h: doc fix. Sun Aug 23 06:53:15 1992 Karl Berry (karl@hayley) * regex.[ch] (re_comp): no const in the return type (from djm). Fri Aug 14 07:25:46 1992 Karl Berry (karl@hayley) * regex.c (DO_RANGE): declare variables as unsigned chars, not signed chars (from jimb). Wed Jul 29 18:33:53 1992 Karl Berry (karl@claude.cs.umb.edu) * Version 0.9. * GNUmakefile (distclean): do not remove regex.texinfo. (realclean): remove it here. * tregress.c (simple_test): initialize buf.buffer. Sun Jul 26 08:59:38 1992 Karl Berry (karl@hayley) * regex.c (push_dummy_failure): new opcode and corresponding case in the various routines. Pushed at the end of alternatives. * regex.c (jump_past_next_alt): rename to `jump_past_alt', for brevity. (no_pop_jump): rename to `jump'. * regex.c (regex_compile) [DEBUG]: terminate printing of pattern with a newline. * NEWS: new file. * tregress.c (simple_{compile,match,test}): routines to simplify all these little tests. * tregress.c: test for matching as much as possible. Fri Jul 10 06:53:32 1992 Karl Berry (karl@hayley) * Version 0.8. Wed Jul 8 06:39:31 1992 Karl Berry (karl@hayley) * regex.c (SIGN_EXTEND_CHAR): #undef any previous definition, as ours should always work properly. Mon Jul 6 07:10:50 1992 Karl Berry (karl@hayley) * iregex.c (main) [DEBUG]: conditionalize the call to print_compiled_pattern. * iregex.c (main): initialize buf.buffer to NULL. * tregress (test_regress): likewise. * regex.c (alloca) [sparc]: #if on HAVE_ALLOCA_H instead. * tregress.c (test_regress): didn't have jla's test quite right. Sat Jul 4 09:02:12 1992 Karl Berry (karl@hayley) * regex.c (re_match_2): only REGEX_ALLOCATE all the register vectors if the pattern actually has registers. (match_end): new variable to avoid having to use best_regend[0]. * regex.c (IS_IN_FIRST_STRING): rename to FIRST_STRING_P. * regex.c: doc fixes. * tregess.c (test_regress): new fastmap test forwarded by rms. * tregress.c (test_regress): initialize the fastmap field. * tregress.c (test_regress): new test from jla that aborted in re_search_2. Fri Jul 3 09:10:05 1992 Karl Berry (karl@hayley) * tregress.c (test_regress): add tests for translating charsets, from kaoru. * GNUmakefile (common): add alloca.o. * alloca.c: new file, copied from bison. * other.c (test_others): remove var `buf', since it's no longer used. * Below changes from ro@TechFak.Uni-Bielefeld.DE. * tregress.c (test_regress): initialize buf.allocated. * regex.c (re_compile_fastmap): initialize `succeed_n_p'. * GNUmakefile (regex): depend on $(common). Wed Jul 1 07:12:46 1992 Karl Berry (karl@hayley) * Version 0.7. * regex.c: doc fixes. Mon Jun 29 08:09:47 1992 Karl Berry (karl@fosse) * regex.c (pop_failure_point): change string vars to `const char *' from `unsigned char *'. * regex.c: consolidate debugging stuff. (print_partial_compiled_pattern): avoid enum clash. Mon Jun 29 07:50:27 1992 Karl Berry (karl@hayley) * xmalloc.c: new file. * GNUmakefile (common): add it. * iregex.c (print_regs): new routine (from jimb). (main): call it. Sat Jun 27 10:50:59 1992 Jim Blandy (jimb@pogo.cs.oberlin.edu) * xregex.c (re_match_2): When we have accepted a match and restored d from best_regend[0], we need to set dend appropriately as well. Sun Jun 28 08:48:41 1992 Karl Berry (karl@hayley) * tregress.c: rename from regress.c. * regex.c (print_compiled_pattern): improve charset case to ease byte-counting. Also, don't distinguish between Emacs and non-Emacs {not,}wordchar opcodes. * regex.c (print_fastmap): move here. * test.c: from here. * regex.c (print_{{partial,}compiled_pattern,double_string}): rename from ..._printer. Change calls here and in test.c. * regex.c: create from xregex.c and regexinc.c for once and for all, and change the debug fns to be extern, instead of static. * GNUmakefile: remove traces of xregex.c. * test.c: put in externs, instead of including regexinc.c. * xregex.c: move interactive main program and scanstring to iregex.c. * iregex.c: new file. * upcase.c, printchar.c: new files. * various doc fixes and other cosmetic changes throughout. * regexinc.c (compiled_pattern_printer): change variable name, for consistency. (partial_compiled_pattern_printer): print other info about the compiled pattern, besides just the opcodes. * xregex.c (regex_compile) [DEBUG]: print the compiled pattern when we're done. * xregex.c (re_compile_fastmap): in the duplicate case, set `can_be_null' and return. Also, set `bufp->can_be_null' according to a new variable, `path_can_be_null'. Also, rewrite main while loop to not test `p != NULL', since we never set it that way. Also, eliminate special `can_be_null' value for the endline case. (re_search_2): don't test for the special value. * regex.h (struct re_pattern_buffer): remove the definition. Sat Jun 27 15:00:40 1992 Karl Berry (karl@hayley) * xregex.c (re_compile_fastmap): remove the `RE_' from `REG_RE_MATCH_NULL_AT_END'. Also, assert the fastmap in the pattern buffer is non-null. Also, reset `succeed_n_p' after we've paid attention to it, instead of every time through the loop. Also, in the `anychar' case, only clear fastmap['\n'] if the syntax says to, and don't return prematurely. Also, rearrange cases in some semblance of a rational order. * regex.h (REG_RE_MATCH_NULL_AT_END): remove the `RE_' from the name. * other.c: take bug reports from here. * regress.c: new file for them. * GNUmakefile (test): add it. * main.c (main): new possible test. * test.h (test_type): new value in enum. Thu Jun 25 17:37:43 1992 Karl Berry (karl@hayley) * xregex.c (scanstring) [test]: new function from jimb to allow some escapes. (main) [test]: call it (on the string, not the pattern). * xregex.c (main): make return type `int'. Wed Jun 24 10:43:03 1992 Karl Berry (karl@hayley) * xregex.c (pattern_offset_t): change to `int', for the benefit of patterns which compile to more than 2^15 bytes. * xregex.c (GET_BUFFER_SPACE): remove spurious braces. * xregex.texinfo (Using Registers): put in a stub to ``document'' the new function. * regex.h (re_set_registers) [!__STDC__]: declare. * xregex.c (re_set_registers): declare K&R style (also move to a different place in the file). Mon Jun 8 18:03:28 1992 Jim Blandy (jimb@pogo.cs.oberlin.edu) * regex.h (RE_NREGS): Doc fix. * xregex.c (re_set_registers): New function. * regex.h (re_set_registers): Declaration for new function. Fri Jun 5 06:55:18 1992 Karl Berry (karl@hayley) * main.c (main): `return 0' instead of `exit (0)'. (From Paul Eggert) * regexinc.c (SIGN_EXTEND_CHAR): cast to unsigned char. (extract_number, EXTRACT_NUMBER): don't bother to cast here. Tue Jun 2 07:37:53 1992 Karl Berry (karl@hayley) * Version 0.6. * Change copyrights to `1985, 89, ...'. * regex.h (REG_RE_MATCH_NULL_AT_END): new macro. * xregex.c (re_compile_fastmap): initialize `can_be_null' to `p==pend', instead of in the test at the top of the loop (as it was, it was always being set). Also, set `can_be_null'=1 if we would jump to the end of the pattern in the `on_failure_jump' cases. (re_search_2): check if `can_be_null' is 1, not nonzero. This was the original test in rms' regex; why did we change this? * xregex.c (re_compile_fastmap): rename `is_a_succeed_n' to `succeed_n_p'. Sat May 30 08:09:08 1992 Karl Berry (karl@hayley) * xregex.c (re_compile_pattern): declare `regnum' as `unsigned', not `regnum_t', for the benefit of those patterns with more than 255 groups. * xregex.c: rename `failure_stack' to `fail_stack', for brevity; likewise for `match_nothing' to `match_null'. * regexinc.c (REGEX_REALLOCATE): take both the new and old sizes, and copy only the old bytes. * xregex.c (DOUBLE_FAILURE_STACK): pass both old and new. * This change from Thorsten Ohl. Fri May 29 11:45:22 1992 Karl Berry (karl@hayley) * regexinc.c (SIGN_EXTEND_CHAR): define as `(signed char) c' instead of relying on __CHAR_UNSIGNED__, to work with compilers other than GCC. From Per Bothner. * main.c (main): change return type to `int'. Mon May 18 06:37:08 1992 Karl Berry (karl@hayley) * regex.h (RE_SYNTAX_AWK): typo in RE_RE_UNMATCHED... Fri May 15 10:44:46 1992 Karl Berry (karl@hayley) * Version 0.5. Sun May 3 13:54:00 1992 Karl Berry (karl@hayley) * regex.h (struct re_pattern_buffer): now it's just `regs_allocated'. (REGS_UNALLOCATED, REGS_REALLOCATE, REGS_FIXED): new constants. * xregex.c (regexec, re_compile_pattern): set the field appropriately. (re_match_2): and use it. bufp can't be const any more. Fri May 1 15:43:09 1992 Karl Berry (karl@hayley) * regexinc.c: unconditionally include , first. * regex.h (struct re_pattern_buffer): rename `caller_allocated_regs' to `regs_allocated_p'. * xregex.c (re_compile_pattern): same change here. (regexec): and here. (re_match_2): reallocate registers if necessary. Fri Apr 10 07:46:50 1992 Karl Berry (karl@hayley) * regex.h (RE_SYNTAX{_POSIX,}_AWK): new definitions from Arnold. Sun Mar 15 07:34:30 1992 Karl Berry (karl at hayley) * GNUmakefile (dist): versionize regex.{c,h,texinfo}. Tue Mar 10 07:05:38 1992 Karl Berry (karl at hayley) * Version 0.4. * xregex.c (PUSH_FAILURE_POINT): always increment the failure id. (DEBUG_STATEMENT) [DEBUG]: execute the statement even if `debug'==0. * xregex.c (pop_failure_point): if the saved string location is null, keep the current value. (re_match_2): at fail, test for a dummy failure point by checking the restored pattern value, not string value. (re_match_2): new case, `on_failure_keep_string_jump'. (regex_compile): output this opcode in the .*\n case. * regexinc.c (re_opcode_t): define the opcode. (partial_compiled_pattern_pattern): add the new case. Mon Mar 9 09:09:27 1992 Karl Berry (karl at hayley) * xregex.c (regex_compile): optimize .*\n to output an unconditional jump to the ., instead of pushing failure points each time through the loop. * xregex.c (DOUBLE_FAILURE_STACK): compute the maximum size ourselves (and correctly); change callers. Sun Mar 8 17:07:46 1992 Karl Berry (karl at hayley) * xregex.c (failure_stack_elt_t): change to `const char *', to avoid warnings. * regex.h (re_set_syntax): declare this. * xregex.c (pop_failure_point) [DEBUG]: conditionally pass the original strings and sizes; change callers. Thu Mar 5 16:35:35 1992 Karl Berry (karl at claude.cs.umb.edu) * xregex.c (regnum_t): new type for register/group numbers. (compile_stack_elt_t, regex_compile): use it. * xregex.c (regexec): declare len as `int' to match re_search. * xregex.c (re_match_2): don't declare p1 twice. * xregex.c: change `while (1)' to `for (;;)' to avoid silly compiler warnings. * regex.h [__STDC__]: use #if, not #ifdef. * regexinc.c (REGEX_REALLOCATE): cast the result of alloca to (char *), to avoid warnings. * xregex.c (regerror): declare variable as const. * xregex.c (re_compile_pattern, re_comp): define as returning a const char *. * regex.h (re_compile_pattern, re_comp): likewise. Thu Mar 5 15:57:56 1992 Karl Berry (karl@hal) * xregex.c (regcomp): declare `syntax' as unsigned. * xregex.c (re_match_2): try to avoid compiler warnings about unsigned comparisons. * GNUmakefile (test-xlc): new target. * regex.h (reg_errcode_t): remove trailing comma from definition. * regexinc.c (re_opcode_t): likewise. Thu Mar 5 06:56:07 1992 Karl Berry (karl at hayley) * GNUmakefile (dist): add version numbers automatically. (versionfiles): new variable. (regex.{c,texinfo}): don't add version numbers here. * regex.h: put in placeholder instead of the version number. Fri Feb 28 07:11:33 1992 Karl Berry (karl at hayley) * xregex.c (re_error_msg): declare const, since it is. Sun Feb 23 05:41:57 1992 Karl Berry (karl at fosse) * xregex.c (PAT_PUSH{,_2,_3}, ...): cast args to avoid warnings. (regex_compile, regexec): return REG_NOERROR, instead of 0, on success. (boolean): define as char, and #define false and true. * regexinc.c (STREQ): cast the result. Sun Feb 23 07:45:38 1992 Karl Berry (karl at hayley) * GNUmakefile (test-cc, test-hc, test-pcc): new targets. * regex.inc (extract_number, extract_number_and_incr) [DEBUG]: only define if we are debugging. * xregex.c [_AIX]: do #pragma alloca first if necessary. * regexinc.c [_AIX]: remove the #pragma from here. * regex.h (reg_syntax_t): declare as unsigned, and redo the enum as #define's again. Some compilers do stupid things with enums. Thu Feb 20 07:19:47 1992 Karl Berry (karl at hayley) * Version 0.3. * xregex.c, regex.h (newline_anchor_match_p): rename to `newline_anchor'; dumb idea to change the name. Tue Feb 18 07:09:02 1992 Karl Berry (karl at hayley) * regexinc.c: go back to original, i.e., don't include or define strchr. * xregex.c (regexec): don't bother with adding characters after newlines to the fastmap; instead, just don't use a fastmap. * xregex.c (regcomp): set the buffer and fastmap fields to zero. * xregex.texinfo (GNU r.e. compiling): have to initialize more than two fields. * regex.h (struct re_pattern_buffer): rename `newline_anchor' to `newline_anchor_match_p', as we're back to two cases. * xregex.c (regcomp, re_compile_pattern, re_comp): change accordingly. (re_match_2): at begline and endline, POSIX is not a special case anymore; just check newline_anchor_match_p. Thu Feb 13 16:29:33 1992 Karl Berry (karl at hayley) * xregex.c (*empty_string*): rename to *null_string*, for brevity. Wed Feb 12 06:36:22 1992 Karl Berry (karl at hayley) * xregex.c (re_compile_fastmap): at endline, don't set fastmap['\n']. (re_match_2): rewrite the begline/endline cases to take account of the new field newline_anchor. Tue Feb 11 14:34:55 1992 Karl Berry (karl at hayley) * regexinc.c [!USG etc.]: include and define strchr as index. * xregex.c (re_search_2): when searching backwards, declare `c' as a char and use casts when using it as an array subscript. * xregex.c (regcomp): if REG_NEWLINE, set RE_HAT_LISTS_NOT_NEWLINE. Set the `newline_anchor' field appropriately. (regex_compile): compile [^...] as matching a \n according to the syntax bit. (regexec): if doing REG_NEWLINE stuff, compile a fastmap and add characters after any \n's to the newline. * regex.h (RE_HAT_LISTS_NOT_NEWLINE): new syntax bit. (struct re_pattern_buffer): rename `posix_newline' to `newline_anchor', define constants for its values. Mon Feb 10 07:22:50 1992 Karl Berry (karl at hayley) * xregex.c (re_compile_fastmap): combine the code at the top and bottom of the loop, as it's essentially identical. Sun Feb 9 10:02:19 1992 Karl Berry (karl at hayley) * xregex.texinfo (POSIX Translate Tables): remove this, as it doesn't match the spec. * xregex.c (re_compile_fastmap): if we finish off a path, go back to the top (to set can_be_null) instead of returning immediately. * xregex.texinfo: changes from bob. Sat Feb 1 07:03:25 1992 Karl Berry (karl at hayley) * xregex.c (re_search_2): doc fix (from rms). Fri Jan 31 09:52:04 1992 Karl Berry (karl at hayley) * xregex.texinfo (GNU Searching): clarify the range arg. * xregex.c (re_match_2, at_endline_op_p): add extra parens to get rid of GCC 2's (silly, IMHO) warning about && within ||. * xregex.c (common_op_match_empty_string_p): use MATCH_NOTHING_UNSET_VALUE, not -1. Thu Jan 16 08:43:02 1992 Karl Berry (karl at hayley) * xregex.c (SET_REGS_MATCHED): only set the registers from lowest to highest. * regexinc.c (MIN): new macro. * xregex.c (re_match_2): only check min (num_regs, regs->num_regs) when we set the returned regs. * xregex.c (re_match_2): set registers after the first num_regs to -1 before we return. Tue Jan 14 16:01:42 1992 Karl Berry (karl at hayley) * xregex.c (re_match_2): initialize max (RE_NREGS, re_nsub + 1) registers (from rms). * xregex.c, regex.h: don't abbreviate `19xx' to `xx'. * regexinc.c [!emacs]: include before . (from ro@thp.Uni-Koeln.DE). Thu Jan 9 07:23:00 1992 Karl Berry (karl at hayley) * xregex.c (*unmatchable): rename to `match_empty_string_p'. (CAN_MATCH_NOTHING): rename to `REG_MATCH_EMPTY_STRING_P'. * regexinc.c (malloc, realloc): remove prototypes, as they can cause clashes (from rms). Mon Jan 6 12:43:24 1992 Karl Berry (karl at claude.cs.umb.edu) * Version 0.2. Sun Jan 5 10:50:38 1992 Karl Berry (karl at hayley) * xregex.texinfo: bring more or less up-to-date. * GNUmakefile (regex.texinfo): generate from regex.h and xregex.texinfo. * include.awk: new file. * xregex.c: change all calls to the fn extract_number_and_incr to the macro. * xregex.c (re_match_2) [emacs]: in at_dot, use PTR_CHAR_POS + 1, instead of bf_* and sl_*. Cast d to unsigned char *, to match the declaration in Emacs' buffer.h. [emacs19]: in before_dot, at_dot, and after_dot, likewise. * regexinc.c: unconditionally include . * regexinc.c (alloca) [!alloca]: Emacs config files sometimes define this, so don't define it if it's already defined. Sun Jan 5 06:06:53 1992 Karl Berry (karl at fosse) * xregex.c (re_comp): fix type conflicts with regex_compile (we haven't been compiling this). * regexinc.c (SIGN_EXTEND_CHAR): use `__CHAR_UNSIGNED__', not `CHAR_UNSIGNED'. * regexinc.c (NULL) [!NULL]: define it (as zero). * regexinc.c (extract_number): remove the temporaries. Sun Jan 5 07:50:14 1992 Karl Berry (karl at hayley) * regex.h (regerror) [!__STDC__]: return a size_t, not a size_t *. * xregex.c (PUSH_FAILURE_POINT, ...): declare `destination' as `char *' instead of `void *', to match alloca declaration. * xregex.c (regerror): use `size_t' for the intermediate values as well as the return type. * xregex.c (regexec): cast the result of malloc. * xregex.c (regexec): don't initialize `private_preg' in the declaration, as old C compilers can't do that. * xregex.c (main) [test]: declare printchar void. * xregex.c (assert) [!DEBUG]: define this to do nothing, and remove #ifdef DEBUG's from around asserts. * xregex.c (re_match_2): remove error message when not debugging. Sat Jan 4 09:45:29 1992 Karl Berry (karl at hayley) * other.c: test the bizarre duplicate case in re_compile_fastmap that I just noticed. * test.c (general_test): don't test registers beyond the end of correct_regs, as well as regs. * xregex.c (regex_compile): at handle_close, don't assign to *inner_group_loc if we didn't push a start_memory (because the group number was too big). In fact, don't push or pop the inner_group_offset in that case. * regex.c: rename to xregex.c, since it's not the whole thing. * regex.texinfo: likewise. * GNUmakefile: change to match. * regex.c [DEBUG]: only include if debugging. * regexinc.c (SIGN_EXTEND_CHAR) [CHAR_UNSIGNED]: if it's already defined, don't redefine it. * regex.c: define _GNU_SOURCE at the beginning. * regexinc.c (isblank) [!isblank]: define it. (isgraph) [!isgraph]: change conditional to this, and remove the sequent stuff. * regex.c (regex_compile): add `blank' character class. * regex.c (regex_compile): don't use a uchar variable to loop through all characters. * regex.c (regex_compile): at '[', improve logic for checking that we have enough space for the charset. * regex.h (struct re_pattern_buffer): declare translate as char * again. We only use it as an array subscript once, I think. * regex.c (TRANSLATE): new macro to cast the data character before subscripting. (num_internal_regs): rename to `num_regs'. Fri Jan 3 07:58:01 1992 Karl Berry (karl at hayley) * regex.h (struct re_pattern_buffer): declare `allocated' and `used' as unsigned long, since these are never negative. * regex.c (compile_stack_element): rename to compile_stack_elt_t. (failure_stack_element): similarly. * regexinc.c (TALLOC, RETALLOC): new macros to simplify allocation of arrays. * regex.h (re_*) [__STDC__]: don't declare string args unsigned char *; that makes them incompatible with string constants. (struct re_pattern_buffer): declare the pattern and translate table as unsigned char *. * regex.c (most routines): use unsigned char vs. char consistently. * regex.h (re_compile_pattern): do not declare the length arg as const. * regex.c (re_compile_pattern): likewise. * regex.c (POINTER_TO_REG): rename to `POINTER_TO_OFFSET'. * regex.h (re_registers): declare `start' and `end' as `regoff_t', instead of `int'. * regex.c (regexec): if either of the malloc's for the register information fail, return failure. * regex.h (RE_NREGS): define this again, as 30 (from jla). (RE_ALLOCATE_REGISTERS): remove this. (RE_SYNTAX_*): remove it from definitions. (re_pattern_buffer): remove `return_default_num_regs', add `caller_allocated_regs'. * regex.c (re_compile_pattern): clear no_sub and caller_allocated_regs in the pattern. (regcomp): set caller_allocated_regs. (re_match_2): do all register allocation at the end of the match; implement new semantics. * regex.c (MAX_REGNUM): new macro. (regex_compile): at handle_open and handle_close, if the group number is too large, don't push the start/stop memory. Thu Jan 2 07:56:10 1992 Karl Berry (karl at hayley) * regex.c (re_match_2): if the back reference is to a group that never matched, then goto fail, not really_fail. Also, don't test if the pattern can match the empty string. Why did we ever do that? (really_fail): this label no longer needed. * regexinc.c [STDC_HEADERS]: use only this to test if we should include . * regex.c (DO_RANGE, regex_compile): translate in all cases except the single character after a \. * regex.h (RE_AWK_CLASS_HACK): rename to RE_BACKSLASH_ESCAPE_IN_LISTS. * regex.c (regex_compile): change use. * regex.c (re_compile_fastmap): do not translate the characters again; we already translated them at compilation. (From ylo@ngs.fi.) * regex.c (re_match_2): in case for at_dot, invert sense of comparison and find the character number properly. (From worley@compass.com.) (re_match_2) [emacs]: remove the cases for before_dot and after_dot, since there's no way to specify them, and the code is wrong (judging from this change). Wed Jan 1 09:13:38 1992 Karl Berry (karl at hayley) * psx-{interf,basic,extend}.c, other.c: set `t' as the first thing, so that if we run them in sucession, general_test's kludge to see if we're doing POSIX tests works. * test.h (test_type): add `all_test'. * main.c: add case for `all_test'. * regexinc.c (partial_compiled_pattern_printer, double_string_printer): don't print anything if we're passed null. * regex.c (PUSH_FAILURE_POINT): do not scan for the highest and lowest active registers. (re_match_2): compute lowest/highest active regs at start_memory and stop_memory. (NO_{LOW,HIGH}EST_ACTIVE_REG): new sentinel values. (pop_failure_point): return the lowest/highest active reg values popped; change calls. * regex.c [DEBUG]: include . (various routines) [DEBUG]: change conditionals to assertions. * regex.c (DEBUG_STATEMENT): new macro. (PUSH_FAILURE_POINT): use it to increment num_regs_pushed. (re_match_2) [DEBUG]: only declare num_regs_pushed if DEBUG. * regex.c (*can_match_nothing): rename to *unmatchable. * regex.c (re_match_2): at stop_memory, adjust argument reading. * regex.h (re_pattern_buffer): declare `can_be_null' as a 2-bit bit field. * regex.h (re_pattern_buffer): declare `buffer' unsigned char *; no, dumb idea. The pattern can have signed number. * regex.c (re_match_2): in maybe_pop_jump case, skip over the right number of args to the group operators, and don't do anything with endline if posix_newline is not set. * regex.c, regexinc.c (all the things we just changed): go back to putting the inner group count after the start_memory, because we need it in the on_failure_jump case in re_match_2. But leave it after the stop_memory also, since we need it there in re_match_2, and we don't have any way of getting back to the start_memory. * regexinc.c (partial_compiled_pattern_printer): adjust argument reading for start/stop_memory. * regex.c (re_compile_fastmap, group_can_match_nothing): likewise. Tue Dec 31 10:15:08 1991 Karl Berry (karl at hayley) * regex.c (bits list routines): remove these. (re_match_2): get the number of inner groups from the pattern, instead of keeping track of it at start and stop_memory. Put the count after the stop_memory, not after the start_memory. (compile_stack_element): remove `fixup_inner_group' member, since we now put it in when we can compute it. (regex_compile): at handle_open, don't push the inner group offset, and at handle_close, don't pop it. * regex.c (level routines): remove these, and their uses in regex_compile. This was another manifestation of having to find $'s that were endlines. * regex.c (regexec): this does searching, not matching (a well-disguised part of the standard). So rewrite to use `re_search' instead of `re_match'. * psx-interf.c (test_regexec): add tests to, uh, match. * regex.h (RE_TIGHT_ALT): remove this; nobody uses it. * regex.c: remove the code that was supposed to implement it. * other.c (test_others): ^ and $ never match newline characters; RE_CONTEXT_INVALID_OPS doesn't affect anchors. * psx-interf.c (test_regerror): update for new error messages. * psx-extend.c: it's now ok to have an alternative be just a $, so remove all the tests which supposed that was invalid. Wed Dec 25 09:00:05 1991 Karl Berry (karl at hayley) * regex.c (regex_compile): in handle_open, don't skip over ^ and $ when checking for an empty group. POSIX has changed the grammar. * psx-extend.c (test_posix_extended): thus, move (^$) tests to valid section. * regexinc.c (boolean): move from here to test.h and regex.c. * test files: declare verbose, omit_register_tests, and test_should_match as boolean. * psx-interf.c (test_posix_c_interface): remove the `c_'. * main.c: likewise. * psx-basic.c (test_posix_basic): ^ ($) is an anchor after (before) an open (close) group. * regex.c (re_match_2): in endline, correct precedence of posix_newline condition. Tue Dec 24 06:45:11 1991 Karl Berry (karl at hayley) * test.h: incorporate private-tst.h. * test files: include test.h, not private-tst.h. * test.c (general_test): set posix_newline to zero if we are doing POSIX tests (unfortunately, it's difficult to call regcomp in this case, which is what we should really be doing). * regex.h (reg_syntax_t): make this an enumeration type which defines the syntax bits; renames re_syntax_t. * regex.c (at_endline_op_p): don't preincrement p; then if it's not an empty string op, we lose. * regex.h (reg_errcode_t): new enumeration type of the error codes. * regex.c (regex_compile): return that type. * regex.c (regex_compile): in [, initialize just_had_a_char_class to false; somehow I had changed this to true. * regex.h (RE_NO_CONSECUTIVE_REPEATS): remove this, since we don't use it, and POSIX doesn't require this behavior anymore. * regex.c (regex_compile): remove it from here. * regex.c (regex_compile): remove the no_op insertions for verify_and_adjust_endlines, since that doesn't exist anymore. * regex.c (regex_compile) [DEBUG]: use printchar to print the pattern, so unprintable bytes will print properly. * regex.c: move re_error_msg back. * test.c (general_test): print the compile error if the pattern was invalid. Mon Dec 23 08:54:53 1991 Karl Berry (karl at hayley) * regexinc.c: move re_error_msg here. * regex.c (re_error_msg): the ``message'' for success must be NULL, to keep the interface to re_compile_pattern the same. (regerror): if the msg is null, use "Success". * rename most test files for consistency. Change Makefile correspondingly. * test.c (most routines): add casts to (unsigned char *) when we call re_{match,search}{,_2}. Sun Dec 22 09:26:06 1991 Karl Berry (karl at hayley) * regex.c (re_match_2): declare string args as unsigned char * again; don't declare non-pointer args const; declare the pattern buffer const. (re_match): likewise. (re_search_2, re_search): likewise, except don't declare the pattern const, since we make a fastmap. * regex.h [__STDC__]: change prototypes. * regex.c (regex_compile): return an error code, not a string. (re_err_list): new table to map from error codes to string. (re_compile_pattern): return an element of re_err_list. (regcomp): don't test all the strings. (regerror): just use the list. (put_in_buffer): remove this. * regex.c (equivalent_failure_points): remove this. * regex.c (re_match_2): don't copy the string arguments into non-const pointers. We never alter the data. * regex.c (re_match_2): move assignment to `is_a_jump_n' out of the main loop. Just initialize it right before we do something with it. * regex.[ch] (re_match_2): don't declare the int parameters const. Sat Dec 21 08:52:20 1991 Karl Berry (karl at hayley) * regex.h (re_syntax_t): new type; declare to be unsigned (previously we used int, but since we do bit operations on this, unsigned is better, according to H&S). (obscure_syntax, re_pattern_buffer): use that type. * regex.c (re_set_syntax, regex_compile): likewise. * regex.h (re_pattern_buffer): new field `posix_newline'. * regex.c (re_comp, re_compile_pattern): set to zero. (regcomp): set to REG_NEWLINE. * regex.h (RE_HAT_LISTS_NOT_NEWLINE): remove this (we can just check `posix_newline' instead.) * regex.c (op_list_type, op_list, add_op): remove these. (verify_and_adjust_endlines): remove this. (pattern_offset_list_type, *pattern_offset* routines): and these. These things all implemented the nonleading/nontrailing position code, which was very long, had a few remaining problems, and is no longer needed. So... * regexinc.c (STREQ): new macro to abbreviate strcmp(,)==0, for brevity. Change various places in regex.c to use it. * regex{,inc}.c (enum regexpcode): change to a typedef re_opcode_t, for brevity. * regex.h (re_syntax_table) [SYNTAX_TABLE]: remove this; it should only be in regex.c, I think, since we don't define it in this case. Maybe it should be conditional on !SYNTAX_TABLE? * regexinc.c (partial_compiled_pattern_printer): simplify and distinguish the emacs/not-emacs (not)wordchar cases. Fri Dec 20 08:11:38 1991 Karl Berry (karl at hayley) * regexinc.c (regexpcode) [emacs]: only define the Emacs opcodes if we are ifdef emacs. * regex.c (BUF_PUSH*): rename to PAT_PUSH*. * regex.c (regex_compile): in $ case, go back to essentially the original code for deciding endline op vs. normal char. (at_endline_op_p): new routine. * regex.h (RE_ANCHORS_ONLY_AT_ENDS, RE_CONTEXT_INVALID_ANCHORS, RE_REPEATED_ANCHORS_AWAY, RE_NO_ANCHOR_AT_NEWLINE): remove these. POSIX has simplified the rules for anchors in draft 11.2. (RE_NEWLINE_ORDINARY): new syntax bit. (RE_CONTEXT_INDEP_ANCHORS): change description to be compatible with POSIX. * regex.texinfo (Syntax Bits): remove the descriptions. Mon Dec 16 08:12:40 1991 Karl Berry (karl at hayley) * regex.c (re_match_2): in jump_past_next_alt, unconditionally goto no_pop. The only register we were finding was one which enclosed the whole alternative expression, not one around an individual alternative. So we were never doing what we thought we were doing, and this way makes (|a) against the empty string fail. * regex.c (regex_compile): remove `highest_ever_regnum', and don't restore regnum from the stack; just put it into a temporary to put into the stop_memory. Otherwise, groups aren't numbered consecutively. * regex.c (is_in_compile_stack): rename to `group_in_compile_stack'; remove unnecessary test for the stack being empty. * regex.c (re_match_2): in on_failure_jump, skip no_op's before checking for the start_memory, in case we were called from succeed_n. Sun Dec 15 16:20:48 1991 Karl Berry (karl at hayley) * regex.c (regex_compile): in duplicate case, use highest_ever_regnum instead of regnum, since the latter is reverted at stop_memory. * regex.c (re_match_2): in on_failure_jump, if the * applied to a group, save the information for that group and all inner groups (by making it active), even though we're not inside it yet. Sat Dec 14 09:50:59 1991 Karl Berry (karl at hayley) * regex.c (PUSH_FAILURE_ITEM, POP_FAILURE_ITEM): new macros. Use them instead of copying the stack manipulating a zillion times. * regex.c (PUSH_FAILURE_POINT, pop_failure_point) [DEBUG]: save and restore a unique identification value for each failure point. * regexinc.c (partial_compiled_pattern_printer): don't print an extra / after duplicate commands. * regex.c (regex_compile): in back-reference case, allow a back reference to register `regnum'. Otherwise, even `\(\)\1' fails, since regnum is 1 at the back-reference. * regex.c (re_match_2): in fail, don't examine the pattern if we restored to pend. * test_private.h: rename to private_tst.h. Change includes. * regex.c (extend_bits_list): compute existing size for realloc in bytes, not blocks. * regex.c (re_match_2): in jump_past_next_alt, the for loop was missing its (empty) statement. Even so, some register tests still fail, although in a different way than in the previous change. Fri Dec 13 15:55:08 1991 Karl Berry (karl at hayley) * regex.c (re_match_2): in jump_past_next_alt, unconditionally goto no_pop, since we weren't properly detecting if the alternative matched something anyway. No, we need to not jump to keep the register values correct; just change to not look at register zero and not test RE_NO_EMPTY_ALTS (which is a compile-time thing). * regex.c (SET_REGS_MATCHED): start the loop at 1, since we never care about register zero until the very end. (I think.) * regex.c (PUSH_FAILURE_POINT, pop_failure_point): go back to pushing and popping the active registers, instead of only doing the registers before a group: (fooq|fo|o)*qbar against fooqbar fails, since we restore back into the middle of group 1, yet it isn't active, because the previous restore clobbered the active flag. Thu Dec 12 17:25:36 1991 Karl Berry (karl at hayley) * regex.c (PUSH_FAILURE_POINT): do not call `equivalent_failure_points' after all; it causes the registers to be ``wrong'' (according to POSIX), and an infinite loop on `((a*)*)*' against `ab'. * regex.c (re_compile_fastmap): don't push `pend' on the failure stack. Tue Dec 10 10:30:03 1991 Karl Berry (karl at hayley) * regex.c (PUSH_FAILURE_POINT): if pushing same failure point that is on the top of the stack, fail. (equivalent_failure_points): new routine. * regex.c (re_match_2): add debug statements for every opcode we execute. * regex.c (regex_compile/handle_close): restore `fixup_inner_group_count' and `regnum' from the stack. Mon Dec 9 13:51:15 1991 Karl Berry (karl at hayley) * regex.c (PUSH_FAILURE_POINT): declare `this_reg' as int, so unsigned arithmetic doesn't happen when we don't want to save the registers. Tue Dec 3 08:11:10 1991 Karl Berry (karl at hayley) * regex.c (extend_bits_list): divide size by bits/block. * regex.c (init_bits_list): remove redundant assignmen to `bits_list_ptr'. * regexinc.c (partial_compiled_pattern_printer): don't do *p++ twice in the same expr. * regex.c (re_match_2): at on_failure_jump, use the correct pattern positions for getting the stuff following the start_memory. * regex.c (struct register_info): remove the bits_list for the inner groups; make that a separate variable. Mon Dec 2 10:42:07 1991 Karl Berry (karl at hayley) * regex.c (PUSH_FAILURE_POINT): don't pass `failure_stack' as an arg; change callers. * regex.c (PUSH_FAILURE_POINT): print items in order they are pushed. (pop_failure_point): likewise. * regex.c (main): prompt for the pattern and string. * regex.c (FREE_VARIABLES) [!REGEX_MALLOC]: declare as nothing; remove #ifdefs from around calls. * regex.c (extract_number, extract_number_and_incr): declare static. * regex.c: remove the canned main program. * main.c: new file. * Makefile (COMMON): add main.o. Tue Sep 24 06:26:51 1991 Kathy Hargreaves (kathy at fosse) * regex.c (re_match_2): Made `pend' and `dend' not register variables. Only set string2 to string1 if string1 isn't null. Send address of p, d, regstart, regend, and reg_info to pop_failure_point. Put in more debug statements. * regex.c [debug]: Added global variable. (DEBUG_*PRINT*): Only print if `debug' is true. (DEBUG_DOUBLE_STRING_PRINTER): Changed DEBUG_STRING_PRINTER's name to this. Changed some comments. (PUSH_FAILURE_POINT): Moved and added some debugging statements. Was saving regstart on the stack twice instead of saving both regstart and regend; remedied this. [NUM_REGS_ITEMS]: Changed from 3 to 4, as now save lowest and highest active registers instead of highest used one. [NUM_NON_REG_ITEMS]: Changed name of NUM_OTHER_ITEMS to this. (NUM_FAILURE_ITEMS): Use active registers instead of number 0 through highest used one. (re_match_2): Have pop_failure_point put things in the variables. (pop_failure_point): Have it do what the fail case in re_match_2 did with the failure stack, instead of throwing away the stuff popped off. re_match_2 can ignore results when it doesn't need them. Thu Sep 5 13:23:28 1991 Kathy Hargreaves (kathy at fosse) * regex.c (banner): Changed copyright years to be separate. * regex.c [CHAR_UNSIGNED]: Put __ at both ends of this name. [DEBUG, debug_count, *debug_p, DEBUG_PRINT_1, DEBUG_PRINT_2, DEBUG_COMPILED_PATTERN_PRINTER ,DEBUG_STRING_PRINTER]: defined these for debugging. (extract_number): Added this (debuggable) routine version of the macro EXTRACT_NUMBER. Ditto for EXTRACT_NUMBER_AND_INCR. (re_compile_pattern): Set return_default_num_regs if the syntax bit RE_ALLOCATE_REGISTERS is set. [REGEX_MALLOC]: Renamed USE_ALLOCA to this. (BUF_POP): Got rid of this, as don't ever use it. (regex_compile): Made the type of `pattern' not be register. If DEBUG, print the pattern to compile. (re_match_2): If had a `$' in the pattern before a `^' then don't record the `^' as an anchor. Put (enum regexpcode) before references to b, as suggested [RE_NO_BK_BRACES]: Changed RE_NO_BK_CURLY_BRACES to this. (remove_pattern_offset): Removed this unused routine. (PUSH_FAILURE_POINT): Changed to only save active registers. Put in debugging statements. (re_compile_fastmap): Made `pattern' not a register variable. Use routine for extracting numbers instead of macro. (re_match_2): Made `p', `mcnt' and `mcnt2' not register variables. Added `num_regs_pushed' for debugging. Only malloc registers if the syntax bit RE_ALLOCATE_REGISTERS is set. Put in debug statements. Put the macro NOTE_INNER_GROUP's code inline, as it was the only called in one place. For debugging, extract numbers using routines instead of macros. In case fail: only restore pushed active registers, and added debugging statements. (pop_failure_point): Test for underfull stack. (group_can_match_nothing, common_op_can_match_nothing): For debugging, extract numbers using routines instead of macros. (regexec): Changed formal parameters to not be prototypes. Don't initialize `regs' or `private_preg' in their declarations. Tue Jul 23 18:38:36 1991 Kathy Hargreaves (kathy at hayley) * regex.h [RE_CONTEX_INDEP_OPS]: Moved the anchor stuff out of this bit. [RE_UNMATCHED_RIGHT_PAREN_ORD]: Defined this bit. [RE_CONTEXT_INVALID_ANCHORS]: Defined this bit. [RE_CONTEXT_INDEP_ANCHORS]: Defined this bit. Added RE_CONTEXT_INDEP_ANCHORS to all syntaxes which had RE_CONTEXT_INDEP_OPS. Took RE_ANCHORS_ONLY_AT_ENDS out of the POSIX basic syntax. Added RE_UNMATCHED_RIGHT_PAREN_ORD to the POSIX extended syntax. Took RE_REPEATED_ANCHORS_AWAY out of the POSIX extended syntax. Defined REG_NOERROR (which will probably have to go away again). Changed the type `off_t' to `regoff_t'. * regex.c: Changed some commments. (regex_compile): Added variable `had_an_endline' to keep track of if hit a `$' since the beginning of the pattern or the last alternative (if any). Changed RE_CONTEXT_INVALID_OPS and RE_CONTEXT_INDEP_OPS to RE_CONTEXT_INVALID_ANCHORS and RE_CONTEXT_INDEP_ANCHORS where appropriate. Put a `no_op' in the pattern if a repeat is only zero or one times; in this case and if it is many times (whereupon a jump backwards is pushed instead), keep track of the operator for verify_and_adjust_endlines. If RE_UNMATCHED_RIGHT_PAREN is set, make an unmatched close-group operator match `)'. Changed all error exits to exit (1). (remove_pattern_offset): Added this routine, but don't use it. (verify_and_adjust_endlines): At top of routine, if initialize routines run out of memory, return true after setting enough_memory false. At end of endline, et al. case, don't set *p to no_op. Repetition operators also set the level and active groups' match statuses, unless RE_REPEATED_ANCHORS_AWAY is set. (get_group_match_status): Put a return in front of call to get_bit. (re_compile_fastmap): Changed is_a_succeed_n to a boolean. If at end of pattern, then if the failure stack isn't empty, go back to the failure point. In *jump* case, only pop the stack if what's on top of it is where we've just jumped to. (re_search_2): Return -2 instead of val if val is -2. (group_can_match_nothing, alternative_can_match_nothing, common_op_can-match_nothing): Now pass in reg_info for the `duplicate' case. (re_match_2): Don't skip over the next alternative also if empty alternatives aren't allowed. In fail case, if failed to a backwards jump that's part of a repetition loop, pop the current failure point and use the next one. (pop_failure_point): Check that there's as many register items on the failure stack as the stack says there are. (common_op_can_match_nothing): Added variables `ret' and `reg_no' so can set reg_info for the group encountered. Also break without doing anything if hit a no_op or the other kinds of `endline's. If not done already, set reg_info in start_memory case. Put in no_pop_jump for an optimized succeed_n of zero repetitions. In succeed_n case, if the number isn't zero, then return false. Added `duplicate' case. Sat Jul 13 11:27:38 1991 Kathy Hargreaves (kathy at hayley) * regex.h (REG_NOERROR): Added this error code definition. * regex.c: Took some redundant parens out of macros. (enum regexpcode): Added jump_past_next_alt. Wrapped some macros in `do..while (0)'. Changed some comments. (regex_compile): Use `fixup_alt_jump' instead of `fixup_jump'. Use `maybe_pop_jump' instead of `maybe_pop_failure_jump'. Use `jump_past_next_alt' instead of `no_pop_jump' when at the end of an alternative. (re_match_2): Used REGEX_ALLOCATE for the registers stuff. In stop_memory case: Add more boolean tests to see if the group is in a loop. Added jump_past_next_alt case, which doesn't jump over the next alternative if the last one didn't match anything. Unfortunately, to make this work with, e.g., `(a+?*|b)*' against `bb', I also had to pop the alternative's failure point, which in turn broke backtracking! In fail case: Detect a dummy failure point by looking at failure_stack.avail - 2, not stack[-2]. (pop_failure_point): Only pop if the stack isn't empty; don't give an error if it is. (Not sure yet this is correct.) (group_can_match_nothing): Make it return a boolean instead of int. Make it take an argument indicating the end of where it should look. If find a group that can match nothing, set the pointer argument to past the group in the pattern. Took out cases which can share with alternative_can_match_nothing and call common_op_can_match_nothing. Took ++ out of switch, so could call common_op_can_match_nothing. Wrote lots more for on_failure_jump case to handle alternatives. Main loop now doesn't look for matching stop_memory, but rather the argument END; return true if hit the matching stop_memory; this way can call itself for inner groups. (alternative_can_match_nothing): Added for alternatives. (common_op_can_match_nothing): Added for previous two routines' common operators. (regerror): Returns a message saying there's no error if gets sent REG_NOERROR. Wed Jul 3 10:43:15 1991 Kathy Hargreaves (kathy at hayley) * regex.c: Removed unnecessary enclosing parens from several macros. Put `do..while (0)' around a few. Corrected some comments. (INIT_FAILURE_STACK_SIZE): Deleted in favor of using INIT_FAILURE_ALLOC. (INIT_FAILURE_STACK, DOUBLE_FAILURE_STACK, PUSH_PATTERN_OP, PUSH_FAILURE_POINT): Made routines of the same name (but with all lowercase letters) into these macros, so could use `alloca' when USE_ALLOCA is defined. The reason is stated below for bits lists. Deleted analogous routines. (re_compile_fastmap): Added variable void *destination for PUSH_PATTERN_OP. (re_match_2): Added variable void *destination for REGEX_REALLOCATE. Used the failure stack macros in place of the routines. Detected a dummy failure point by inspecting the failure stack's (avail - 2)th element, not failure_stack.stack[-2]. This bug arose when used the failure stack macros instead of the routines. * regex.c [USE_ALLOCA]: Put this conditional around previous alloca stuff and defined these to work differently depending on whether or not USE_ALLOCA is defined: (REGEX_ALLOCATE): Uses either `alloca' or `malloc'. (REGEX_REALLOCATE): Uses either `alloca' or `realloc'. (INIT_BITS_LIST, EXTEND_BITS_LIST, SET_BIT_TO_VALUE): Defined macro versions of routines with the same name (only with all lowercase letters) so could use `alloc' in re_match_2. This is to prevent core leaks when C-g is used in Emacs and to make things faster and avoid storage fragmentation. These things have to be macros because the results of `alloca' go away with the routine by which it's called. (BITS_BLOCK_SIZE, BITS_BLOCK, BITS_MASK): Moved to above the above-mentioned macros instead of before the routines defined below regex_compile. (set_bit_to_value): Compacted some code. (reg_info_type): Changed inner_groups field to be bits_list_type so could be arbitrarily long and thus handle arbitrary nesting. (NOTE_INNER_GROUP): Put `do...while (0)' around it so could use as a statement. Changed code to use bits lists. Added variable void *destination for REGEX_REALLOCATE (whose call is several levels in). Changed variable name of `this_bit' to `this_reg'. (FREE_VARIABLES): Only define and use if USE_ALLOCA is defined. (re_match_2): Use REGEX_ALLOCATE instead of malloc. Instead of setting INNER_GROUPS of reg_info to zero, have to use INIT_BITS_LIST and return -2 (and free variables if USE_ALLOCA isn't defined) if it fails. Fri Jun 28 13:45:07 1991 Karl Berry (karl at hayley) * regex.c (re_match_2): set value of `dend' when we restore `d'. * regex.c: remove declaration of alloca. * regex.c (MISSING_ISGRAPH): rename to `ISGRAPH_MISSING'. * regex.h [_POSIX_SOURCE]: remove these conditionals; always define POSIX stuff. * regex.c (_POSIX_SOURCE): change conditionals to use `POSIX' instead. Sat Jun 1 16:56:50 1991 Kathy Hargreaves (kathy at hayley) * regex.*: Changed RE_CONTEXTUAL_* to RE_CONTEXT_*, RE_TIGHT_VBAR to RE_TIGHT_ALT, RE_NEWLINE_OR to RE_NEWLINE_ALT, and RE_DOT_MATCHES_NEWLINE to RE_DOT_NEWLINE. Wed May 29 09:24:11 1991 Karl Berry (karl at hayley) * regex.texinfo (POSIX Pattern Buffers): cross-reference the correct node name (Match-beginning-of-line, not ..._line). (Syntax Bits): put @code around all syntax bits. Sat May 18 16:29:58 1991 Karl Berry (karl at hayley) * regex.c (global): add casts to keep broken compilers from complaining about malloc and realloc calls. * regex.c (isgraph) [MISSING_ISGRAPH]: change test to this, instead of `#ifndef isgraph', since broken compilers can't have both a macro and a symbol by the same name. * regex.c (re_comp, re_exec) [_POSIX_SOURCE]: do not define. (regcomp, regfree, regexec, regerror) [_POSIX_SOURCE && !emacs]: only define in this case. Mon May 6 17:37:04 1991 Kathy Hargreaves (kathy at hayley) * regex.h (re_search, re_search_2): Changed BUFFER to not be const. * regex.c (re_compile_pattern): `^' is in a leading position if it precedes a newline. (various routines): Added or changed header comments. (double_pattern_offsets_list): Changed name from `extend_pattern_offsets_list'. (adjust_pattern_offsets_list): Changed return value from unsigned to void. (verify_and_adjust_endlines): Now returns `true' and `false' instead of 1 and 0. `$' is in a leading position if it follows a newline. (set_bit_to_value, get_bit_value): Exit with error if POSITION < 0 so now calling routines don't have to. (init_failure_stack, inspect_failure_stack_top, pop_failure_stack_top, push_pattern_op, double_failure_stack): Now return value unsigned instead of boolean. (re_search, re_search_2): Changed BUFP to not be const. (re_search_2): Added variable const `private_bufp' to send to re_match_2. (push_failure_point): Made return value unsigned instead of boolean. Sat May 4 15:32:22 1991 Kathy Hargreaves (kathy at hayley) * regex.h (re_compile_fastmap): Added extern for this. Changed some comments. * regex.c (re_compile_pattern): In case handle_bar: put invalid pattern test before levels matching stuff. Changed some commments. Added optimizing test for detecting an empty alternative that ends with a trailing '$' at the end of the pattern. (re_compile_fastmap): Moved failure_stack stuff to before this so could use it. Made its stack dynamic. Made it return an int so that it could return -2 if its stack couldn't be allocated. Added to header comment (about the return values). (init_failure_stack): Wrote so both re_match_2 and re_compile_fastmap could use it similar stacks. (double_failure_stack): Added for above reasons. (push_pattern_op): Wrote for re_compile_fastmap. (re_search_2): Now return -2 if re_compile_fastmap does. (re_match_2): Made regstart and regend type failure_stack_element*. (push_failure_point): Made pattern_place and string_place type failure_stack_element*. Call double_failure_stack now. Return true instead of 1. Wed May 1 12:57:21 1991 Kathy Hargreaves (kathy at hayley) * regex.c (remove_intervening_anchors): Avoid erroneously making ops into no_op's by making them no_op only when they're beglines. (verify_and_adjust_endlines): Don't make '$' a normal character if it's before a newline. Look for the endline op in *p, not p[1]. (failure_stack_element): Added this declaration. (failure_stack_type): Added this declaration. (INIT_FAILURE_STACK_SIZE, FAILURE_STACK_EMPTY, FAILURE_STACK_PTR_EMPTY, REMAINING_AVAIL_SLOTS): Added for failure stack. (FAILURE_ITEM_SIZE, PUSH_FAILURE_POINT): Deleted. (FREE_VARIABLES): Now free failure_stack.stack instead of stackb. (re_match_2): deleted variables `initial_stack', `stackb', `stackp', and `stacke' and added `failure_stack' to replace them. Replaced calls to PUSH_FAILURE_POINT with those to push_failure_point. (push_failure_point): Added for re_match_2. (pop_failure_point): Rewrote to use a failure_stack_type of stack. (can_match_nothing): Moved definition to below re_match_2. (bcmp_translate): Moved definition to below re_match_2. Mon Apr 29 14:20:54 1991 Kathy Hargreaves (kathy at hayley) * regex.c (enum regexpcode): Added codes endline_before_newline and repeated_endline_before_newline so could detect these types of endlines in the intermediate stages of a compiled pattern. (INIT_FAILURE_ALLOC): Renamed NFAILURES to this and set it to 5. (BUF_PUSH): Put `do {...} while 0' around this. (BUF_PUSH_2): Defined this to cut down on expansion of EXTEND_BUFFER. (regex_compile): Changed some comments. Now push endline_before_newline if find a `$' before a newline in the pattern. If a `$' might turn into an ordinary character, set laststart to point to it. In '^' case, if syntax bit RE_TIGHT_VBAR is set, then for `^' to be in a leading position, it must be first in the pattern. Don't have to check in one of the else clauses that it's not set. If RE_CONTEXTUAL_INDEP_OPS isn't set but RE_ANCHORS_ONLY_AT_ENDS is, make '^' a normal character if it isn't first in the pattern. Can only detect at the end if a '$' after an alternation op is a trailing one, so can't immediately detect empty alternatives if a '$' follows a vbar. Added a picture of the ``success jumps'' in alternatives. Have to set bufp->used before calling verify_and_adjust_endlines. Also do it before returning all error strings. (remove_intervening_anchors): Now replaces the anchor with repeated_endline_before_newline if it's an endline_before_newline. (verify_and_adjust_endlines): Deleted SYNTAX parameter (could use bufp's) and added GROUP_FORWARD_MATCH_STATUS so could detect back references referring to empty groups. Added variable `bend' to point past the end of the pattern buffer. Added variable `previous_p' so wouldn't have to reinspect the pattern buffer to see what op we just looked at. Added endline_before_newline and repeated_endline_before_newline cases. When checking if in a trailing position, added case where '$' has to be at the pattern's end if either of the syntax bits RE_ANCHORS_ONLY_AT_ENDS or RE_TIGHT_VBAR are set. Since `endline' can have the intermediate form `endline_in_repeat', have to change it to `endline' if RE_REPEATED_ANCHORS_AWAY isn't set. Now disallow empty alternatives with trailing endlines in them if RE_NO_EMPTY_ALTS is set. Now don't make '$' an ordinary character if it precedes a newline. Don't make it an ordinary character if it's before a newline. Back references now affect the level matching something only if they refer to nonempty groups. (can_match_nothing): Now increment p1 in the switch, which changes many of the cases, but makes the code more like what it was derived from. Adjust the return statement to reflect above. (struct register_info): Made `can_match_nothing' field an int instead of a bit so could have -1 in it if never set. (MAX_FAILURE_ITEMS): Changed name from MAX_NUM_FAILURE_ITEMS. (FAILURE_ITEM_SIZE): Defined how much space a failure items uses. (PUSH_FAILURE_POINT): Changed variable `last_used_reg's name to `highest_used_reg'. Added variable `num_stack_items' and changed `len's name to `stack_length'. Test failure stack limit in terms of number of items in it, not in terms of its length. rms' fix tested length against number of items, which was a misunderstanding. Use `realloc' instead of `alloca' to extend the failure stack. Use shifts instead of multiplying by 2. (FREE_VARIABLES): Free `stackb' instead of `initial_stack', as might may have been reallocated. (re_match_2): When mallocing `initial_stack', now multiply the number of items wanted (what was there before) by FAILURE_ITEM_SIZE. (pop_failure_point): Need this procedure form of the macro of the same name for debugging, so left it in and deleted the macro. (recomp): Don't free the pattern buffer's translate field. Mon Apr 15 09:47:47 1991 Kathy Hargreaves (kathy at hayley) * regex.h (RE_DUP_MAX): Moved to outside of #ifdef _POSIX_SOURCE. * regex.c (#include ): Removed #ifdef _POSIX_SOURCE condition. (malloc, realloc): Made return type void* #ifdef __STDC__. (enum regexpcode): Added endline_in_repeat for the compiler's use; this never ends up on the final compiled pattern. (INIT_PATTERN_OFFSETS_LIST_SIZE): Initial size for pattern_offsets_list_type. (pattern_offset_type): Type for pattern offsets. (pattern_offsets_list_type): Type for keeping a list of pattern offsets. (anchor_list_type): Changed to above type. (PATTERN_OFFSETS_LIST_PTR_FULL): Tests if a pattern offsets list is full. (ANCHOR_LIST_PTR_FULL): Changed to above. (BIT_BLOCK_SIZE): Changed to BITS_BLOCK_SIZE and moved to above bits list routines below regex_compile. (op_list_type): Defined to be pattern_offsets_list_type. (compile_stack_type): Changed offsets to be pattern_offset_type instead of unsigned. (pointer): Changed the name of all structure fields from this to `avail'. (COMPILE_STACK_FULL): Changed so the stack is full if `avail' is equal to `size' instead of `size' - 1. (GET_BUFFER_SPACE): Changed `>=' to `>' in the while statement. (regex_compile): Added variable `enough_memory' so could check that routine that verifies '$' positions could return an allocation error. (group_count): Deleted this variable, as `regnum' already does this work. (op_list): Added this variable to keep track of operations needed for verifying '$' positions. (anchor_list): Now initialize using routine `init_pattern_offsets_list'. Consolidated the three bits_list initializations. In case '$': Instead of trying to go past constructs which can follow '$', merely detect the special case where it has to be at the pattern's end, fix up any fixup jumps if necessary, record the anchor if necessary and add an `endline' (and possibly two `no-op's) to the pattern; will call a routine at the end to verify if it's in a valid position or not. (init_pattern_offsets_list): Added to initialize pattern offsets lists. (extend_anchor_list): Renamed this extend_pattern_offsets_list and renamed parameters and internal variables appropriately. (add_pattern_offset): Added this routine which both record_anchor_position and add_op call. (adjust_pattern_offsets_list): Add this routine to adjust by some increment all the pattern offsets a list of such after a given position. (record_anchor_position): Now send in offset instead of calculating it and just call add_pattern_offset. (adjust_anchor_list): Replaced by above routine. (remove_intervening_anchors): If the anchor is an `endline' then replace it with `endline_in_repeat' instead of `no_op'. (add_op): Added this routine to call in regex_compile wherever push something relevant to verifying '$' positions. (verify_and_adjust_endlines): Added routine to (1) verify that '$'s in a pattern buffer (represented by `endline') were in valid positions and (2) whether or not they were anchors. (BITS_BLOCK_SIZE): Renamed BIT_BLOCK_SIZE and moved to right above bits list routines. (BITS_BLOCK): Defines which array element of a bits list the bit corresponding to a given position is in. (BITS_MASK): Has a 1 where the bit (in a bit list array element) for a given position is. Mon Apr 1 12:09:06 1991 Kathy Hargreaves (kathy at hayley) * regex.c (BIT_BLOCK_SIZE): Defined this for using with bits_list_type, abstracted from level_list_type so could use for more things than just the level match status. (regex_compile): Renamed `level_list' variable to `level_match_status'. Added variable `group_match_status' of type bits_list_type. Kept track of whether or not for all groups any of them matched other than the empty string, so detect if a back reference in front of a '^' made it nonleading or not. Do this by setting a match status bit for all active groups whenever leave a group that matches other than the empty string. Could detect which groups are active by going through the stack each time, but or-ing a bits list of active groups with a bits list of group match status is faster, so make a bits list of active groups instead. Have to check that '^' isn't in a leading position before going to normal_char. Whenever set level match status of the current level, also set the match status of all active groups. Increase the group count and make that group active whenever open a group. When close a group, only set the next level down if the current level matches other than the empty string, and make the current group inactive. At a back reference, only set a level's match status if the group to which the back reference refers matches other than the empty string. (init_bits_list): Added to initialize a bits list. (get_level_value): Deleted this. (Made into get_level_match_status.) (extend_bits_list): Added to extend a bits list. (Made this from deleted routine `extend_level_list'.) (get_bit): Added to get a bit value from a bits list. (Made this from deleted routine `get_level_value'.) (set_bit_to_value): Added to set a bit in a bits list. (Made this from deleted routine `set_level_value'.) (get_level_match_status): Added this to get the match status of a given level. (Made from get_level_value.) (set_this_level, set_next_lower_level): Made all routines which set bits extend the bits list if necessary, thus they now return an unsigned value to indicate whether or not the reallocation failed. (increase_level): No longer extends the level list. (make_group_active): Added to mark as active a given group in an active groups list. (make_group_inactive): Added to mark as inactive a given group in an active groups list. (set_match_status_of_active_groups): Added to set the match status of all currently active groups. (get_group_match_status): Added to get a given group's match status. (no_levels_match_anything): Removed the paramenter LEVEL. (PUSH_FAILURE_POINT): Added rms' bug fix and changed RE_NREGS to num_internal_regs. Sun Mar 31 09:04:30 1991 Kathy Hargreaves (kathy at hayley) * regex.h (RE_ANCHORS_ONLY_AT_ENDS): Added syntax so could constrain '^' and '$' to only be anchors if at the beginning and end of the pattern. (RE_SYNTAX_POSIX_BASIC): Added the above bit. * regex.c (enum regexcode): Changed `unused' to `no_op'. (this_and_lower_levels_match_nothing): Deleted forward reference. (regex_compile): case '^': if the syntax bit RE_ANCHORS_ONLY_AT_ENDS is set, then '^' is only an anchor if at the beginning of the pattern; only record anchor position if the syntax bit RE_REPEATED_ANCHORS_AWAY is set; the '^' is a normal char if the syntax bit RE_ANCHORS_ONLY_AT_END is set and we're not at the beginning of the pattern (and neither RE_CONTEXTUAL_INDEP_OPS nor RE_CONTEXTUAL_INDEP_OPS syntax bits are set). Only adjust the anchor list if the syntax bit RE_REPEATED_ANCHORS_AWAY is set. * regex.c (level_list_type): Use to detect when '^' is in a leading position. (regex_compile): Added level_list_type level_list variable in which we keep track of whether or not a grouping level (in its current or most recent incarnation) matches anything besides the empty string. Set the bit for the i-th level when detect it should match something other than the empty string and the bit for the (i-1)-th level when leave the i-th group. Clear all bits for the i-th and higher levels if none of 0--(i - 1)-th's bits are set when encounter an alternation operator on that level. If no levels are set when hit a '^', then it is in a leading position. We keep track of which level we're at by increasing a variable current_level whenever we encounter an open-group operator and decreasing it whenever we encounter a close-group operator. Have to adjust the anchor list contents whenever insert something ahead of them (such as on_failure_jump's) in the pattern. (adjust_anchor_list): Adjusts the offsets in an anchor list by a given increment starting at a given start position. (get_level_value): Returns the bit setting of a given level. (set_level_value): Sets the bit of a given level to a given value. (set_this_level): Sets (to 1) the bit of a given level. (set_next_lower_level): Sets (to 1) the bit of (LEVEL - 1) for a given LEVEL. (clear_this_and_higher_levels): Clears the bits for a given level and any higher levels. (extend_level_list): Adds sizeof(unsigned) more bits to a level list. (increase_level): Increases by 1 the value of a given level variable. (decrease_level): Decreases by 1 the value of a given level variable. (lower_levels_match_nothing): Checks if any levels lower than the given one match anything. (no_levels_match_anything): Checks if any levels match anything. (re_match_2): At case wordbeg: before looking at d-1, check that we're not at the string's beginning. At case wordend: Added some illuminating parentheses. Mon Mar 25 13:58:51 1991 Kathy Hargreaves (kathy at hayley) * regex.h (RE_NO_ANCHOR_AT_NEWLINE): Changed syntax bit name from RE_ANCHOR_NOT_NEWLINE because an anchor never matches the newline itself, just the empty string either before or after it. (RE_REPEATED_ANCHORS_AWAY): Added this syntax bit for ignoring anchors inside groups which are operated on by repetition operators. (RE_DOT_MATCHES_NEWLINE): Added this bit so the match-any-character operator could match a newline when it's set. (RE_SYNTAX_POSIX_BASIC): Set RE_DOT_MATCHES_NEWLINE in this. (RE_SYNTAX_POSIX_EXTENDED): Set RE_DOT_MATCHES_NEWLINE and RE_REPEATED_ANCHORS_AWAY in this. (regerror): Changed prototypes to new POSIX spec. * regex.c (anchor_list_type): Added so could null out anchors inside repeated groups. (ANCHOR_LIST_PTR_FULL): Added for above type. (compile_stack_element): Changed name from stack_element. (compile_stack_type): Changed name from compile_stack. (INIT_COMPILE_STACK_SIZE): Changed name from INIT_STACK_SIZE. (COMPILE_STACK_EMPTY): Changed name from STACK_EMPTY. (COMPILE_STACK_FULL): Changed name from STACK_FULL. (regex_compile): Changed SYNTAX parameter to non-const. Changed variable name `stack' to `compile_stack'. If syntax bit RE_REPEATED_ANCHORS_AWAY is set, then naively put anchors in a list when encounter them and then set them to `unused' when detect they are within a group operated on by a repetition operator. Need something more sophisticated than this, as they should only get set to `unused' if they are in positions where they would be anchors. Also need a better way to detect contextually invalid anchors. Changed some commments. (is_in_compile_stack): Changed name from `is_in_stack'. (extend_anchor_list): Added to do anchor stuff. (record_anchor_position): Added to do anchor stuff. (remove_intervening_anchors): Added to do anchor stuff. (re_match_2): Now match a newline with the match-any-character operator if RE_DOT_MATCHES_NEWLINE is set. Compacted some code. (regcomp): Added new POSIX newline information to the header commment. If REG_NEWLINE cflag is set, then now unset RE_DOT_MATCHES_NEWLINE in syntax. (put_in_buffer): Added to do new POSIX regerror spec. Called by regerror. (regerror): Changed to take a pattern buffer, error buffer and its size, and return type `size_t', the size of the full error message, and the first ERRBUF_SIZE - 1 characters of the full error message in the error buffer. Wed Feb 27 16:38:33 1991 Kathy Hargreaves (kathy at hayley) * regex.h (#include ): Removed this as new POSIX standard has the user include it. (RE_SYNTAX_POSIX_BASIC and RE_SYNTAX_POSIX_EXTENDED): Removed RE_HAT_LISTS_NOT_NEWLINE as new POSIX standard has the cflag REG_NEWLINE now set this. Similarly, added syntax bit RE_ANCHOR_NOT_NEWLINE as this is now unset by REG_NEWLINE. (RE_SYNTAX_POSIX_BASIC): Removed syntax bit RE_NO_CONSECUTIVE_REPEATS as POSIX now allows them. * regex.c (#include ): Added this as new POSIX standard has the user include it instead of us putting it in regex.h. (extern char *re_syntax_table): Made into an extern so the user could allocate it. (DO_RANGE): If don't find a range end, now goto invalid_range_end instead of unmatched_left_bracket. (regex_compile): Made variable SYNTAX non-const.???? Reformatted some code. (re_compile_fastmap): Moved is_a_succeed_n's declaration to inner braces. Compacted some code. (SET_NEWLINE_FLAG): Removed and put inline. (regcomp): Made variable `syntax' non-const so can unset RE_ANCHOR_NOT_NEWLINE syntax bit if cflag RE_NEWLINE is set. If cflag RE_NEWLINE is set, set the RE_HAT_LISTS_NOT_NEWLINE syntax bit and unset RE_ANCHOR_NOT_NEWLINE one of `syntax'. Wed Feb 20 16:33:38 1991 Kathy Hargreaves (kathy at hayley) * regex.h (RE_NO_CONSECUTIVE_REPEATS): Changed name from RE_NO_CONSEC_REPEATS. (REG_ENESTING): Deleted this POSIX return value, as the stack is now unbounded. (struct re_pattern_buffer): Changed some comments. (re_compile_pattern): Changed a comment. Deleted check on stack upper bound and corresponding error. Now when there's no interval contents and it's the end of the pattern, go to unmatched_left_curly_brace instead of end_of_pattern. Removed nesting_too_deep error, as the stack is now unbounded. (regcomp): Removed REG_ENESTING case, as the stack is now unbounded. (regerror): Removed REG_ENESTING case, as the stack is now unbounded. * regex.c (MAX_STACK_SIZE): Deleted because don't need upper bound on array indexed with an unsigned number. Sun Feb 17 15:50:24 1991 Kathy Hargreaves (kathy at hayley) * regex.h: Changed and added some comments. * regex.c (init_syntax_once): Made `_' a word character. (re_compile_pattern): Added a comment. (re_match_2): Redid header comment. (regexec): With header comment about PMATCH, corrected and removed details found regex.h, adding a reference. Fri Feb 15 09:21:31 1991 Kathy Hargreaves (kathy at hayley) * regex.c (DO_RANGE): Removed argument parentheses. Now get untranslated range start and end characters and set list bits for the translated (if at all) versions of them and all characters between them. (re_match_2): Now use regs->num_regs instead of num_regs_wanted wherever possible. (regcomp): Now build case-fold translate table using isupper and tolower facilities so will work on foreign language characters. Sat Feb 9 16:40:03 1991 Kathy Hargreaves (kathy at hayley) * regex.h (RE_HAT_LISTS_NOT_NEWLINE): Changed syntax bit name from RE_LISTS_NOT_NEWLINE as it only affects nonmatching lists. Changed all references to the match-beginning-of-string operator to match-beginning-of-line operator, as this is what it does. (RE_NO_CONSEC_REPEATS): Added this syntax bit. (RE_SYNTAX_POSIX_BASIC): Added above bit to this. (REG_PREMATURE_END): Changed name to REG_EEND. (REG_EXCESS_NESTING): Changed name to REG_ENESTING. (REG_TOO_BIG): Changed name to REG_ESIZE. (REG_INVALID_PREV_RE): Deleted this return POSIX value. Added and changed some comments. * regex.c (re_compile_pattern): Now sets the pattern buffer's `return_default_num_regs' field. (typedef struct stack_element, stack_type, INIT_STACK_SIZE, MAX_STACK_SIZE, STACK_EMPTY, STACK_FULL): Added for regex_compile. (INIT_BUF_SIZE): Changed value from 28 to 32. (BUF_PUSH): Changed name from BUFPUSH. (MAX_BUF_SIZE): Added so could use in many places. (IS_CHAR_CLASS_STRING): Replaced is_char_class with this. (regex_compile): Added a stack which could grow dynamically and which has struct elements. Go back to initializing `zero_times_ok' and `many_time_ok' to 0 and |=ing them inside the loop. Now disallow consecutive repetition operators if the syntax bit RE_NO_CONSEC_REPEATS is set. Now detect trailing backslash when the compiler is expecting a `?' or a `+'. Changed calls to GET_BUFFER_SPACE which asked for 6 to ask for 3, as that's all they needed. Now check for trailing backslash inside lists. Now disallow an empty alternative right before an end-of-line operator. Now get buffer space before leaving space for a fixup jump. Now check if at pattern end when at open-interval operator. Added some comments. Now check if non-interval repetition operators follow an interval one if the syntax bit RE_NO_CONSEC_REPEATS is set. Now only check if what precedes an interval repetition operator isn't a regular expression which matches one character if the syntax bit RE_NO_CONSEC_REPEATS is set. Now return "Unmatched [ or [^" instead of "Unmatched [". (is_in_stack): Added to check if a given register number is in the stack. (re_match_2): If initial variable allocations fail, return -2, instead of -1. Now set reg's `num_regs' field when allocating regs. Now before allocating them, free regs->start and end if they aren't NULL and return -2 if either allocation fails. Now use regs->num_regs instead of num_regs_wanted to control regs loops. Now increment past the newline when matching it with an end-of-line operator. (recomp): Added to the header comment. Now return REG_ESUBREG if regex_compile returns "Unmatched [ or [^" instead of doing so if it returns "Unmatched [". Now return REG_BADRPT if in addition to returning "Missing preceding regular expression", regex_compile returns "Invalid preceding regular expression". Now return new return value names (see regex.h changes). (regexec): Added to header comment. Initialize regs structure. Now match whole string. Now always free regs.start and regs.end instead of just when the string matched. (regerror): Now return "Regex error: Unmatched [ or [^.\n" instead of "Regex error: Unmatched [.\n". Now return "Regex error: Preceding regular expression either missing or not simple.\n" instead of "Regex error: Missing preceding regular expression.\n". Removed REG_INVALID_PREV_RE case (it got subsumed into the REG_BADRPT case). Thu Jan 17 09:52:35 1991 Kathy Hargreaves (kathy at hayley) * regex.h: Changed a comment. * regex.c: Changed and added large header comments. (re_compile_pattern): Now if detect that `laststart' for an interval points to a byte code for a regular expression which matches more than one character, make it an internal error. (regerror): Return error message, don't print it. Tue Jan 15 15:32:49 1991 Kathy Hargreaves (kathy at hayley) * regex.h (regcomp return codes): Added GNU ones. Updated some comments. * regex.c (DO_RANGE): Changed `obscure_syntax' to `syntax'. (regex_compile): Added `following_left_brace' to keep track of where pseudo interval following a valid interval starts. Changed some instances that returned "Invalid regular expression" to instead return error strings coinciding with POSIX error codes. Changed some comments. Now consider only things between `[:' and `:]' to be possible character class names. Now a character class expression can't end a pattern; at least a `]' must close the list. Now if the syntax bit RE_NO_BK_CURLY_BRACES is set, then a valid interval must be followed by yet another to get an error for preceding an interval (in this case, the second one) with a regular expression that matches more than one character. Now if what follows a valid interval begins with a open interval operator but doesn't begin a valid interval, then set following_left_bracket to it, put it in C and go to normal_char label. Added some comments. Return "Invalid character class name" instead of "Invalid character class". (regerror): Return messages for all POSIX error codes except REG_ECOLLATE and REG_NEWLINE, along with all GNU error codes. Added `break's after all cases. (main): Call re_set_syntax instead of setting `obscure_syntax' directly. Sat Jan 12 13:37:59 1991 Kathy Hargreaves (kathy at hayley) * regex.h (Copyright): Updated date. (#include ): Include unconditionally. (RE_CANNOT_MATCH_NEWLINE): Deleted this syntax bit. (RE_SYNTAX_POSIX_BASIC, RE_SYNTAX_POSIX_EXTENDED): Removed setting the RE_ANCHOR_NOT_NEWLINE syntax bit from these. Changed and added some comments. (struct re_pattern_buffer): Changed some flags from chars to bits. Added field `syntax'; holds which syntax pattern was compiled with. Added bit flag `return_default_num_regs'. (externs for GNU and Berkeley UNIX routines): Added `const's to parameter types to be compatible with POSIX. (#define const): Added to support old C compilers. * regex.c (Copyright): Updated date. (enum regexpcode): Deleted `newline'. (regex_compile): Renamed re_compile_pattern to this, added a syntax parameter so it can set the pattern buffer's `syntax' field. Made `pattern', and `size' `const's so could pass to POSIX interface routines; also made `const' whatever interval variables had to be to make this work. Changed references to `obscure_syntax' to new parameter `syntax'. Deleted putting `newline' in buffer when see `\n'. Consider invalid character classes which have nothing wrong except the character class name; if so, return character-class error. (is_char_class): Added routine for regex_compile. (re_compile_pattern): added a new one which calls regex_compile with `obscure_syntax' as the actual parameter for the formal `syntax'. Gave this the old routine's header comments. Made `pattern', and `size' `const's so could use POSIX interface routine parameters. (re_search, re_search_2, re_match, re_match_2): Changed `pbufp' to `bufp'. (re_search_2, re_match_2): Changed `mstop' to `stop'. (re_search, re_search_2): Made all parameters except `regs' `const's so could use POSIX interface routines parameters. (re_search_2): Added private copies of `const' parameters so could change their values. (re_match_2): Made all parameters except `regs' `const's so could use POSIX interface routines parameters. Changed `size1' and `size2' parameters to `size1_arg' and `size2_arg' and so could change; added local `size1' and `size2' and set to these. Added some comments. Deleted `newline' case. `begline' can also possibly match if `d' contains a newline; if it does, we have to increment d to point past the newline. Replaced references to `obscure_syntax' with `bufp->syntax'. (re_comp, re_exec): Made parameter `s' a `const' so could use POSIX interface routines parameters. Now call regex_compile, passing `obscure_syntax' via the `syntax' parameter. (re_exec): Made local `len' a `const' so could pass to re_search. (regcomp): Added header comment. Added local `syntax' to set and pass to regex_compile rather than setting global `obscure_syntax' and passing it. Call regex_compile with its `syntax' parameter rather than re_compile_pattern. Return REG_ECTYPE if character-class error. (regexec): Don't initialize `regs' to anything. Made `private_preg' a nonpointer so could set to what the constant `preg' points. Initialize `private_preg's `return_default_num_regs' field to zero because want to return `nmatch' registers, not however many there are subexpressions in the pattern. Also test if `nmatch' > 0 to see if should pass re_match `regs'. Tue Jan 8 15:57:17 1991 Kathy Hargreaves (kathy at hayley) * regex.h (struct re_pattern_buffer): Reworded comment. * regex.c (EXTEND_BUFFER): Also reset beg_interval. (re_search_2): Return val if val = -2. (NUM_REG_ITEMS): Listed items in comment. (NUM_OTHER_ITEMS): Defined this for using in > 1 definition. (MAX_NUM_FAILURE_ITEMS): Replaced `+ 2' with NUM_OTHER_ITEMS. (NUM_FAILURE_ITEMS): As with definition above and added to comment. (PUSH_FAILURE_POINT): Replaced `* 2's with `<< 1's. (re_match_2): Test with equality with 1 to see pbufp->bol and pbufp->eol are set. Fri Jan 4 15:07:22 1991 Kathy Hargreaves (kathy at hayley) * regex.h (struct re_pattern_buffer): Reordered some fields. Updated some comments. Added not_bol and not_eol fields. (extern regcomp, regexec, regerror): Added return types. (extern regfree): Added `extern'. * regex.c (min): Deleted unused macro. (re_match_2): Compacted some code. Removed call to macro `min' from `for' loop. Fixed so unused registers get filled with -1's. Fail if the pattern buffer's `not_bol' field is set and encounter a `begline'. Fail if the pattern buffer's `not_eol' field is set and encounter a `endline'. Deleted redundant check for empty stack in fail case. Don't free pattern buffer's components in re_comp. (regexec): Initialize variable regs. Added `private_preg' pattern buffer so could set `not_bol' and `not_eol' fields and hand to re_match. Deleted naive attempt to detect anchors. Set private pattern buffer's `not_bol' and `not_eol' fields according to eflags value. `nmatch' must also be > 0 for us to bother allocating registers to send to re_match and filling pmatch with their results after the call to re_match. Send private pattern buffer instead of argument to re_match. If use the registers, always free them and then set them to NULL. (regerror): Added this Posix routine. (regfree): Added this Posix routine. Tue Jan 1 15:02:45 1991 Kathy Hargreaves (kathy at hayley) * regex.h (RE_NREGS): Deleted this definition, as now the user can choose how many registers to have. (REG_NOTBOL, REG_NOTEOL): Defined these Posix eflag bits. (REG_NOMATCH, REG_BADPAT, REG_ECOLLATE, REG_ECTYPE, REG_EESCAPE, REG_ESUBREG, REG_EBRACK, REG_EPAREN, REG_EBRACE, REG_BADBR, REG_ERANGE, REG_ESPACE, REG_BADRPT, REG_ENEWLINE): Defined these return values for Posix's regcomp and regexec. Updated some comments. (struct re_pattern_buffer): Now typedef this as regex_t instead of the other way around. (struct re_registers): Added num_regs field. Made start and end fields pointers to char instead of fixed size arrays. (regmatch_t): Added this Posix register type. (regcomp, regexec, regerror, regfree): Added externs for these Posix routines. * regex.c (enum boolean): Typedefed this. (re_pattern_buffer): Reformatted some comments. (re_compile_pattern): Updated some comments. Always push start_memory and its attendant number whenever encounter a group, not just when its number is less than the previous maximum number of registers; same for stop_memory. Get 4 bytes of buffer space instead of 2 when pushing a set_number_at. (can_match_nothing): Added this to elaborate on and replace code in re_match_2. (reg_info_type): Made can_match_nothing field a bit instead of int. (MIN): Added for re_match_2. (re_match_2 macros): Changed all `for' loops which used RE_NREGS to now use num_internal_regs as upper bounds. (MAX_NUM_FAILURE_ITEMS): Use num_internal_regs instead of RE_NREGS. (POP_FAILURE_POINT): Added check for empty stack. (FREE_VARIABLES): Added this to free (and set to NULL) variables allocated in re_match_2. (re_match_2): Rearranged parameters to be in order. Added variables num_regs_wanted (how many registers the user wants) and num_internal_regs (how many groups there are). Allocated initial_stack, regstart, regend, old_regstart, old_regend, reginfo, best_regstart, and best_regend---all which used to be fixed size arrays. Free them all and return -1 if any fail. Free above variables if starting position pos isn't valid. Changed all `for' loops which used RE_NREGS to now use num_internal_regs as upper bounds---except for the loops which fill regs; then use num_regs_wanted. Allocate regs if the user has passed it and wants more than 0 registers filled. Set regs->start[i] and regs->end[i] to -1 if either regstart[i] or regend[i] equals -1, not just the first. Free allocated variables before returning. Updated some comments. (regcomp): Return REG_ESPACE, REG_BADPAT, REG_EPAREN when appropriate. Free translate array. (regexec): Added this Posix interface routine. Mon Dec 24 14:21:13 1990 Kathy Hargreaves (kathy at hayley) * regex.h: If _POSIX_SOURCE is defined then #include . Added syntax bit RE_CANNOT_MATCH_NEWLINE. Defined Posix cflags: REG_EXTENDED, REG_NEWLINE, REG_ICASE, and REG_NOSUB. Added fields re_nsub and no_sub to struct re_pattern_buffer. Typedefed regex_t to be `struct re_pattern_buffer'. * regex.c (CHAR_SET_SIZE): Defined this to be 256 and replaced incidences of this value with this constant. (re_compile_pattern): Added switch case for `\n' and put `newline' into the pattern buffer when encounter this. Increment the pattern_buffer's `re_nsub' field whenever open a group. (re_match_2): Match a newline with `newline'---provided the syntax bit RE_CANNOT_MATCH_NEWLINE isn't set. (regcomp): Added this Posix interface routine. (enum test_type): Added interface_test tag. (main): Added Posix interface test. Tue Dec 18 12:58:12 1990 Kathy Hargreaves (kathy at hayley) * regex.h (struct re_pattern_buffer): reformatted so would fit in texinfo documentation. Thu Nov 29 15:49:16 1990 Kathy Hargreaves (kathy at hayley) * regex.h (RE_NO_EMPTY_ALTS): Added this bit. (RE_SYNTAX_POSIX_EXTENDED): Added above bit. * regex.c (re_compile_pattern): Disallow empty alternatives only when RE_NO_EMPTY_ALTS is set, not when RE_CONTEXTUAL_INVALID_OPS is. Changed RE_NO_BK_CURLY_BRACES to RE_NO_BK_PARENS when testing for empty groups at label handle_open. At label handle_bar: disallow empty alternatives if RE_NO_EMPTY_ALTS is set. Rewrote some comments. (re_compile_fastmap): cleaned up code. (re_search_2): Rewrote comment. (struct register_info): Added field `inner_groups'; it records which groups are inside of the current one. Added field can_match_nothing; it's set if the current group can match nothing. Added field ever_match_something; it's set if current group ever matched something. (INNER_GROUPS): Added macro to access inner_groups field of struct register_info. (CAN_MATCH_NOTHING): Added macro to access can_match_nothing field of struct register_info. (EVER_MATCHED_SOMETHING): Added macro to access ever_matched_something field of struct register_info. (NOTE_INNER_GROUP): Defined macro to record that a given group is inside of all currently active groups. (re_match_2): Added variables *p1 and mcnt2 (multipurpose). Added old_regstart and old_regend arrays to hold previous register values if they need be restored. Initialize added fields and variables. case start_memory: Find out if the group can match nothing. Save previous register values in old_restart and old_regend. Record that current group is inside of all currently active groups. If the group is inside a loop and it ever matched anything, restore its registers to values before the last failed match. Restore the registers for the inner groups, too. case duplicate: Can back reference to a group that never matched if it can match nothing. Thu Nov 29 11:12:54 1990 Karl Berry (karl at hayley) * regex.c (bcopy, ...): define these if either _POSIX_SOURCE or STDC_HEADERS is defined; same for including . Sat Oct 6 16:04:55 1990 Kathy Hargreaves (kathy at hayley) * regex.h (struct re_pattern_buffer): Changed field comments. * regex.c (re_compile_pattern): Allow a `$' to precede an alternation operator (`|' or `\|'). Disallow `^' and/or `$' in empty groups if the syntax bit RE_NO_EMPTY_GROUPS is set. Wait until have parsed a valid `\{...\}' interval expression before testing RE_CONTEXTUAL_INVALID_OPS to see if it's invalidated by that. Don't use RE_NO_BK_CURLY_BRACES to test whether or not a validly parsed interval expression is invalid if it has no preceding re; rather, use RE_CONTEXTUAL_INVALID_OPS. If an interval parses, but there is no preceding regular expression, yet the syntax bit RE_CONTEXTUAL_INDEP_OPS is set, then that interval can match the empty regular expression; if the bit isn't set, then the characters in the interval expression are parsed as themselves (sans the backslashes). In unfetch_interval case: Moved PATFETCH to above the test for RE_NO_BK_CURLY_BRACES being set, which would force a goto normal_backslash; the code at both normal_backsl and normal_char expect a character in `c.' Sun Sep 30 11:13:48 1990 Kathy Hargreaves (kathy at hayley) * regex.h: Changed some comments to use the terms used in the documentation. (RE_CONTEXTUAL_INDEP_OPS): Changed name from `RE_CONTEXT_INDEP_OPS'. (RE_LISTS_NOT_NEWLINE): Changed name from `RE_HAT_NOT_NEWLINE.' (RE_ANCHOR_NOT_NEWLINE): Added this syntax bit. (RE_NO_EMPTY_GROUPS): Added this syntax bit. (RE_NO_HYPHEN_RANGE_END): Deleted this syntax bit. (RE_SYNTAX_...): Reformatted. (RE_SYNTAX_POSIX_BASIC, RE_SYNTAX_EXTENDED): Added syntax bits RE_ANCHOR_NOT_NEWLINE and RE_NO_EMPTY_GROUPS, and deleted RE_NO_HYPHEN_RANGE_END. (RE_SYNTAX_POSIX_EXTENDED): Added syntax bit RE_DOT_NOT_NULL. * regex.c (bcopy, bcmp, bzero): Define if _POSIX_SOURCE is defined. (_POSIX_SOURCE): ifdef this, #include (#ifdef emacs): Changed comment of the #endif for the its #else clause to be `not emacs', not `emacs.' (no_pop_jump): Changed name from `jump'. (pop_failure_jump): Changed name from `finalize_jump.' (maybe_pop_failure_jump): Changed name from `maybe_finalize_jump'. (no_pop_jump_n): Changed name from `jump_n.' (EXTEND_BUFFER): Use shift instead of multiplication to double buf->allocated. (DO_RANGE, recompile_pattern): Added macro to set the list bits for a range. (re_compile_pattern): Fixed grammar problems in some comments. Checked that RE_NO_BK_VBAR is set to make `$' valid before a `|' and not set to make it valid before a `\|'. Checked that RE_NO_BK_PARENS is set to make `$' valid before a ')' and not set to make it valid before a `\)'. Disallow ranges starting with `-', unless the range is the first item in a list, rather than disallowing ranges which end with `-'. Disallow empty groups if the syntax bit RE_NO_EMPTY_GROUPS is set. Disallow nothing preceding `{' and `\{' if they represent the open-interval operator and RE_CONTEXTUAL_INVALID_OPS is set. (register_info_type): typedef-ed this using `struct register_info.' (SET_REGS_MATCHED): Compacted the code. (re_match_2): Made it fail if back reference a group which we've never matched. Made `^' not match a newline if the syntax bit RE_ANCHOR_NOT_NEWLINE is set. (really_fail): Added this label so could force a final fail that would not try to use the failure stack to recover. Sat Aug 25 14:23:01 1990 Kathy Hargreaves (kathy at hayley) * regex.h (RE_CONTEXTUAL_OPS): Changed name from RE_CONTEXT_OPS. (global): Rewrote comments and rebroke some syntax #define lines. * regex.c (isgraph): Added definition for sequents. (global): Now refer to character set lists as ``lists.'' Rewrote comments containing ``\('' or ``\)'' to now refer to ``groups.'' (RE_CONTEXTUAL_OPS): Changed name from RE_CONTEXT_OPS. (re_compile_pattern): Expanded header comment. Sun Jul 15 14:50:25 1990 Kathy Hargreaves (kathy at hayley) * regex.h (RE_CONTEX_INDEP_OPS): the comment's sense got turned around when we changed how it read; changed it to be correct. Sat Jul 14 16:38:06 1990 Kathy Hargreaves (kathy at hayley) * regex.h (RE_NO_EMPTY_BK_REF): changed name to RE_NO_MISSING_BK_REF, as this describes it better. * regex.c (re_compile_pattern): changed RE_NO_EMPTY_BK_REF to RE_NO_MISSING_BK_REF, as above. Thu Jul 12 11:45:05 1990 Kathy Hargreaves (kathy at hayley) * regex.h (RE_NO_EMPTY_BRACKETS): removed this syntax bit, as bracket expressions should *never* be empty regardless of the syntax. Removes this bit from RE_SYNTAX_POSIX_BASIC and RE_SYNTAX_POSIX_EXTENDED. * regex.c (SET_LIST_BIT): in the comment, now refer to character sets as (non)matching sets, as bracket expressions can now match other things in addition to characters. (re_compile_pattern): refer to groups as such instead of `\(...\)' or somesuch, because groups can now be enclosed in either plain parens or backslashed ones, depending on the syntax. In the '[' case, added a boolean just_had_a_char_class to detect whether or not a character class begins a range (which is invalid). Restore way of breaking out of a bracket expression to original way. Add way to detect a range if the last thing in a bracket expression was a character class. Took out check for c != ']' at the end of a character class in the else clause, as it had already been checked in the if part that also checked the validity of the string. Set or clear just_had_a_char_class as appropriate. Added some comments. Changed references to character sets to ``(non)matching lists.'' Sun Jul 1 12:11:29 1990 Karl Berry (karl at hayley) * regex.h (BYTEWIDTH): moved back to regex.c. * regex.h (re_compile_fastmap): removed declaration; this shouldn't be advertised. Mon May 28 15:27:53 1990 Kathy Hargreaves (kathy at hayley) * regex.c (ifndef Sword): Made comments more specific. (global): include so can write fatal messages on standard error. Replaced calls to assert with fprintfs to stderr and exit (1)'s. (PREFETCH): Reformatted to make more readable. (AT_STRINGS_BEG): Defined to test if we're at the beginning of the virtual concatenation of string1 and string2. (AT_STRINGS_END): Defined to test if at the end of the virtual concatenation of string1 and string2. (AT_WORD_BOUNDARY): Defined to test if are at a word boundary. (IS_A_LETTER(d)): Defined to test if the contents of the pointer D is a letter. (re_match_2): Rewrote the wordbound, notwordbound, wordbeg, wordend, begbuf, and endbuf cases in terms of the above four new macros. Called SET_REGS_MATCHED in the matchsyntax, matchnotsyntax, wordchar, and notwordchar cases. Mon May 14 14:49:13 1990 Kathy Hargreaves (kathy at hayley) * regex.c (re_search_2): Fixed RANGE to not ever take STARTPOS outside of virtual concatenation of STRING1 and STRING2. Updated header comment as to this. (re_match_2): Clarified comment about MSTOP in header. Sat May 12 15:39:00 1990 Kathy Hargreaves (kathy at hayley) * regex.c (re_search_2): Checked for out-of-range STARTPOS. Added comments. When searching backwards, not only get the character with which to compare to the fastmap from string2 if the starting position >= size1, but also if size1 is zero; this is so won't get a segmentation fault if string1 is null. Reformatted code at label advance. Thu Apr 12 20:26:21 1990 Kathy Hargreaves (kathy at hayley) * regex.h: Added #pragma once and #ifdef...endif __REGEXP_LIBRARY. (RE_EXACTN_VALUE): Added for search.c to use. Reworded some comments. regex.c: Punctuated some comments correctly. (NULL): Removed this. (RE_EXACTN_VALUE): Added for search.c to use. (): Moved this include to top of file. (): Added this include. (struct regexpcode): Assigned 0 to unused and 1 to exactn because of RE_EXACTN_VALUE. Added comment. (various macros): Lined up backslashes near end of line. (insert_jump): Cleaned up the header comment. (re_search): Corrected the header comment. (re_search_2): Cleaned up and completed the header comment. (re_max_failures): Updated comment. (struct register_info): Constructed as bits so as to save space on the stack when pushing register information. (IS_ACTIVE): Macro for struct register_info. (MATCHED_SOMETHING): Macro for struct register_info. (NUM_REG_ITEMS): How many register information items for each register we have to push on the stack at each failure. (MAX_NUM_FAILURE_ITEMS): If push all the registers on failure, this is how many items we push on the stack. (PUSH_FAILURE_POINT): Now pushes whether or not the register is currently active, and whether or not it matched something. Checks that there's enough space allocated to accomodate all the items we currently want to push. (Before, a test for an empty stack sufficed because we always pushed and popped the same number of items). Replaced ``2'' with MAX_NUM_FAILURE_POINTS when ``2'' refers to how many things get pushed on the stack each time. When copy the stack into the newly allocated storage, now only copy the area in use. Clarified comment. (POP_FAILURE_POINT): Defined to use in places where put number of registers on the stack into a variable before using it to decrement the stack, so as to not confuse the compiler. (IS_IN_FIRST_STRING): Defined to check if a pointer points into the first string. (SET_REGS_MATCHED): Changed to use the struct register_info bits; also set the matched-something bit to false if the register isn't currently active. (This is a redundant setting.) (re_match_2): Cleaned up and completed the header comment. Updated the failure stack comment. Replaced the ``2'' with MAX_NUM_FAILURE_ITEMS in the static allocation of initial_stack, because now more than two (now up to MAX_FAILURE_ITEMS) items get pushed on the failure stack each time. Ditto for stackb. Trashed restart_seg1, regend_seg1, best_regstart_seg1, and best_regend_seg1 because they could have erroneous information in them, such as when matching ``a'' (in string1) and ``ab'' (in string2) with ``(a)*ab''; before using IS_IN_FIRST_STRING to see whether or not the register starts or ends in string1, regstart[1] pointed past the end of string1, yet regstart_seg1 was 0! Added variable reg_info of type struct register_info to keep track of currently active registers and whether or not they currently match anything. Commented best_regs_set. Trashed reg_active and reg_matched_something and put the information they held into reg_info; saves space on the stack. Replaced NULL with '\000'. In begline case, compacted the code. Used assert to exit if had an internal error. In begbuf case, because now force the string we're working on into string2 if there aren't two strings, now allow d == string2 if there is no string1 (and the check for that is size1 == 0!); also now succeeds if there aren't any strings at all. (main, ifdef canned): Put test type into a variable so could change it while debugging. Sat Mar 24 12:24:13 1990 Kathy Hargreaves (kathy at hayley) * regex.c (GET_UNSIGNED_NUMBER): Deleted references to num_fetches. (re_compile_pattern): Deleted num_fetches because could keep track of the number of fetches done by saving a pointer into the pattern. Added variable beg_interval to be used as a pointer, as above. Assert that beg_interval points to something when it's used as above. Initialize succeed_n's to lower_bound because re_compile_fastmap needs to know it. (re_compile_fastmap): Deleted unnecessary variable is_a_jump_n. Added comment. (re_match_2): Put number of registers on the stack into a variable before using it to decrement the stack, so as to not confuse the compiler. Updated comments. Used error routine instead of printf and exit. In exactn case, restored longer code from ``original'' regex.c which doesn't test translate inside a loop. * regex.h: Moved #define NULL and the enum regexpcode definition and to regex.c. Changed some comments. regex.c (global): Updated comments about compiling and for the re_compile_pattern jump routines. Added #define NULL and the enum regexpcode definition (from regex.h). (enum regexpcode): Added set_number_at to reset the n's of succeed_n's and jump_n's. (re_set_syntax): Updated its comment. (re_compile_pattern): Moved its heading comment to after its macros. Moved its include statement to the top of the file. Commented or added to comments of its macros. In start_memory case: Push laststart value before adding start_memory and its register number to the buffer, as they might not get added. Added code to put a set_number_at before each succeed_n and one after each jump_n; rewrote code in what seemed a more straightforward manner to put all these things in the pattern so the succeed_n's would correctly jump to the set_number_at's of the matching jump_n's, and so the jump_n's would correctly jump to after the set_number_at's of the matching succeed_n's. Initialize succeed_n n's to -1. (insert_op_2): Added this to insert an operation followed by two integers. (re_compile_fastmap): Added set_number_at case. (re_match_2): Moved heading comment to after macros. Added mention of REGS to heading comment. No longer turn a succeed_n with n = 0 into an on_failure_jump, because n needs to be reset each time through a loop. Check to see if a succeed_n's n is set by its set_number_at. Added set_number_at case. Updated some comments. (main): Added another main to run posix tests, which is compiled ifdef both test and canned. (Old main is still compiled ifdef test only). Tue Mar 19 09:22:55 1990 Kathy Hargreaves (kathy at hayley) * regex.[hc]: Change all instances of the word ``legal'' to ``valid'' and all instances of ``illegal'' to ``invalid.'' Sun Mar 4 12:11:31 1990 Kathy Hargreaves (kathy at hayley) * regex.h: Added syntax bit RE_NO_EMPTY_RANGES which is set if an ending range point has to collate higher or equal to the starting range point. Added syntax bit RE_NO_HYPHEN_RANGE_END which is set if a hyphen can't be an ending range point. Set to two above bits in RE_SYNTAX_POSIX_BASIC and RE_SYNTAX_POSIX_EXTENDED. regex.c: (re_compile_pattern): Don't allow empty ranges if the RE_NO_EMPTY_RANGES syntax bit is set. Don't let a hyphen be a range end if the RE_NO_HYPHEN_RANGE_END syntax bit is set. (ESTACK_PUSH_2): renamed this PUSH_FAILURE_POINT and made it push all the used registers on the stack, as well as the number of the highest numbered register used, and (as before) the two failure points. (re_match_2): Fixed up comments. Added arrays best_regstart[], best_regstart_seg1[], best_regend[], and best_regend_seg1[] to keep track of the best match so far whenever reach the end of the pattern but not the end of the string, and there are still failure points on the stack with which to backtrack; if so, do the saving and force a fail. If reach the end of the pattern but not the end of the string, but there are no more failure points to try, restore the best match so far, set the registers and return. Compacted some code. In stop_memory case, if the subexpression we've just left is in a loop, push onto the stack the loop's on_failure_jump failure point along with the current pointer into the string (d). In finalize_jump case, in addition to popping the failure points, pop the saved registers. In the fail case, restore the registers, as well as the failure points. Sun Feb 18 15:08:10 1990 Kathy Hargreaves (kathy at hayley) * regex.c: (global): Defined a macro GET_BUFFER_SPACE which makes sure you have a specified number of buffer bytes allocated. Redefined the macro BUFPUSH to use this. Added comments. (re_compile_pattern): Call GET_BUFFER_SPACE before storing or inserting any jumps. (re_match_2): Set d to string1 + pos and dend to end_match_1 only if string1 isn't null. Force exit from a loop if it's around empty parentheses. In stop_memory case, if found some jumps, increment p2 before extracting address to which to jump. Also, don't need to know how many more times can jump_n. In begline case, d must equal string1 or string2, in that order, only if they are not null. In maybe_finalize_jump case, skip over start_memorys' and stop_memorys' register numbers, too. Thu Feb 15 15:53:55 1990 Kathy Hargreaves (kathy at hayley) * regex.c (BUFPUSH): off by one goof in deciding whether to EXTEND_BUFFER. Wed Jan 24 17:07:46 1990 Kathy Hargreaves (kathy at hayley) * regex.h: Moved definition of NULL to here. Got rid of ``In other words...'' comment. Added to some comments. regex.c: (re_compile_pattern): Tried to bulletproof some code, i.e., checked if backward references (e.g., p[-1]) were within the range of pattern. (re_compile_fastmap): Fixed a bug in succeed_n part where was getting the amount to jump instead of how many times to jump. (re_search_2): Changed the name of the variable ``total'' to ``total_size.'' Condensed some code. (re_match_2): Moved the comment about duplicate from above the start_memory case to above duplicate case. (global): Rewrote some comments. Added commandline arguments to testing. Wed Jan 17 11:47:27 1990 Kathy Hargreaves (kathy at hayley) * regex.c: (global): Defined a macro STORE_NUMBER which stores a number into two contiguous bytes. Also defined STORE_NUMBER_AND_INCR which does the same thing and then increments the pointer to the storage place to point after the number. Defined a macro EXTRACT_NUMBER which extracts a number from two continguous bytes. Also defined EXTRACT_NUMBER_AND_INCR which does the same thing and then increments the pointer to the source to point to after where the number was. Tue Jan 16 12:09:19 1990 Kathy Hargreaves (kathy at hayley) * regex.h: Incorporated rms' changes. Defined RE_NO_BK_REFS syntax bit which is set when want to interpret back reference patterns as literals. Defined RE_NO_EMPTY_BRACKETS syntax bit which is set when want empty bracket expressions to be illegal. Defined RE_CONTEXTUAL_ILLEGAL_OPS syntax bit which is set when want it to be illegal for *, +, ? and { to be first in an re or come immediately after a | or a (, and for ^ not to appear in a nonleading position and $ in a nontrailing position (outside of bracket expressions, that is). Defined RE_LIMITED_OPS syntax bit which is set when want +, ? and | to always be literals instead of ops. Fixed up the Posix syntax. Changed the syntax bit comments from saying, e.g., ``0 means...'' to ``If this bit is set, it means...''. Changed the syntax bit defines to use shifts instead of integers. * regex.c: (global): Incorporated rms' changes. (re_compile_pattern): Incorporated rms' changes Made it illegal for a $ to appear anywhere but inside a bracket expression or at the end of an re when RE_CONTEXTUAL_ILLEGAL_OPS is set. Made the same hold for $ except it has to be at the beginning of an re instead of the end. Made the re "[]" illegal if RE_NO_EMPTY_BRACKETS is set. Made it illegal for | to be first or last in an re, or immediately follow another | or a (. Added and embellished some comments. Allowed \{ to be interpreted as a literal if RE_NO_BK_CURLY_BRACES is set. Made it illegal for *, +, ?, and { to appear first in an re, or immediately follow a | or a ( when RE_CONTEXTUAL_ILLEGAL_OPS is set. Made back references interpreted as literals if RE_NO_BK_REFS is set. Made recursive intervals either illegal (if RE_NO_BK_CURLY_BRACES isn't set) or interpreted as literals (if is set), if RE_INTERVALS is set. Made it treat +, ? and | as literals if RE_LIMITED_OPS is set. Cleaned up some code. Thu Dec 21 15:31:32 1989 Kathy Hargreaves (kathy at hayley) * regex.c: (global): Moved RE_DUP_MAX to regex.h and made it equal 2^15 - 1 instead of 1000. Defined NULL to be zero. Moved the definition of BYTEWIDTH to regex.h. Made the global variable obscure_syntax nonstatic so the tests in another file could use it. (re_compile_pattern): Defined a maximum length (CHAR_CLASS_MAX_LENGTH) for character class strings (i.e., what's between the [: and the :]'s). Defined a macro SET_LIST_BIT(c) which sets the bit for C in a character set list. Took out comments that EXTEND_BUFFER clobbers C. Made the string "^" match itself, if not RE_CONTEXT_IND_OPS. Added character classes to bracket expressions. Change the laststart pointer saved with the start of each subexpression to point to start_memory instead of after the following register number. This is because the subexpression might be in a loop. Added comments and compacted some code. Made intervals only work if preceded by an re matching a single character or a subexpression. Made back references to nonexistent subexpressions illegal if using POSIX syntax. Made intervals work on the last preceding character of a concatenation of characters, e.g., ab{0,} matches abbb, not abab. Moved macro PREFETCH to outside the routine. (re_compile_fastmap): Added succeed_n to work analogously to on_failure_jump if n is zero and jump_n to work analogously to the other backward jumps. (re_match_2): Defined macro SET_REGS_MATCHED to set which current subexpressions had matches within them. Changed some comments. Added reg_active and reg_matched_something arrays to keep track of in which subexpressions currently have matched something. Defined MATCHING_IN_FIRST_STRING and replaced ``dend == end_match_1'' with it to make code easier to understand. Fixed so can apply * and intervals to arbitrarily nested subexpressions. (Lots of previous bugs here.) Changed so won't match a newline if syntax bit RE_DOT_NOT_NULL is set. Made the upcase array nonstatic so the testing file could use it also. (main.c): Moved the tests out to another file. (tests.c): Moved all the testing stuff here. Sat Nov 18 19:30:30 1989 Kathy Hargreaves (kathy at hayley) * regex.c: (re_compile_pattern): Defined RE_DUP_MAX, the maximum number of times an interval can match a pattern. Added macro GET_UNSIGNED_NUMBER (used to get below): Added variables lower_bound and upper_bound for upper and lower bounds of intervals. Added variable num_fetches so intervals could do backtracking. Added code to handle '{' and "\{" and intervals. Added to comments. (store_jump_n): (Added) Stores a jump with a number following the relative address (for intervals). (insert_jump_n): (Added) Inserts a jump_n. (re_match_2): Defined a macro ESTACK_PUSH_2 for the error stack; it checks for overflow and reallocates if necessary. * regex.h: Added bits (RE_INTERVALS and RE_NO_BK_CURLY_BRACES) to obscure syntax to indicate whether or not a syntax handles intervals and recognizes either \{ and \} or { and } as operators. Also added two syntaxes RE_SYNTAX_POSIX_BASIC and RE_POSIX_EXTENDED and two command codes to the enumeration regexpcode; they are succeed_n and jump_n. Sat Nov 18 19:30:30 1989 Kathy Hargreaves (kathy at hayley) * regex.c: (re_compile_pattern): Defined INIT_BUFF_SIZE to get rid of repeated constants in code. Tested with value 1. Renamed PATPUSH as BUFPUSH, since it pushes things onto the buffer, not the pattern. Also made this macro extend the buffer if it's full (so could do the following): Took out code at top of loop that checks to see if buffer is going to be full after 10 additions (and reallocates if necessary). (insert_jump): Rearranged declaration lines so comments would read better. (re_match_2): Compacted exactn code and added more comments. (main): Defined macros TEST_MATCH and MATCH_SELF to do testing; took out loop so could use these instead. Tue Oct 24 20:57:18 1989 Kathy Hargreaves (kathy at hayley) * regex.c (re_set_syntax): Gave argument `syntax' a type. (store_jump, insert_jump): made them void functions. Local Variables: mode: indented-text left-margin: 8 version-control: never End: lyskom-server-2.1.2/src/libraries/regex/INSTALL0000664000015100472110000001314505533104316014727 This is a generic INSTALL file for utilities distributions. If this package does not come with, e.g., installable documentation or data files, please ignore the references to them below. To compile this package: 1. Configure the package for your system. In the directory that this file is in, type `./configure'. If you're using `csh' on an old version of System V, you might need to type `sh configure' instead to prevent `csh' from trying to execute `configure' itself. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation, and creates the Makefile(s) (one in each subdirectory of the source directory). In some packages it creates a C header file containing system-dependent definitions. It also creates a file `config.status' that you can run in the future to recreate the current configuration. Running `configure' takes a minute or two. While it is running, it prints some messages that tell what it is doing. If you don't want to see the messages, run `configure' with its standard output redirected to `/dev/null'; for example, `./configure >/dev/null'. To compile the package in a different directory from the one containing the source code, you must use a version of `make' that supports the VPATH variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run `configure'. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If for some reason `configure' is not in the source code directory that you are configuring, then it will report that it can't find the source code. In that case, run `configure' with the option `--srcdir=DIR', where DIR is the directory that contains the source code. By default, `make install' will install the package's files in /usr/local/bin, /usr/local/lib, /usr/local/man, etc. You can specify an installation prefix other than /usr/local by giving `configure' the option `--prefix=PATH'. Alternately, you can do so by giving a value for the `prefix' variable when you run `make', e.g., make prefix=/usr/gnu You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH' or set the `make' variable `exec_prefix' to PATH, the package will use PATH as the prefix for installing programs and libraries. Data files and documentation will still use the regular prefix. Normally, all files are installed using the regular prefix. Another `configure' option is useful mainly in `Makefile' rules for updating `config.status' and `Makefile'. The `--no-create' option figures out the configuration for your system and records it in `config.status', without actually configuring the package (creating `Makefile's and perhaps a configuration header file). Later, you can run `./config.status' to actually configure the package. You can also give `config.status' the `--recheck' option, which makes it re-run `configure' with the same arguments you used before. This option is useful if you change `configure'. Some packages pay attention to `--with-PACKAGE' options to `configure', where PACKAGE is something like `gnu-libc' or `x' (for the X Window System). The README should mention any --with- options that the package recognizes. `configure' ignores any other arguments that you give it. If your system requires unusual options for compilation or linking that `configure' doesn't know about, you can give `configure' initial values for some variables by setting them in the environment. In Bourne-compatible shells, you can do that on the command line like this: CC='gcc -traditional' DEFS=-D_POSIX_SOURCE ./configure The `make' variables that you might want to override with environment variables when running `configure' are: (For these variables, any value given in the environment overrides the value that `configure' would choose:) CC C compiler program. Default is `cc', or `gcc' if `gcc' is in your PATH. INSTALL Program to use to install files. Default is `install' if you have it, `cp' otherwise. (For these variables, any value given in the environment is added to the value that `configure' chooses:) DEFS Configuration options, in the form `-Dfoo -Dbar ...' Do not use this variable in packages that create a configuration header file. LIBS Libraries to link with, in the form `-lfoo -lbar ...' If you need to do unusual things to compile the package, we encourage you to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the README so we can include them in the next release. 2. Type `make' to compile the package. If you want, you can override the `make' variables CFLAGS and LDFLAGS like this: make CFLAGS=-O2 LDFLAGS=-s 3. If the package comes with self-tests and you want to run them, type `make check'. If you're not sure whether there are any, try it; if `make' responds with something like make: *** No way to make target `check'. Stop. then the package does not come with self-tests. 4. Type `make install' to install programs, data files, and documentation. 5. You can remove the program binaries and object files from the source directory by typing `make clean'. To also remove the Makefile(s), the header file containing system-dependent definitions (if the package uses one), and `config.status' (all the files that `configure' created), type `make distclean'. The file `configure.in' is used as a template to create `configure' by a program called `autoconf'. You will only need it if you want to regenerate `configure' using a newer version of `autoconf'. lyskom-server-2.1.2/src/libraries/regex/Makefile.am0000664000015100472110000000216207717413243015737 # $Id: Makefile.am,v 1.4 2003/08/16 11:29:05 ceder Exp $ # Copyright (C) 1998 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # noinst_LIBRARIES = libregex.a libregex_a_SOURCES = regex.c regex.h EXTRA_DIST = .cvsignore SUBDIRS = doc test MOSTLYCLEANFILES = *.da *.bb *.gcov *.bbg lyskom-server-2.1.2/src/libraries/regex/Makefile.in0000664000015100472110000004014307723707425015756 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # $Id: Makefile.am,v 1.4 2003/08/16 11:29:05 ceder Exp $ # Copyright (C) 1998 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEBUG_CALLS = @DEBUG_CALLS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EFENCE = @EFENCE@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FLEX = @FLEX@ HAVE_PYTHON_FALSE = @HAVE_PYTHON_FALSE@ HAVE_PYTHON_TRUE = @HAVE_PYTHON_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSURE = @INSURE@ LANGUAGE_SUFFIX = @LANGUAGE_SUFFIX@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ SED = @SED@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRACED_ALLOCATIONS = @TRACED_ALLOCATIONS@ U = @U@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ YACC = @YACC@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ noinst_LIBRARIES = libregex.a libregex_a_SOURCES = regex.c regex.h EXTRA_DIST = .cvsignore SUBDIRS = doc test MOSTLYCLEANFILES = *.da *.bb *.gcov *.bbg subdir = src/libraries/regex ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) libregex_a_AR = $(AR) cru libregex_a_LIBADD = am_libregex_a_OBJECTS = regex.$(OBJEXT) libregex_a_OBJECTS = $(am_libregex_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/scripts/depcomp am__depfiles_maybe = depfiles @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/regex.Po COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ DIST_SOURCES = $(libregex_a_SOURCES) RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \ ps-recursive install-info-recursive uninstall-info-recursive \ all-recursive install-data-recursive install-exec-recursive \ installdirs-recursive install-recursive uninstall-recursive \ check-recursive installcheck-recursive DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \ Makefile.in NEWS configure configure.in DIST_SUBDIRS = $(SUBDIRS) SOURCES = $(libregex_a_SOURCES) all: all-recursive .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/libraries/regex/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libregex.a: $(libregex_a_OBJECTS) $(libregex_a_DEPENDENCIES) -rm -f libregex.a $(libregex_a_AR) libregex.a $(libregex_a_OBJECTS) $(libregex_a_LIBADD) $(RANLIB) libregex.a mostlyclean-compile: -rm -f *.$(OBJEXT) core *.core distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regex.Po@am__quote@ distclean-depend: -rm -rf ./$(DEPDIR) .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ @am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ @am__fastdepCC_TRUE@ fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< .c.obj: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ @am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ @am__fastdepCC_TRUE@ fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` uninstall-info-am: # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ETAGS = etags ETAGSFLAGS = CTAGS = ctags CTAGSFLAGS = tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if (etags --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ else \ include_option=--include; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -f $$subdir/TAGS && \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$tags$$unique" \ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = ../../.. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d $(distdir)/$$subdir \ || mkdir $(distdir)/$$subdir \ || exit 1; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" \ distdir=../$(distdir)/$$subdir \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(LIBRARIES) installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-recursive distclean-am: clean-am distclean-compile distclean-depend \ distclean-generic distclean-tags dvi: dvi-recursive dvi-am: info: info-recursive info-am: install-data-am: install-exec-am: install-info: install-info-recursive install-man: installcheck-am: maintainer-clean: maintainer-clean-recursive maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-info-am uninstall-info: uninstall-info-recursive .PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \ clean-generic clean-noinstLIBRARIES clean-recursive ctags \ ctags-recursive distclean distclean-compile distclean-depend \ distclean-generic distclean-recursive distclean-tags distdir \ dvi dvi-am dvi-recursive info info-am info-recursive install \ install-am install-data install-data-am install-data-recursive \ install-exec install-exec-am install-exec-recursive \ install-info install-info-am install-info-recursive install-man \ install-recursive install-strip installcheck installcheck-am \ installdirs installdirs-am installdirs-recursive \ maintainer-clean maintainer-clean-generic \ maintainer-clean-recursive mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-recursive pdf pdf-am \ pdf-recursive ps ps-am ps-recursive tags tags-recursive \ uninstall uninstall-am uninstall-info-am \ uninstall-info-recursive uninstall-recursive # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/src/libraries/regex/NEWS0000664000015100472110000000375005533104317014377 Version 0.12 * regex.c does not #define bcmp/bcopy/bzero if they already are. * regex.h does not redefine `const' if it is already defined, even if __STDC__ is not defined. * RE_SYNTAX_ED added (same as POSIX BRE's). * The following bugs have been fixed, among others: * The pattern \w+ doesn't infinite loop. * The pattern ".+\n" is compiled correctly. * Expressions with more than MAX_REGNUM groups are compiled correctly. * Patterns that end in a repetition operator (e.g., `*') match slightly faster if no looping is actually necessary. Version 0.11 (17 Sep 92) * Back-references to nonexistent subexpressions, as in the r.e. `abc\1', are always invalid. Previously, they could match the literal digit, e.g., the stated r.e. might have matched `abc1'. * Empty subexpressions are always valid (POSIX leaves this undefined). * Simplified rules for ^ and $ being anchors. * One minor speedup (rewriting the C procedure `pop_failure_point' as a macro again). * Bug fixes involving: - Declarations in regex.h and non-ANSI compilers. - Bracket expressions with characters between 0x80-0xff. - Memory leak in re_match_2 on systems requiring `alloca (0)' to free alloca'd storage. * Test and documentation files moved into subdirectories. Version 0.10 (9 Sep 92) * `obscure_syntax' is now called `re_default_syntax'. * `re_comp's return type is no longer `const', for compatibility with BSD. * POSIX syntaxes now include as much functionality as possible (consistent with the standard). * Compilation conditionals normalized to what the rest of GNU is migrating towards these days. * Bug fixes involving: - Ranges with characters between 0x80 and 0xff, e.g., [\001-\377]. - `re_compile_fastmap' and the sequence `.*\n'. - Intervals with exact counts, e.g., a{5}. * Changed distribution to use a standard Makefile, install the info files, use a configure script, etc. Version 0.9 * The longest match was not always chosen: `a*|ab' didn't match `aab'. lyskom-server-2.1.2/src/libraries/regex/configure0000775000015100472110000002763605533104345015621 #!/bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf. # Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. # 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 2, 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, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # Usage: configure [--srcdir=DIR] [--host=HOST] [--gas] [--nfp] [--no-create] # [--prefix=PREFIX] [--exec-prefix=PREFIX] [--with-PACKAGE] [TARGET] # Ignores all args except --srcdir, --prefix, --exec-prefix, --no-create, and # --with-PACKAGE unless this script has special code to handle it. for arg do # Handle --exec-prefix with a space before the argument. if test x$next_exec_prefix = xyes; then exec_prefix=$arg; next_exec_prefix= # Handle --host with a space before the argument. elif test x$next_host = xyes; then next_host= # Handle --prefix with a space before the argument. elif test x$next_prefix = xyes; then prefix=$arg; next_prefix= # Handle --srcdir with a space before the argument. elif test x$next_srcdir = xyes; then srcdir=$arg; next_srcdir= else case $arg in # For backward compatibility, also recognize exact --exec_prefix. -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* | --exec=* | --exe=* | --ex=* | --e=*) exec_prefix=`echo $arg | sed 's/[-a-z_]*=//'` ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- | --exec | --exe | --ex | --e) next_exec_prefix=yes ;; -gas | --gas | --ga | --g) ;; -host=* | --host=* | --hos=* | --ho=* | --h=*) ;; -host | --host | --hos | --ho | --h) next_host=yes ;; -nfp | --nfp | --nf) ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre | --no-cr | --no-c | --no- | --no) no_create=1 ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=`echo $arg | sed 's/[-a-z_]*=//'` ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) next_prefix=yes ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=* | --s=*) srcdir=`echo $arg | sed 's/[-a-z_]*=//'` ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr | --s) next_srcdir=yes ;; -with-* | --with-*) package=`echo $arg|sed 's/-*with-//'` # Delete all the valid chars; see if any are left. if test -n "`echo $package|sed 's/[-a-zA-Z0-9_]*//g'`"; then echo "configure: $package: invalid package name" >&2; exit 1 fi eval "with_`echo $package|sed s/-/_/g`=1" ;; *) ;; esac fi done trap 'rm -f conftest* core; exit 1' 1 3 15 rm -f conftest* compile='${CC-cc} $CFLAGS $DEFS conftest.c -o conftest $LIBS >/dev/null 2>&1' # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. unique_file=regex.c # Find the source files, if location was not specified. if test -z "$srcdir"; then srcdirdefaulted=yes # Try the directory containing this script, then `..'. prog=$0 confdir=`echo $prog|sed 's%/[^/][^/]*$%%'` test "X$confdir" = "X$prog" && confdir=. srcdir=$confdir if test ! -r $srcdir/$unique_file; then srcdir=.. fi fi if test ! -r $srcdir/$unique_file; then if test x$srcdirdefaulted = xyes; then echo "configure: Can not find sources in \`${confdir}' or \`..'." 1>&2 else echo "configure: Can not find sources in \`${srcdir}'." 1>&2 fi exit 1 fi # Preserve a srcdir of `.' to avoid automounter screwups with pwd. # But we can't avoid them for `..', to make subdirectories work. case $srcdir in .|/*|~*) ;; *) srcdir=`cd $srcdir; pwd` ;; # Make relative path absolute. esac if test -z "$CC"; then echo checking for gcc saveifs="$IFS"; IFS="${IFS}:" for dir in $PATH; do test -z "$dir" && dir=. if test -f $dir/gcc; then CC="gcc" break fi done IFS="$saveifs" fi test -z "$CC" && CC="cc" # Find out if we are using GNU C, under whatever name. cat > conftest.c < conftest.out 2>&1 if egrep yes conftest.out >/dev/null 2>&1; then GCC=1 # For later tests. fi rm -f conftest* # Make sure to not get the incompatible SysV /etc/install and # /usr/sbin/install, which might be in PATH before a BSD-like install, # or the SunOS /usr/etc/install directory, or the AIX /bin/install, # or the AFS install, which mishandles nonexistent args. (Sigh.) if test -z "$INSTALL"; then echo checking for install saveifs="$IFS"; IFS="${IFS}:" for dir in $PATH; do test -z "$dir" && dir=. case $dir in /etc|/usr/sbin|/usr/etc|/usr/afsws/bin) ;; *) if test -f $dir/install; then if grep dspmsg $dir/install >/dev/null 2>&1; then : # AIX else INSTALL="$dir/install -c" INSTALL_PROGRAM='$(INSTALL)' INSTALL_DATA='$(INSTALL) -m 644' break fi fi ;; esac done IFS="$saveifs" fi INSTALL=${INSTALL-cp} INSTALL_PROGRAM=${INSTALL_PROGRAM-'$(INSTALL)'} INSTALL_DATA=${INSTALL_DATA-'$(INSTALL)'} echo checking for AIX echo checking how to run the C preprocessor if test -z "$CPP"; then CPP='${CC-cc} -E' cat > conftest.c < EOF err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` if test -z "$err"; then : else CPP=/lib/cpp fi rm -f conftest* fi cat > conftest.c < conftest.out 2>&1" if egrep "yes" conftest.out >/dev/null 2>&1; then DEFS="$DEFS -D_ALL_SOURCE=1" fi rm -f conftest* echo checking for DYNIX/ptx libseq cat > conftest.c < conftest.out 2>&1" if egrep "yes" conftest.out >/dev/null 2>&1; then SEQUENT=1 fi rm -f conftest* test -n "$SEQUENT" && test -f /usr/lib/libseq.a && LIBS="$LIBS -lseq" echo checking for POSIXized ISC if test -d /etc/conf/kconfig.d && grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1 then ISC=1 # If later tests want to check for ISC. DEFS="$DEFS -D_POSIX_SOURCE=1" if test -n "$GCC"; then CC="$CC -posix" else CC="$CC -Xp" fi fi echo checking for minix/config.h cat > conftest.c < EOF err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` if test -z "$err"; then MINIX=1 fi rm -f conftest* # The Minix shell can't assign to the same variable on the same line! if test -n "$MINIX"; then DEFS="$DEFS -D_POSIX_SOURCE=1" DEFS="$DEFS -D_POSIX_1_SOURCE=2" DEFS="$DEFS -D_MINIX=1" fi echo checking for ANSI C header files cat > conftest.c < #include #include #include EOF err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` if test -z "$err"; then # SunOS string.h does not declare mem*, contrary to ANSI. echo '#include ' > conftest.c eval "$CPP $DEFS conftest.c > conftest.out 2>&1" if egrep "memchr" conftest.out >/dev/null 2>&1; then # SGI's /bin/cc from Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. cat > conftest.c < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #define XOR(e,f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF eval $compile if test -s conftest && (./conftest; exit) 2>/dev/null; then DEFS="$DEFS -DSTDC_HEADERS=1" fi rm -f conftest* fi rm -f conftest* fi rm -f conftest* for hdr in string.h do trhdr=HAVE_`echo $hdr | tr '[a-z]./' '[A-Z]__'` echo checking for ${hdr} cat > conftest.c < EOF err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` if test -z "$err"; then DEFS="$DEFS -D${trhdr}=1" fi rm -f conftest* done # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! echo checking for working alloca.h cat > conftest.c < main() { exit(0); } t() { char *p = alloca(2 * sizeof(int)); } EOF if eval $compile; then DEFS="$DEFS -DHAVE_ALLOCA_H=1" fi rm -f conftest* decl="#ifdef __GNUC__ #define alloca __builtin_alloca #else #if HAVE_ALLOCA_H #include #else #ifdef _AIX #pragma alloca #else char *alloca (); #endif #endif #endif " echo checking for alloca cat > conftest.c < conftest.c < config.status </dev/null`: # # $0 $* for arg do case "\$arg" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) exec /bin/sh $0 $* ;; *) echo "Usage: config.status --recheck" 2>&1; exit 1 ;; esac done trap 'rm -f Makefile doc/Makefile test/Makefile; exit 1' 1 3 15 CC='$CC' INSTALL='$INSTALL' INSTALL_PROGRAM='$INSTALL_PROGRAM' INSTALL_DATA='$INSTALL_DATA' CPP='$CPP' ALLOCA='$ALLOCA' LIBS='$LIBS' srcdir='$srcdir' DEFS='$DEFS' prefix='$prefix' exec_prefix='$exec_prefix' prsub='$prsub' EOF cat >> config.status <<\EOF top_srcdir=$srcdir for file in .. Makefile doc/Makefile test/Makefile; do if [ "x$file" != "x.." ]; then srcdir=$top_srcdir # Remove last slash and all that follows it. Not all systems have dirname. dir=`echo $file|sed 's%/[^/][^/]*$%%'` if test "$dir" != "$file"; then test "$top_srcdir" != . && srcdir=$top_srcdir/$dir test ! -d $dir && mkdir $dir fi echo creating $file rm -f $file echo "# Generated automatically from `echo $file|sed 's|.*/||'`.in by configure." > $file sed -e " $prsub s%@CC@%$CC%g s%@INSTALL@%$INSTALL%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g s%@INSTALL_DATA@%$INSTALL_DATA%g s%@CPP@%$CPP%g s%@ALLOCA@%$ALLOCA%g s%@LIBS@%$LIBS%g s%@srcdir@%$srcdir%g s%@DEFS@%$DEFS% " $top_srcdir/${file}.in >> $file fi; done exit 0 EOF chmod +x config.status test -n "$no_create" || ./config.status lyskom-server-2.1.2/src/libraries/regex/configure.in0000664000015100472110000000066705533104337016217 dnl Process this file with autoconf to produce a configure script. AC_INIT(regex.c) AC_PROG_CC AC_PROG_INSTALL dnl I'm not sure if AC_AIX and AC_DYNIX_SEQ are really necessary. The dnl Autoconf documentation isn't specific about which BSD functions they dnl provide. AC_AIX AC_DYNIX_SEQ AC_ISC_POSIX AC_MINIX AC_STDC_HEADERS AC_HAVE_HEADERS(string.h) AC_ALLOCA AC_CONST AC_PREFIX(gcc) AC_OUTPUT(Makefile doc/Makefile test/Makefile) lyskom-server-2.1.2/src/libraries/regex/regex.c0000664000015100472110000047373506023113702015165 /* Extended regular expression matching and search library, version 0.12. (Implements POSIX draft P10003.2/D11.2, except for internationalization features.) Copyright (C) 1993 Free Software Foundation, Inc. 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 2, 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, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* AIX requires this to be the first thing in the file. */ #if defined (_AIX) && !defined (REGEX_MALLOC) #pragma alloca #endif #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif /* We need this for `regex.h', and perhaps for the Emacs include files. */ #include #ifdef HAVE_CONFIG_H #include "config.h" #endif /* The `emacs' switch turns on certain matching commands that make sense only in Emacs. */ #ifdef emacs #include "lisp.h" #include "buffer.h" #include "syntax.h" /* Emacs uses `NULL' as a predicate. */ #undef NULL #else /* not emacs */ /* We used to test for `BSTRING' here, but only GCC and Emacs define `BSTRING', as far as I know, and neither of them use this code. */ #if HAVE_STRING_H || STDC_HEADERS #include #ifndef bcmp #define bcmp(s1, s2, n) memcmp ((s1), (s2), (n)) #endif #ifndef bcopy #define bcopy(s, d, n) memcpy ((d), (s), (n)) #endif #ifndef bzero #define bzero(s, n) memset ((s), 0, (n)) #endif #else #include #endif #ifdef STDC_HEADERS #include #else char *malloc (); char *realloc (); #endif /* Define the syntax stuff for \<, \>, etc. */ /* This must be nonzero for the wordchar and notwordchar pattern commands in re_match_2. */ #ifndef Sword #define Sword 1 #endif #ifdef SYNTAX_TABLE extern char *re_syntax_table; #else /* not SYNTAX_TABLE */ /* How many characters in the character set. */ #define CHAR_SET_SIZE 256 static char re_syntax_table[CHAR_SET_SIZE]; static void init_syntax_once () { register int c; static int done = 0; if (done) return; bzero (re_syntax_table, sizeof re_syntax_table); for (c = 'a'; c <= 'z'; c++) re_syntax_table[c] = Sword; for (c = 'A'; c <= 'Z'; c++) re_syntax_table[c] = Sword; for (c = '0'; c <= '9'; c++) re_syntax_table[c] = Sword; re_syntax_table['_'] = Sword; done = 1; } #endif /* not SYNTAX_TABLE */ #define SYNTAX(c) re_syntax_table[c] #endif /* not emacs */ /* Get the interface, including the syntax bits. */ #include "regex.h" /* isalpha etc. are used for the character classes. */ #include #ifndef isascii #define isascii(c) 1 #endif #ifdef isblank #define ISBLANK(c) (isascii (c) && isblank (c)) #else #define ISBLANK(c) ((c) == ' ' || (c) == '\t') #endif #ifdef isgraph #define ISGRAPH(c) (isascii (c) && isgraph (c)) #else #define ISGRAPH(c) (isascii (c) && isprint (c) && !isspace (c)) #endif #define ISPRINT(c) (isascii (c) && isprint (c)) #define ISDIGIT(c) (isascii (c) && isdigit (c)) #define ISALNUM(c) (isascii (c) && isalnum (c)) #define ISALPHA(c) (isascii (c) && isalpha (c)) #define ISCNTRL(c) (isascii (c) && iscntrl (c)) #define ISLOWER(c) (isascii (c) && islower (c)) #define ISPUNCT(c) (isascii (c) && ispunct (c)) #define ISSPACE(c) (isascii (c) && isspace (c)) #define ISUPPER(c) (isascii (c) && isupper (c)) #define ISXDIGIT(c) (isascii (c) && isxdigit (c)) #ifndef NULL #define NULL 0 #endif /* We remove any previous definition of `SIGN_EXTEND_CHAR', since ours (we hope) works properly with all combinations of machines, compilers, `char' and `unsigned char' argument types. (Per Bothner suggested the basic approach.) */ #undef SIGN_EXTEND_CHAR #if __STDC__ #define SIGN_EXTEND_CHAR(c) ((signed char) (c)) #else /* not __STDC__ */ /* As in Harbison and Steele. */ #define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128) #endif /* Should we use malloc or alloca? If REGEX_MALLOC is not defined, we use `alloca' instead of `malloc'. This is because using malloc in re_search* or re_match* could cause memory leaks when C-g is used in Emacs; also, malloc is slower and causes storage fragmentation. On the other hand, malloc is more portable, and easier to debug. Because we sometimes use alloca, some routines have to be macros, not functions -- `alloca'-allocated space disappears at the end of the function it is called in. */ #ifdef REGEX_MALLOC #define REGEX_ALLOCATE malloc #define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize) #else /* not REGEX_MALLOC */ /* Emacs already defines alloca, sometimes. */ #ifndef alloca /* Make alloca work the best possible way. */ #ifdef __GNUC__ #define alloca __builtin_alloca #else /* not __GNUC__ */ #if HAVE_ALLOCA_H #include #else /* not __GNUC__ or HAVE_ALLOCA_H */ #ifndef _AIX /* Already did AIX, up at the top. */ char *alloca (); #endif /* not _AIX */ #endif /* not HAVE_ALLOCA_H */ #endif /* not __GNUC__ */ #endif /* not alloca */ #define REGEX_ALLOCATE alloca /* Assumes a `char *destination' variable. */ #define REGEX_REALLOCATE(source, osize, nsize) \ (destination = (char *) alloca (nsize), \ bcopy (source, destination, osize), \ destination) #endif /* not REGEX_MALLOC */ /* True if `size1' is non-NULL and PTR is pointing anywhere inside `string1' or just past its end. This works if PTR is NULL, which is a good thing. */ #define FIRST_STRING_P(ptr) \ (size1 && string1 <= (ptr) && (ptr) <= string1 + size1) /* (Re)Allocate N items of type T using malloc, or fail. */ #define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t))) #define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t))) #define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t))) #define BYTEWIDTH 8 /* In bits. */ #define STREQ(s1, s2) ((strcmp (s1, s2) == 0)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) typedef char boolean; #define false 0 #define true 1 /* These are the command codes that appear in compiled regular expressions. Some opcodes are followed by argument bytes. A command code can specify any interpretation whatsoever for its arguments. Zero bytes may appear in the compiled regular expression. The value of `exactn' is needed in search.c (search_buffer) in Emacs. So regex.h defines a symbol `RE_EXACTN_VALUE' to be 1; the value of `exactn' we use here must also be 1. */ typedef enum { no_op = 0, /* Followed by one byte giving n, then by n literal bytes. */ exactn = 1, /* Matches any (more or less) character. */ anychar, /* Matches any one char belonging to specified set. First following byte is number of bitmap bytes. Then come bytes for a bitmap saying which chars are in. Bits in each byte are ordered low-bit-first. A character is in the set if its bit is 1. A character too large to have a bit in the map is automatically not in the set. */ charset, /* Same parameters as charset, but match any character that is not one of those specified. */ charset_not, /* Start remembering the text that is matched, for storing in a register. Followed by one byte with the register number, in the range 0 to one less than the pattern buffer's re_nsub field. Then followed by one byte with the number of groups inner to this one. (This last has to be part of the start_memory only because we need it in the on_failure_jump of re_match_2.) */ start_memory, /* Stop remembering the text that is matched and store it in a memory register. Followed by one byte with the register number, in the range 0 to one less than `re_nsub' in the pattern buffer, and one byte with the number of inner groups, just like `start_memory'. (We need the number of inner groups here because we don't have any easy way of finding the corresponding start_memory when we're at a stop_memory.) */ stop_memory, /* Match a duplicate of something remembered. Followed by one byte containing the register number. */ duplicate, /* Fail unless at beginning of line. */ begline, /* Fail unless at end of line. */ endline, /* Succeeds if at beginning of buffer (if emacs) or at beginning of string to be matched (if not). */ begbuf, /* Analogously, for end of buffer/string. */ endbuf, /* Followed by two byte relative address to which to jump. */ jump, /* Same as jump, but marks the end of an alternative. */ jump_past_alt, /* Followed by two-byte relative address of place to resume at in case of failure. */ on_failure_jump, /* Like on_failure_jump, but pushes a placeholder instead of the current string position when executed. */ on_failure_keep_string_jump, /* Throw away latest failure point and then jump to following two-byte relative address. */ pop_failure_jump, /* Change to pop_failure_jump if know won't have to backtrack to match; otherwise change to jump. This is used to jump back to the beginning of a repeat. If what follows this jump clearly won't match what the repeat does, such that we can be sure that there is no use backtracking out of repetitions already matched, then we change it to a pop_failure_jump. Followed by two-byte address. */ maybe_pop_jump, /* Jump to following two-byte address, and push a dummy failure point. This failure point will be thrown away if an attempt is made to use it for a failure. A `+' construct makes this before the first repeat. Also used as an intermediary kind of jump when compiling an alternative. */ dummy_failure_jump, /* Push a dummy failure point and continue. Used at the end of alternatives. */ push_dummy_failure, /* Followed by two-byte relative address and two-byte number n. After matching N times, jump to the address upon failure. */ succeed_n, /* Followed by two-byte relative address, and two-byte number n. Jump to the address N times, then fail. */ jump_n, /* Set the following two-byte relative address to the subsequent two-byte number. The address *includes* the two bytes of number. */ set_number_at, wordchar, /* Matches any word-constituent character. */ notwordchar, /* Matches any char that is not a word-constituent. */ wordbeg, /* Succeeds if at word beginning. */ wordend, /* Succeeds if at word end. */ wordbound, /* Succeeds if at a word boundary. */ notwordbound /* Succeeds if not at a word boundary. */ #ifdef emacs ,before_dot, /* Succeeds if before point. */ at_dot, /* Succeeds if at point. */ after_dot, /* Succeeds if after point. */ /* Matches any character whose syntax is specified. Followed by a byte which contains a syntax code, e.g., Sword. */ syntaxspec, /* Matches any character whose syntax is not that specified. */ notsyntaxspec #endif /* emacs */ } re_opcode_t; /* Common operations on the compiled pattern. */ /* Store NUMBER in two contiguous bytes starting at DESTINATION. */ #define STORE_NUMBER(destination, number) \ do { \ (destination)[0] = (number) & 0377; \ (destination)[1] = (number) >> 8; \ } while (0) /* Same as STORE_NUMBER, except increment DESTINATION to the byte after where the number is stored. Therefore, DESTINATION must be an lvalue. */ #define STORE_NUMBER_AND_INCR(destination, number) \ do { \ STORE_NUMBER (destination, number); \ (destination) += 2; \ } while (0) /* Put into DESTINATION a number stored in two contiguous bytes starting at SOURCE. */ #define EXTRACT_NUMBER(destination, source) \ do { \ (destination) = *(source) & 0377; \ (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8; \ } while (0) #ifdef DEBUG static void extract_number (dest, source) int *dest; unsigned char *source; { int temp = SIGN_EXTEND_CHAR (*(source + 1)); *dest = *source & 0377; *dest += temp << 8; } #ifndef EXTRACT_MACROS /* To debug the macros. */ #undef EXTRACT_NUMBER #define EXTRACT_NUMBER(dest, src) extract_number (&dest, src) #endif /* not EXTRACT_MACROS */ #endif /* DEBUG */ /* Same as EXTRACT_NUMBER, except increment SOURCE to after the number. SOURCE must be an lvalue. */ #define EXTRACT_NUMBER_AND_INCR(destination, source) \ do { \ EXTRACT_NUMBER (destination, source); \ (source) += 2; \ } while (0) #ifdef DEBUG static void extract_number_and_incr (destination, source) int *destination; unsigned char **source; { extract_number (destination, *source); *source += 2; } #ifndef EXTRACT_MACROS #undef EXTRACT_NUMBER_AND_INCR #define EXTRACT_NUMBER_AND_INCR(dest, src) \ extract_number_and_incr (&dest, &src) #endif /* not EXTRACT_MACROS */ #endif /* DEBUG */ /* If DEBUG is defined, Regex prints many voluminous messages about what it is doing (if the variable `debug' is nonzero). If linked with the main program in `iregex.c', you can enter patterns and strings interactively. And if linked with the main program in `main.c' and the other test files, you can run the already-written tests. */ #ifdef DEBUG /* We use standard I/O for debugging. */ #include /* It is useful to test things that ``must'' be true when debugging. */ #include static int debug = 0; #define DEBUG_STATEMENT(e) e #define DEBUG_PRINT1(x) if (debug) printf (x) #define DEBUG_PRINT2(x1, x2) if (debug) printf (x1, x2) #define DEBUG_PRINT3(x1, x2, x3) if (debug) printf (x1, x2, x3) #define DEBUG_PRINT4(x1, x2, x3, x4) if (debug) printf (x1, x2, x3, x4) #define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) \ if (debug) print_partial_compiled_pattern (s, e) #define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) \ if (debug) print_double_string (w, s1, sz1, s2, sz2) extern void printchar (); /* Print the fastmap in human-readable form. */ void print_fastmap (fastmap) char *fastmap; { unsigned was_a_range = 0; unsigned i = 0; while (i < (1 << BYTEWIDTH)) { if (fastmap[i++]) { was_a_range = 0; printchar (i - 1); while (i < (1 << BYTEWIDTH) && fastmap[i]) { was_a_range = 1; i++; } if (was_a_range) { printf ("-"); printchar (i - 1); } } } putchar ('\n'); } /* Print a compiled pattern string in human-readable form, starting at the START pointer into it and ending just before the pointer END. */ void print_partial_compiled_pattern (start, end) unsigned char *start; unsigned char *end; { int mcnt, mcnt2; unsigned char *p = start; unsigned char *pend = end; if (start == NULL) { printf ("(null)\n"); return; } /* Loop over pattern commands. */ while (p < pend) { switch ((re_opcode_t) *p++) { case no_op: printf ("/no_op"); break; case exactn: mcnt = *p++; printf ("/exactn/%d", mcnt); do { putchar ('/'); printchar (*p++); } while (--mcnt); break; case start_memory: mcnt = *p++; printf ("/start_memory/%d/%d", mcnt, *p++); break; case stop_memory: mcnt = *p++; printf ("/stop_memory/%d/%d", mcnt, *p++); break; case duplicate: printf ("/duplicate/%d", *p++); break; case anychar: printf ("/anychar"); break; case charset: case charset_not: { register int c; printf ("/charset%s", (re_opcode_t) *(p - 1) == charset_not ? "_not" : ""); assert (p + *p < pend); for (c = 0; c < *p; c++) { unsigned bit; unsigned char map_byte = p[1 + c]; putchar ('/'); for (bit = 0; bit < BYTEWIDTH; bit++) if (map_byte & (1 << bit)) printchar (c * BYTEWIDTH + bit); } p += 1 + *p; break; } case begline: printf ("/begline"); break; case endline: printf ("/endline"); break; case on_failure_jump: extract_number_and_incr (&mcnt, &p); printf ("/on_failure_jump/0/%d", mcnt); break; case on_failure_keep_string_jump: extract_number_and_incr (&mcnt, &p); printf ("/on_failure_keep_string_jump/0/%d", mcnt); break; case dummy_failure_jump: extract_number_and_incr (&mcnt, &p); printf ("/dummy_failure_jump/0/%d", mcnt); break; case push_dummy_failure: printf ("/push_dummy_failure"); break; case maybe_pop_jump: extract_number_and_incr (&mcnt, &p); printf ("/maybe_pop_jump/0/%d", mcnt); break; case pop_failure_jump: extract_number_and_incr (&mcnt, &p); printf ("/pop_failure_jump/0/%d", mcnt); break; case jump_past_alt: extract_number_and_incr (&mcnt, &p); printf ("/jump_past_alt/0/%d", mcnt); break; case jump: extract_number_and_incr (&mcnt, &p); printf ("/jump/0/%d", mcnt); break; case succeed_n: extract_number_and_incr (&mcnt, &p); extract_number_and_incr (&mcnt2, &p); printf ("/succeed_n/0/%d/0/%d", mcnt, mcnt2); break; case jump_n: extract_number_and_incr (&mcnt, &p); extract_number_and_incr (&mcnt2, &p); printf ("/jump_n/0/%d/0/%d", mcnt, mcnt2); break; case set_number_at: extract_number_and_incr (&mcnt, &p); extract_number_and_incr (&mcnt2, &p); printf ("/set_number_at/0/%d/0/%d", mcnt, mcnt2); break; case wordbound: printf ("/wordbound"); break; case notwordbound: printf ("/notwordbound"); break; case wordbeg: printf ("/wordbeg"); break; case wordend: printf ("/wordend"); #ifdef emacs case before_dot: printf ("/before_dot"); break; case at_dot: printf ("/at_dot"); break; case after_dot: printf ("/after_dot"); break; case syntaxspec: printf ("/syntaxspec"); mcnt = *p++; printf ("/%d", mcnt); break; case notsyntaxspec: printf ("/notsyntaxspec"); mcnt = *p++; printf ("/%d", mcnt); break; #endif /* emacs */ case wordchar: printf ("/wordchar"); break; case notwordchar: printf ("/notwordchar"); break; case begbuf: printf ("/begbuf"); break; case endbuf: printf ("/endbuf"); break; default: printf ("?%d", *(p-1)); } } printf ("/\n"); } void print_compiled_pattern (bufp) struct re_pattern_buffer *bufp; { unsigned char *buffer = bufp->buffer; print_partial_compiled_pattern (buffer, buffer + bufp->used); printf ("%d bytes used/%d bytes allocated.\n", bufp->used, bufp->allocated); if (bufp->fastmap_accurate && bufp->fastmap) { printf ("fastmap: "); print_fastmap (bufp->fastmap); } printf ("re_nsub: %d\t", bufp->re_nsub); printf ("regs_alloc: %d\t", bufp->regs_allocated); printf ("can_be_null: %d\t", bufp->can_be_null); printf ("newline_anchor: %d\n", bufp->newline_anchor); printf ("no_sub: %d\t", bufp->no_sub); printf ("not_bol: %d\t", bufp->not_bol); printf ("not_eol: %d\t", bufp->not_eol); printf ("syntax: %d\n", bufp->syntax); /* Perhaps we should print the translate table? */ } void print_double_string (where, string1, size1, string2, size2) const char *where; const char *string1; const char *string2; int size1; int size2; { unsigned this_char; if (where == NULL) printf ("(null)"); else { if (FIRST_STRING_P (where)) { for (this_char = where - string1; this_char < size1; this_char++) printchar (string1[this_char]); where = string2; } for (this_char = where - string2; this_char < size2; this_char++) printchar (string2[this_char]); } } #else /* not DEBUG */ #undef assert #define assert(e) #define DEBUG_STATEMENT(e) #define DEBUG_PRINT1(x) #define DEBUG_PRINT2(x1, x2) #define DEBUG_PRINT3(x1, x2, x3) #define DEBUG_PRINT4(x1, x2, x3, x4) #define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) #define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) #endif /* not DEBUG */ /* Set by `re_set_syntax' to the current regexp syntax to recognize. Can also be assigned to arbitrarily: each pattern buffer stores its own syntax, so it can be changed between regex compilations. */ reg_syntax_t re_syntax_options = RE_SYNTAX_EMACS; /* Specify the precise syntax of regexps for compilation. This provides for compatibility for various utilities which historically have different, incompatible syntaxes. The argument SYNTAX is a bit mask comprised of the various bits defined in regex.h. We return the old syntax. */ reg_syntax_t re_set_syntax (syntax) reg_syntax_t syntax; { reg_syntax_t ret = re_syntax_options; re_syntax_options = syntax; return ret; } /* This table gives an error message for each of the error codes listed in regex.h. Obviously the order here has to be same as there. */ static const char *re_error_msg[] = { NULL, /* REG_NOERROR */ "No match", /* REG_NOMATCH */ "Invalid regular expression", /* REG_BADPAT */ "Invalid collation character", /* REG_ECOLLATE */ "Invalid character class name", /* REG_ECTYPE */ "Trailing backslash", /* REG_EESCAPE */ "Invalid back reference", /* REG_ESUBREG */ "Unmatched [ or [^", /* REG_EBRACK */ "Unmatched ( or \\(", /* REG_EPAREN */ "Unmatched \\{", /* REG_EBRACE */ "Invalid content of \\{\\}", /* REG_BADBR */ "Invalid range end", /* REG_ERANGE */ "Memory exhausted", /* REG_ESPACE */ "Invalid preceding regular expression", /* REG_BADRPT */ "Premature end of regular expression", /* REG_EEND */ "Regular expression too big", /* REG_ESIZE */ "Unmatched ) or \\)", /* REG_ERPAREN */ }; /* Subroutine declarations and macros for regex_compile. */ static void store_op1 (), store_op2 (); static void insert_op1 (), insert_op2 (); static boolean at_begline_loc_p (), at_endline_loc_p (); static boolean group_in_compile_stack (); static reg_errcode_t compile_range (); /* Fetch the next character in the uncompiled pattern---translating it if necessary. Also cast from a signed character in the constant string passed to us by the user to an unsigned char that we can use as an array index (in, e.g., `translate'). */ #define PATFETCH(c) \ do {if (p == pend) return REG_EEND; \ c = (unsigned char) *p++; \ if (translate) c = translate[c]; \ } while (0) /* Fetch the next character in the uncompiled pattern, with no translation. */ #define PATFETCH_RAW(c) \ do {if (p == pend) return REG_EEND; \ c = (unsigned char) *p++; \ } while (0) /* Go backwards one character in the pattern. */ #define PATUNFETCH p-- /* If `translate' is non-null, return translate[D], else just D. We cast the subscript to translate because some data is declared as `char *', to avoid warnings when a string constant is passed. But when we use a character as a subscript we must make it unsigned. */ #define TRANSLATE(d) (translate ? translate[(unsigned char) (d)] : (d)) /* Macros for outputting the compiled pattern into `buffer'. */ /* If the buffer isn't allocated when it comes in, use this. */ #define INIT_BUF_SIZE 32 /* Make sure we have at least N more bytes of space in buffer. */ #define GET_BUFFER_SPACE(n) \ while (b - bufp->buffer + (n) > bufp->allocated) \ EXTEND_BUFFER () /* Make sure we have one more byte of buffer space and then add C to it. */ #define BUF_PUSH(c) \ do { \ GET_BUFFER_SPACE (1); \ *b++ = (unsigned char) (c); \ } while (0) /* Ensure we have two more bytes of buffer space and then append C1 and C2. */ #define BUF_PUSH_2(c1, c2) \ do { \ GET_BUFFER_SPACE (2); \ *b++ = (unsigned char) (c1); \ *b++ = (unsigned char) (c2); \ } while (0) /* As with BUF_PUSH_2, except for three bytes. */ #define BUF_PUSH_3(c1, c2, c3) \ do { \ GET_BUFFER_SPACE (3); \ *b++ = (unsigned char) (c1); \ *b++ = (unsigned char) (c2); \ *b++ = (unsigned char) (c3); \ } while (0) /* Store a jump with opcode OP at LOC to location TO. We store a relative address offset by the three bytes the jump itself occupies. */ #define STORE_JUMP(op, loc, to) \ store_op1 (op, loc, (to) - (loc) - 3) /* Likewise, for a two-argument jump. */ #define STORE_JUMP2(op, loc, to, arg) \ store_op2 (op, loc, (to) - (loc) - 3, arg) /* Like `STORE_JUMP', but for inserting. Assume `b' is the buffer end. */ #define INSERT_JUMP(op, loc, to) \ insert_op1 (op, loc, (to) - (loc) - 3, b) /* Like `STORE_JUMP2', but for inserting. Assume `b' is the buffer end. */ #define INSERT_JUMP2(op, loc, to, arg) \ insert_op2 (op, loc, (to) - (loc) - 3, arg, b) /* This is not an arbitrary limit: the arguments which represent offsets into the pattern are two bytes long. So if 2^16 bytes turns out to be too small, many things would have to change. */ #define MAX_BUF_SIZE (1L << 16) /* Extend the buffer by twice its current size via realloc and reset the pointers that pointed into the old block to point to the correct places in the new one. If extending the buffer results in it being larger than MAX_BUF_SIZE, then flag memory exhausted. */ #define EXTEND_BUFFER() \ do { \ unsigned char *old_buffer = bufp->buffer; \ if (bufp->allocated == MAX_BUF_SIZE) \ return REG_ESIZE; \ bufp->allocated <<= 1; \ if (bufp->allocated > MAX_BUF_SIZE) \ bufp->allocated = MAX_BUF_SIZE; \ bufp->buffer = (unsigned char *) realloc (bufp->buffer, bufp->allocated);\ if (bufp->buffer == NULL) \ return REG_ESPACE; \ /* If the buffer moved, move all the pointers into it. */ \ if (old_buffer != bufp->buffer) \ { \ b = (b - old_buffer) + bufp->buffer; \ begalt = (begalt - old_buffer) + bufp->buffer; \ if (fixup_alt_jump) \ fixup_alt_jump = (fixup_alt_jump - old_buffer) + bufp->buffer;\ if (laststart) \ laststart = (laststart - old_buffer) + bufp->buffer; \ if (pending_exact) \ pending_exact = (pending_exact - old_buffer) + bufp->buffer; \ } \ } while (0) /* Since we have one byte reserved for the register number argument to {start,stop}_memory, the maximum number of groups we can report things about is what fits in that byte. */ #define MAX_REGNUM 255 /* But patterns can have more than `MAX_REGNUM' registers. We just ignore the excess. */ typedef unsigned regnum_t; /* Macros for the compile stack. */ /* Since offsets can go either forwards or backwards, this type needs to be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1. */ typedef int pattern_offset_t; typedef struct { pattern_offset_t begalt_offset; pattern_offset_t fixup_alt_jump; pattern_offset_t inner_group_offset; pattern_offset_t laststart_offset; regnum_t regnum; } compile_stack_elt_t; typedef struct { compile_stack_elt_t *stack; unsigned size; unsigned avail; /* Offset of next open position. */ } compile_stack_type; #define INIT_COMPILE_STACK_SIZE 32 #define COMPILE_STACK_EMPTY (compile_stack.avail == 0) #define COMPILE_STACK_FULL (compile_stack.avail == compile_stack.size) /* The next available element. */ #define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail]) /* Set the bit for character C in a list. */ #define SET_LIST_BIT(c) \ (b[((unsigned char) (c)) / BYTEWIDTH] \ |= 1 << (((unsigned char) c) % BYTEWIDTH)) /* Get the next unsigned number in the uncompiled pattern. */ #define GET_UNSIGNED_NUMBER(num) \ { if (p != pend) \ { \ PATFETCH (c); \ while (ISDIGIT (c)) \ { \ if (num < 0) \ num = 0; \ num = num * 10 + c - '0'; \ if (p == pend) \ break; \ PATFETCH (c); \ } \ } \ } #define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */ #define IS_CHAR_CLASS(string) \ (STREQ (string, "alpha") || STREQ (string, "upper") \ || STREQ (string, "lower") || STREQ (string, "digit") \ || STREQ (string, "alnum") || STREQ (string, "xdigit") \ || STREQ (string, "space") || STREQ (string, "print") \ || STREQ (string, "punct") || STREQ (string, "graph") \ || STREQ (string, "cntrl") || STREQ (string, "blank")) /* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX. Returns one of error codes defined in `regex.h', or zero for success. Assumes the `allocated' (and perhaps `buffer') and `translate' fields are set in BUFP on entry. If it succeeds, results are put in BUFP (if it returns an error, the contents of BUFP are undefined): `buffer' is the compiled pattern; `syntax' is set to SYNTAX; `used' is set to the length of the compiled pattern; `fastmap_accurate' is zero; `re_nsub' is the number of subexpressions in PATTERN; `not_bol' and `not_eol' are zero; The `fastmap' and `newline_anchor' fields are neither examined nor set. */ static reg_errcode_t regex_compile (pattern, size, syntax, bufp) const char *pattern; int size; reg_syntax_t syntax; struct re_pattern_buffer *bufp; { /* We fetch characters from PATTERN here. Even though PATTERN is `char *' (i.e., signed), we declare these variables as unsigned, so they can be reliably used as array indices. */ register unsigned char c, c1; /* A random tempory spot in PATTERN. */ const char *p1; /* Points to the end of the buffer, where we should append. */ register unsigned char *b; /* Keeps track of unclosed groups. */ compile_stack_type compile_stack; /* Points to the current (ending) position in the pattern. */ const char *p = pattern; const char *pend = pattern + size; /* How to translate the characters in the pattern. */ char *translate = bufp->translate; /* Address of the count-byte of the most recently inserted `exactn' command. This makes it possible to tell if a new exact-match character can be added to that command or if the character requires a new `exactn' command. */ unsigned char *pending_exact = 0; /* Address of start of the most recently finished expression. This tells, e.g., postfix * where to find the start of its operand. Reset at the beginning of groups and alternatives. */ unsigned char *laststart = 0; /* Address of beginning of regexp, or inside of last group. */ unsigned char *begalt; /* Place in the uncompiled pattern (i.e., the {) to which to go back if the interval is invalid. */ const char *beg_interval; /* Address of the place where a forward jump should go to the end of the containing expression. Each alternative of an `or' -- except the last -- ends with a forward jump of this sort. */ unsigned char *fixup_alt_jump = 0; /* Counts open-groups as they are encountered. Remembered for the matching close-group on the compile stack, so the same register number is put in the stop_memory as the start_memory. */ regnum_t regnum = 0; #ifdef DEBUG DEBUG_PRINT1 ("\nCompiling pattern: "); if (debug) { unsigned debug_count; for (debug_count = 0; debug_count < size; debug_count++) printchar (pattern[debug_count]); putchar ('\n'); } #endif /* DEBUG */ /* Initialize the compile stack. */ compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t); if (compile_stack.stack == NULL) return REG_ESPACE; compile_stack.size = INIT_COMPILE_STACK_SIZE; compile_stack.avail = 0; /* Initialize the pattern buffer. */ bufp->syntax = syntax; bufp->fastmap_accurate = 0; bufp->not_bol = bufp->not_eol = 0; /* Set `used' to zero, so that if we return an error, the pattern printer (for debugging) will think there's no pattern. We reset it at the end. */ bufp->used = 0; /* Always count groups, whether or not bufp->no_sub is set. */ bufp->re_nsub = 0; #if !defined (emacs) && !defined (SYNTAX_TABLE) /* Initialize the syntax table. */ init_syntax_once (); #endif if (bufp->allocated == 0) { if (bufp->buffer) { /* If zero allocated, but buffer is non-null, try to realloc enough space. This loses if buffer's address is bogus, but that is the user's responsibility. */ RETALLOC (bufp->buffer, INIT_BUF_SIZE, unsigned char); } else { /* Caller did not allocate a buffer. Do it for them. */ bufp->buffer = TALLOC (INIT_BUF_SIZE, unsigned char); } if (!bufp->buffer) return REG_ESPACE; bufp->allocated = INIT_BUF_SIZE; } begalt = b = bufp->buffer; /* Loop through the uncompiled pattern until we're at the end. */ while (p != pend) { PATFETCH (c); switch (c) { case '^': { if ( /* If at start of pattern, it's an operator. */ p == pattern + 1 /* If context independent, it's an operator. */ || syntax & RE_CONTEXT_INDEP_ANCHORS /* Otherwise, depends on what's come before. */ || at_begline_loc_p (pattern, p, syntax)) BUF_PUSH (begline); else goto normal_char; } break; case '$': { if ( /* If at end of pattern, it's an operator. */ p == pend /* If context independent, it's an operator. */ || syntax & RE_CONTEXT_INDEP_ANCHORS /* Otherwise, depends on what's next. */ || at_endline_loc_p (p, pend, syntax)) BUF_PUSH (endline); else goto normal_char; } break; case '+': case '?': if ((syntax & RE_BK_PLUS_QM) || (syntax & RE_LIMITED_OPS)) goto normal_char; handle_plus: case '*': /* If there is no previous pattern... */ if (!laststart) { if (syntax & RE_CONTEXT_INVALID_OPS) return REG_BADRPT; else if (!(syntax & RE_CONTEXT_INDEP_OPS)) goto normal_char; } { /* Are we optimizing this jump? */ boolean keep_string_p = false; /* 1 means zero (many) matches is allowed. */ char zero_times_ok = 0, many_times_ok = 0; /* If there is a sequence of repetition chars, collapse it down to just one (the right one). We can't combine interval operators with these because of, e.g., `a{2}*', which should only match an even number of `a's. */ for (;;) { zero_times_ok |= c != '+'; many_times_ok |= c != '?'; if (p == pend) break; PATFETCH (c); if (c == '*' || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?'))) ; else if (syntax & RE_BK_PLUS_QM && c == '\\') { if (p == pend) return REG_EESCAPE; PATFETCH (c1); if (!(c1 == '+' || c1 == '?')) { PATUNFETCH; PATUNFETCH; break; } c = c1; } else { PATUNFETCH; break; } /* If we get here, we found another repeat character. */ } /* Star, etc. applied to an empty pattern is equivalent to an empty pattern. */ if (!laststart) break; /* Now we know whether or not zero matches is allowed and also whether or not two or more matches is allowed. */ if (many_times_ok) { /* More than one repetition is allowed, so put in at the end a backward relative jump from `b' to before the next jump we're going to put in below (which jumps from laststart to after this jump). But if we are at the `*' in the exact sequence `.*\n', insert an unconditional jump backwards to the ., instead of the beginning of the loop. This way we only push a failure point once, instead of every time through the loop. */ assert (p - 1 > pattern); /* Allocate the space for the jump. */ GET_BUFFER_SPACE (3); /* We know we are not at the first character of the pattern, because laststart was nonzero. And we've already incremented `p', by the way, to be the character after the `*'. Do we have to do something analogous here for null bytes, because of RE_DOT_NOT_NULL? */ if (TRANSLATE (*(p - 2)) == TRANSLATE ('.') && zero_times_ok && p < pend && TRANSLATE (*p) == TRANSLATE ('\n') && !(syntax & RE_DOT_NEWLINE)) { /* We have .*\n. */ STORE_JUMP (jump, b, laststart); keep_string_p = true; } else /* Anything else. */ STORE_JUMP (maybe_pop_jump, b, laststart - 3); /* We've added more stuff to the buffer. */ b += 3; } /* On failure, jump from laststart to b + 3, which will be the end of the buffer after this jump is inserted. */ GET_BUFFER_SPACE (3); INSERT_JUMP (keep_string_p ? on_failure_keep_string_jump : on_failure_jump, laststart, b + 3); pending_exact = 0; b += 3; if (!zero_times_ok) { /* At least one repetition is required, so insert a `dummy_failure_jump' before the initial `on_failure_jump' instruction of the loop. This effects a skip over that instruction the first time we hit that loop. */ GET_BUFFER_SPACE (3); INSERT_JUMP (dummy_failure_jump, laststart, laststart + 6); b += 3; } } break; case '.': laststart = b; BUF_PUSH (anychar); break; case '[': { boolean had_char_class = false; if (p == pend) return REG_EBRACK; /* Ensure that we have enough space to push a charset: the opcode, the length count, and the bitset; 34 bytes in all. */ GET_BUFFER_SPACE (34); laststart = b; /* We test `*p == '^' twice, instead of using an if statement, so we only need one BUF_PUSH. */ BUF_PUSH (*p == '^' ? charset_not : charset); if (*p == '^') p++; /* Remember the first position in the bracket expression. */ p1 = p; /* Push the number of bytes in the bitmap. */ BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH); /* Clear the whole map. */ bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH); /* charset_not matches newline according to a syntax bit. */ if ((re_opcode_t) b[-2] == charset_not && (syntax & RE_HAT_LISTS_NOT_NEWLINE)) SET_LIST_BIT ('\n'); /* Read in characters and ranges, setting map bits. */ for (;;) { if (p == pend) return REG_EBRACK; PATFETCH (c); /* \ might escape characters inside [...] and [^...]. */ if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\') { if (p == pend) return REG_EESCAPE; PATFETCH (c1); SET_LIST_BIT (c1); continue; } /* Could be the end of the bracket expression. If it's not (i.e., when the bracket expression is `[]' so far), the ']' character bit gets set way below. */ if (c == ']' && p != p1 + 1) break; /* Look ahead to see if it's a range when the last thing was a character class. */ if (had_char_class && c == '-' && *p != ']') return REG_ERANGE; /* Look ahead to see if it's a range when the last thing was a character: if this is a hyphen not at the beginning or the end of a list, then it's the range operator. */ if (c == '-' && !(p - 2 >= pattern && p[-2] == '[') && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^') && *p != ']') { reg_errcode_t ret = compile_range (&p, pend, translate, syntax, b); if (ret != REG_NOERROR) return ret; } else if (p[0] == '-' && p[1] != ']') { /* This handles ranges made up of characters only. */ reg_errcode_t ret; /* Move past the `-'. */ PATFETCH (c1); ret = compile_range (&p, pend, translate, syntax, b); if (ret != REG_NOERROR) return ret; } /* See if we're at the beginning of a possible character class. */ else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':') { /* Leave room for the null. */ char str[CHAR_CLASS_MAX_LENGTH + 1]; PATFETCH (c); c1 = 0; /* If pattern is `[[:'. */ if (p == pend) return REG_EBRACK; for (;;) { PATFETCH (c); if (c == ':' || c == ']' || p == pend || c1 == CHAR_CLASS_MAX_LENGTH) break; str[c1++] = c; } str[c1] = '\0'; /* If isn't a word bracketed by `[:' and:`]': undo the ending character, the letters, and leave the leading `:' and `[' (but set bits for them). */ if (c == ':' && *p == ']') { int ch; boolean is_alnum = STREQ (str, "alnum"); boolean is_alpha = STREQ (str, "alpha"); boolean is_blank = STREQ (str, "blank"); boolean is_cntrl = STREQ (str, "cntrl"); boolean is_digit = STREQ (str, "digit"); boolean is_graph = STREQ (str, "graph"); boolean is_lower = STREQ (str, "lower"); boolean is_print = STREQ (str, "print"); boolean is_punct = STREQ (str, "punct"); boolean is_space = STREQ (str, "space"); boolean is_upper = STREQ (str, "upper"); boolean is_xdigit = STREQ (str, "xdigit"); if (!IS_CHAR_CLASS (str)) return REG_ECTYPE; /* Throw away the ] at the end of the character class. */ PATFETCH (c); if (p == pend) return REG_EBRACK; for (ch = 0; ch < 1 << BYTEWIDTH; ch++) { if ( (is_alnum && ISALNUM (ch)) || (is_alpha && ISALPHA (ch)) || (is_blank && ISBLANK (ch)) || (is_cntrl && ISCNTRL (ch)) || (is_digit && ISDIGIT (ch)) || (is_graph && ISGRAPH (ch)) || (is_lower && ISLOWER (ch)) || (is_print && ISPRINT (ch)) || (is_punct && ISPUNCT (ch)) || (is_space && ISSPACE (ch)) || (is_upper && ISUPPER (ch)) || (is_xdigit && ISXDIGIT (ch))) SET_LIST_BIT (ch); } had_char_class = true; } else { c1++; while (c1--) PATUNFETCH; SET_LIST_BIT ('['); SET_LIST_BIT (':'); had_char_class = false; } } else { had_char_class = false; SET_LIST_BIT (c); } } /* Discard any (non)matching list bytes that are all 0 at the end of the map. Decrease the map-length byte too. */ while ((int) b[-1] > 0 && b[b[-1] - 1] == 0) b[-1]--; b += b[-1]; } break; case '(': if (syntax & RE_NO_BK_PARENS) goto handle_open; else goto normal_char; case ')': if (syntax & RE_NO_BK_PARENS) goto handle_close; else goto normal_char; case '\n': if (syntax & RE_NEWLINE_ALT) goto handle_alt; else goto normal_char; case '|': if (syntax & RE_NO_BK_VBAR) goto handle_alt; else goto normal_char; case '{': if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES) goto handle_interval; else goto normal_char; case '\\': if (p == pend) return REG_EESCAPE; /* Do not translate the character after the \, so that we can distinguish, e.g., \B from \b, even if we normally would translate, e.g., B to b. */ PATFETCH_RAW (c); switch (c) { case '(': if (syntax & RE_NO_BK_PARENS) goto normal_backslash; handle_open: bufp->re_nsub++; regnum++; if (COMPILE_STACK_FULL) { RETALLOC (compile_stack.stack, compile_stack.size << 1, compile_stack_elt_t); if (compile_stack.stack == NULL) return REG_ESPACE; compile_stack.size <<= 1; } /* These are the values to restore when we hit end of this group. They are all relative offsets, so that if the whole pattern moves because of realloc, they will still be valid. */ COMPILE_STACK_TOP.begalt_offset = begalt - bufp->buffer; COMPILE_STACK_TOP.fixup_alt_jump = fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0; COMPILE_STACK_TOP.laststart_offset = b - bufp->buffer; COMPILE_STACK_TOP.regnum = regnum; /* We will eventually replace the 0 with the number of groups inner to this one. But do not push a start_memory for groups beyond the last one we can represent in the compiled pattern. */ if (regnum <= MAX_REGNUM) { COMPILE_STACK_TOP.inner_group_offset = b - bufp->buffer + 2; BUF_PUSH_3 (start_memory, regnum, 0); } compile_stack.avail++; fixup_alt_jump = 0; laststart = 0; begalt = b; /* If we've reached MAX_REGNUM groups, then this open won't actually generate any code, so we'll have to clear pending_exact explicitly. */ pending_exact = 0; break; case ')': if (syntax & RE_NO_BK_PARENS) goto normal_backslash; if (COMPILE_STACK_EMPTY) if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD) goto normal_backslash; else return REG_ERPAREN; handle_close: if (fixup_alt_jump) { /* Push a dummy failure point at the end of the alternative for a possible future `pop_failure_jump' to pop. See comments at `push_dummy_failure' in `re_match_2'. */ BUF_PUSH (push_dummy_failure); /* We allocated space for this jump when we assigned to `fixup_alt_jump', in the `handle_alt' case below. */ STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1); } /* See similar code for backslashed left paren above. */ if (COMPILE_STACK_EMPTY) if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD) goto normal_char; else return REG_ERPAREN; /* Since we just checked for an empty stack above, this ``can't happen''. */ assert (compile_stack.avail != 0); { /* We don't just want to restore into `regnum', because later groups should continue to be numbered higher, as in `(ab)c(de)' -- the second group is #2. */ regnum_t this_group_regnum; compile_stack.avail--; begalt = bufp->buffer + COMPILE_STACK_TOP.begalt_offset; fixup_alt_jump = COMPILE_STACK_TOP.fixup_alt_jump ? bufp->buffer + COMPILE_STACK_TOP.fixup_alt_jump - 1 : 0; laststart = bufp->buffer + COMPILE_STACK_TOP.laststart_offset; this_group_regnum = COMPILE_STACK_TOP.regnum; /* If we've reached MAX_REGNUM groups, then this open won't actually generate any code, so we'll have to clear pending_exact explicitly. */ pending_exact = 0; /* We're at the end of the group, so now we know how many groups were inside this one. */ if (this_group_regnum <= MAX_REGNUM) { unsigned char *inner_group_loc = bufp->buffer + COMPILE_STACK_TOP.inner_group_offset; *inner_group_loc = regnum - this_group_regnum; BUF_PUSH_3 (stop_memory, this_group_regnum, regnum - this_group_regnum); } } break; case '|': /* `\|'. */ if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR) goto normal_backslash; handle_alt: if (syntax & RE_LIMITED_OPS) goto normal_char; /* Insert before the previous alternative a jump which jumps to this alternative if the former fails. */ GET_BUFFER_SPACE (3); INSERT_JUMP (on_failure_jump, begalt, b + 6); pending_exact = 0; b += 3; /* The alternative before this one has a jump after it which gets executed if it gets matched. Adjust that jump so it will jump to this alternative's analogous jump (put in below, which in turn will jump to the next (if any) alternative's such jump, etc.). The last such jump jumps to the correct final destination. A picture: _____ _____ | | | | | v | v a | b | c If we are at `b', then fixup_alt_jump right now points to a three-byte space after `a'. We'll put in the jump, set fixup_alt_jump to right after `b', and leave behind three bytes which we'll fill in when we get to after `c'. */ if (fixup_alt_jump) STORE_JUMP (jump_past_alt, fixup_alt_jump, b); /* Mark and leave space for a jump after this alternative, to be filled in later either by next alternative or when know we're at the end of a series of alternatives. */ fixup_alt_jump = b; GET_BUFFER_SPACE (3); b += 3; laststart = 0; begalt = b; break; case '{': /* If \{ is a literal. */ if (!(syntax & RE_INTERVALS) /* If we're at `\{' and it's not the open-interval operator. */ || ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES)) || (p - 2 == pattern && p == pend)) goto normal_backslash; handle_interval: { /* If got here, then the syntax allows intervals. */ /* At least (most) this many matches must be made. */ int lower_bound = -1, upper_bound = -1; beg_interval = p - 1; if (p == pend) { if (syntax & RE_NO_BK_BRACES) goto unfetch_interval; else return REG_EBRACE; } GET_UNSIGNED_NUMBER (lower_bound); if (c == ',') { GET_UNSIGNED_NUMBER (upper_bound); if (upper_bound < 0) upper_bound = RE_DUP_MAX; } else /* Interval such as `{1}' => match exactly once. */ upper_bound = lower_bound; if (lower_bound < 0 || upper_bound > RE_DUP_MAX || lower_bound > upper_bound) { if (syntax & RE_NO_BK_BRACES) goto unfetch_interval; else return REG_BADBR; } if (!(syntax & RE_NO_BK_BRACES)) { if (c != '\\') return REG_EBRACE; PATFETCH (c); } if (c != '}') { if (syntax & RE_NO_BK_BRACES) goto unfetch_interval; else return REG_BADBR; } /* We just parsed a valid interval. */ /* If it's invalid to have no preceding re. */ if (!laststart) { if (syntax & RE_CONTEXT_INVALID_OPS) return REG_BADRPT; else if (syntax & RE_CONTEXT_INDEP_OPS) laststart = b; else goto unfetch_interval; } /* If the upper bound is zero, don't want to succeed at all; jump from `laststart' to `b + 3', which will be the end of the buffer after we insert the jump. */ if (upper_bound == 0) { GET_BUFFER_SPACE (3); INSERT_JUMP (jump, laststart, b + 3); b += 3; } /* Otherwise, we have a nontrivial interval. When we're all done, the pattern will look like: set_number_at set_number_at succeed_n jump_n (The upper bound and `jump_n' are omitted if `upper_bound' is 1, though.) */ else { /* If the upper bound is > 1, we need to insert more at the end of the loop. */ unsigned nbytes = 10 + (upper_bound > 1) * 10; GET_BUFFER_SPACE (nbytes); /* Initialize lower bound of the `succeed_n', even though it will be set during matching by its attendant `set_number_at' (inserted next), because `re_compile_fastmap' needs to know. Jump to the `jump_n' we might insert below. */ INSERT_JUMP2 (succeed_n, laststart, b + 5 + (upper_bound > 1) * 5, lower_bound); b += 5; /* Code to initialize the lower bound. Insert before the `succeed_n'. The `5' is the last two bytes of this `set_number_at', plus 3 bytes of the following `succeed_n'. */ insert_op2 (set_number_at, laststart, 5, lower_bound, b); b += 5; if (upper_bound > 1) { /* More than one repetition is allowed, so append a backward jump to the `succeed_n' that starts this interval. When we've reached this during matching, we'll have matched the interval once, so jump back only `upper_bound - 1' times. */ STORE_JUMP2 (jump_n, b, laststart + 5, upper_bound - 1); b += 5; /* The location we want to set is the second parameter of the `jump_n'; that is `b-2' as an absolute address. `laststart' will be the `set_number_at' we're about to insert; `laststart+3' the number to set, the source for the relative address. But we are inserting into the middle of the pattern -- so everything is getting moved up by 5. Conclusion: (b - 2) - (laststart + 3) + 5, i.e., b - laststart. We insert this at the beginning of the loop so that if we fail during matching, we'll reinitialize the bounds. */ insert_op2 (set_number_at, laststart, b - laststart, upper_bound - 1, b); b += 5; } } pending_exact = 0; beg_interval = NULL; } break; unfetch_interval: /* If an invalid interval, match the characters as literals. */ assert (beg_interval); p = beg_interval; beg_interval = NULL; /* normal_char and normal_backslash need `c'. */ PATFETCH (c); if (!(syntax & RE_NO_BK_BRACES)) { if (p > pattern && p[-1] == '\\') goto normal_backslash; } goto normal_char; #ifdef emacs /* There is no way to specify the before_dot and after_dot operators. rms says this is ok. --karl */ case '=': BUF_PUSH (at_dot); break; case 's': laststart = b; PATFETCH (c); BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]); break; case 'S': laststart = b; PATFETCH (c); BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]); break; #endif /* emacs */ case 'w': laststart = b; BUF_PUSH (wordchar); break; case 'W': laststart = b; BUF_PUSH (notwordchar); break; case '<': BUF_PUSH (wordbeg); break; case '>': BUF_PUSH (wordend); break; case 'b': BUF_PUSH (wordbound); break; case 'B': BUF_PUSH (notwordbound); break; case '`': BUF_PUSH (begbuf); break; case '\'': BUF_PUSH (endbuf); break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (syntax & RE_NO_BK_REFS) goto normal_char; c1 = c - '0'; if (c1 > regnum) return REG_ESUBREG; /* Can't back reference to a subexpression if inside of it. */ if (group_in_compile_stack (compile_stack, c1)) goto normal_char; laststart = b; BUF_PUSH_2 (duplicate, c1); break; case '+': case '?': if (syntax & RE_BK_PLUS_QM) goto handle_plus; else goto normal_backslash; default: normal_backslash: /* You might think it would be useful for \ to mean not to translate; but if we don't translate it it will never match anything. */ c = TRANSLATE (c); goto normal_char; } break; default: /* Expects the character in `c'. */ normal_char: /* If no exactn currently being built. */ if (!pending_exact /* If last exactn not at current position. */ || pending_exact + *pending_exact + 1 != b /* We have only one byte following the exactn for the count. */ || *pending_exact == (1 << BYTEWIDTH) - 1 /* If followed by a repetition operator. */ || *p == '*' || *p == '^' || ((syntax & RE_BK_PLUS_QM) ? *p == '\\' && (p[1] == '+' || p[1] == '?') : (*p == '+' || *p == '?')) || ((syntax & RE_INTERVALS) && ((syntax & RE_NO_BK_BRACES) ? *p == '{' : (p[0] == '\\' && p[1] == '{')))) { /* Start building a new exactn. */ laststart = b; BUF_PUSH_2 (exactn, 0); pending_exact = b - 1; } BUF_PUSH (c); (*pending_exact)++; break; } /* switch (c) */ } /* while p != pend */ /* Through the pattern now. */ if (fixup_alt_jump) STORE_JUMP (jump_past_alt, fixup_alt_jump, b); if (!COMPILE_STACK_EMPTY) return REG_EPAREN; free (compile_stack.stack); /* We have succeeded; set the length of the buffer. */ bufp->used = b - bufp->buffer; #ifdef DEBUG if (debug) { DEBUG_PRINT1 ("\nCompiled pattern: "); print_compiled_pattern (bufp); } #endif /* DEBUG */ return REG_NOERROR; } /* regex_compile */ /* Subroutines for `regex_compile'. */ /* Store OP at LOC followed by two-byte integer parameter ARG. */ static void store_op1 (op, loc, arg) re_opcode_t op; unsigned char *loc; int arg; { *loc = (unsigned char) op; STORE_NUMBER (loc + 1, arg); } /* Like `store_op1', but for two two-byte parameters ARG1 and ARG2. */ static void store_op2 (op, loc, arg1, arg2) re_opcode_t op; unsigned char *loc; int arg1, arg2; { *loc = (unsigned char) op; STORE_NUMBER (loc + 1, arg1); STORE_NUMBER (loc + 3, arg2); } /* Copy the bytes from LOC to END to open up three bytes of space at LOC for OP followed by two-byte integer parameter ARG. */ static void insert_op1 (op, loc, arg, end) re_opcode_t op; unsigned char *loc; int arg; unsigned char *end; { register unsigned char *pfrom = end; register unsigned char *pto = end + 3; while (pfrom != loc) *--pto = *--pfrom; store_op1 (op, loc, arg); } /* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2. */ static void insert_op2 (op, loc, arg1, arg2, end) re_opcode_t op; unsigned char *loc; int arg1, arg2; unsigned char *end; { register unsigned char *pfrom = end; register unsigned char *pto = end + 5; while (pfrom != loc) *--pto = *--pfrom; store_op2 (op, loc, arg1, arg2); } /* P points to just after a ^ in PATTERN. Return true if that ^ comes after an alternative or a begin-subexpression. We assume there is at least one character before the ^. */ static boolean at_begline_loc_p (pattern, p, syntax) const char *pattern, *p; reg_syntax_t syntax; { const char *prev = p - 2; boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\'; return /* After a subexpression? */ (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash)) /* After an alternative? */ || (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash)); } /* The dual of at_begline_loc_p. This one is for $. We assume there is at least one character after the $, i.e., `P < PEND'. */ static boolean at_endline_loc_p (p, pend, syntax) const char *p, *pend; int syntax; { const char *next = p; boolean next_backslash = *next == '\\'; const char *next_next = p + 1 < pend ? p + 1 : NULL; return /* Before a subexpression? */ (syntax & RE_NO_BK_PARENS ? *next == ')' : next_backslash && next_next && *next_next == ')') /* Before an alternative? */ || (syntax & RE_NO_BK_VBAR ? *next == '|' : next_backslash && next_next && *next_next == '|'); } /* Returns true if REGNUM is in one of COMPILE_STACK's elements and false if it's not. */ static boolean group_in_compile_stack (compile_stack, regnum) compile_stack_type compile_stack; regnum_t regnum; { int this_element; for (this_element = compile_stack.avail - 1; this_element >= 0; this_element--) if (compile_stack.stack[this_element].regnum == regnum) return true; return false; } /* Read the ending character of a range (in a bracket expression) from the uncompiled pattern *P_PTR (which ends at PEND). We assume the starting character is in `P[-2]'. (`P[-1]' is the character `-'.) Then we set the translation of all bits between the starting and ending characters (inclusive) in the compiled pattern B. Return an error code. We use these short variable names so we can use the same macros as `regex_compile' itself. */ static reg_errcode_t compile_range (p_ptr, pend, translate, syntax, b) const char **p_ptr, *pend; char *translate; reg_syntax_t syntax; unsigned char *b; { unsigned this_char; const char *p = *p_ptr; int range_start, range_end; if (p == pend) return REG_ERANGE; /* Even though the pattern is a signed `char *', we need to fetch with unsigned char *'s; if the high bit of the pattern character is set, the range endpoints will be negative if we fetch using a signed char *. We also want to fetch the endpoints without translating them; the appropriate translation is done in the bit-setting loop below. */ range_start = ((unsigned char *) p)[-2]; range_end = ((unsigned char *) p)[0]; /* Have to increment the pointer into the pattern string, so the caller isn't still at the ending character. */ (*p_ptr)++; /* If the start is after the end, the range is empty. */ if (range_start > range_end) return syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR; /* Here we see why `this_char' has to be larger than an `unsigned char' -- the range is inclusive, so if `range_end' == 0xff (assuming 8-bit characters), we would otherwise go into an infinite loop, since all characters <= 0xff. */ for (this_char = range_start; this_char <= range_end; this_char++) { SET_LIST_BIT (TRANSLATE (this_char)); } return REG_NOERROR; } /* Failure stack declarations and macros; both re_compile_fastmap and re_match_2 use a failure stack. These have to be macros because of REGEX_ALLOCATE. */ /* Number of failure points for which to initially allocate space when matching. If this number is exceeded, we allocate more space, so it is not a hard limit. */ #ifndef INIT_FAILURE_ALLOC #define INIT_FAILURE_ALLOC 5 #endif /* Roughly the maximum number of failure points on the stack. Would be exactly that if always used MAX_FAILURE_SPACE each time we failed. This is a variable only so users of regex can assign to it; we never change it ourselves. */ int re_max_failures = 2000; typedef const unsigned char *fail_stack_elt_t; typedef struct { fail_stack_elt_t *stack; unsigned size; unsigned avail; /* Offset of next open position. */ } fail_stack_type; #define FAIL_STACK_EMPTY() (fail_stack.avail == 0) #define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0) #define FAIL_STACK_FULL() (fail_stack.avail == fail_stack.size) #define FAIL_STACK_TOP() (fail_stack.stack[fail_stack.avail]) /* Initialize `fail_stack'. Do `return -2' if the alloc fails. */ #define INIT_FAIL_STACK() \ do { \ fail_stack.stack = (fail_stack_elt_t *) \ REGEX_ALLOCATE (INIT_FAILURE_ALLOC * sizeof (fail_stack_elt_t)); \ \ if (fail_stack.stack == NULL) \ return -2; \ \ fail_stack.size = INIT_FAILURE_ALLOC; \ fail_stack.avail = 0; \ } while (0) /* Double the size of FAIL_STACK, up to approximately `re_max_failures' items. Return 1 if succeeds, and 0 if either ran out of memory allocating space for it or it was already too large. REGEX_REALLOCATE requires `destination' be declared. */ #define DOUBLE_FAIL_STACK(fail_stack) \ ((fail_stack).size > re_max_failures * MAX_FAILURE_ITEMS \ ? 0 \ : ((fail_stack).stack = (fail_stack_elt_t *) \ REGEX_REALLOCATE ((fail_stack).stack, \ (fail_stack).size * sizeof (fail_stack_elt_t), \ ((fail_stack).size << 1) * sizeof (fail_stack_elt_t)), \ \ (fail_stack).stack == NULL \ ? 0 \ : ((fail_stack).size <<= 1, \ 1))) /* Push PATTERN_OP on FAIL_STACK. Return 1 if was able to do so and 0 if ran out of memory allocating space to do so. */ #define PUSH_PATTERN_OP(pattern_op, fail_stack) \ ((FAIL_STACK_FULL () \ && !DOUBLE_FAIL_STACK (fail_stack)) \ ? 0 \ : ((fail_stack).stack[(fail_stack).avail++] = pattern_op, \ 1)) /* This pushes an item onto the failure stack. Must be a four-byte value. Assumes the variable `fail_stack'. Probably should only be called from within `PUSH_FAILURE_POINT'. */ #define PUSH_FAILURE_ITEM(item) \ fail_stack.stack[fail_stack.avail++] = (fail_stack_elt_t) item /* The complement operation. Assumes `fail_stack' is nonempty. */ #define POP_FAILURE_ITEM() fail_stack.stack[--fail_stack.avail] /* Used to omit pushing failure point id's when we're not debugging. */ #ifdef DEBUG #define DEBUG_PUSH PUSH_FAILURE_ITEM #define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_ITEM () #else #define DEBUG_PUSH(item) #define DEBUG_POP(item_addr) #endif /* Push the information about the state we will need if we ever fail back to it. Requires variables fail_stack, regstart, regend, reg_info, and num_regs be declared. DOUBLE_FAIL_STACK requires `destination' be declared. Does `return FAILURE_CODE' if runs out of memory. */ #define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code) \ do { \ char *destination; \ /* Must be int, so when we don't save any registers, the arithmetic \ of 0 + -1 isn't done as unsigned. */ \ int this_reg; \ \ DEBUG_STATEMENT (failure_id++); \ DEBUG_STATEMENT (nfailure_points_pushed++); \ DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id); \ DEBUG_PRINT2 (" Before push, next avail: %d\n", (fail_stack).avail);\ DEBUG_PRINT2 (" size: %d\n", (fail_stack).size);\ \ DEBUG_PRINT2 (" slots needed: %d\n", NUM_FAILURE_ITEMS); \ DEBUG_PRINT2 (" available: %d\n", REMAINING_AVAIL_SLOTS); \ \ /* Ensure we have enough space allocated for what we will push. */ \ while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS) \ { \ if (!DOUBLE_FAIL_STACK (fail_stack)) \ return failure_code; \ \ DEBUG_PRINT2 ("\n Doubled stack; size now: %d\n", \ (fail_stack).size); \ DEBUG_PRINT2 (" slots available: %d\n", REMAINING_AVAIL_SLOTS);\ } \ \ /* Push the info, starting with the registers. */ \ DEBUG_PRINT1 ("\n"); \ \ for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \ this_reg++) \ { \ DEBUG_PRINT2 (" Pushing reg: %d\n", this_reg); \ DEBUG_STATEMENT (num_regs_pushed++); \ \ DEBUG_PRINT2 (" start: 0x%x\n", regstart[this_reg]); \ PUSH_FAILURE_ITEM (regstart[this_reg]); \ \ DEBUG_PRINT2 (" end: 0x%x\n", regend[this_reg]); \ PUSH_FAILURE_ITEM (regend[this_reg]); \ \ DEBUG_PRINT2 (" info: 0x%x\n ", reg_info[this_reg]); \ DEBUG_PRINT2 (" match_null=%d", \ REG_MATCH_NULL_STRING_P (reg_info[this_reg])); \ DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg])); \ DEBUG_PRINT2 (" matched_something=%d", \ MATCHED_SOMETHING (reg_info[this_reg])); \ DEBUG_PRINT2 (" ever_matched=%d", \ EVER_MATCHED_SOMETHING (reg_info[this_reg])); \ DEBUG_PRINT1 ("\n"); \ PUSH_FAILURE_ITEM (reg_info[this_reg].word); \ } \ \ DEBUG_PRINT2 (" Pushing low active reg: %d\n", lowest_active_reg);\ PUSH_FAILURE_ITEM (lowest_active_reg); \ \ DEBUG_PRINT2 (" Pushing high active reg: %d\n", highest_active_reg);\ PUSH_FAILURE_ITEM (highest_active_reg); \ \ DEBUG_PRINT2 (" Pushing pattern 0x%x: ", pattern_place); \ DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend); \ PUSH_FAILURE_ITEM (pattern_place); \ \ DEBUG_PRINT2 (" Pushing string 0x%x: `", string_place); \ DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2, \ size2); \ DEBUG_PRINT1 ("'\n"); \ PUSH_FAILURE_ITEM (string_place); \ \ DEBUG_PRINT2 (" Pushing failure id: %u\n", failure_id); \ DEBUG_PUSH (failure_id); \ } while (0) /* This is the number of items that are pushed and popped on the stack for each register. */ #define NUM_REG_ITEMS 3 /* Individual items aside from the registers. */ #ifdef DEBUG #define NUM_NONREG_ITEMS 5 /* Includes failure point id. */ #else #define NUM_NONREG_ITEMS 4 #endif /* We push at most this many items on the stack. */ #define MAX_FAILURE_ITEMS ((num_regs - 1) * NUM_REG_ITEMS + NUM_NONREG_ITEMS) /* We actually push this many items. */ #define NUM_FAILURE_ITEMS \ ((highest_active_reg - lowest_active_reg + 1) * NUM_REG_ITEMS \ + NUM_NONREG_ITEMS) /* How many items can still be added to the stack without overflowing it. */ #define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail) /* Pops what PUSH_FAIL_STACK pushes. We restore into the parameters, all of which should be lvalues: STR -- the saved data position. PAT -- the saved pattern position. LOW_REG, HIGH_REG -- the highest and lowest active registers. REGSTART, REGEND -- arrays of string positions. REG_INFO -- array of information about each subexpression. Also assumes the variables `fail_stack' and (if debugging), `bufp', `pend', `string1', `size1', `string2', and `size2'. */ #define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\ { \ DEBUG_STATEMENT (fail_stack_elt_t failure_id;) \ int this_reg; \ const unsigned char *string_temp; \ \ assert (!FAIL_STACK_EMPTY ()); \ \ /* Remove failure points and point to how many regs pushed. */ \ DEBUG_PRINT1 ("POP_FAILURE_POINT:\n"); \ DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \ DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \ \ assert (fail_stack.avail >= NUM_NONREG_ITEMS); \ \ DEBUG_POP (&failure_id); \ DEBUG_PRINT2 (" Popping failure id: %u\n", failure_id); \ \ /* If the saved string location is NULL, it came from an \ on_failure_keep_string_jump opcode, and we want to throw away the \ saved NULL, thus retaining our current position in the string. */ \ string_temp = POP_FAILURE_ITEM (); \ if (string_temp != NULL) \ str = (const char *) string_temp; \ \ DEBUG_PRINT2 (" Popping string 0x%x: `", str); \ DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2); \ DEBUG_PRINT1 ("'\n"); \ \ pat = (unsigned char *) POP_FAILURE_ITEM (); \ DEBUG_PRINT2 (" Popping pattern 0x%x: ", pat); \ DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \ \ /* Restore register info. */ \ high_reg = (unsigned) POP_FAILURE_ITEM (); \ DEBUG_PRINT2 (" Popping high active reg: %d\n", high_reg); \ \ low_reg = (unsigned) POP_FAILURE_ITEM (); \ DEBUG_PRINT2 (" Popping low active reg: %d\n", low_reg); \ \ for (this_reg = high_reg; this_reg >= low_reg; this_reg--) \ { \ DEBUG_PRINT2 (" Popping reg: %d\n", this_reg); \ \ reg_info[this_reg].word = POP_FAILURE_ITEM (); \ DEBUG_PRINT2 (" info: 0x%x\n", reg_info[this_reg]); \ \ regend[this_reg] = (const char *) POP_FAILURE_ITEM (); \ DEBUG_PRINT2 (" end: 0x%x\n", regend[this_reg]); \ \ regstart[this_reg] = (const char *) POP_FAILURE_ITEM (); \ DEBUG_PRINT2 (" start: 0x%x\n", regstart[this_reg]); \ } \ \ DEBUG_STATEMENT (nfailure_points_popped++); \ } /* POP_FAILURE_POINT */ /* re_compile_fastmap computes a ``fastmap'' for the compiled pattern in BUFP. A fastmap records which of the (1 << BYTEWIDTH) possible characters can start a string that matches the pattern. This fastmap is used by re_search to skip quickly over impossible starting points. The caller must supply the address of a (1 << BYTEWIDTH)-byte data area as BUFP->fastmap. We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in the pattern buffer. Returns 0 if we succeed, -2 if an internal error. */ int re_compile_fastmap (bufp) struct re_pattern_buffer *bufp; { int j, k; fail_stack_type fail_stack; #ifndef REGEX_MALLOC char *destination; #endif /* We don't push any register information onto the failure stack. */ unsigned num_regs = 0; register char *fastmap = bufp->fastmap; unsigned char *pattern = bufp->buffer; unsigned long size = bufp->used; const unsigned char *p = pattern; register unsigned char *pend = pattern + size; /* Assume that each path through the pattern can be null until proven otherwise. We set this false at the bottom of switch statement, to which we get only if a particular path doesn't match the empty string. */ boolean path_can_be_null = true; /* We aren't doing a `succeed_n' to begin with. */ boolean succeed_n_p = false; assert (fastmap != NULL && p != NULL); INIT_FAIL_STACK (); bzero (fastmap, 1 << BYTEWIDTH); /* Assume nothing's valid. */ bufp->fastmap_accurate = 1; /* It will be when we're done. */ bufp->can_be_null = 0; while (p != pend || !FAIL_STACK_EMPTY ()) { if (p == pend) { bufp->can_be_null |= path_can_be_null; /* Reset for next path. */ path_can_be_null = true; p = fail_stack.stack[--fail_stack.avail]; } /* We should never be about to go beyond the end of the pattern. */ assert (p < pend); #ifdef SWITCH_ENUM_BUG switch ((int) ((re_opcode_t) *p++)) #else switch ((re_opcode_t) *p++) #endif { /* I guess the idea here is to simply not bother with a fastmap if a backreference is used, since it's too hard to figure out the fastmap for the corresponding group. Setting `can_be_null' stops `re_search_2' from using the fastmap, so that is all we do. */ case duplicate: bufp->can_be_null = 1; return 0; /* Following are the cases which match a character. These end with `break'. */ case exactn: fastmap[p[1]] = 1; break; case charset: for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--) if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))) fastmap[j] = 1; break; case charset_not: /* Chars beyond end of map must be allowed. */ for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++) fastmap[j] = 1; for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--) if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))) fastmap[j] = 1; break; case wordchar: for (j = 0; j < (1 << BYTEWIDTH); j++) if (SYNTAX (j) == Sword) fastmap[j] = 1; break; case notwordchar: for (j = 0; j < (1 << BYTEWIDTH); j++) if (SYNTAX (j) != Sword) fastmap[j] = 1; break; case anychar: /* `.' matches anything ... */ for (j = 0; j < (1 << BYTEWIDTH); j++) fastmap[j] = 1; /* ... except perhaps newline. */ if (!(bufp->syntax & RE_DOT_NEWLINE)) fastmap['\n'] = 0; /* Return if we have already set `can_be_null'; if we have, then the fastmap is irrelevant. Something's wrong here. */ else if (bufp->can_be_null) return 0; /* Otherwise, have to check alternative paths. */ break; #ifdef emacs case syntaxspec: k = *p++; for (j = 0; j < (1 << BYTEWIDTH); j++) if (SYNTAX (j) == (enum syntaxcode) k) fastmap[j] = 1; break; case notsyntaxspec: k = *p++; for (j = 0; j < (1 << BYTEWIDTH); j++) if (SYNTAX (j) != (enum syntaxcode) k) fastmap[j] = 1; break; /* All cases after this match the empty string. These end with `continue'. */ case before_dot: case at_dot: case after_dot: continue; #endif /* not emacs */ case no_op: case begline: case endline: case begbuf: case endbuf: case wordbound: case notwordbound: case wordbeg: case wordend: case push_dummy_failure: continue; case jump_n: case pop_failure_jump: case maybe_pop_jump: case jump: case jump_past_alt: case dummy_failure_jump: EXTRACT_NUMBER_AND_INCR (j, p); p += j; if (j > 0) continue; /* Jump backward implies we just went through the body of a loop and matched nothing. Opcode jumped to should be `on_failure_jump' or `succeed_n'. Just treat it like an ordinary jump. For a * loop, it has pushed its failure point already; if so, discard that as redundant. */ if ((re_opcode_t) *p != on_failure_jump && (re_opcode_t) *p != succeed_n) continue; p++; EXTRACT_NUMBER_AND_INCR (j, p); p += j; /* If what's on the stack is where we are now, pop it. */ if (!FAIL_STACK_EMPTY () && fail_stack.stack[fail_stack.avail - 1] == p) fail_stack.avail--; continue; case on_failure_jump: case on_failure_keep_string_jump: handle_on_failure_jump: EXTRACT_NUMBER_AND_INCR (j, p); /* For some patterns, e.g., `(a?)?', `p+j' here points to the end of the pattern. We don't want to push such a point, since when we restore it above, entering the switch will increment `p' past the end of the pattern. We don't need to push such a point since we obviously won't find any more fastmap entries beyond `pend'. Such a pattern can match the null string, though. */ if (p + j < pend) { if (!PUSH_PATTERN_OP (p + j, fail_stack)) return -2; } else bufp->can_be_null = 1; if (succeed_n_p) { EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */ succeed_n_p = false; } continue; case succeed_n: /* Get to the number of times to succeed. */ p += 2; /* Increment p past the n for when k != 0. */ EXTRACT_NUMBER_AND_INCR (k, p); if (k == 0) { p -= 4; succeed_n_p = true; /* Spaghetti code alert. */ goto handle_on_failure_jump; } continue; case set_number_at: p += 4; continue; case start_memory: case stop_memory: p += 2; continue; default: abort (); /* We have listed all the cases. */ } /* switch *p++ */ /* Getting here means we have found the possible starting characters for one path of the pattern -- and that the empty string does not match. We need not follow this path further. Instead, look at the next alternative (remembered on the stack), or quit if no more. The test at the top of the loop does these things. */ path_can_be_null = false; p = pend; } /* while p */ /* Set `can_be_null' for the last path (also the first path, if the pattern is empty). */ bufp->can_be_null |= path_can_be_null; return 0; } /* re_compile_fastmap */ /* Set REGS to hold NUM_REGS registers, storing them in STARTS and ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use this memory for recording register information. STARTS and ENDS must be allocated using the malloc library routine, and must each be at least NUM_REGS * sizeof (regoff_t) bytes long. If NUM_REGS == 0, then subsequent matches should allocate their own register data. Unless this function is called, the first search or match using PATTERN_BUFFER will allocate its own register data, without freeing the old data. */ void re_set_registers (bufp, regs, num_regs, starts, ends) struct re_pattern_buffer *bufp; struct re_registers *regs; unsigned num_regs; regoff_t *starts, *ends; { if (num_regs) { bufp->regs_allocated = REGS_REALLOCATE; regs->num_regs = num_regs; regs->start = starts; regs->end = ends; } else { bufp->regs_allocated = REGS_UNALLOCATED; regs->num_regs = 0; regs->start = regs->end = (regoff_t) 0; } } /* Searching routines. */ /* Like re_search_2, below, but only one string is specified, and doesn't let you say where to stop matching. */ int re_search (bufp, string, size, startpos, range, regs) struct re_pattern_buffer *bufp; const char *string; int size, startpos, range; struct re_registers *regs; { return re_search_2 (bufp, NULL, 0, string, size, startpos, range, regs, size); } /* Using the compiled pattern in BUFP->buffer, first tries to match the virtual concatenation of STRING1 and STRING2, starting first at index STARTPOS, then at STARTPOS + 1, and so on. STRING1 and STRING2 have length SIZE1 and SIZE2, respectively. RANGE is how far to scan while trying to match. RANGE = 0 means try only at STARTPOS; in general, the last start tried is STARTPOS + RANGE. In REGS, return the indices of the virtual concatenation of STRING1 and STRING2 that matched the entire BUFP->buffer and its contained subexpressions. Do not consider matching one past the index STOP in the virtual concatenation of STRING1 and STRING2. We return either the position in the strings at which the match was found, -1 if no match, or -2 if error (such as failure stack overflow). */ int re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop) struct re_pattern_buffer *bufp; const char *string1, *string2; int size1, size2; int startpos; int range; struct re_registers *regs; int stop; { int val; register char *fastmap = bufp->fastmap; register char *translate = bufp->translate; int total_size = size1 + size2; int endpos = startpos + range; /* Check for out-of-range STARTPOS. */ if (startpos < 0 || startpos > total_size) return -1; /* Fix up RANGE if it might eventually take us outside the virtual concatenation of STRING1 and STRING2. */ if (endpos < -1) range = -1 - startpos; else if (endpos > total_size) range = total_size - startpos; /* If the search isn't to be a backwards one, don't waste time in a search for a pattern that must be anchored. */ if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == begbuf && range > 0) { if (startpos > 0) return -1; else range = 1; } /* Update the fastmap now if not correct already. */ if (fastmap && !bufp->fastmap_accurate) if (re_compile_fastmap (bufp) == -2) return -2; /* Loop through the string, looking for a place to start matching. */ for (;;) { /* If a fastmap is supplied, skip quickly over characters that cannot be the start of a match. If the pattern can match the null string, however, we don't need to skip characters; we want the first null string. */ if (fastmap && startpos < total_size && !bufp->can_be_null) { if (range > 0) /* Searching forwards. */ { register const char *d; register int lim = 0; int irange = range; if (startpos < size1 && startpos + range >= size1) lim = range - (size1 - startpos); d = (startpos >= size1 ? string2 - size1 : string1) + startpos; /* Written out as an if-else to avoid testing `translate' inside the loop. */ if (translate) while (range > lim && !fastmap[(unsigned char) translate[(unsigned char) *d++]]) range--; else while (range > lim && !fastmap[(unsigned char) *d++]) range--; startpos += irange - range; } else /* Searching backwards. */ { register char c = (size1 == 0 || startpos >= size1 ? string2[startpos - size1] : string1[startpos]); if (!fastmap[(unsigned char) TRANSLATE (c)]) goto advance; } } /* If can't match the null string, and that's all we have left, fail. */ if (range >= 0 && startpos == total_size && fastmap && !bufp->can_be_null) return -1; val = re_match_2 (bufp, string1, size1, string2, size2, startpos, regs, stop); if (val >= 0) return startpos; if (val == -2) return -2; advance: if (!range) break; else if (range > 0) { range--; startpos++; } else { range++; startpos--; } } return -1; } /* re_search_2 */ /* Declarations and macros for re_match_2. */ static int bcmp_translate (); static boolean alt_match_null_string_p (), common_op_match_null_string_p (), group_match_null_string_p (); /* Structure for per-register (a.k.a. per-group) information. This must not be longer than one word, because we push this value onto the failure stack. Other register information, such as the starting and ending positions (which are addresses), and the list of inner groups (which is a bits list) are maintained in separate variables. We are making a (strictly speaking) nonportable assumption here: that the compiler will pack our bit fields into something that fits into the type of `word', i.e., is something that fits into one item on the failure stack. */ typedef union { fail_stack_elt_t word; struct { /* This field is one if this group can match the empty string, zero if not. If not yet determined, `MATCH_NULL_UNSET_VALUE'. */ #define MATCH_NULL_UNSET_VALUE 3 unsigned match_null_string_p : 2; unsigned is_active : 1; unsigned matched_something : 1; unsigned ever_matched_something : 1; } bits; } register_info_type; #define REG_MATCH_NULL_STRING_P(R) ((R).bits.match_null_string_p) #define IS_ACTIVE(R) ((R).bits.is_active) #define MATCHED_SOMETHING(R) ((R).bits.matched_something) #define EVER_MATCHED_SOMETHING(R) ((R).bits.ever_matched_something) /* Call this when have matched a real character; it sets `matched' flags for the subexpressions which we are currently inside. Also records that those subexprs have matched. */ #define SET_REGS_MATCHED() \ do \ { \ unsigned r; \ for (r = lowest_active_reg; r <= highest_active_reg; r++) \ { \ MATCHED_SOMETHING (reg_info[r]) \ = EVER_MATCHED_SOMETHING (reg_info[r]) \ = 1; \ } \ } \ while (0) /* This converts PTR, a pointer into one of the search strings `string1' and `string2' into an offset from the beginning of that string. */ #define POINTER_TO_OFFSET(ptr) \ (FIRST_STRING_P (ptr) ? (ptr) - string1 : (ptr) - string2 + size1) /* Registers are set to a sentinel when they haven't yet matched. */ #define REG_UNSET_VALUE ((char *) -1) #define REG_UNSET(e) ((e) == REG_UNSET_VALUE) /* Macros for dealing with the split strings in re_match_2. */ #define MATCHING_IN_FIRST_STRING (dend == end_match_1) /* Call before fetching a character with *d. This switches over to string2 if necessary. */ #define PREFETCH() \ while (d == dend) \ { \ /* End of string2 => fail. */ \ if (dend == end_match_2) \ goto fail; \ /* End of string1 => advance to string2. */ \ d = string2; \ dend = end_match_2; \ } /* Test if at very beginning or at very end of the virtual concatenation of `string1' and `string2'. If only one string, it's `string2'. */ #define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2) #define AT_STRINGS_END(d) ((d) == end2) /* Test if D points to a character which is word-constituent. We have two special cases to check for: if past the end of string1, look at the first character in string2; and if before the beginning of string2, look at the last character in string1. */ #define WORDCHAR_P(d) \ (SYNTAX ((d) == end1 ? *string2 \ : (d) == string2 - 1 ? *(end1 - 1) : *(d)) \ == Sword) /* Test if the character before D and the one at D differ with respect to being word-constituent. */ #define AT_WORD_BOUNDARY(d) \ (AT_STRINGS_BEG (d) || AT_STRINGS_END (d) \ || WORDCHAR_P (d - 1) != WORDCHAR_P (d)) /* Free everything we malloc. */ #ifdef REGEX_MALLOC #define FREE_VAR(var) if (var) free (var); var = NULL #define FREE_VARIABLES() \ do { \ FREE_VAR (fail_stack.stack); \ FREE_VAR (regstart); \ FREE_VAR (regend); \ FREE_VAR (old_regstart); \ FREE_VAR (old_regend); \ FREE_VAR (best_regstart); \ FREE_VAR (best_regend); \ FREE_VAR (reg_info); \ FREE_VAR (reg_dummy); \ FREE_VAR (reg_info_dummy); \ } while (0) #else /* not REGEX_MALLOC */ /* Some MIPS systems (at least) want this to free alloca'd storage. */ #define FREE_VARIABLES() alloca (0) #endif /* not REGEX_MALLOC */ /* These values must meet several constraints. They must not be valid register values; since we have a limit of 255 registers (because we use only one byte in the pattern for the register number), we can use numbers larger than 255. They must differ by 1, because of NUM_FAILURE_ITEMS above. And the value for the lowest register must be larger than the value for the highest register, so we do not try to actually save any registers when none are active. */ #define NO_HIGHEST_ACTIVE_REG (1 << BYTEWIDTH) #define NO_LOWEST_ACTIVE_REG (NO_HIGHEST_ACTIVE_REG + 1) /* Matching routines. */ #ifndef emacs /* Emacs never uses this. */ /* re_match is like re_match_2 except it takes only a single string. */ int re_match (bufp, string, size, pos, regs) struct re_pattern_buffer *bufp; const char *string; int size, pos; struct re_registers *regs; { return re_match_2 (bufp, NULL, 0, string, size, pos, regs, size); } #endif /* not emacs */ /* re_match_2 matches the compiled pattern in BUFP against the the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1 and SIZE2, respectively). We start matching at POS, and stop matching at STOP. If REGS is non-null and the `no_sub' field of BUFP is nonzero, we store offsets for the substring each group matched in REGS. See the documentation for exactly how many groups we fill. We return -1 if no match, -2 if an internal error (such as the failure stack overflowing). Otherwise, we return the length of the matched substring. */ int re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) struct re_pattern_buffer *bufp; const char *string1, *string2; int size1, size2; int pos; struct re_registers *regs; int stop; { /* General temporaries. */ int mcnt; unsigned char *p1; /* Just past the end of the corresponding string. */ const char *end1, *end2; /* Pointers into string1 and string2, just past the last characters in each to consider matching. */ const char *end_match_1, *end_match_2; /* Where we are in the data, and the end of the current string. */ const char *d, *dend; /* Where we are in the pattern, and the end of the pattern. */ unsigned char *p = bufp->buffer; register unsigned char *pend = p + bufp->used; /* We use this to map every character in the string. */ char *translate = bufp->translate; /* Failure point stack. Each place that can handle a failure further down the line pushes a failure point on this stack. It consists of restart, regend, and reg_info for all registers corresponding to the subexpressions we're currently inside, plus the number of such registers, and, finally, two char *'s. The first char * is where to resume scanning the pattern; the second one is where to resume scanning the strings. If the latter is zero, the failure point is a ``dummy''; if a failure happens and the failure point is a dummy, it gets discarded and the next next one is tried. */ fail_stack_type fail_stack; #ifdef DEBUG static unsigned failure_id = 0; unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0; #endif /* We fill all the registers internally, independent of what we return, for use in backreferences. The number here includes an element for register zero. */ unsigned num_regs = bufp->re_nsub + 1; /* The currently active registers. */ unsigned lowest_active_reg = NO_LOWEST_ACTIVE_REG; unsigned highest_active_reg = NO_HIGHEST_ACTIVE_REG; /* Information on the contents of registers. These are pointers into the input strings; they record just what was matched (on this attempt) by a subexpression part of the pattern, that is, the regnum-th regstart pointer points to where in the pattern we began matching and the regnum-th regend points to right after where we stopped matching the regnum-th subexpression. (The zeroth register keeps track of what the whole pattern matches.) */ const char **regstart, **regend; /* If a group that's operated upon by a repetition operator fails to match anything, then the register for its start will need to be restored because it will have been set to wherever in the string we are when we last see its open-group operator. Similarly for a register's end. */ const char **old_regstart, **old_regend; /* The is_active field of reg_info helps us keep track of which (possibly nested) subexpressions we are currently in. The matched_something field of reg_info[reg_num] helps us tell whether or not we have matched any of the pattern so far this time through the reg_num-th subexpression. These two fields get reset each time through any loop their register is in. */ register_info_type *reg_info; /* The following record the register info as found in the above variables when we find a match better than any we've seen before. This happens as we backtrack through the failure points, which in turn happens only if we have not yet matched the entire string. */ unsigned best_regs_set = false; const char **best_regstart, **best_regend; /* Logically, this is `best_regend[0]'. But we don't want to have to allocate space for that if we're not allocating space for anything else (see below). Also, we never need info about register 0 for any of the other register vectors, and it seems rather a kludge to treat `best_regend' differently than the rest. So we keep track of the end of the best match so far in a separate variable. We initialize this to NULL so that when we backtrack the first time and need to test it, it's not garbage. */ const char *match_end = NULL; /* Used when we pop values we don't care about. */ const char **reg_dummy; register_info_type *reg_info_dummy; #ifdef DEBUG /* Counts the total number of registers pushed. */ unsigned num_regs_pushed = 0; #endif DEBUG_PRINT1 ("\n\nEntering re_match_2.\n"); INIT_FAIL_STACK (); /* Do not bother to initialize all the register variables if there are no groups in the pattern, as it takes a fair amount of time. If there are groups, we include space for register 0 (the whole pattern), even though we never use it, since it simplifies the array indexing. We should fix this. */ if (bufp->re_nsub) { regstart = REGEX_TALLOC (num_regs, const char *); regend = REGEX_TALLOC (num_regs, const char *); old_regstart = REGEX_TALLOC (num_regs, const char *); old_regend = REGEX_TALLOC (num_regs, const char *); best_regstart = REGEX_TALLOC (num_regs, const char *); best_regend = REGEX_TALLOC (num_regs, const char *); reg_info = REGEX_TALLOC (num_regs, register_info_type); reg_dummy = REGEX_TALLOC (num_regs, const char *); reg_info_dummy = REGEX_TALLOC (num_regs, register_info_type); if (!(regstart && regend && old_regstart && old_regend && reg_info && best_regstart && best_regend && reg_dummy && reg_info_dummy)) { FREE_VARIABLES (); return -2; } } #ifdef REGEX_MALLOC else { /* We must initialize all our variables to NULL, so that `FREE_VARIABLES' doesn't try to free them. */ regstart = regend = old_regstart = old_regend = best_regstart = best_regend = reg_dummy = NULL; reg_info = reg_info_dummy = (register_info_type *) NULL; } #endif /* REGEX_MALLOC */ /* The starting position is bogus. */ if (pos < 0 || pos > size1 + size2) { FREE_VARIABLES (); return -1; } /* Initialize subexpression text positions to -1 to mark ones that no start_memory/stop_memory has been seen for. Also initialize the register information struct. */ for (mcnt = 1; mcnt < num_regs; mcnt++) { regstart[mcnt] = regend[mcnt] = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE; REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE; IS_ACTIVE (reg_info[mcnt]) = 0; MATCHED_SOMETHING (reg_info[mcnt]) = 0; EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0; } /* We move `string1' into `string2' if the latter's empty -- but not if `string1' is null. */ if (size2 == 0 && string1 != NULL) { string2 = string1; size2 = size1; string1 = 0; size1 = 0; } end1 = string1 + size1; end2 = string2 + size2; /* Compute where to stop matching, within the two strings. */ if (stop <= size1) { end_match_1 = string1 + stop; end_match_2 = string2; } else { end_match_1 = end1; end_match_2 = string2 + stop - size1; } /* `p' scans through the pattern as `d' scans through the data. `dend' is the end of the input string that `d' points within. `d' is advanced into the following input string whenever necessary, but this happens before fetching; therefore, at the beginning of the loop, `d' can be pointing at the end of a string, but it cannot equal `string2'. */ if (size1 > 0 && pos <= size1) { d = string1 + pos; dend = end_match_1; } else { d = string2 + pos - size1; dend = end_match_2; } DEBUG_PRINT1 ("The compiled pattern is: "); DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend); DEBUG_PRINT1 ("The string to match is: `"); DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2); DEBUG_PRINT1 ("'\n"); /* This loops over pattern commands. It exits by returning from the function if the match is complete, or it drops through if the match fails at this starting point in the input data. */ for (;;) { DEBUG_PRINT2 ("\n0x%x: ", p); if (p == pend) { /* End of pattern means we might have succeeded. */ DEBUG_PRINT1 ("end of pattern ... "); /* If we haven't matched the entire string, and we want the longest match, try backtracking. */ if (d != end_match_2) { DEBUG_PRINT1 ("backtracking.\n"); if (!FAIL_STACK_EMPTY ()) { /* More failure points to try. */ boolean same_str_p = (FIRST_STRING_P (match_end) == MATCHING_IN_FIRST_STRING); /* If exceeds best match so far, save it. */ if (!best_regs_set || (same_str_p && d > match_end) || (!same_str_p && !MATCHING_IN_FIRST_STRING)) { best_regs_set = true; match_end = d; DEBUG_PRINT1 ("\nSAVING match as best so far.\n"); for (mcnt = 1; mcnt < num_regs; mcnt++) { best_regstart[mcnt] = regstart[mcnt]; best_regend[mcnt] = regend[mcnt]; } } goto fail; } /* If no failure points, don't restore garbage. */ else if (best_regs_set) { restore_best_regs: /* Restore best match. It may happen that `dend == end_match_1' while the restored d is in string2. For example, the pattern `x.*y.*z' against the strings `x-' and `y-z-', if the two strings are not consecutive in memory. */ DEBUG_PRINT1 ("Restoring best registers.\n"); d = match_end; dend = ((d >= string1 && d <= end1) ? end_match_1 : end_match_2); for (mcnt = 1; mcnt < num_regs; mcnt++) { regstart[mcnt] = best_regstart[mcnt]; regend[mcnt] = best_regend[mcnt]; } } } /* d != end_match_2 */ DEBUG_PRINT1 ("Accepting match.\n"); /* If caller wants register contents data back, do it. */ if (regs && !bufp->no_sub) { /* Have the register data arrays been allocated? */ if (bufp->regs_allocated == REGS_UNALLOCATED) { /* No. So allocate them with malloc. We need one extra element beyond `num_regs' for the `-1' marker GNU code uses. */ regs->num_regs = MAX (RE_NREGS, num_regs + 1); regs->start = TALLOC (regs->num_regs, regoff_t); regs->end = TALLOC (regs->num_regs, regoff_t); if (regs->start == NULL || regs->end == NULL) return -2; bufp->regs_allocated = REGS_REALLOCATE; } else if (bufp->regs_allocated == REGS_REALLOCATE) { /* Yes. If we need more elements than were already allocated, reallocate them. If we need fewer, just leave it alone. */ if (regs->num_regs < num_regs + 1) { regs->num_regs = num_regs + 1; RETALLOC (regs->start, regs->num_regs, regoff_t); RETALLOC (regs->end, regs->num_regs, regoff_t); if (regs->start == NULL || regs->end == NULL) return -2; } } else assert (bufp->regs_allocated == REGS_FIXED); /* Convert the pointer data in `regstart' and `regend' to indices. Register zero has to be set differently, since we haven't kept track of any info for it. */ if (regs->num_regs > 0) { regs->start[0] = pos; regs->end[0] = (MATCHING_IN_FIRST_STRING ? d - string1 : d - string2 + size1); } /* Go through the first `min (num_regs, regs->num_regs)' registers, since that is all we initialized. */ for (mcnt = 1; mcnt < MIN (num_regs, regs->num_regs); mcnt++) { if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt])) regs->start[mcnt] = regs->end[mcnt] = -1; else { regs->start[mcnt] = POINTER_TO_OFFSET (regstart[mcnt]); regs->end[mcnt] = POINTER_TO_OFFSET (regend[mcnt]); } } /* If the regs structure we return has more elements than were in the pattern, set the extra elements to -1. If we (re)allocated the registers, this is the case, because we always allocate enough to have at least one -1 at the end. */ for (mcnt = num_regs; mcnt < regs->num_regs; mcnt++) regs->start[mcnt] = regs->end[mcnt] = -1; } /* regs && !bufp->no_sub */ FREE_VARIABLES (); DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n", nfailure_points_pushed, nfailure_points_popped, nfailure_points_pushed - nfailure_points_popped); DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed); mcnt = d - pos - (MATCHING_IN_FIRST_STRING ? string1 : string2 - size1); DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt); return mcnt; } /* Otherwise match next pattern command. */ #ifdef SWITCH_ENUM_BUG switch ((int) ((re_opcode_t) *p++)) #else switch ((re_opcode_t) *p++) #endif { /* Ignore these. Used to ignore the n of succeed_n's which currently have n == 0. */ case no_op: DEBUG_PRINT1 ("EXECUTING no_op.\n"); break; /* Match the next n pattern characters exactly. The following byte in the pattern defines n, and the n bytes after that are the characters to match. */ case exactn: mcnt = *p++; DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt); /* This is written out as an if-else so we don't waste time testing `translate' inside the loop. */ if (translate) { do { PREFETCH (); if (translate[(unsigned char) *d++] != (char) *p++) goto fail; } while (--mcnt); } else { do { PREFETCH (); if (*d++ != (char) *p++) goto fail; } while (--mcnt); } SET_REGS_MATCHED (); break; /* Match any character except possibly a newline or a null. */ case anychar: DEBUG_PRINT1 ("EXECUTING anychar.\n"); PREFETCH (); if ((!(bufp->syntax & RE_DOT_NEWLINE) && TRANSLATE (*d) == '\n') || (bufp->syntax & RE_DOT_NOT_NULL && TRANSLATE (*d) == '\000')) goto fail; SET_REGS_MATCHED (); DEBUG_PRINT2 (" Matched `%d'.\n", *d); d++; break; case charset: case charset_not: { register unsigned char c; boolean not = (re_opcode_t) *(p - 1) == charset_not; DEBUG_PRINT2 ("EXECUTING charset%s.\n", not ? "_not" : ""); PREFETCH (); c = TRANSLATE (*d); /* The character to match. */ /* Cast to `unsigned' instead of `unsigned char' in case the bit list is a full 32 bytes long. */ if (c < (unsigned) (*p * BYTEWIDTH) && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH))) not = !not; p += 1 + *p; if (!not) goto fail; SET_REGS_MATCHED (); d++; break; } /* The beginning of a group is represented by start_memory. The arguments are the register number in the next byte, and the number of groups inner to this one in the next. The text matched within the group is recorded (in the internal registers data structure) under the register number. */ case start_memory: DEBUG_PRINT3 ("EXECUTING start_memory %d (%d):\n", *p, p[1]); /* Find out if this group can match the empty string. */ p1 = p; /* To send to group_match_null_string_p. */ if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE) REG_MATCH_NULL_STRING_P (reg_info[*p]) = group_match_null_string_p (&p1, pend, reg_info); /* Save the position in the string where we were the last time we were at this open-group operator in case the group is operated upon by a repetition operator, e.g., with `(a*)*b' against `ab'; then we want to ignore where we are now in the string in case this attempt to match fails. */ old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p]) ? REG_UNSET (regstart[*p]) ? d : regstart[*p] : regstart[*p]; DEBUG_PRINT2 (" old_regstart: %d\n", POINTER_TO_OFFSET (old_regstart[*p])); regstart[*p] = d; DEBUG_PRINT2 (" regstart: %d\n", POINTER_TO_OFFSET (regstart[*p])); IS_ACTIVE (reg_info[*p]) = 1; MATCHED_SOMETHING (reg_info[*p]) = 0; /* This is the new highest active register. */ highest_active_reg = *p; /* If nothing was active before, this is the new lowest active register. */ if (lowest_active_reg == NO_LOWEST_ACTIVE_REG) lowest_active_reg = *p; /* Move past the register number and inner group count. */ p += 2; break; /* The stop_memory opcode represents the end of a group. Its arguments are the same as start_memory's: the register number, and the number of inner groups. */ case stop_memory: DEBUG_PRINT3 ("EXECUTING stop_memory %d (%d):\n", *p, p[1]); /* We need to save the string position the last time we were at this close-group operator in case the group is operated upon by a repetition operator, e.g., with `((a*)*(b*)*)*' against `aba'; then we want to ignore where we are now in the string in case this attempt to match fails. */ old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p]) ? REG_UNSET (regend[*p]) ? d : regend[*p] : regend[*p]; DEBUG_PRINT2 (" old_regend: %d\n", POINTER_TO_OFFSET (old_regend[*p])); regend[*p] = d; DEBUG_PRINT2 (" regend: %d\n", POINTER_TO_OFFSET (regend[*p])); /* This register isn't active anymore. */ IS_ACTIVE (reg_info[*p]) = 0; /* If this was the only register active, nothing is active anymore. */ if (lowest_active_reg == highest_active_reg) { lowest_active_reg = NO_LOWEST_ACTIVE_REG; highest_active_reg = NO_HIGHEST_ACTIVE_REG; } else { /* We must scan for the new highest active register, since it isn't necessarily one less than now: consider (a(b)c(d(e)f)g). When group 3 ends, after the f), the new highest active register is 1. */ unsigned char r = *p - 1; while (r > 0 && !IS_ACTIVE (reg_info[r])) r--; /* If we end up at register zero, that means that we saved the registers as the result of an `on_failure_jump', not a `start_memory', and we jumped to past the innermost `stop_memory'. For example, in ((.)*) we save registers 1 and 2 as a result of the *, but when we pop back to the second ), we are at the stop_memory 1. Thus, nothing is active. */ if (r == 0) { lowest_active_reg = NO_LOWEST_ACTIVE_REG; highest_active_reg = NO_HIGHEST_ACTIVE_REG; } else highest_active_reg = r; } /* If just failed to match something this time around with a group that's operated on by a repetition operator, try to force exit from the ``loop'', and restore the register information for this group that we had before trying this last match. */ if ((!MATCHED_SOMETHING (reg_info[*p]) || (re_opcode_t) p[-3] == start_memory) && (p + 2) < pend) { boolean is_a_jump_n = false; p1 = p + 2; mcnt = 0; switch ((re_opcode_t) *p1++) { case jump_n: is_a_jump_n = true; case pop_failure_jump: case maybe_pop_jump: case jump: case dummy_failure_jump: EXTRACT_NUMBER_AND_INCR (mcnt, p1); if (is_a_jump_n) p1 += 2; break; default: /* do nothing */ ; } p1 += mcnt; /* If the next operation is a jump backwards in the pattern to an on_failure_jump right before the start_memory corresponding to this stop_memory, exit from the loop by forcing a failure after pushing on the stack the on_failure_jump's jump in the pattern, and d. */ if (mcnt < 0 && (re_opcode_t) *p1 == on_failure_jump && (re_opcode_t) p1[3] == start_memory && p1[4] == *p) { /* If this group ever matched anything, then restore what its registers were before trying this last failed match, e.g., with `(a*)*b' against `ab' for regstart[1], and, e.g., with `((a*)*(b*)*)*' against `aba' for regend[3]. Also restore the registers for inner groups for, e.g., `((a*)(b*))*' against `aba' (register 3 would otherwise get trashed). */ if (EVER_MATCHED_SOMETHING (reg_info[*p])) { unsigned r; EVER_MATCHED_SOMETHING (reg_info[*p]) = 0; /* Restore this and inner groups' (if any) registers. */ for (r = *p; r < *p + *(p + 1); r++) { regstart[r] = old_regstart[r]; /* xx why this test? */ if ((int) old_regend[r] >= (int) regstart[r]) regend[r] = old_regend[r]; } } p1++; EXTRACT_NUMBER_AND_INCR (mcnt, p1); PUSH_FAILURE_POINT (p1 + mcnt, d, -2); goto fail; } } /* Move past the register number and the inner group count. */ p += 2; break; /* \ has been turned into a `duplicate' command which is followed by the numeric value of as the register number. */ case duplicate: { register const char *d2, *dend2; int regno = *p++; /* Get which register to match against. */ DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno); /* Can't back reference a group which we've never matched. */ if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno])) goto fail; /* Where in input to try to start matching. */ d2 = regstart[regno]; /* Where to stop matching; if both the place to start and the place to stop matching are in the same string, then set to the place to stop, otherwise, for now have to use the end of the first string. */ dend2 = ((FIRST_STRING_P (regstart[regno]) == FIRST_STRING_P (regend[regno])) ? regend[regno] : end_match_1); for (;;) { /* If necessary, advance to next segment in register contents. */ while (d2 == dend2) { if (dend2 == end_match_2) break; if (dend2 == regend[regno]) break; /* End of string1 => advance to string2. */ d2 = string2; dend2 = regend[regno]; } /* At end of register contents => success */ if (d2 == dend2) break; /* If necessary, advance to next segment in data. */ PREFETCH (); /* How many characters left in this segment to match. */ mcnt = dend - d; /* Want how many consecutive characters we can match in one shot, so, if necessary, adjust the count. */ if (mcnt > dend2 - d2) mcnt = dend2 - d2; /* Compare that many; failure if mismatch, else move past them. */ if (translate ? bcmp_translate (d, d2, mcnt, translate) : bcmp (d, d2, mcnt)) goto fail; d += mcnt, d2 += mcnt; } } break; /* begline matches the empty string at the beginning of the string (unless `not_bol' is set in `bufp'), and, if `newline_anchor' is set, after newlines. */ case begline: DEBUG_PRINT1 ("EXECUTING begline.\n"); if (AT_STRINGS_BEG (d)) { if (!bufp->not_bol) break; } else if (d[-1] == '\n' && bufp->newline_anchor) { break; } /* In all other cases, we fail. */ goto fail; /* endline is the dual of begline. */ case endline: DEBUG_PRINT1 ("EXECUTING endline.\n"); if (AT_STRINGS_END (d)) { if (!bufp->not_eol) break; } /* We have to ``prefetch'' the next character. */ else if ((d == end1 ? *string2 : *d) == '\n' && bufp->newline_anchor) { break; } goto fail; /* Match at the very beginning of the data. */ case begbuf: DEBUG_PRINT1 ("EXECUTING begbuf.\n"); if (AT_STRINGS_BEG (d)) break; goto fail; /* Match at the very end of the data. */ case endbuf: DEBUG_PRINT1 ("EXECUTING endbuf.\n"); if (AT_STRINGS_END (d)) break; goto fail; /* on_failure_keep_string_jump is used to optimize `.*\n'. It pushes NULL as the value for the string on the stack. Then `pop_failure_point' will keep the current value for the string, instead of restoring it. To see why, consider matching `foo\nbar' against `.*\n'. The .* matches the foo; then the . fails against the \n. But the next thing we want to do is match the \n against the \n; if we restored the string value, we would be back at the foo. Because this is used only in specific cases, we don't need to check all the things that `on_failure_jump' does, to make sure the right things get saved on the stack. Hence we don't share its code. The only reason to push anything on the stack at all is that otherwise we would have to change `anychar's code to do something besides goto fail in this case; that seems worse than this. */ case on_failure_keep_string_jump: DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump"); EXTRACT_NUMBER_AND_INCR (mcnt, p); DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt); PUSH_FAILURE_POINT (p + mcnt, NULL, -2); break; /* Uses of on_failure_jump: Each alternative starts with an on_failure_jump that points to the beginning of the next alternative. Each alternative except the last ends with a jump that in effect jumps past the rest of the alternatives. (They really jump to the ending jump of the following alternative, because tensioning these jumps is a hassle.) Repeats start with an on_failure_jump that points past both the repetition text and either the following jump or pop_failure_jump back to this on_failure_jump. */ case on_failure_jump: on_failure: DEBUG_PRINT1 ("EXECUTING on_failure_jump"); EXTRACT_NUMBER_AND_INCR (mcnt, p); DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt); /* If this on_failure_jump comes right before a group (i.e., the original * applied to a group), save the information for that group and all inner ones, so that if we fail back to this point, the group's information will be correct. For example, in \(a*\)*\1, we need the preceding group, and in \(\(a*\)b*\)\2, we need the inner group. */ /* We can't use `p' to check ahead because we push a failure point to `p + mcnt' after we do this. */ p1 = p; /* We need to skip no_op's before we look for the start_memory in case this on_failure_jump is happening as the result of a completed succeed_n, as in \(a\)\{1,3\}b\1 against aba. */ while (p1 < pend && (re_opcode_t) *p1 == no_op) p1++; if (p1 < pend && (re_opcode_t) *p1 == start_memory) { /* We have a new highest active register now. This will get reset at the start_memory we are about to get to, but we will have saved all the registers relevant to this repetition op, as described above. */ highest_active_reg = *(p1 + 1) + *(p1 + 2); if (lowest_active_reg == NO_LOWEST_ACTIVE_REG) lowest_active_reg = *(p1 + 1); } DEBUG_PRINT1 (":\n"); PUSH_FAILURE_POINT (p + mcnt, d, -2); break; /* A smart repeat ends with `maybe_pop_jump'. We change it to either `pop_failure_jump' or `jump'. */ case maybe_pop_jump: EXTRACT_NUMBER_AND_INCR (mcnt, p); DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt); { register unsigned char *p2 = p; /* Compare the beginning of the repeat with what in the pattern follows its end. If we can establish that there is nothing that they would both match, i.e., that we would have to backtrack because of (as in, e.g., `a*a') then we can change to pop_failure_jump, because we'll never have to backtrack. This is not true in the case of alternatives: in `(a|ab)*' we do need to backtrack to the `ab' alternative (e.g., if the string was `ab'). But instead of trying to detect that here, the alternative has put on a dummy failure point which is what we will end up popping. */ /* Skip over open/close-group commands. */ while (p2 + 2 < pend && ((re_opcode_t) *p2 == stop_memory || (re_opcode_t) *p2 == start_memory)) p2 += 3; /* Skip over args, too. */ /* If we're at the end of the pattern, we can change. */ if (p2 == pend) { /* Consider what happens when matching ":\(.*\)" against ":/". I don't really understand this code yet. */ p[-3] = (unsigned char) pop_failure_jump; DEBUG_PRINT1 (" End of pattern: change to `pop_failure_jump'.\n"); } else if ((re_opcode_t) *p2 == exactn || (bufp->newline_anchor && (re_opcode_t) *p2 == endline)) { register unsigned char c = *p2 == (unsigned char) endline ? '\n' : p2[2]; p1 = p + mcnt; /* p1[0] ... p1[2] are the `on_failure_jump' corresponding to the `maybe_finalize_jump' of this case. Examine what follows. */ if ((re_opcode_t) p1[3] == exactn && p1[5] != c) { p[-3] = (unsigned char) pop_failure_jump; DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n", c, p1[5]); } else if ((re_opcode_t) p1[3] == charset || (re_opcode_t) p1[3] == charset_not) { int not = (re_opcode_t) p1[3] == charset_not; if (c < (unsigned char) (p1[4] * BYTEWIDTH) && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH))) not = !not; /* `not' is equal to 1 if c would match, which means that we can't change to pop_failure_jump. */ if (!not) { p[-3] = (unsigned char) pop_failure_jump; DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); } } } } p -= 2; /* Point at relative address again. */ if ((re_opcode_t) p[-1] != pop_failure_jump) { p[-1] = (unsigned char) jump; DEBUG_PRINT1 (" Match => jump.\n"); goto unconditional_jump; } /* Note fall through. */ /* The end of a simple repeat has a pop_failure_jump back to its matching on_failure_jump, where the latter will push a failure point. The pop_failure_jump takes off failure points put on by this pop_failure_jump's matching on_failure_jump; we got through the pattern to here from the matching on_failure_jump, so didn't fail. */ case pop_failure_jump: { /* We need to pass separate storage for the lowest and highest registers, even though we don't care about the actual values. Otherwise, we will restore only one register from the stack, since lowest will == highest in `pop_failure_point'. */ unsigned dummy_low_reg, dummy_high_reg; unsigned char *pdummy; const char *sdummy; DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n"); POP_FAILURE_POINT (sdummy, pdummy, dummy_low_reg, dummy_high_reg, reg_dummy, reg_dummy, reg_info_dummy); } /* Note fall through. */ /* Unconditionally jump (without popping any failure points). */ case jump: unconditional_jump: EXTRACT_NUMBER_AND_INCR (mcnt, p); /* Get the amount to jump. */ DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt); p += mcnt; /* Do the jump. */ DEBUG_PRINT2 ("(to 0x%x).\n", p); break; /* We need this opcode so we can detect where alternatives end in `group_match_null_string_p' et al. */ case jump_past_alt: DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n"); goto unconditional_jump; /* Normally, the on_failure_jump pushes a failure point, which then gets popped at pop_failure_jump. We will end up at pop_failure_jump, also, and with a pattern of, say, `a+', we are skipping over the on_failure_jump, so we have to push something meaningless for pop_failure_jump to pop. */ case dummy_failure_jump: DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n"); /* It doesn't matter what we push for the string here. What the code at `fail' tests is the value for the pattern. */ PUSH_FAILURE_POINT (0, 0, -2); goto unconditional_jump; /* At the end of an alternative, we need to push a dummy failure point in case we are followed by a `pop_failure_jump', because we don't want the failure point for the alternative to be popped. For example, matching `(a|ab)*' against `aab' requires that we match the `ab' alternative. */ case push_dummy_failure: DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n"); /* See comments just above at `dummy_failure_jump' about the two zeroes. */ PUSH_FAILURE_POINT (0, 0, -2); break; /* Have to succeed matching what follows at least n times. After that, handle like `on_failure_jump'. */ case succeed_n: EXTRACT_NUMBER (mcnt, p + 2); DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt); assert (mcnt >= 0); /* Originally, this is how many times we HAVE to succeed. */ if (mcnt > 0) { mcnt--; p += 2; STORE_NUMBER_AND_INCR (p, mcnt); DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p, mcnt); } else if (mcnt == 0) { DEBUG_PRINT2 (" Setting two bytes from 0x%x to no_op.\n", p+2); p[2] = (unsigned char) no_op; p[3] = (unsigned char) no_op; goto on_failure; } break; case jump_n: EXTRACT_NUMBER (mcnt, p + 2); DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt); /* Originally, this is how many times we CAN jump. */ if (mcnt) { mcnt--; STORE_NUMBER (p + 2, mcnt); goto unconditional_jump; } /* If don't have to jump any more, skip over the rest of command. */ else p += 4; break; case set_number_at: { DEBUG_PRINT1 ("EXECUTING set_number_at.\n"); EXTRACT_NUMBER_AND_INCR (mcnt, p); p1 = p + mcnt; EXTRACT_NUMBER_AND_INCR (mcnt, p); DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p1, mcnt); STORE_NUMBER (p1, mcnt); break; } case wordbound: DEBUG_PRINT1 ("EXECUTING wordbound.\n"); if (AT_WORD_BOUNDARY (d)) break; goto fail; case notwordbound: DEBUG_PRINT1 ("EXECUTING notwordbound.\n"); if (AT_WORD_BOUNDARY (d)) goto fail; break; case wordbeg: DEBUG_PRINT1 ("EXECUTING wordbeg.\n"); if (WORDCHAR_P (d) && (AT_STRINGS_BEG (d) || !WORDCHAR_P (d - 1))) break; goto fail; case wordend: DEBUG_PRINT1 ("EXECUTING wordend.\n"); if (!AT_STRINGS_BEG (d) && WORDCHAR_P (d - 1) && (!WORDCHAR_P (d) || AT_STRINGS_END (d))) break; goto fail; #ifdef emacs #ifdef emacs19 case before_dot: DEBUG_PRINT1 ("EXECUTING before_dot.\n"); if (PTR_CHAR_POS ((unsigned char *) d) >= point) goto fail; break; case at_dot: DEBUG_PRINT1 ("EXECUTING at_dot.\n"); if (PTR_CHAR_POS ((unsigned char *) d) != point) goto fail; break; case after_dot: DEBUG_PRINT1 ("EXECUTING after_dot.\n"); if (PTR_CHAR_POS ((unsigned char *) d) <= point) goto fail; break; #else /* not emacs19 */ case at_dot: DEBUG_PRINT1 ("EXECUTING at_dot.\n"); if (PTR_CHAR_POS ((unsigned char *) d) + 1 != point) goto fail; break; #endif /* not emacs19 */ case syntaxspec: DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt); mcnt = *p++; goto matchsyntax; case wordchar: DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n"); mcnt = (int) Sword; matchsyntax: PREFETCH (); if (SYNTAX (*d++) != (enum syntaxcode) mcnt) goto fail; SET_REGS_MATCHED (); break; case notsyntaxspec: DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt); mcnt = *p++; goto matchnotsyntax; case notwordchar: DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n"); mcnt = (int) Sword; matchnotsyntax: PREFETCH (); if (SYNTAX (*d++) == (enum syntaxcode) mcnt) goto fail; SET_REGS_MATCHED (); break; #else /* not emacs */ case wordchar: DEBUG_PRINT1 ("EXECUTING non-Emacs wordchar.\n"); PREFETCH (); if (!WORDCHAR_P (d)) goto fail; SET_REGS_MATCHED (); d++; break; case notwordchar: DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n"); PREFETCH (); if (WORDCHAR_P (d)) goto fail; SET_REGS_MATCHED (); d++; break; #endif /* not emacs */ default: abort (); } continue; /* Successfully executed one pattern command; keep going. */ /* We goto here if a matching operation fails. */ fail: if (!FAIL_STACK_EMPTY ()) { /* A restart point is known. Restore to that state. */ DEBUG_PRINT1 ("\nFAIL:\n"); POP_FAILURE_POINT (d, p, lowest_active_reg, highest_active_reg, regstart, regend, reg_info); /* If this failure point is a dummy, try the next one. */ if (!p) goto fail; /* If we failed to the end of the pattern, don't examine *p. */ assert (p <= pend); if (p < pend) { boolean is_a_jump_n = false; /* If failed to a backwards jump that's part of a repetition loop, need to pop this failure point and use the next one. */ switch ((re_opcode_t) *p) { case jump_n: is_a_jump_n = true; case maybe_pop_jump: case pop_failure_jump: case jump: p1 = p + 1; EXTRACT_NUMBER_AND_INCR (mcnt, p1); p1 += mcnt; if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n) || (!is_a_jump_n && (re_opcode_t) *p1 == on_failure_jump)) goto fail; break; default: /* do nothing */ ; } } if (d >= string1 && d <= end1) dend = end_match_1; } else break; /* Matching at this starting point really fails. */ } /* for (;;) */ if (best_regs_set) goto restore_best_regs; FREE_VARIABLES (); return -1; /* Failure to match. */ } /* re_match_2 */ /* Subroutine definitions for re_match_2. */ /* We are passed P pointing to a register number after a start_memory. Return true if the pattern up to the corresponding stop_memory can match the empty string, and false otherwise. If we find the matching stop_memory, sets P to point to one past its number. Otherwise, sets P to an undefined byte less than or equal to END. We don't handle duplicates properly (yet). */ static boolean group_match_null_string_p (p, end, reg_info) unsigned char **p, *end; register_info_type *reg_info; { int mcnt; /* Point to after the args to the start_memory. */ unsigned char *p1 = *p + 2; while (p1 < end) { /* Skip over opcodes that can match nothing, and return true or false, as appropriate, when we get to one that can't, or to the matching stop_memory. */ switch ((re_opcode_t) *p1) { /* Could be either a loop or a series of alternatives. */ case on_failure_jump: p1++; EXTRACT_NUMBER_AND_INCR (mcnt, p1); /* If the next operation is not a jump backwards in the pattern. */ if (mcnt >= 0) { /* Go through the on_failure_jumps of the alternatives, seeing if any of the alternatives cannot match nothing. The last alternative starts with only a jump, whereas the rest start with on_failure_jump and end with a jump, e.g., here is the pattern for `a|b|c': /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6 /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3 /exactn/1/c So, we have to first go through the first (n-1) alternatives and then deal with the last one separately. */ /* Deal with the first (n-1) alternatives, which start with an on_failure_jump (see above) that jumps to right past a jump_past_alt. */ while ((re_opcode_t) p1[mcnt-3] == jump_past_alt) { /* `mcnt' holds how many bytes long the alternative is, including the ending `jump_past_alt' and its number. */ if (!alt_match_null_string_p (p1, p1 + mcnt - 3, reg_info)) return false; /* Move to right after this alternative, including the jump_past_alt. */ p1 += mcnt; /* Break if it's the beginning of an n-th alternative that doesn't begin with an on_failure_jump. */ if ((re_opcode_t) *p1 != on_failure_jump) break; /* Still have to check that it's not an n-th alternative that starts with an on_failure_jump. */ p1++; EXTRACT_NUMBER_AND_INCR (mcnt, p1); if ((re_opcode_t) p1[mcnt-3] != jump_past_alt) { /* Get to the beginning of the n-th alternative. */ p1 -= 3; break; } } /* Deal with the last alternative: go back and get number of the `jump_past_alt' just before it. `mcnt' contains the length of the alternative. */ EXTRACT_NUMBER (mcnt, p1 - 2); if (!alt_match_null_string_p (p1, p1 + mcnt, reg_info)) return false; p1 += mcnt; /* Get past the n-th alternative. */ } /* if mcnt > 0 */ break; case stop_memory: assert (p1[1] == **p); *p = p1 + 2; return true; default: if (!common_op_match_null_string_p (&p1, end, reg_info)) return false; } } /* while p1 < end */ return false; } /* group_match_null_string_p */ /* Similar to group_match_null_string_p, but doesn't deal with alternatives: It expects P to be the first byte of a single alternative and END one byte past the last. The alternative can contain groups. */ static boolean alt_match_null_string_p (p, end, reg_info) unsigned char *p, *end; register_info_type *reg_info; { int mcnt; unsigned char *p1 = p; while (p1 < end) { /* Skip over opcodes that can match nothing, and break when we get to one that can't. */ switch ((re_opcode_t) *p1) { /* It's a loop. */ case on_failure_jump: p1++; EXTRACT_NUMBER_AND_INCR (mcnt, p1); p1 += mcnt; break; default: if (!common_op_match_null_string_p (&p1, end, reg_info)) return false; } } /* while p1 < end */ return true; } /* alt_match_null_string_p */ /* Deals with the ops common to group_match_null_string_p and alt_match_null_string_p. Sets P to one after the op and its arguments, if any. */ static boolean common_op_match_null_string_p (p, end, reg_info) unsigned char **p, *end; register_info_type *reg_info; { int mcnt; boolean ret; int reg_no; unsigned char *p1 = *p; switch ((re_opcode_t) *p1++) { case no_op: case begline: case endline: case begbuf: case endbuf: case wordbeg: case wordend: case wordbound: case notwordbound: #ifdef emacs case before_dot: case at_dot: case after_dot: #endif break; case start_memory: reg_no = *p1; assert (reg_no > 0 && reg_no <= MAX_REGNUM); ret = group_match_null_string_p (&p1, end, reg_info); /* Have to set this here in case we're checking a group which contains a group and a back reference to it. */ if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE) REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret; if (!ret) return false; break; /* If this is an optimized succeed_n for zero times, make the jump. */ case jump: EXTRACT_NUMBER_AND_INCR (mcnt, p1); if (mcnt >= 0) p1 += mcnt; else return false; break; case succeed_n: /* Get to the number of times to succeed. */ p1 += 2; EXTRACT_NUMBER_AND_INCR (mcnt, p1); if (mcnt == 0) { p1 -= 4; EXTRACT_NUMBER_AND_INCR (mcnt, p1); p1 += mcnt; } else return false; break; case duplicate: if (!REG_MATCH_NULL_STRING_P (reg_info[*p1])) return false; break; case set_number_at: p1 += 4; default: /* All other opcodes mean we cannot match the empty string. */ return false; } *p = p1; return true; } /* common_op_match_null_string_p */ /* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN bytes; nonzero otherwise. */ static int bcmp_translate (s1, s2, len, translate) unsigned char *s1, *s2; register int len; char *translate; { register unsigned char *p1 = s1, *p2 = s2; while (len) { if (translate[*p1++] != translate[*p2++]) return 1; len--; } return 0; } /* Entry points for GNU code. */ /* re_compile_pattern is the GNU regular expression compiler: it compiles PATTERN (of length SIZE) and puts the result in BUFP. Returns 0 if the pattern was valid, otherwise an error string. Assumes the `allocated' (and perhaps `buffer') and `translate' fields are set in BUFP on entry. We call regex_compile to do the actual compilation. */ const char * re_compile_pattern (pattern, length, bufp) const char *pattern; int length; struct re_pattern_buffer *bufp; { reg_errcode_t ret; /* GNU code is written to assume at least RE_NREGS registers will be set (and at least one extra will be -1). */ bufp->regs_allocated = REGS_UNALLOCATED; /* And GNU code determines whether or not to get register information by passing null for the REGS argument to re_match, etc., not by setting no_sub. */ bufp->no_sub = 0; /* Match anchors at newline. */ bufp->newline_anchor = 1; ret = regex_compile (pattern, length, re_syntax_options, bufp); return re_error_msg[(int) ret]; } /* Entry points compatible with 4.2 BSD regex library. We don't define them if this is an Emacs or POSIX compilation. */ #if !defined (emacs) && !defined (_POSIX_SOURCE) /* BSD has one and only one pattern buffer. */ static struct re_pattern_buffer re_comp_buf; char * re_comp (s) const char *s; { reg_errcode_t ret; if (!s) { if (!re_comp_buf.buffer) return "No previous regular expression"; return 0; } if (!re_comp_buf.buffer) { re_comp_buf.buffer = (unsigned char *) malloc (200); if (re_comp_buf.buffer == NULL) return "Memory exhausted"; re_comp_buf.allocated = 200; re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH); if (re_comp_buf.fastmap == NULL) return "Memory exhausted"; } /* Since `re_exec' always passes NULL for the `regs' argument, we don't need to initialize the pattern buffer fields which affect it. */ /* Match anchors at newlines. */ re_comp_buf.newline_anchor = 1; ret = regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf); /* Yes, we're discarding `const' here. */ return (char *) re_error_msg[(int) ret]; } int re_exec (s) const char *s; { const int len = strlen (s); return 0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0); } #endif /* not emacs and not _POSIX_SOURCE */ /* POSIX.2 functions. Don't define these for Emacs. */ #ifndef emacs /* regcomp takes a regular expression as a string and compiles it. PREG is a regex_t *. We do not expect any fields to be initialized, since POSIX says we shouldn't. Thus, we set `buffer' to the compiled pattern; `used' to the length of the compiled pattern; `syntax' to RE_SYNTAX_POSIX_EXTENDED if the REG_EXTENDED bit in CFLAGS is set; otherwise, to RE_SYNTAX_POSIX_BASIC; `newline_anchor' to REG_NEWLINE being set in CFLAGS; `fastmap' and `fastmap_accurate' to zero; `re_nsub' to the number of subexpressions in PATTERN. PATTERN is the address of the pattern string. CFLAGS is a series of bits which affect compilation. If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we use POSIX basic syntax. If REG_NEWLINE is set, then . and [^...] don't match newline. Also, regexec will try a match beginning after every newline. If REG_ICASE is set, then we considers upper- and lowercase versions of letters to be equivalent when matching. If REG_NOSUB is set, then when PREG is passed to regexec, that routine will report only success or failure, and nothing about the registers. It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for the return codes and their meanings.) */ int regcomp (preg, pattern, cflags) regex_t *preg; const char *pattern; int cflags; { reg_errcode_t ret; unsigned syntax = (cflags & REG_EXTENDED) ? RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC; /* regex_compile will allocate the space for the compiled pattern. */ preg->buffer = 0; preg->allocated = 0; /* Don't bother to use a fastmap when searching. This simplifies the REG_NEWLINE case: if we used a fastmap, we'd have to put all the characters after newlines into the fastmap. This way, we just try every character. */ preg->fastmap = 0; if (cflags & REG_ICASE) { unsigned i; preg->translate = (char *) malloc (CHAR_SET_SIZE); if (preg->translate == NULL) return (int) REG_ESPACE; /* Map uppercase characters to corresponding lowercase ones. */ for (i = 0; i < CHAR_SET_SIZE; i++) preg->translate[i] = ISUPPER (i) ? tolower (i) : i; } else preg->translate = NULL; /* If REG_NEWLINE is set, newlines are treated differently. */ if (cflags & REG_NEWLINE) { /* REG_NEWLINE implies neither . nor [^...] match newline. */ syntax &= ~RE_DOT_NEWLINE; syntax |= RE_HAT_LISTS_NOT_NEWLINE; /* It also changes the matching behavior. */ preg->newline_anchor = 1; } else preg->newline_anchor = 0; preg->no_sub = !!(cflags & REG_NOSUB); /* POSIX says a null character in the pattern terminates it, so we can use strlen here in compiling the pattern. */ ret = regex_compile (pattern, strlen (pattern), syntax, preg); /* POSIX doesn't distinguish between an unmatched open-group and an unmatched close-group: both are REG_EPAREN. */ if (ret == REG_ERPAREN) ret = REG_EPAREN; return (int) ret; } /* regexec searches for a given pattern, specified by PREG, in the string STRING. If NMATCH is zero or REG_NOSUB was set in the cflags argument to `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at least NMATCH elements, and we set them to the offsets of the corresponding matched substrings. EFLAGS specifies `execution flags' which affect matching: if REG_NOTBOL is set, then ^ does not match at the beginning of the string; if REG_NOTEOL is set, then $ does not match at the end. We return 0 if we find a match and REG_NOMATCH if not. */ int regexec (preg, string, nmatch, pmatch, eflags) const regex_t *preg; const char *string; size_t nmatch; regmatch_t pmatch[]; int eflags; { int ret; struct re_registers regs; regex_t private_preg; int len = strlen (string); boolean want_reg_info = !preg->no_sub && nmatch > 0; private_preg = *preg; private_preg.not_bol = !!(eflags & REG_NOTBOL); private_preg.not_eol = !!(eflags & REG_NOTEOL); /* The user has told us exactly how many registers to return information about, via `nmatch'. We have to pass that on to the matching routines. */ private_preg.regs_allocated = REGS_FIXED; if (want_reg_info) { regs.num_regs = nmatch; regs.start = TALLOC (nmatch, regoff_t); regs.end = TALLOC (nmatch, regoff_t); if (regs.start == NULL || regs.end == NULL) return (int) REG_NOMATCH; } /* Perform the searching operation. */ ret = re_search (&private_preg, string, len, /* start: */ 0, /* range: */ len, want_reg_info ? ®s : (struct re_registers *) 0); /* Copy the register information to the POSIX structure. */ if (want_reg_info) { if (ret >= 0) { unsigned r; for (r = 0; r < nmatch; r++) { pmatch[r].rm_so = regs.start[r]; pmatch[r].rm_eo = regs.end[r]; } } /* If we needed the temporary register info, free the space now. */ free (regs.start); free (regs.end); } /* We want zero return to mean success, unlike `re_search'. */ return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH; } /* Returns a message corresponding to an error code, ERRCODE, returned from either regcomp or regexec. We don't use PREG here. */ size_t regerror (errcode, preg, errbuf, errbuf_size) int errcode; const regex_t *preg; char *errbuf; size_t errbuf_size; { const char *msg; size_t msg_size; if (errcode < 0 || errcode >= (sizeof (re_error_msg) / sizeof (re_error_msg[0]))) /* Only error codes returned by the rest of the code should be passed to this routine. If we are given anything else, or if other regex code generates an invalid error code, then the program has a bug. Dump core so we can fix it. */ abort (); msg = re_error_msg[errcode]; /* POSIX doesn't require that we do anything in this case, but why not be nice. */ if (! msg) msg = "Success"; msg_size = strlen (msg) + 1; /* Includes the null. */ if (errbuf_size != 0) { if (msg_size > errbuf_size) { strncpy (errbuf, msg, errbuf_size - 1); errbuf[errbuf_size - 1] = 0; } else strcpy (errbuf, msg); } return msg_size; } /* Free dynamically allocated space used by PREG. */ void regfree (preg) regex_t *preg; { if (preg->buffer != NULL) free (preg->buffer); preg->buffer = NULL; preg->allocated = 0; preg->used = 0; if (preg->fastmap != NULL) free (preg->fastmap); preg->fastmap = NULL; preg->fastmap_accurate = 0; if (preg->translate != NULL) free (preg->translate); preg->translate = NULL; } #endif /* not emacs */ /* Local variables: make-backup-files: t version-control: t trim-versions-without-asking: nil End: */ lyskom-server-2.1.2/src/libraries/regex/regex.h0000664000015100472110000004441605533104375015173 /* Definitions for data structures and routines for the regular expression library, version 0.12. Copyright (C) 1985, 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. 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 2, 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, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __REGEXP_LIBRARY_H__ #define __REGEXP_LIBRARY_H__ /* POSIX says that must be included (by the caller) before . */ #ifdef VMS /* VMS doesn't have `size_t' in , even though POSIX says it should be there. */ #include #endif /* The following bits are used to determine the regexp syntax we recognize. The set/not-set meanings are chosen so that Emacs syntax remains the value 0. The bits are given in alphabetical order, and the definitions shifted by one from the previous bit; thus, when we add or remove a bit, only one other definition need change. */ typedef unsigned reg_syntax_t; /* If this bit is not set, then \ inside a bracket expression is literal. If set, then such a \ quotes the following character. */ #define RE_BACKSLASH_ESCAPE_IN_LISTS (1) /* If this bit is not set, then + and ? are operators, and \+ and \? are literals. If set, then \+ and \? are operators and + and ? are literals. */ #define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1) /* If this bit is set, then character classes are supported. They are: [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:], [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:]. If not set, then character classes are not supported. */ #define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1) /* If this bit is set, then ^ and $ are always anchors (outside bracket expressions, of course). If this bit is not set, then it depends: ^ is an anchor if it is at the beginning of a regular expression or after an open-group or an alternation operator; $ is an anchor if it is at the end of a regular expression, or before a close-group or an alternation operator. This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because POSIX draft 11.2 says that * etc. in leading positions is undefined. We already implemented a previous draft which made those constructs invalid, though, so we haven't changed the code back. */ #define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1) /* If this bit is set, then special characters are always special regardless of where they are in the pattern. If this bit is not set, then special characters are special only in some contexts; otherwise they are ordinary. Specifically, * + ? and intervals are only special when not after the beginning, open-group, or alternation operator. */ #define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1) /* If this bit is set, then *, +, ?, and { cannot be first in an re or immediately after an alternation or begin-group operator. */ #define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1) /* If this bit is set, then . matches newline. If not set, then it doesn't. */ #define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1) /* If this bit is set, then . doesn't match NUL. If not set, then it does. */ #define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1) /* If this bit is set, nonmatching lists [^...] do not match newline. If not set, they do. */ #define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1) /* If this bit is set, either \{...\} or {...} defines an interval, depending on RE_NO_BK_BRACES. If not set, \{, \}, {, and } are literals. */ #define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1) /* If this bit is set, +, ? and | aren't recognized as operators. If not set, they are. */ #define RE_LIMITED_OPS (RE_INTERVALS << 1) /* If this bit is set, newline is an alternation operator. If not set, newline is literal. */ #define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1) /* If this bit is set, then `{...}' defines an interval, and \{ and \} are literals. If not set, then `\{...\}' defines an interval. */ #define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1) /* If this bit is set, (...) defines a group, and \( and \) are literals. If not set, \(...\) defines a group, and ( and ) are literals. */ #define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1) /* If this bit is set, then \ matches . If not set, then \ is a back-reference. */ #define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1) /* If this bit is set, then | is an alternation operator, and \| is literal. If not set, then \| is an alternation operator, and | is literal. */ #define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1) /* If this bit is set, then an ending range point collating higher than the starting range point, as in [z-a], is invalid. If not set, then when ending range point collates higher than the starting range point, the range is ignored. */ #define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1) /* If this bit is set, then an unmatched ) is ordinary. If not set, then an unmatched ) is invalid. */ #define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1) /* This global variable defines the particular regexp syntax to use (for some interfaces). When a regexp is compiled, the syntax used is stored in the pattern buffer, so changing this does not affect already-compiled regexps. */ extern reg_syntax_t re_syntax_options; /* Define combinations of the above bits for the standard possibilities. (The [[[ comments delimit what gets put into the Texinfo file, so don't delete them!) */ /* [[[begin syntaxes]]] */ #define RE_SYNTAX_EMACS 0 #define RE_SYNTAX_AWK \ (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \ | RE_NO_BK_PARENS | RE_NO_BK_REFS \ | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \ | RE_UNMATCHED_RIGHT_PAREN_ORD) #define RE_SYNTAX_POSIX_AWK \ (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS) #define RE_SYNTAX_GREP \ (RE_BK_PLUS_QM | RE_CHAR_CLASSES \ | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \ | RE_NEWLINE_ALT) #define RE_SYNTAX_EGREP \ (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \ | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \ | RE_NEWLINE_ALT | RE_NO_BK_PARENS \ | RE_NO_BK_VBAR) #define RE_SYNTAX_POSIX_EGREP \ (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES) /* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */ #define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC #define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC /* Syntax bits common to both basic and extended POSIX regex syntax. */ #define _RE_SYNTAX_POSIX_COMMON \ (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \ | RE_INTERVALS | RE_NO_EMPTY_RANGES) #define RE_SYNTAX_POSIX_BASIC \ (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM) /* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this isn't minimal, since other operators, such as \`, aren't disabled. */ #define RE_SYNTAX_POSIX_MINIMAL_BASIC \ (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS) #define RE_SYNTAX_POSIX_EXTENDED \ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \ | RE_NO_BK_PARENS | RE_NO_BK_VBAR \ | RE_UNMATCHED_RIGHT_PAREN_ORD) /* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */ #define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \ | RE_NO_BK_PARENS | RE_NO_BK_REFS \ | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD) /* [[[end syntaxes]]] */ /* Maximum number of duplicates an interval can allow. Some systems (erroneously) define this in other header files, but we want our value, so remove any previous define. */ #ifdef RE_DUP_MAX #undef RE_DUP_MAX #endif #define RE_DUP_MAX ((1 << 15) - 1) /* POSIX `cflags' bits (i.e., information for `regcomp'). */ /* If this bit is set, then use extended regular expression syntax. If not set, then use basic regular expression syntax. */ #define REG_EXTENDED 1 /* If this bit is set, then ignore case when matching. If not set, then case is significant. */ #define REG_ICASE (REG_EXTENDED << 1) /* If this bit is set, then anchors do not match at newline characters in the string. If not set, then anchors do match at newlines. */ #define REG_NEWLINE (REG_ICASE << 1) /* If this bit is set, then report only success or fail in regexec. If not set, then returns differ between not matching and errors. */ #define REG_NOSUB (REG_NEWLINE << 1) /* POSIX `eflags' bits (i.e., information for regexec). */ /* If this bit is set, then the beginning-of-line operator doesn't match the beginning of the string (presumably because it's not the beginning of a line). If not set, then the beginning-of-line operator does match the beginning of the string. */ #define REG_NOTBOL 1 /* Like REG_NOTBOL, except for the end-of-line. */ #define REG_NOTEOL (1 << 1) /* If any error codes are removed, changed, or added, update the `re_error_msg' table in regex.c. */ typedef enum { REG_NOERROR = 0, /* Success. */ REG_NOMATCH, /* Didn't find a match (for regexec). */ /* POSIX regcomp return error codes. (In the order listed in the standard.) */ REG_BADPAT, /* Invalid pattern. */ REG_ECOLLATE, /* Not implemented. */ REG_ECTYPE, /* Invalid character class name. */ REG_EESCAPE, /* Trailing backslash. */ REG_ESUBREG, /* Invalid back reference. */ REG_EBRACK, /* Unmatched left bracket. */ REG_EPAREN, /* Parenthesis imbalance. */ REG_EBRACE, /* Unmatched \{. */ REG_BADBR, /* Invalid contents of \{\}. */ REG_ERANGE, /* Invalid range end. */ REG_ESPACE, /* Ran out of memory. */ REG_BADRPT, /* No preceding re for repetition op. */ /* Error codes we've added. */ REG_EEND, /* Premature end. */ REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */ REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */ } reg_errcode_t; /* This data structure represents a compiled pattern. Before calling the pattern compiler, the fields `buffer', `allocated', `fastmap', `translate', and `no_sub' can be set. After the pattern has been compiled, the `re_nsub' field is available. All other fields are private to the regex routines. */ struct re_pattern_buffer { /* [[[begin pattern_buffer]]] */ /* Space that holds the compiled pattern. It is declared as `unsigned char *' because its elements are sometimes used as array indexes. */ unsigned char *buffer; /* Number of bytes to which `buffer' points. */ unsigned long allocated; /* Number of bytes actually used in `buffer'. */ unsigned long used; /* Syntax setting with which the pattern was compiled. */ reg_syntax_t syntax; /* Pointer to a fastmap, if any, otherwise zero. re_search uses the fastmap, if there is one, to skip over impossible starting points for matches. */ char *fastmap; /* Either a translate table to apply to all characters before comparing them, or zero for no translation. The translation is applied to a pattern when it is compiled and to a string when it is matched. */ char *translate; /* Number of subexpressions found by the compiler. */ size_t re_nsub; /* Zero if this pattern cannot match the empty string, one else. Well, in truth it's used only in `re_search_2', to see whether or not we should use the fastmap, so we don't set this absolutely perfectly; see `re_compile_fastmap' (the `duplicate' case). */ unsigned can_be_null : 1; /* If REGS_UNALLOCATED, allocate space in the `regs' structure for `max (RE_NREGS, re_nsub + 1)' groups. If REGS_REALLOCATE, reallocate space if necessary. If REGS_FIXED, use what's there. */ #define REGS_UNALLOCATED 0 #define REGS_REALLOCATE 1 #define REGS_FIXED 2 unsigned regs_allocated : 2; /* Set to zero when `regex_compile' compiles a pattern; set to one by `re_compile_fastmap' if it updates the fastmap. */ unsigned fastmap_accurate : 1; /* If set, `re_match_2' does not return information about subexpressions. */ unsigned no_sub : 1; /* If set, a beginning-of-line anchor doesn't match at the beginning of the string. */ unsigned not_bol : 1; /* Similarly for an end-of-line anchor. */ unsigned not_eol : 1; /* If true, an anchor at a newline matches. */ unsigned newline_anchor : 1; /* [[[end pattern_buffer]]] */ }; typedef struct re_pattern_buffer regex_t; /* search.c (search_buffer) in Emacs needs this one opcode value. It is defined both in `regex.c' and here. */ #define RE_EXACTN_VALUE 1 /* Type for byte offsets within the string. POSIX mandates this. */ typedef int regoff_t; /* This is the structure we store register match data in. See regex.texinfo for a full description of what registers match. */ struct re_registers { unsigned num_regs; regoff_t *start; regoff_t *end; }; /* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer, `re_match_2' returns information about at least this many registers the first time a `regs' structure is passed. */ #ifndef RE_NREGS #define RE_NREGS 30 #endif /* POSIX specification for registers. Aside from the different names than `re_registers', POSIX uses an array of structures, instead of a structure of arrays. */ typedef struct { regoff_t rm_so; /* Byte offset from string's start to substring's start. */ regoff_t rm_eo; /* Byte offset from string's start to substring's end. */ } regmatch_t; /* Declarations for routines. */ /* To avoid duplicating every routine declaration -- once with a prototype (if we are ANSI), and once without (if we aren't) -- we use the following macro to declare argument types. This unfortunately clutters up the declarations a bit, but I think it's worth it. */ #if __STDC__ #define _RE_ARGS(args) args #else /* not __STDC__ */ #define _RE_ARGS(args) () #endif /* not __STDC__ */ /* Sets the current default syntax to SYNTAX, and return the old syntax. You can also simply assign to the `re_syntax_options' variable. */ extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax)); /* Compile the regular expression PATTERN, with length LENGTH and syntax given by the global `re_syntax_options', into the buffer BUFFER. Return NULL if successful, and an error string if not. */ extern const char *re_compile_pattern _RE_ARGS ((const char *pattern, int length, struct re_pattern_buffer *buffer)); /* Compile a fastmap for the compiled pattern in BUFFER; used to accelerate searches. Return 0 if successful and -2 if was an internal error. */ extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer)); /* Search in the string STRING (with length LENGTH) for the pattern compiled into BUFFER. Start searching at position START, for RANGE characters. Return the starting position of the match, -1 for no match, or -2 for an internal error. Also return register information in REGS (if REGS and BUFFER->no_sub are nonzero). */ extern int re_search _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, int length, int start, int range, struct re_registers *regs)); /* Like `re_search', but search in the concatenation of STRING1 and STRING2. Also, stop searching at index START + STOP. */ extern int re_search_2 _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, int length1, const char *string2, int length2, int start, int range, struct re_registers *regs, int stop)); /* Like `re_search', but return how many characters in STRING the regexp in BUFFER matched, starting at position START. */ extern int re_match _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, int length, int start, struct re_registers *regs)); /* Relates to `re_match' as `re_search_2' relates to `re_search'. */ extern int re_match_2 _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, int length1, const char *string2, int length2, int start, struct re_registers *regs, int stop)); /* Set REGS to hold NUM_REGS registers, storing them in STARTS and ENDS. Subsequent matches using BUFFER and REGS will use this memory for recording register information. STARTS and ENDS must be allocated with malloc, and must each be at least `NUM_REGS * sizeof (regoff_t)' bytes long. If NUM_REGS == 0, then subsequent matches should allocate their own register data. Unless this function is called, the first search or match using PATTERN_BUFFER will allocate its own register data, without freeing the old data. */ extern void re_set_registers _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs, unsigned num_regs, regoff_t *starts, regoff_t *ends)); /* 4.2 bsd compatibility. */ extern char *re_comp _RE_ARGS ((const char *)); extern int re_exec _RE_ARGS ((const char *)); /* POSIX compatibility. */ extern int regcomp _RE_ARGS ((regex_t *preg, const char *pattern, int cflags)); extern int regexec _RE_ARGS ((const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags)); extern size_t regerror _RE_ARGS ((int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)); extern void regfree _RE_ARGS ((regex_t *preg)); #endif /* not __REGEXP_LIBRARY_H__ */ /* Local variables: make-backup-files: t version-control: t trim-versions-without-asking: nil End: */ lyskom-server-2.1.2/src/libraries/regex/.cvsignore0000664000015100472110000000010006716305400015662 .deps Makefile Makefile.in *.da *.bb *.bbg *.gcov config.status lyskom-server-2.1.2/src/libraries/regex/doc/0000777000015100472110000000000007723710331014524 5lyskom-server-2.1.2/src/libraries/regex/doc/Makefile.am0000664000015100472110000000231407717413243016503 # $Id: Makefile.am,v 1.2 2003/08/16 11:29:05 ceder Exp $ # Copyright (C) 1998 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Distribute the files that are present in the regex distribution. # Nothing here gets installed et c when part of the lyskomd distribution. EXTRA_DIST = .cvsignore include.awk regex.aux regex.cps regex.info \ regex.texi texinfo.tex xregex.texi lyskom-server-2.1.2/src/libraries/regex/doc/Makefile.in0000664000015100472110000002050507723707426016524 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # $Id: Makefile.am,v 1.2 2003/08/16 11:29:05 ceder Exp $ # Copyright (C) 1998 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../../../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEBUG_CALLS = @DEBUG_CALLS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EFENCE = @EFENCE@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FLEX = @FLEX@ HAVE_PYTHON_FALSE = @HAVE_PYTHON_FALSE@ HAVE_PYTHON_TRUE = @HAVE_PYTHON_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSURE = @INSURE@ LANGUAGE_SUFFIX = @LANGUAGE_SUFFIX@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ SED = @SED@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRACED_ALLOCATIONS = @TRACED_ALLOCATIONS@ U = @U@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ YACC = @YACC@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ # Distribute the files that are present in the regex distribution. # Nothing here gets installed et c when part of the lyskomd distribution. EXTRA_DIST = .cvsignore include.awk regex.aux regex.cps regex.info \ regex.texi texinfo.tex xregex.texi subdir = src/libraries/regex/doc ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = DIST_SOURCES = DIST_COMMON = Makefile.am Makefile.in texinfo.tex all: all-am .SUFFIXES: $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/libraries/regex/doc/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) uninstall-info-am: tags: TAGS TAGS: ctags: CTAGS CTAGS: DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = ../../../.. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am info info-am install \ install-am install-data install-data-am install-exec \ install-exec-am install-info install-info-am install-man \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \ uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/src/libraries/regex/doc/texinfo.tex0000664000015100472110000037363605533104451016657 %% TeX macros to handle texinfo files % Copyright (C) 1985, 86, 88, 90, 91, 92, 1993 Free Software Foundation, Inc. %This texinfo.tex file 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 2, or (at %your option) any later version. %This texinfo.tex file 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 texinfo.tex file; see the file COPYING. If not, write %to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, %USA. %In other words, you are welcome to use, share and improve this program. %You are forbidden to forbid anyone else to use, share and improve %what you give them. Help stamp out software-hoarding! \def\texinfoversion{2.104} \message{Loading texinfo package [Version \texinfoversion]:} \message{} % Print the version number if in a .fmt file. \everyjob{\message{[Texinfo version \texinfoversion]}\message{}} % Save some parts of plain tex whose names we will redefine. \let\ptexlbrace=\{ \let\ptexrbrace=\} \let\ptexdots=\dots \let\ptexdot=\. \let\ptexstar=\* \let\ptexend=\end \let\ptexbullet=\bullet \let\ptexb=\b \let\ptexc=\c \let\ptexi=\i \let\ptext=\t \let\ptexl=\l \let\ptexL=\L \def\tie{\penalty 10000\ } % Save plain tex definition of ~. \message{Basics,} \chardef\other=12 % If this character appears in an error message or help string, it % starts a new line in the output. \newlinechar = `^^J % Ignore a token. % \def\gobble#1{} \hyphenation{ap-pen-dix} \hyphenation{mini-buf-fer mini-buf-fers} \hyphenation{eshell} % Margin to add to right of even pages, to left of odd pages. \newdimen \bindingoffset \bindingoffset=0pt \newdimen \normaloffset \normaloffset=\hoffset \newdimen\pagewidth \newdimen\pageheight \pagewidth=\hsize \pageheight=\vsize % Sometimes it is convenient to have everything in the transcript file % and nothing on the terminal. We don't just call \tracingall here, % since that produces some useless output on the terminal. % \def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% \def\loggingall{\tracingcommands2 \tracingstats2 \tracingpages1 \tracingoutput1 \tracinglostchars1 \tracingmacros2 \tracingparagraphs1 \tracingrestores1 \showboxbreadth\maxdimen\showboxdepth\maxdimen }% %---------------------Begin change----------------------- % %%%% For @cropmarks command. % Dimensions to add cropmarks at corners Added by P. A. MacKay, 12 Nov. 1986 % \newdimen\cornerlong \newdimen\cornerthick \newdimen \topandbottommargin \newdimen \outerhsize \newdimen \outervsize \cornerlong=1pc\cornerthick=.3pt % These set size of cropmarks \outerhsize=7in %\outervsize=9.5in % Alternative @smallbook page size is 9.25in \outervsize=9.25in \topandbottommargin=.75in % %---------------------End change----------------------- % \onepageout takes a vbox as an argument. Note that \pagecontents % does insertions itself, but you have to call it yourself. \chardef\PAGE=255 \output={\onepageout{\pagecontents\PAGE}} \def\onepageout#1{\hoffset=\normaloffset \ifodd\pageno \advance\hoffset by \bindingoffset \else \advance\hoffset by -\bindingoffset\fi {\escapechar=`\\\relax % makes sure backslash is used in output files. \shipout\vbox{{\let\hsize=\pagewidth \makeheadline} \pagebody{#1}% {\let\hsize=\pagewidth \makefootline}}}% \advancepageno \ifnum\outputpenalty>-20000 \else\dosupereject\fi} %%%% For @cropmarks command %%%% % Here is a modification of the main output routine for Near East Publications % This provides right-angle cropmarks at all four corners. % The contents of the page are centerlined into the cropmarks, % and any desired binding offset is added as an \hskip on either % site of the centerlined box. (P. A. MacKay, 12 November, 1986) % \def\croppageout#1{\hoffset=0pt % make sure this doesn't mess things up {\escapechar=`\\\relax % makes sure backslash is used in output files. \shipout \vbox to \outervsize{\hsize=\outerhsize \vbox{\line{\ewtop\hfill\ewtop}} \nointerlineskip \line{\vbox{\moveleft\cornerthick\nstop} \hfill \vbox{\moveright\cornerthick\nstop}} \vskip \topandbottommargin \centerline{\ifodd\pageno\hskip\bindingoffset\fi \vbox{ {\let\hsize=\pagewidth \makeheadline} \pagebody{#1} {\let\hsize=\pagewidth \makefootline}} \ifodd\pageno\else\hskip\bindingoffset\fi} \vskip \topandbottommargin plus1fill minus1fill \boxmaxdepth\cornerthick \line{\vbox{\moveleft\cornerthick\nsbot} \hfill \vbox{\moveright\cornerthick\nsbot}} \nointerlineskip \vbox{\line{\ewbot\hfill\ewbot}} }} \advancepageno \ifnum\outputpenalty>-20000 \else\dosupereject\fi} % % Do @cropmarks to get crop marks \def\cropmarks{\let\onepageout=\croppageout } \def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} {\catcode`\@ =11 \gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi \dimen@=\dp#1 \unvbox#1 \ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi \ifr@ggedbottom \kern-\dimen@ \vfil \fi} } % % Here are the rules for the cropmarks. Note that they are % offset so that the space between them is truly \outerhsize or \outervsize % (P. A. MacKay, 12 November, 1986) % \def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} \def\nstop{\vbox {\hrule height\cornerthick depth\cornerlong width\cornerthick}} \def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} \def\nsbot{\vbox {\hrule height\cornerlong depth\cornerthick width\cornerthick}} % Parse an argument, then pass it to #1. The argument is the rest of % the input line (except we remove a trailing comment). #1 should be a % macro which expects an ordinary undelimited TeX argument. % \def\parsearg#1{% \let\next = #1% \begingroup \obeylines \futurelet\temp\parseargx } % If the next token is an obeyed space (from an @example environment or % the like), remove it and recurse. Otherwise, we're done. \def\parseargx{% % \obeyedspace is defined far below, after the definition of \sepspaces. \ifx\obeyedspace\temp \expandafter\parseargdiscardspace \else \expandafter\parseargline \fi } % Remove a single space (as the delimiter token to the macro call). {\obeyspaces % \gdef\parseargdiscardspace {\futurelet\temp\parseargx}} {\obeylines % \gdef\parseargline#1^^M{% \endgroup % End of the group started in \parsearg. % % First remove any @c comment, then any @comment. % Result of each macro is put in \toks0. \argremovec #1\c\relax % \expandafter\argremovecomment \the\toks0 \comment\relax % % % Call the caller's macro, saved as \next in \parsearg. \expandafter\next\expandafter{\the\toks0}% }% } % Since all \c{,omment} does is throw away the argument, we can let TeX % do that for us. The \relax here is matched by the \relax in the call % in \parseargline; it could be more or less anything, its purpose is % just to delimit the argument to the \c. \def\argremovec#1\c#2\relax{\toks0 = {#1}} \def\argremovecomment#1\comment#2\relax{\toks0 = {#1}} % \argremovec{,omment} might leave us with trailing spaces, though; e.g., % @end itemize @c foo % will have two active spaces as part of the argument with the % `itemize'. Here we remove all active spaces from #1, and assign the % result to \toks0. % % This loses if there are any *other* active characters besides spaces % in the argument -- _ ^ +, for example -- since they get expanded. % Fortunately, Texinfo does not define any such commands. (If it ever % does, the catcode of the characters in questionwill have to be changed % here.) But this means we cannot call \removeactivespaces as part of % \argremovec{,omment}, since @c uses \parsearg, and thus the argument % that \parsearg gets might well have any character at all in it. % \def\removeactivespaces#1{% \begingroup \ignoreactivespaces \edef\temp{#1}% \global\toks0 = \expandafter{\temp}% \endgroup } % Change the active space to expand to nothing. % \begingroup \obeyspaces \gdef\ignoreactivespaces{\obeyspaces\let =\empty} \endgroup \def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} %% These are used to keep @begin/@end levels from running away %% Call \inENV within environments (after a \begingroup) \newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi} \def\ENVcheck{% \ifENV\errmessage{Still within an environment. Type Return to continue.} \endgroup\fi} % This is not perfect, but it should reduce lossage % @begin foo is the same as @foo, for now. \newhelp\EMsimple{Type to continue.} \outer\def\begin{\parsearg\beginxxx} \def\beginxxx #1{% \expandafter\ifx\csname #1\endcsname\relax {\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else \csname #1\endcsname\fi} % @end foo executes the definition of \Efoo. % \def\end{\parsearg\endxxx} \def\endxxx #1{% \removeactivespaces{#1}% \edef\endthing{\the\toks0}% % \expandafter\ifx\csname E\endthing\endcsname\relax \expandafter\ifx\csname \endthing\endcsname\relax % There's no \foo, i.e., no ``environment'' foo. \errhelp = \EMsimple \errmessage{Undefined command `@end \endthing'}% \else \unmatchedenderror\endthing \fi \else % Everything's ok; the right environment has been started. \csname E\endthing\endcsname \fi } % There is an environment #1, but it hasn't been started. Give an error. % \def\unmatchedenderror#1{% \errhelp = \EMsimple \errmessage{This `@end #1' doesn't have a matching `@#1'}% } % Define the control sequence \E#1 to give an unmatched @end error. % \def\defineunmatchedend#1{% \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}% } % Single-spacing is done by various environments. \newskip\singlespaceskip \singlespaceskip = \baselineskip \def\singlespace{% {\advance \baselineskip by -\singlespaceskip \kern \baselineskip}% \baselineskip=\singlespaceskip } %% Simple single-character @ commands % @@ prints an @ % Kludge this until the fonts are right (grr). \def\@{{\tt \char '100}} % This is turned off because it was never documented % and you can use @w{...} around a quote to suppress ligatures. %% Define @` and @' to be the same as ` and ' %% but suppressing ligatures. %\def\`{{`}} %\def\'{{'}} % Used to generate quoted braces. \def\mylbrace {{\tt \char '173}} \def\myrbrace {{\tt \char '175}} \let\{=\mylbrace \let\}=\myrbrace % @: forces normal size whitespace following. \def\:{\spacefactor=1000 } % @* forces a line break. \def\*{\hfil\break\hbox{}\ignorespaces} % @. is an end-of-sentence period. \def\.{.\spacefactor=3000 } % @w prevents a word break. Without the \leavevmode, @w at the % beginning of a paragraph, when TeX is still in vertical mode, would % produce a whole line of output instead of starting the paragraph. \def\w#1{\leavevmode\hbox{#1}} % @group ... @end group forces ... to be all on one page, by enclosing % it in a TeX vbox. We use \vtop instead of \vbox to construct the box % to keep its height that of a normal line. According to the rules for % \topskip (p.114 of the TeXbook), the glue inserted is % max (\topskip - \ht (first item), 0). If that height is large, % therefore, no glue is inserted, and the space between the headline and % the text is small, which looks bad. % \def\group{\begingroup \ifnum\catcode13=\active \else \errhelp = \groupinvalidhelp \errmessage{@group invalid in context where filling is enabled}% \fi % % The \vtop we start below produces a box with normal height and large % depth; thus, TeX puts \baselineskip glue before it, and (when the % next line of text is done) \lineskip glue after it. (See p.82 of % the TeXbook.) But the next line of text also gets us \parskip glue. % Final result: space below is slightly more than space above. \def\Egroup{% \egroup % End the \vtop. \endgroup % End the \group. }% % \vtop\bgroup % We have to put a strut on the last line in case the @group is in % the midst of an example, rather than completely enclosing it. % Otherwise, the interline space between the last line of the group % and the first line afterwards is too small. But we can't put the % strut in \Egroup, since there it would be on a line by itself. % Hence this just inserts a strut at the beginning of each line. \everypar = {\strut}% % % We do @comment here in case we are called inside an environment, % such as @example, where each end-of-line in the input causes an % end-of-line in the output. We don't want the end-of-line after % the `@group' to put extra space in the output. Since @group % should appear on a line by itself (according to the Texinfo % manual), we don't worry about eating any user text. \comment } % % TeX puts in an \escapechar (i.e., `@') at the beginning of the help % message, so this ends up printing `@group can only ...'. % \newhelp\groupinvalidhelp{% group can only be used in environments such as @example,^^J% where each line of input produces a line of output.} % @need space-in-mils % forces a page break if there is not space-in-mils remaining. \newdimen\mil \mil=0.001in \def\need{\parsearg\needx} % Old definition--didn't work. %\def\needx #1{\par % %% This method tries to make TeX break the page naturally %% if the depth of the box does not fit. %{\baselineskip=0pt% %\vtop to #1\mil{\vfil}\kern -#1\mil\penalty 10000 %\prevdepth=-1000pt %}} \def\needx#1{% % Go into vertical mode, so we don't make a big box in the middle of a % paragraph. \par % % Don't add any leading before our big empty box, but allow a page % break, since the best break might be right here. \allowbreak \nointerlineskip \vtop to #1\mil{\vfil}% % % TeX does not even consider page breaks if a penalty added to the % main vertical list is 10000 or more. But in order to see if the % empty box we just added fits on the page, we must make it consider % page breaks. On the other hand, we don't want to actually break the % page after the empty box. So we use a penalty of 9999. % % There is an extremely small chance that TeX will actually break the % page at this \penalty, if there are no other feasible breakpoints in % sight. (If the user is using lots of big @group commands, which % almost-but-not-quite fill up a page, TeX will have a hard time doing % good page breaking, for example.) However, I could not construct an % example where a page broke at this \penalty; if it happens in a real % document, then we can reconsider our strategy. \penalty9999 % % Back up by the size of the box, whether we did a page break or not. \kern -#1\mil % % Do not allow a page break right after this kern. \nobreak } % @br forces paragraph break \let\br = \par % @dots{} output some dots \def\dots{$\ldots$} % @page forces the start of a new page \def\page{\par\vfill\supereject} % @exdent text.... % outputs text on separate line in roman font, starting at standard page margin % This records the amount of indent in the innermost environment. % That's how much \exdent should take out. \newskip\exdentamount % This defn is used inside fill environments such as @defun. \def\exdent{\parsearg\exdentyyy} \def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}} % This defn is used inside nofill environments such as @example. \def\nofillexdent{\parsearg\nofillexdentyyy} \def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount \leftline{\hskip\leftskip{\rm#1}}}} %\hbox{{\rm#1}}\hfil\break}} % @include file insert text of that file as input. \def\include{\parsearg\includezzz} %Use \input\thisfile to avoid blank after \input, which may be an active %char (in which case the blank would become the \input argument). %The grouping keeps the value of \thisfile correct even when @include %is nested. \def\includezzz #1{\begingroup \def\thisfile{#1}\input\thisfile \endgroup} \def\thisfile{} % @center line outputs that line, centered \def\center{\parsearg\centerzzz} \def\centerzzz #1{{\advance\hsize by -\leftskip \advance\hsize by -\rightskip \centerline{#1}}} % @sp n outputs n lines of vertical space \def\sp{\parsearg\spxxx} \def\spxxx #1{\par \vskip #1\baselineskip} % @comment ...line which is ignored... % @c is the same as @comment % @ignore ... @end ignore is another way to write a comment \def\comment{\catcode 64=\other \catcode 123=\other \catcode 125=\other% \parsearg \commentxxx} \def\commentxxx #1{\catcode 64=0 \catcode 123=1 \catcode 125=2 } \let\c=\comment % Prevent errors for section commands. % Used in @ignore and in failing conditionals. \def\ignoresections{% \let\chapter=\relax \let\unnumbered=\relax \let\top=\relax \let\unnumberedsec=\relax \let\unnumberedsection=\relax \let\unnumberedsubsec=\relax \let\unnumberedsubsection=\relax \let\unnumberedsubsubsec=\relax \let\unnumberedsubsubsection=\relax \let\section=\relax \let\subsec=\relax \let\subsubsec=\relax \let\subsection=\relax \let\subsubsection=\relax \let\appendix=\relax \let\appendixsec=\relax \let\appendixsection=\relax \let\appendixsubsec=\relax \let\appendixsubsection=\relax \let\appendixsubsubsec=\relax \let\appendixsubsubsection=\relax \let\contents=\relax \let\smallbook=\relax \let\titlepage=\relax } % Used in nested conditionals, where we have to parse the Texinfo source % and so want to turn off most commands, in case they are used % incorrectly. % \def\ignoremorecommands{% \let\defcv = \relax \let\deffn = \relax \let\deffnx = \relax \let\defindex = \relax \let\defivar = \relax \let\defmac = \relax \let\defmethod = \relax \let\defop = \relax \let\defopt = \relax \let\defspec = \relax \let\deftp = \relax \let\deftypefn = \relax \let\deftypefun = \relax \let\deftypevar = \relax \let\deftypevr = \relax \let\defun = \relax \let\defvar = \relax \let\defvr = \relax \let\ref = \relax \let\xref = \relax \let\printindex = \relax \let\pxref = \relax \let\settitle = \relax \let\include = \relax } % Ignore @ignore ... @end ignore. % \def\ignore{\doignore{ignore}} % Also ignore @ifinfo, @menu, and @direntry text. % \def\ifinfo{\doignore{ifinfo}} \def\menu{\doignore{menu}} \def\direntry{\doignore{direntry}} % Ignore text until a line `@end #1'. % \def\doignore#1{\begingroup % Don't complain about control sequences we have declared \outer. \ignoresections % % Define a command to swallow text until we reach `@end #1'. \long\def\doignoretext##1\end #1{\enddoignore}% % % Make sure that spaces turn into tokens that match what \doignoretext wants. \catcode32 = 10 % % And now expand that command. \doignoretext } % What we do to finish off ignored text. % \def\enddoignore{\endgroup\ignorespaces}% \newif\ifwarnedobs\warnedobsfalse \def\obstexwarn{% \ifwarnedobs\relax\else % We need to warn folks that they may have trouble with TeX 3.0. % This uses \immediate\write16 rather than \message to get newlines. \immediate\write16{} \immediate\write16{***WARNING*** for users of Unix TeX 3.0!} \immediate\write16{This manual trips a bug in TeX version 3.0 (tex hangs).} \immediate\write16{If you are running another version of TeX, relax.} \immediate\write16{If you are running Unix TeX 3.0, kill this TeX process.} \immediate\write16{ Then upgrade your TeX installation if you can.} \immediate\write16{If you are stuck with version 3.0, run the} \immediate\write16{ script ``tex3patch'' from the Texinfo distribution} \immediate\write16{ to use a workaround.} \immediate\write16{} \warnedobstrue \fi } % **In TeX 3.0, setting text in \nullfont hangs tex. For a % workaround (which requires the file ``dummy.tfm'' to be installed), % uncomment the following line: %%%%%\font\nullfont=dummy\let\obstexwarn=\relax % Ignore text, except that we keep track of conditional commands for % purposes of nesting, up to an `@end #1' command. % \def\nestedignore#1{% \obstexwarn % We must actually expand the ignored text to look for the @end % command, so that nested ignore constructs work. Thus, we put the % text into a \vbox and then do nothing with the result. To minimize % the change of memory overflow, we follow the approach outlined on % page 401 of the TeXbook: make the current font be a dummy font. % \setbox0 = \vbox\bgroup % Don't complain about control sequences we have declared \outer. \ignoresections % % Define `@end #1' to end the box, which will in turn undefine the % @end command again. \expandafter\def\csname E#1\endcsname{\egroup\ignorespaces}% % % We are going to be parsing Texinfo commands. Most cause no % trouble when they are used incorrectly, but some commands do % complicated argument parsing or otherwise get confused, so we % undefine them. % % We can't do anything about stray @-signs, unfortunately; % they'll produce `undefined control sequence' errors. \ignoremorecommands % % Set the current font to be \nullfont, a TeX primitive, and define % all the font commands to also use \nullfont. We don't use % dummy.tfm, as suggested in the TeXbook, because not all sites % might have that installed. Therefore, math mode will still % produce output, but that should be an extremely small amount of % stuff compared to the main input. % \nullfont \let\tenrm = \nullfont \let\tenit = \nullfont \let\tensl = \nullfont \let\tenbf = \nullfont \let\tentt = \nullfont \let\smallcaps = \nullfont \let\tensf = \nullfont % % Don't complain when characters are missing from the fonts. \tracinglostchars = 0 % % Don't bother to do space factor calculations. \frenchspacing % % Don't report underfull hboxes. \hbadness = 10000 % % Do minimal line-breaking. \pretolerance = 10000 % % Do not execute instructions in @tex \def\tex{\doignore{tex}} } % @set VAR sets the variable VAR to an empty value. % @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. % % Since we want to separate VAR from REST-OF-LINE (which might be % empty), we can't just use \parsearg; we have to insert a space of our % own to delimit the rest of the line, and then take it out again if we % didn't need it. % \def\set{\parsearg\setxxx} \def\setxxx#1{\setyyy#1 \endsetyyy} \def\setyyy#1 #2\endsetyyy{% \def\temp{#2}% \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted. \fi } \def\setzzz#1#2 \endsetzzz{\expandafter\xdef\csname SET#1\endcsname{#2}} % @clear VAR clears (i.e., unsets) the variable VAR. % \def\clear{\parsearg\clearxxx} \def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax} % @value{foo} gets the text saved in variable foo. % \def\value#1{\expandafter \ifx\csname SET#1\endcsname\relax {\{No value for ``#1''\}} \else \csname SET#1\endcsname \fi} % @ifset VAR ... @end ifset reads the `...' iff VAR has been defined % with @set. % \def\ifset{\parsearg\ifsetxxx} \def\ifsetxxx #1{% \expandafter\ifx\csname SET#1\endcsname\relax \expandafter\ifsetfail \else \expandafter\ifsetsucceed \fi } \def\ifsetsucceed{\conditionalsucceed{ifset}} \def\ifsetfail{\nestedignore{ifset}} \defineunmatchedend{ifset} % @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been % defined with @set, or has been undefined with @clear. % \def\ifclear{\parsearg\ifclearxxx} \def\ifclearxxx #1{% \expandafter\ifx\csname SET#1\endcsname\relax \expandafter\ifclearsucceed \else \expandafter\ifclearfail \fi } \def\ifclearsucceed{\conditionalsucceed{ifclear}} \def\ifclearfail{\nestedignore{ifclear}} \defineunmatchedend{ifclear} % @iftex always succeeds; we read the text following, through @end % iftex). But `@end iftex' should be valid only after an @iftex. % \def\iftex{\conditionalsucceed{iftex}} \defineunmatchedend{iftex} % We can't just want to start a group at @iftex (for example) and end it % at @end iftex, since then @set commands inside the conditional have no % effect (they'd get reverted at the end of the group). So we must % define \Eiftex to redefine itself to be its previous value. (We can't % just define it to fail again with an ``unmatched end'' error, since % the @ifset might be nested.) % \def\conditionalsucceed#1{% \edef\temp{% % Remember the current value of \E#1. \let\nece{prevE#1} = \nece{E#1}% % % At the `@end #1', redefine \E#1 to be its previous value. \def\nece{E#1}{\let\nece{E#1} = \nece{prevE#1}}% }% \temp } % We need to expand lots of \csname's, but we don't want to expand the % control sequences after we've constructed them. % \def\nece#1{\expandafter\noexpand\csname#1\endcsname} % @asis just yields its argument. Used with @table, for example. % \def\asis#1{#1} % @math means output in math mode. % We don't use $'s directly in the definition of \math because control % sequences like \math are expanded when the toc file is written. Then, % we read the toc file back, the $'s will be normal characters (as they % should be, according to the definition of Texinfo). So we must use a % control sequence to switch into and out of math mode. % % This isn't quite enough for @math to work properly in indices, but it % seems unlikely it will ever be needed there. % \let\implicitmath = $ \def\math#1{\implicitmath #1\implicitmath} % @bullet and @minus need the same treatment as @math, just above. \def\bullet{\implicitmath\ptexbullet\implicitmath} \def\minus{\implicitmath-\implicitmath} \def\node{\ENVcheck\parsearg\nodezzz} \def\nodezzz#1{\nodexxx [#1,]} \def\nodexxx[#1,#2]{\gdef\lastnode{#1}} \let\nwnode=\node \let\lastnode=\relax \def\donoderef{\ifx\lastnode\relax\else \expandafter\expandafter\expandafter\setref{\lastnode}\fi \let\lastnode=\relax} \def\unnumbnoderef{\ifx\lastnode\relax\else \expandafter\expandafter\expandafter\unnumbsetref{\lastnode}\fi \let\lastnode=\relax} \def\appendixnoderef{\ifx\lastnode\relax\else \expandafter\expandafter\expandafter\appendixsetref{\lastnode}\fi \let\lastnode=\relax} \let\refill=\relax % @setfilename is done at the beginning of every texinfo file. % So open here the files we need to have open while reading the input. % This makes it possible to make a .fmt file for texinfo. \def\setfilename{% \readauxfile \opencontents \openindices \fixbackslash % Turn off hack to swallow `\input texinfo'. \global\let\setfilename=\comment % Ignore extra @setfilename cmds. \comment % Ignore the actual filename. } \outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} \def\inforef #1{\inforefzzz #1,,,,**} \def\inforefzzz #1,#2,#3,#4**{See Info file \file{\ignorespaces #3{}}, node \samp{\ignorespaces#1{}}} \message{fonts,} % Font-change commands. % Texinfo supports the sans serif font style, which plain TeX does not. % So we set up a \sf analogous to plain's \rm, etc. \newfam\sffam \def\sf{\fam=\sffam \tensf} \let\li = \sf % Sometimes we call it \li, not \sf. %% Try out Computer Modern fonts at \magstephalf \let\mainmagstep=\magstephalf \ifx\bigger\relax \let\mainmagstep=\magstep1 \font\textrm=cmr12 \font\texttt=cmtt12 \else \font\textrm=cmr10 scaled \mainmagstep \font\texttt=cmtt10 scaled \mainmagstep \fi % Instead of cmb10, you many want to use cmbx10. % cmbx10 is a prettier font on its own, but cmb10 % looks better when embedded in a line with cmr10. \font\textbf=cmb10 scaled \mainmagstep \font\textit=cmti10 scaled \mainmagstep \font\textsl=cmsl10 scaled \mainmagstep \font\textsf=cmss10 scaled \mainmagstep \font\textsc=cmcsc10 scaled \mainmagstep \font\texti=cmmi10 scaled \mainmagstep \font\textsy=cmsy10 scaled \mainmagstep % A few fonts for @defun, etc. \font\defbf=cmbx10 scaled \magstep1 %was 1314 \font\deftt=cmtt10 scaled \magstep1 \def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf} % Fonts for indices and small examples. % We actually use the slanted font rather than the italic, % because texinfo normally uses the slanted fonts for that. % Do not make many font distinctions in general in the index, since they % aren't very useful. \font\ninett=cmtt9 \font\indrm=cmr9 \font\indit=cmsl9 \let\indsl=\indit \let\indtt=\ninett \let\indsf=\indrm \let\indbf=\indrm \let\indsc=\indrm \font\indi=cmmi9 \font\indsy=cmsy9 % Fonts for headings \font\chaprm=cmbx12 scaled \magstep2 \font\chapit=cmti12 scaled \magstep2 \font\chapsl=cmsl12 scaled \magstep2 \font\chaptt=cmtt12 scaled \magstep2 \font\chapsf=cmss12 scaled \magstep2 \let\chapbf=\chaprm \font\chapsc=cmcsc10 scaled\magstep3 \font\chapi=cmmi12 scaled \magstep2 \font\chapsy=cmsy10 scaled \magstep3 \font\secrm=cmbx12 scaled \magstep1 \font\secit=cmti12 scaled \magstep1 \font\secsl=cmsl12 scaled \magstep1 \font\sectt=cmtt12 scaled \magstep1 \font\secsf=cmss12 scaled \magstep1 \font\secbf=cmbx12 scaled \magstep1 \font\secsc=cmcsc10 scaled\magstep2 \font\seci=cmmi12 scaled \magstep1 \font\secsy=cmsy10 scaled \magstep2 % \font\ssecrm=cmbx10 scaled \magstep1 % This size an font looked bad. % \font\ssecit=cmti10 scaled \magstep1 % The letters were too crowded. % \font\ssecsl=cmsl10 scaled \magstep1 % \font\ssectt=cmtt10 scaled \magstep1 % \font\ssecsf=cmss10 scaled \magstep1 %\font\ssecrm=cmb10 scaled 1315 % Note the use of cmb rather than cmbx. %\font\ssecit=cmti10 scaled 1315 % Also, the size is a little larger than %\font\ssecsl=cmsl10 scaled 1315 % being scaled magstep1. %\font\ssectt=cmtt10 scaled 1315 %\font\ssecsf=cmss10 scaled 1315 %\let\ssecbf=\ssecrm \font\ssecrm=cmbx12 scaled \magstephalf \font\ssecit=cmti12 scaled \magstephalf \font\ssecsl=cmsl12 scaled \magstephalf \font\ssectt=cmtt12 scaled \magstephalf \font\ssecsf=cmss12 scaled \magstephalf \font\ssecbf=cmbx12 scaled \magstephalf \font\ssecsc=cmcsc10 scaled \magstep1 \font\sseci=cmmi12 scaled \magstephalf \font\ssecsy=cmsy10 scaled \magstep1 % The smallcaps and symbol fonts should actually be scaled \magstep1.5, % but that is not a standard magnification. % Fonts for title page: \font\titlerm = cmbx12 scaled \magstep3 \let\authorrm = \secrm % In order for the font changes to affect most math symbols and letters, % we have to define the \textfont of the standard families. Since % texinfo doesn't allow for producing subscripts and superscripts, we % don't bother to reset \scriptfont and \scriptscriptfont (which would % also require loading a lot more fonts). % \def\resetmathfonts{% \textfont0 = \tenrm \textfont1 = \teni \textfont2 = \tensy \textfont\itfam = \tenit \textfont\slfam = \tensl \textfont\bffam = \tenbf \textfont\ttfam = \tentt \textfont\sffam = \tensf } % The font-changing commands redefine the meanings of \tenSTYLE, instead % of just \STYLE. We do this so that font changes will continue to work % in math mode, where it is the current \fam that is relevant in most % cases, not the current. Plain TeX does, for example, % \def\bf{\fam=\bffam \tenbf} By redefining \tenbf, we obviate the need % to redefine \bf itself. \def\textfonts{% \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \resetmathfonts} \def\chapfonts{% \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \resetmathfonts} \def\secfonts{% \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy \resetmathfonts} \def\subsecfonts{% \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy \resetmathfonts} \def\indexfonts{% \let\tenrm=\indrm \let\tenit=\indit \let\tensl=\indsl \let\tenbf=\indbf \let\tentt=\indtt \let\smallcaps=\indsc \let\tensf=\indsf \let\teni=\indi \let\tensy=\indsy \resetmathfonts} % Set up the default fonts, so we can use them for creating boxes. % \textfonts % Count depth in font-changes, for error checks \newcount\fontdepth \fontdepth=0 % Fonts for short table of contents. \font\shortcontrm=cmr12 \font\shortcontbf=cmbx12 \font\shortcontsl=cmsl12 %% Add scribe-like font environments, plus @l for inline lisp (usually sans %% serif) and @ii for TeX italic % \smartitalic{ARG} outputs arg in italics, followed by an italic correction % unless the following character is such as not to need one. \def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else\/\fi\fi\fi} \def\smartitalic#1{{\sl #1}\futurelet\next\smartitalicx} \let\i=\smartitalic \let\var=\smartitalic \let\dfn=\smartitalic \let\emph=\smartitalic \let\cite=\smartitalic \def\b#1{{\bf #1}} \let\strong=\b % We can't just use \exhyphenpenalty, because that only has effect at % the end of a paragraph. Restore normal hyphenation at the end of the % group within which \nohyphenation is presumably called. % \def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} \def\restorehyphenation{\hyphenchar\font = `- } \def\t#1{% {\tt \nohyphenation \rawbackslash \frenchspacing #1}% \null } \let\ttfont = \t %\def\samp #1{`{\tt \rawbackslash \frenchspacing #1}'\null} \def\samp #1{`\tclose{#1}'\null} \def\key #1{{\tt \nohyphenation \uppercase{#1}}\null} \def\ctrl #1{{\tt \rawbackslash \hat}#1} \let\file=\samp % @code is a modification of @t, % which makes spaces the same size as normal in the surrounding text. \def\tclose#1{% {% % Change normal interword space to be same as for the current font. \spaceskip = \fontdimen2\font % % Switch to typewriter. \tt % % But `\ ' produces the large typewriter interword space. \def\ {{\spaceskip = 0pt{} }}% % % Turn off hyphenation. \nohyphenation % \rawbackslash \frenchspacing #1% }% \null } \let\code=\tclose %\let\exp=\tclose %Was temporary % @kbd is like @code, except that if the argument is just one @key command, % then @kbd has no effect. \def\xkey{\key} \def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}% \ifx\one\xkey\ifx\threex\three \key{#2}% \else\tclose{\look}\fi \else\tclose{\look}\fi} % Typeset a dimension, e.g., `in' or `pt'. The only reason for the % argument is to make the input look right: @dmn{pt} instead of % @dmn{}pt. % \def\dmn#1{\thinspace #1} \def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par} \def\l#1{{\li #1}\null} % \def\r#1{{\rm #1}} % roman font % Use of \lowercase was suggested. \def\sc#1{{\smallcaps#1}} % smallcaps font \def\ii#1{{\it #1}} % italic font \message{page headings,} \newskip\titlepagetopglue \titlepagetopglue = 1.5in \newskip\titlepagebottomglue \titlepagebottomglue = 2pc % First the title page. Must do @settitle before @titlepage. \def\titlefont#1{{\titlerm #1}} \newif\ifseenauthor \newif\iffinishedtitlepage \def\shorttitlepage{\parsearg\shorttitlepagezzz} \def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% \endgroup\page\hbox{}\page} \def\titlepage{\begingroup \parindent=0pt \textfonts \let\subtitlerm=\tenrm % I deinstalled the following change because \cmr12 is undefined. % This change was not in the ChangeLog anyway. --rms. % \let\subtitlerm=\cmr12 \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}% % \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines}% % % Leave some space at the very top of the page. \vglue\titlepagetopglue % % Now you can print the title using @title. \def\title{\parsearg\titlezzz}% \def\titlezzz##1{\leftline{\titlefont{##1}} % print a rule at the page bottom also. \finishedtitlepagefalse \vskip4pt \hrule height 4pt \vskip4pt}% % No rule at page bottom unless we print one at the top with @title. \finishedtitlepagetrue % % Now you can put text using @subtitle. \def\subtitle{\parsearg\subtitlezzz}% \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}% % % @author should come last, but may come many times. \def\author{\parsearg\authorzzz}% \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi {\authorfont \leftline{##1}}}% % % Most title ``pages'' are actually two pages long, with space % at the top of the second. We don't want the ragged left on the second. \let\oldpage = \page \def\page{% \iffinishedtitlepage\else \finishtitlepage \fi \oldpage \let\page = \oldpage \hbox{}}% % \def\page{\oldpage \hbox{}} } \def\Etitlepage{% \iffinishedtitlepage\else \finishtitlepage \fi % It is important to do the page break before ending the group, % because the headline and footline are only empty inside the group. % If we use the new definition of \page, we always get a blank page % after the title page, which we certainly don't want. \oldpage \endgroup \HEADINGSon } \def\finishtitlepage{% \vskip4pt \hrule height 2pt \vskip\titlepagebottomglue \finishedtitlepagetrue } %%% Set up page headings and footings. \let\thispage=\folio \newtoks \evenheadline % Token sequence for heading line of even pages \newtoks \oddheadline % Token sequence for heading line of odd pages \newtoks \evenfootline % Token sequence for footing line of even pages \newtoks \oddfootline % Token sequence for footing line of odd pages % Now make Tex use those variables \headline={{\textfonts\rm \ifodd\pageno \the\oddheadline \else \the\evenheadline \fi}} \footline={{\textfonts\rm \ifodd\pageno \the\oddfootline \else \the\evenfootline \fi}\HEADINGShook} \let\HEADINGShook=\relax % Commands to set those variables. % For example, this is what @headings on does % @evenheading @thistitle|@thispage|@thischapter % @oddheading @thischapter|@thispage|@thistitle % @evenfooting @thisfile|| % @oddfooting ||@thisfile \def\evenheading{\parsearg\evenheadingxxx} \def\oddheading{\parsearg\oddheadingxxx} \def\everyheading{\parsearg\everyheadingxxx} \def\evenfooting{\parsearg\evenfootingxxx} \def\oddfooting{\parsearg\oddfootingxxx} \def\everyfooting{\parsearg\everyfootingxxx} {\catcode`\@=0 % \gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish} \gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{% \global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish} \gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{% \global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\everyheadingxxx #1{\everyheadingyyy #1@|@|@|@|\finish} \gdef\everyheadingyyy #1@|#2@|#3@|#4\finish{% \global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}} \global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish} \gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{% \global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish} \gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{% \global\oddfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\everyfootingxxx #1{\everyfootingyyy #1@|@|@|@|\finish} \gdef\everyfootingyyy #1@|#2@|#3@|#4\finish{% \global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}} \global\oddfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} % }% unbind the catcode of @. % @headings double turns headings on for double-sided printing. % @headings single turns headings on for single-sided printing. % @headings off turns them off. % @headings on same as @headings double, retained for compatibility. % @headings after turns on double-sided headings after this page. % @headings doubleafter turns on double-sided headings after this page. % @headings singleafter turns on single-sided headings after this page. % By default, they are off. \def\headings #1 {\csname HEADINGS#1\endcsname} \def\HEADINGSoff{ \global\evenheadline={\hfil} \global\evenfootline={\hfil} \global\oddheadline={\hfil} \global\oddfootline={\hfil}} \HEADINGSoff % When we turn headings on, set the page number to 1. % For double-sided printing, put current file name in lower left corner, % chapter name on inside top of right hand pages, document % title on inside top of left hand pages, and page numbers on outside top % edge of all pages. \def\HEADINGSdouble{ %\pagealignmacro \global\pageno=1 \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\folio\hfil\thistitle}} \global\oddheadline={\line{\thischapter\hfil\folio}} } % For single-sided printing, chapter title goes across top left of page, % page number on top right. \def\HEADINGSsingle{ %\pagealignmacro \global\pageno=1 \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\thischapter\hfil\folio}} \global\oddheadline={\line{\thischapter\hfil\folio}} } \def\HEADINGSon{\HEADINGSdouble} \def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex} \let\HEADINGSdoubleafter=\HEADINGSafter \def\HEADINGSdoublex{% \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\folio\hfil\thistitle}} \global\oddheadline={\line{\thischapter\hfil\folio}} } \def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} \def\HEADINGSsinglex{% \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\thischapter\hfil\folio}} \global\oddheadline={\line{\thischapter\hfil\folio}} } % Subroutines used in generating headings % Produces Day Month Year style of output. \def\today{\number\day\space \ifcase\month\or January\or February\or March\or April\or May\or June\or July\or August\or September\or October\or November\or December\fi \space\number\year} % Use this if you want the Month Day, Year style of output. %\def\today{\ifcase\month\or %January\or February\or March\or April\or May\or June\or %July\or August\or September\or October\or November\or December\fi %\space\number\day, \number\year} % @settitle line... specifies the title of the document, for headings % It generates no output of its own \def\thistitle{No Title} \def\settitle{\parsearg\settitlezzz} \def\settitlezzz #1{\gdef\thistitle{#1}} \message{tables,} % @tabs -- simple alignment % These don't work. For one thing, \+ is defined as outer. % So these macros cannot even be defined. %\def\tabs{\parsearg\tabszzz} %\def\tabszzz #1{\settabs\+#1\cr} %\def\tabline{\parsearg\tablinezzz} %\def\tablinezzz #1{\+#1\cr} %\def\&{&} % Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x). % default indentation of table text \newdimen\tableindent \tableindent=.8in % default indentation of @itemize and @enumerate text \newdimen\itemindent \itemindent=.3in % margin between end of table item and start of table text. \newdimen\itemmargin \itemmargin=.1in % used internally for \itemindent minus \itemmargin \newdimen\itemmax % Note @table, @vtable, and @vtable define @item, @itemx, etc., with % these defs. % They also define \itemindex % to index the item name in whatever manner is desired (perhaps none). \def\internalBitem{\smallbreak \parsearg\itemzzz} \def\internalBitemx{\par \parsearg\itemzzz} \def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz} \def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \par \parsearg\xitemzzz} \def\internalBkitem{\smallbreak \parsearg\kitemzzz} \def\internalBkitemx{\par \parsearg\kitemzzz} \def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}% \itemzzz {#1}} \def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}% \itemzzz {#1}} \def\itemzzz #1{\begingroup % \advance\hsize by -\rightskip \advance\hsize by -\tableindent \setbox0=\hbox{\itemfont{#1}}% \itemindex{#1}% \nobreak % This prevents a break before @itemx. % % Be sure we are not still in the middle of a paragraph. \parskip=0in \par % % If the item text does not fit in the space we have, put it on a line % by itself, and do not allow a page break either before or after that % line. We do not start a paragraph here because then if the next % command is, e.g., @kindex, the whatsit would get put into the % horizontal list on a line by itself, resulting in extra blank space. \ifdim \wd0>\itemmax \setbox0=\hbox{\hskip \leftskip \hskip -\tableindent \unhbox0}\box0 \nobreak \else % The item text fits into the space. Start a paragraph, so that the % following text (if any) will end up on the same line. Since that % text will be indented by \tableindent, we make the item text be in % a zero-width box. \noindent \rlap{\hskip -\tableindent\box0}% \fi \endgroup } \def\item{\errmessage{@item while not in a table}} \def\itemx{\errmessage{@itemx while not in a table}} \def\kitem{\errmessage{@kitem while not in a table}} \def\kitemx{\errmessage{@kitemx while not in a table}} \def\xitem{\errmessage{@xitem while not in a table}} \def\xitemx{\errmessage{@xitemx while not in a table}} %% Contains a kludge to get @end[description] to work \def\description{\tablez{\dontindex}{1}{}{}{}{}} \def\table{\begingroup\inENV\obeylines\obeyspaces\tablex} {\obeylines\obeyspaces% \gdef\tablex #1^^M{% \tabley\dontindex#1 \endtabley}} \def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex} {\obeylines\obeyspaces% \gdef\ftablex #1^^M{% \tabley\fnitemindex#1 \endtabley \def\Eftable{\endgraf\endgroup\afterenvbreak}% \let\Etable=\relax}} \def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex} {\obeylines\obeyspaces% \gdef\vtablex #1^^M{% \tabley\vritemindex#1 \endtabley \def\Evtable{\endgraf\endgroup\afterenvbreak}% \let\Etable=\relax}} \def\dontindex #1{} \def\fnitemindex #1{\doind {fn}{\code{#1}}}% \def\vritemindex #1{\doind {vr}{\code{#1}}}% {\obeyspaces % \gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup% \tablez{#1}{#2}{#3}{#4}{#5}{#6}}} \def\tablez #1#2#3#4#5#6{% \aboveenvbreak % \begingroup % \def\Edescription{\Etable}% Neccessary kludge. \let\itemindex=#1% \ifnum 0#3>0 \advance \leftskip by #3\mil \fi % \ifnum 0#4>0 \tableindent=#4\mil \fi % \ifnum 0#5>0 \advance \rightskip by #5\mil \fi % \def\itemfont{#2}% \itemmax=\tableindent % \advance \itemmax by -\itemmargin % \advance \leftskip by \tableindent % \exdentamount=\tableindent \parindent = 0pt \parskip = \smallskipamount \ifdim \parskip=0pt \parskip=2pt \fi% \def\Etable{\endgraf\endgroup\afterenvbreak}% \let\item = \internalBitem % \let\itemx = \internalBitemx % \let\kitem = \internalBkitem % \let\kitemx = \internalBkitemx % \let\xitem = \internalBxitem % \let\xitemx = \internalBxitemx % } % This is the counter used by @enumerate, which is really @itemize \newcount \itemno \def\itemize{\parsearg\itemizezzz} \def\itemizezzz #1{% \begingroup % ended by the @end itemsize \itemizey {#1}{\Eitemize} } \def\itemizey #1#2{% \aboveenvbreak % \itemmax=\itemindent % \advance \itemmax by -\itemmargin % \advance \leftskip by \itemindent % \exdentamount=\itemindent \parindent = 0pt % \parskip = \smallskipamount % \ifdim \parskip=0pt \parskip=2pt \fi% \def#2{\endgraf\endgroup\afterenvbreak}% \def\itemcontents{#1}% \let\item=\itemizeitem} % Set sfcode to normal for the chars that usually have another value. % These are `.?!:;,' \def\frenchspacing{\sfcode46=1000 \sfcode63=1000 \sfcode33=1000 \sfcode58=1000 \sfcode59=1000 \sfcode44=1000 } % \splitoff TOKENS\endmark defines \first to be the first token in % TOKENS, and \rest to be the remainder. % \def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% % Allow an optional argument of an uppercase letter, lowercase letter, % or number, to specify the first label in the enumerated list. No % argument is the same as `1'. % \def\enumerate{\parsearg\enumeratezzz} \def\enumeratezzz #1{\enumeratey #1 \endenumeratey} \def\enumeratey #1 #2\endenumeratey{% \begingroup % ended by the @end enumerate % % If we were given no argument, pretend we were given `1'. \def\thearg{#1}% \ifx\thearg\empty \def\thearg{1}\fi % % Detect if the argument is a single token. If so, it might be a % letter. Otherwise, the only valid thing it can be is a number. % (We will always have one token, because of the test we just made. % This is a good thing, since \splitoff doesn't work given nothing at % all -- the first parameter is undelimited.) \expandafter\splitoff\thearg\endmark \ifx\rest\empty % Only one token in the argument. It could still be anything. % A ``lowercase letter'' is one whose \lccode is nonzero. % An ``uppercase letter'' is one whose \lccode is both nonzero, and % not equal to itself. % Otherwise, we assume it's a number. % % We need the \relax at the end of the \ifnum lines to stop TeX from % continuing to look for a . % \ifnum\lccode\expandafter`\thearg=0\relax \numericenumerate % a number (we hope) \else % It's a letter. \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax \lowercaseenumerate % lowercase letter \else \uppercaseenumerate % uppercase letter \fi \fi \else % Multiple tokens in the argument. We hope it's a number. \numericenumerate \fi } % An @enumerate whose labels are integers. The starting integer is % given in \thearg. % \def\numericenumerate{% \itemno = \thearg \startenumeration{\the\itemno}% } % The starting (lowercase) letter is in \thearg. \def\lowercaseenumerate{% \itemno = \expandafter`\thearg \startenumeration{% % Be sure we're not beyond the end of the alphabet. \ifnum\itemno=0 \errmessage{No more lowercase letters in @enumerate; get a bigger alphabet}% \fi \char\lccode\itemno }% } % The starting (uppercase) letter is in \thearg. \def\uppercaseenumerate{% \itemno = \expandafter`\thearg \startenumeration{% % Be sure we're not beyond the end of the alphabet. \ifnum\itemno=0 \errmessage{No more uppercase letters in @enumerate; get a bigger alphabet} \fi \char\uccode\itemno }% } % Call itemizey, adding a period to the first argument and supplying the % common last two arguments. Also subtract one from the initial value in % \itemno, since @item increments \itemno. % \def\startenumeration#1{% \advance\itemno by -1 \itemizey{#1.}\Eenumerate\flushcr } % @alphaenumerate and @capsenumerate are abbreviations for giving an arg % to @enumerate. % \def\alphaenumerate{\enumerate{a}} \def\capsenumerate{\enumerate{A}} \def\Ealphaenumerate{\Eenumerate} \def\Ecapsenumerate{\Eenumerate} % Definition of @item while inside @itemize. \def\itemizeitem{% \advance\itemno by 1 {\let\par=\endgraf \smallbreak}% \ifhmode \errmessage{\in hmode at itemizeitem}\fi {\parskip=0in \hskip 0pt \hbox to 0pt{\hss \itemcontents\hskip \itemmargin}% \vadjust{\penalty 1200}}% \flushcr} \message{indexing,} % Index generation facilities % Define \newwrite to be identical to plain tex's \newwrite % except not \outer, so it can be used within \newindex. {\catcode`\@=11 \gdef\newwrite{\alloc@7\write\chardef\sixt@@n}} % \newindex {foo} defines an index named foo. % It automatically defines \fooindex such that % \fooindex ...rest of line... puts an entry in the index foo. % It also defines \fooindfile to be the number of the output channel for % the file that accumulates this index. The file's extension is foo. % The name of an index should be no more than 2 characters long % for the sake of vms. \def\newindex #1{ \expandafter\newwrite \csname#1indfile\endcsname% Define number for output file \openout \csname#1indfile\endcsname \jobname.#1 % Open the file \expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex \noexpand\doindex {#1}} } % @defindex foo == \newindex{foo} \def\defindex{\parsearg\newindex} % Define @defcodeindex, like @defindex except put all entries in @code. \def\newcodeindex #1{ \expandafter\newwrite \csname#1indfile\endcsname% Define number for output file \openout \csname#1indfile\endcsname \jobname.#1 % Open the file \expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex \noexpand\docodeindex {#1}} } \def\defcodeindex{\parsearg\newcodeindex} % @synindex foo bar makes index foo feed into index bar. % Do this instead of @defindex foo if you don't want it as a separate index. \def\synindex #1 #2 {% \expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname \expandafter\let\csname#1indfile\endcsname=\synindexfoo \expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex \noexpand\doindex {#2}}% } % @syncodeindex foo bar similar, but put all entries made for index foo % inside @code. \def\syncodeindex #1 #2 {% \expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname \expandafter\let\csname#1indfile\endcsname=\synindexfoo \expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex \noexpand\docodeindex {#2}}% } % Define \doindex, the driver for all \fooindex macros. % Argument #1 is generated by the calling \fooindex macro, % and it is "foo", the name of the index. % \doindex just uses \parsearg; it calls \doind for the actual work. % This is because \doind is more useful to call from other macros. % There is also \dosubind {index}{topic}{subtopic} % which makes an entry in a two-level index such as the operation index. \def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} \def\singleindexer #1{\doind{\indexname}{#1}} % like the previous two, but they put @code around the argument. \def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} \def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} \def\indexdummies{% \def\_{{\realbackslash _}}% \def\w{\realbackslash w }% \def\bf{\realbackslash bf }% \def\rm{\realbackslash rm }% \def\sl{\realbackslash sl }% \def\sf{\realbackslash sf}% \def\tt{\realbackslash tt}% \def\gtr{\realbackslash gtr}% \def\less{\realbackslash less}% \def\hat{\realbackslash hat}% \def\char{\realbackslash char}% \def\TeX{\realbackslash TeX}% \def\dots{\realbackslash dots }% \def\copyright{\realbackslash copyright }% \def\tclose##1{\realbackslash tclose {##1}}% \def\code##1{\realbackslash code {##1}}% \def\samp##1{\realbackslash samp {##1}}% \def\t##1{\realbackslash r {##1}}% \def\r##1{\realbackslash r {##1}}% \def\i##1{\realbackslash i {##1}}% \def\b##1{\realbackslash b {##1}}% \def\cite##1{\realbackslash cite {##1}}% \def\key##1{\realbackslash key {##1}}% \def\file##1{\realbackslash file {##1}}% \def\var##1{\realbackslash var {##1}}% \def\kbd##1{\realbackslash kbd {##1}}% \def\dfn##1{\realbackslash dfn {##1}}% \def\emph##1{\realbackslash emph {##1}}% } % \indexnofonts no-ops all font-change commands. % This is used when outputting the strings to sort the index by. \def\indexdummyfont#1{#1} \def\indexdummytex{TeX} \def\indexdummydots{...} \def\indexnofonts{% \let\w=\indexdummyfont \let\t=\indexdummyfont \let\r=\indexdummyfont \let\i=\indexdummyfont \let\b=\indexdummyfont \let\emph=\indexdummyfont \let\strong=\indexdummyfont \let\cite=\indexdummyfont \let\sc=\indexdummyfont %Don't no-op \tt, since it isn't a user-level command % and is used in the definitions of the active chars like <, >, |... %\let\tt=\indexdummyfont \let\tclose=\indexdummyfont \let\code=\indexdummyfont \let\file=\indexdummyfont \let\samp=\indexdummyfont \let\kbd=\indexdummyfont \let\key=\indexdummyfont \let\var=\indexdummyfont \let\TeX=\indexdummytex \let\dots=\indexdummydots } % To define \realbackslash, we must make \ not be an escape. % We must first make another character (@) an escape % so we do not become unable to do a definition. {\catcode`\@=0 \catcode`\\=\other @gdef@realbackslash{\}} \let\indexbackslash=0 %overridden during \printindex. \def\doind #1#2{% {\count10=\lastpenalty % {\indexdummies % Must do this here, since \bf, etc expand at this stage \escapechar=`\\% {\let\folio=0% Expand all macros now EXCEPT \folio \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now % so it will be output as is; and it will print as backslash in the indx. % % Now process the index-string once, with all font commands turned off, % to get the string to sort the index by. {\indexnofonts \xdef\temp1{#2}% }% % Now produce the complete index entry. We process the index-string again, % this time with font commands expanded, to get what to print in the index. \edef\temp{% \write \csname#1indfile\endcsname{% \realbackslash entry {\temp1}{\folio}{#2}}}% \temp }% }\penalty\count10}} \def\dosubind #1#2#3{% {\count10=\lastpenalty % {\indexdummies % Must do this here, since \bf, etc expand at this stage \escapechar=`\\% {\let\folio=0% \def\rawbackslashxx{\indexbackslash}% % % Now process the index-string once, with all font commands turned off, % to get the string to sort the index by. {\indexnofonts \xdef\temp1{#2 #3}% }% % Now produce the complete index entry. We process the index-string again, % this time with font commands expanded, to get what to print in the index. \edef\temp{% \write \csname#1indfile\endcsname{% \realbackslash entry {\temp1}{\folio}{#2}{#3}}}% \temp }% }\penalty\count10}} % The index entry written in the file actually looks like % \entry {sortstring}{page}{topic} % or % \entry {sortstring}{page}{topic}{subtopic} % The texindex program reads in these files and writes files % containing these kinds of lines: % \initial {c} % before the first topic whose initial is c % \entry {topic}{pagelist} % for a topic that is used without subtopics % \primary {topic} % for the beginning of a topic that is used with subtopics % \secondary {subtopic}{pagelist} % for each subtopic. % Define the user-accessible indexing commands % @findex, @vindex, @kindex, @cindex. \def\findex {\fnindex} \def\kindex {\kyindex} \def\cindex {\cpindex} \def\vindex {\vrindex} \def\tindex {\tpindex} \def\pindex {\pgindex} \def\cindexsub {\begingroup\obeylines\cindexsub} {\obeylines % \gdef\cindexsub "#1" #2^^M{\endgroup % \dosubind{cp}{#2}{#1}}} % Define the macros used in formatting output of the sorted index material. % This is what you call to cause a particular index to get printed. % Write % @unnumbered Function Index % @printindex fn \def\printindex{\parsearg\doprintindex} \def\doprintindex#1{% \tex \dobreak \chapheadingskip {10000} \catcode`\%=\other\catcode`\&=\other\catcode`\#=\other \catcode`\$=\other\catcode`\_=\other \catcode`\~=\other % % The following don't help, since the chars were translated % when the raw index was written, and their fonts were discarded % due to \indexnofonts. %\catcode`\"=\active %\catcode`\^=\active %\catcode`\_=\active %\catcode`\|=\active %\catcode`\<=\active %\catcode`\>=\active % % \def\indexbackslash{\rawbackslashxx} \indexfonts\rm \tolerance=9500 \advance\baselineskip -1pt \begindoublecolumns % % See if the index file exists and is nonempty. \openin 1 \jobname.#1s \ifeof 1 % \enddoublecolumns gets confused if there is no text in the index, % and it loses the chapter title and the aux file entries for the % index. The easiest way to prevent this problem is to make sure % there is some text. (Index is nonexistent) \else % % If the index file exists but is empty, then \openin leaves \ifeof % false. We have to make TeX try to read something from the file, so % it can discover if there is anything in it. \read 1 to \temp \ifeof 1 (Index is empty) \else \input \jobname.#1s \fi \fi \closein 1 \enddoublecolumns \Etex } % These macros are used by the sorted index file itself. % Change them to control the appearance of the index. % Same as \bigskipamount except no shrink. % \balancecolumns gets confused if there is any shrink. \newskip\initialskipamount \initialskipamount 12pt plus4pt \def\initial #1{% {\let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt \ifdim\lastskip<\initialskipamount \removelastskip \penalty-200 \vskip \initialskipamount\fi \line{\secbf#1\hfill}\kern 2pt\penalty10000}} % This typesets a paragraph consisting of #1, dot leaders, and then #2 % flush to the right margin. It is used for index and table of contents % entries. The paragraph is indented by \leftskip. % \def\entry #1#2{\begingroup % % Start a new paragraph if necessary, so our assignments below can't % affect previous text. \par % % Do not fill out the last line with white space. \parfillskip = 0in % % No extra space above this paragraph. \parskip = 0in % % Do not prefer a separate line ending with a hyphen to fewer lines. \finalhyphendemerits = 0 % % \hangindent is only relevant when the entry text and page number % don't both fit on one line. In that case, bob suggests starting the % dots pretty far over on the line. Unfortunately, a large % indentation looks wrong when the entry text itself is broken across % lines. So we use a small indentation and put up with long leaders. % % \hangafter is reset to 1 (which is the value we want) at the start % of each paragraph, so we need not do anything with that. \hangindent=2em % % When the entry text needs to be broken, just fill out the first line % with blank space. \rightskip = 0pt plus1fil % % Start a ``paragraph'' for the index entry so the line breaking % parameters we've set above will have an effect. \noindent % % Insert the text of the index entry. TeX will do line-breaking on it. #1% % % If we must, put the page number on a line of its own, and fill out % this line with blank space. (The \hfil is overwhelmed with the % fill leaders glue in \indexdotfill if the page number does fit.) \hfil\penalty50 \null\nobreak\indexdotfill % Have leaders before the page number. % % The `\ ' here is removed by the implicit \unskip that TeX does as % part of (the primitive) \par. Without it, a spurious underfull % \hbox ensues. \ #2% The page number ends the paragraph. \par \endgroup} % Like \dotfill except takes at least 1 em. \def\indexdotfill{\cleaders \hbox{$\mathsurround=0pt \mkern1.5mu . \mkern1.5mu$}\hskip 1em plus 1fill} \def\primary #1{\line{#1\hfil}} \newskip\secondaryindent \secondaryindent=0.5cm \def\secondary #1#2{ {\parfillskip=0in \parskip=0in \hangindent =1in \hangafter=1 \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill #2\par }} %% Define two-column mode, which is used in indexes. %% Adapted from the TeXbook, page 416. \catcode `\@=11 \newbox\partialpage \newdimen\doublecolumnhsize \def\begindoublecolumns{\begingroup % Grab any single-column material above us. \output = {\global\setbox\partialpage =\vbox{\unvbox255\kern -\topskip \kern \baselineskip}}% \eject % % Now switch to the double-column output routine. \output={\doublecolumnout}% % % Change the page size parameters. We could do this once outside this % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 % format, but then we repeat the same computation. Repeating a couple % of assignments once per index is clearly meaningless for the % execution time, so we may as well do it once. % % First we halve the line length, less a little for the gutter between % the columns. We compute the gutter based on the line length, so it % changes automatically with the paper format. The magic constant % below is chosen so that the gutter has the same value (well, +- < % 1pt) as it did when we hard-coded it. % % We put the result in a separate register, \doublecolumhsize, so we % can restore it in \pagesofar, after \hsize itself has (potentially) % been clobbered. % \doublecolumnhsize = \hsize \advance\doublecolumnhsize by -.04154\hsize \divide\doublecolumnhsize by 2 \hsize = \doublecolumnhsize % % Double the \vsize as well. (We don't need a separate register here, % since nobody clobbers \vsize.) \vsize = 2\vsize \doublecolumnpagegoal } \def\enddoublecolumns{\eject \endgroup \pagegoal=\vsize \unvbox\partialpage} \def\doublecolumnsplit{\splittopskip=\topskip \splitmaxdepth=\maxdepth \global\dimen@=\pageheight \global\advance\dimen@ by-\ht\partialpage \global\setbox1=\vsplit255 to\dimen@ \global\setbox0=\vbox{\unvbox1} \global\setbox3=\vsplit255 to\dimen@ \global\setbox2=\vbox{\unvbox3} \ifdim\ht0>\dimen@ \setbox255=\vbox{\unvbox0\unvbox2} \global\setbox255=\copy5 \fi \ifdim\ht2>\dimen@ \setbox255=\vbox{\unvbox0\unvbox2} \global\setbox255=\copy5 \fi } \def\doublecolumnpagegoal{% \dimen@=\vsize \advance\dimen@ by-2\ht\partialpage \global\pagegoal=\dimen@ } \def\pagesofar{\unvbox\partialpage % \hsize=\doublecolumnhsize % have to restore this since output routine \wd0=\hsize \wd2=\hsize \hbox to\pagewidth{\box0\hfil\box2}} \def\doublecolumnout{% \setbox5=\copy255 {\vbadness=10000 \doublecolumnsplit} \ifvbox255 \setbox0=\vtop to\dimen@{\unvbox0} \setbox2=\vtop to\dimen@{\unvbox2} \onepageout\pagesofar \unvbox255 \penalty\outputpenalty \else \setbox0=\vbox{\unvbox5} \ifvbox0 \dimen@=\ht0 \advance\dimen@ by\topskip \advance\dimen@ by-\baselineskip \divide\dimen@ by2 \splittopskip=\topskip \splitmaxdepth=\maxdepth {\vbadness=10000 \loop \global\setbox5=\copy0 \setbox1=\vsplit5 to\dimen@ \setbox3=\vsplit5 to\dimen@ \ifvbox5 \global\advance\dimen@ by1pt \repeat \setbox0=\vbox to\dimen@{\unvbox1} \setbox2=\vbox to\dimen@{\unvbox3} \global\setbox\partialpage=\vbox{\pagesofar} \doublecolumnpagegoal } \fi \fi } \catcode `\@=\other \message{sectioning,} % Define chapters, sections, etc. \newcount \chapno \newcount \secno \secno=0 \newcount \subsecno \subsecno=0 \newcount \subsubsecno \subsubsecno=0 % This counter is funny since it counts through charcodes of letters A, B, ... \newcount \appendixno \appendixno = `\@ \def\appendixletter{\char\the\appendixno} \newwrite \contentsfile % This is called from \setfilename. \def\opencontents{\openout \contentsfile = \jobname.toc} % Each @chapter defines this as the name of the chapter. % page headings and footings can use it. @section does likewise \def\thischapter{} \def\thissection{} \def\seccheck#1{\if \pageno<0 % \errmessage{@#1 not allowed after generating table of contents}\fi % } \def\chapternofonts{% \let\rawbackslash=\relax% \let\frenchspacing=\relax% \def\result{\realbackslash result} \def\equiv{\realbackslash equiv} \def\expansion{\realbackslash expansion} \def\print{\realbackslash print} \def\TeX{\realbackslash TeX} \def\dots{\realbackslash dots} \def\copyright{\realbackslash copyright} \def\tt{\realbackslash tt} \def\bf{\realbackslash bf } \def\w{\realbackslash w} \def\less{\realbackslash less} \def\gtr{\realbackslash gtr} \def\hat{\realbackslash hat} \def\char{\realbackslash char} \def\tclose##1{\realbackslash tclose {##1}} \def\code##1{\realbackslash code {##1}} \def\samp##1{\realbackslash samp {##1}} \def\r##1{\realbackslash r {##1}} \def\b##1{\realbackslash b {##1}} \def\key##1{\realbackslash key {##1}} \def\file##1{\realbackslash file {##1}} \def\kbd##1{\realbackslash kbd {##1}} % These are redefined because @smartitalic wouldn't work inside xdef. \def\i##1{\realbackslash i {##1}} \def\cite##1{\realbackslash cite {##1}} \def\var##1{\realbackslash var {##1}} \def\emph##1{\realbackslash emph {##1}} \def\dfn##1{\realbackslash dfn {##1}} } \newcount\absseclevel % used to calculate proper heading level \newcount\secbase\secbase=0 % @raise/lowersections modify this count % @raisesections: treat @section as chapter, @subsection as section, etc. \def\raisesections{\global\advance\secbase by -1} \let\up=\raisesections % original BFox name % @lowersections: treat @chapter as section, @section as subsection, etc. \def\lowersections{\global\advance\secbase by 1} \let\down=\lowersections % original BFox name % Choose a numbered-heading macro % #1 is heading level if unmodified by @raisesections or @lowersections % #2 is text for heading \def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \chapterzzz{#2} \or \seczzz{#2} \or \numberedsubseczzz{#2} \or \numberedsubsubseczzz{#2} \else \ifnum \absseclevel<0 \chapterzzz{#2} \else \numberedsubsubseczzz{#2} \fi \fi } % like \numhead, but chooses appendix heading levels \def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \appendixzzz{#2} \or \appendixsectionzzz{#2} \or \appendixsubseczzz{#2} \or \appendixsubsubseczzz{#2} \else \ifnum \absseclevel<0 \appendixzzz{#2} \else \appendixsubsubseczzz{#2} \fi \fi } % like \numhead, but chooses numberless heading levels \def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \unnumberedzzz{#2} \or \unnumberedseczzz{#2} \or \unnumberedsubseczzz{#2} \or \unnumberedsubsubseczzz{#2} \else \ifnum \absseclevel<0 \unnumberedzzz{#2} \else \unnumberedsubsubseczzz{#2} \fi \fi } \def\thischaptername{No Chapter Title} \outer\def\chapter{\parsearg\chapteryyy} \def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz \def\chapterzzz #1{\seccheck{chapter}% \secno=0 \subsecno=0 \subsubsecno=0 \global\advance \chapno by 1 \message{Chapter \the\chapno}% \chapmacro {#1}{\the\chapno}% \gdef\thissection{#1}% \gdef\thischaptername{#1}% % We don't substitute the actual chapter name into \thischapter % because we don't want its macros evaluated now. \xdef\thischapter{Chapter \the\chapno: \noexpand\thischaptername}% {\chapternofonts% \edef\temp{{\realbackslash chapentry {#1}{\the\chapno}{\noexpand\folio}}}% \escapechar=`\\% \write \contentsfile \temp % \donoderef % \global\let\section = \numberedsec \global\let\subsection = \numberedsubsec \global\let\subsubsection = \numberedsubsubsec }} \outer\def\appendix{\parsearg\appendixyyy} \def\appendixyyy #1{\apphead0{#1}} % normally apphead0 calls appendixzzz \def\appendixzzz #1{\seccheck{appendix}% \secno=0 \subsecno=0 \subsubsecno=0 \global\advance \appendixno by 1 \message{Appendix \appendixletter}% \chapmacro {#1}{Appendix \appendixletter}% \gdef\thissection{#1}% \gdef\thischaptername{#1}% \xdef\thischapter{Appendix \appendixletter: \noexpand\thischaptername}% {\chapternofonts% \edef\temp{{\realbackslash chapentry {#1}{Appendix \appendixletter}{\noexpand\folio}}}% \escapechar=`\\% \write \contentsfile \temp % \appendixnoderef % \global\let\section = \appendixsec \global\let\subsection = \appendixsubsec \global\let\subsubsection = \appendixsubsubsec }} \outer\def\top{\parsearg\unnumberedyyy} \outer\def\unnumbered{\parsearg\unnumberedyyy} \def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz \def\unnumberedzzz #1{\seccheck{unnumbered}% \secno=0 \subsecno=0 \subsubsecno=0 % % This used to be simply \message{#1}, but TeX fully expands the % argument to \message. Therefore, if #1 contained @-commands, TeX % expanded them. For example, in `@unnumbered The @cite{Book}', TeX % expanded @cite (which turns out to cause errors because \cite is meant % to be executed, not expanded). % % Anyway, we don't want the fully-expanded definition of @cite to appear % as a result of the \message, we just want `@cite' itself. We use % \the to achieve this: TeX expands \the only once, % simply yielding the contents of the . \toks0 = {#1}\message{(\the\toks0)}% % \unnumbchapmacro {#1}% \gdef\thischapter{#1}\gdef\thissection{#1}% {\chapternofonts% \edef\temp{{\realbackslash unnumbchapentry {#1}{\noexpand\folio}}}% \escapechar=`\\% \write \contentsfile \temp % \unnumbnoderef % \global\let\section = \unnumberedsec \global\let\subsection = \unnumberedsubsec \global\let\subsubsection = \unnumberedsubsubsec }} \outer\def\numberedsec{\parsearg\secyyy} \def\secyyy #1{\numhead1{#1}} % normally calls seczzz \def\seczzz #1{\seccheck{section}% \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % \gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}% {\chapternofonts% \edef\temp{{\realbackslash secentry % {#1}{\the\chapno}{\the\secno}{\noexpand\folio}}}% \escapechar=`\\% \write \contentsfile \temp % \donoderef % \penalty 10000 % }} \outer\def\appenixsection{\parsearg\appendixsecyyy} \outer\def\appendixsec{\parsearg\appendixsecyyy} \def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz \def\appendixsectionzzz #1{\seccheck{appendixsection}% \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % \gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}% {\chapternofonts% \edef\temp{{\realbackslash secentry % {#1}{\appendixletter}{\the\secno}{\noexpand\folio}}}% \escapechar=`\\% \write \contentsfile \temp % \appendixnoderef % \penalty 10000 % }} \outer\def\unnumberedsec{\parsearg\unnumberedsecyyy} \def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz \def\unnumberedseczzz #1{\seccheck{unnumberedsec}% \plainsecheading {#1}\gdef\thissection{#1}% {\chapternofonts% \edef\temp{{\realbackslash unnumbsecentry{#1}{\noexpand\folio}}}% \escapechar=`\\% \write \contentsfile \temp % \unnumbnoderef % \penalty 10000 % }} \outer\def\numberedsubsec{\parsearg\numberedsubsecyyy} \def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz \def\numberedsubseczzz #1{\seccheck{subsection}% \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % \subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}% {\chapternofonts% \edef\temp{{\realbackslash subsecentry % {#1}{\the\chapno}{\the\secno}{\the\subsecno}{\noexpand\folio}}}% \escapechar=`\\% \write \contentsfile \temp % \donoderef % \penalty 10000 % }} \outer\def\appendixsubsec{\parsearg\appendixsubsecyyy} \def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz \def\appendixsubseczzz #1{\seccheck{appendixsubsec}% \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % \subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}% {\chapternofonts% \edef\temp{{\realbackslash subsecentry % {#1}{\appendixletter}{\the\secno}{\the\subsecno}{\noexpand\folio}}}% \escapechar=`\\% \write \contentsfile \temp % \appendixnoderef % \penalty 10000 % }} \outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy} \def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz \def\unnumberedsubseczzz #1{\seccheck{unnumberedsubsec}% \plainsecheading {#1}\gdef\thissection{#1}% {\chapternofonts% \edef\temp{{\realbackslash unnumbsubsecentry{#1}{\noexpand\folio}}}% \escapechar=`\\% \write \contentsfile \temp % \unnumbnoderef % \penalty 10000 % }} \outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy} \def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz \def\numberedsubsubseczzz #1{\seccheck{subsubsection}% \gdef\thissection{#1}\global\advance \subsubsecno by 1 % \subsubsecheading {#1} {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}% {\chapternofonts% \edef\temp{{\realbackslash subsubsecentry % {#1} {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno} {\noexpand\folio}}}% \escapechar=`\\% \write \contentsfile \temp % \donoderef % \penalty 10000 % }} \outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy} \def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz \def\appendixsubsubseczzz #1{\seccheck{appendixsubsubsec}% \gdef\thissection{#1}\global\advance \subsubsecno by 1 % \subsubsecheading {#1} {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}% {\chapternofonts% \edef\temp{{\realbackslash subsubsecentry{#1}% {\appendixletter} {\the\secno}{\the\subsecno}{\the\subsubsecno}{\noexpand\folio}}}% \escapechar=`\\% \write \contentsfile \temp % \appendixnoderef % \penalty 10000 % }} \outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy} \def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz \def\unnumberedsubsubseczzz #1{\seccheck{unnumberedsubsubsec}% \plainsecheading {#1}\gdef\thissection{#1}% {\chapternofonts% \edef\temp{{\realbackslash unnumbsubsubsecentry{#1}{\noexpand\folio}}}% \escapechar=`\\% \write \contentsfile \temp % \unnumbnoderef % \penalty 10000 % }} % These are variants which are not "outer", so they can appear in @ifinfo. % Actually, they should now be obsolete; ordinary section commands should work. \def\infotop{\parsearg\unnumberedzzz} \def\infounnumbered{\parsearg\unnumberedzzz} \def\infounnumberedsec{\parsearg\unnumberedseczzz} \def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz} \def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz} \def\infoappendix{\parsearg\appendixzzz} \def\infoappendixsec{\parsearg\appendixseczzz} \def\infoappendixsubsec{\parsearg\appendixsubseczzz} \def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz} \def\infochapter{\parsearg\chapterzzz} \def\infosection{\parsearg\sectionzzz} \def\infosubsection{\parsearg\subsectionzzz} \def\infosubsubsection{\parsearg\subsubsectionzzz} % These macros control what the section commands do, according % to what kind of chapter we are in (ordinary, appendix, or unnumbered). % Define them by default for a numbered chapter. \global\let\section = \numberedsec \global\let\subsection = \numberedsubsec \global\let\subsubsection = \numberedsubsubsec % Define @majorheading, @heading and @subheading % NOTE on use of \vbox for chapter headings, section headings, and % such: % 1) We use \vbox rather than the earlier \line to permit % overlong headings to fold. % 2) \hyphenpenalty is set to 10000 because hyphenation in a % heading is obnoxious; this forbids it. % 3) Likewise, headings look best if no \parindent is used, and % if justification is not attempted. Hence \raggedright. \def\majorheading{\parsearg\majorheadingzzz} \def\majorheadingzzz #1{% {\advance\chapheadingskip by 10pt \chapbreak }% {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\penalty 200} \def\chapheading{\parsearg\chapheadingzzz} \def\chapheadingzzz #1{\chapbreak % {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\penalty 200} \def\heading{\parsearg\secheadingi} \def\subheading{\parsearg\subsecheadingi} \def\subsubheading{\parsearg\subsubsecheadingi} % These macros generate a chapter, section, etc. heading only % (including whitespace, linebreaking, etc. around it), % given all the information in convenient, parsed form. %%% Args are the skip and penalty (usually negative) \def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} \def\setchapterstyle #1 {\csname CHAPF#1\endcsname} %%% Define plain chapter starts, and page on/off switching for it % Parameter controlling skip before chapter headings (if needed) \newskip \chapheadingskip \chapheadingskip = 30pt plus 8pt minus 4pt \def\chapbreak{\dobreak \chapheadingskip {-4000}} \def\chappager{\par\vfill\supereject} \def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi} \def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} \def\CHAPPAGoff{ \global\let\pchapsepmacro=\chapbreak \global\let\pagealignmacro=\chappager} \def\CHAPPAGon{ \global\let\pchapsepmacro=\chappager \global\let\pagealignmacro=\chappager \global\def\HEADINGSon{\HEADINGSsingle}} \def\CHAPPAGodd{ \global\let\pchapsepmacro=\chapoddpage \global\let\pagealignmacro=\chapoddpage \global\def\HEADINGSon{\HEADINGSdouble}} \CHAPPAGon \def\CHAPFplain{ \global\let\chapmacro=\chfplain \global\let\unnumbchapmacro=\unnchfplain} \def\chfplain #1#2{% \pchapsepmacro {% \chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #2\enspace #1}% }% \bigskip \penalty5000 } \def\unnchfplain #1{% \pchapsepmacro % {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\penalty 10000 % } \CHAPFplain % The default \def\unnchfopen #1{% \chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\penalty 10000 % } \def\chfopen #1#2{\chapoddpage {\chapfonts \vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% \par\penalty 5000 % } \def\CHAPFopen{ \global\let\chapmacro=\chfopen \global\let\unnumbchapmacro=\unnchfopen} % Parameter controlling skip before section headings. \newskip \subsecheadingskip \subsecheadingskip = 17pt plus 8pt minus 4pt \def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}} \newskip \secheadingskip \secheadingskip = 21pt plus 8pt minus 4pt \def\secheadingbreak{\dobreak \secheadingskip {-1000}} % @paragraphindent is defined for the Info formatting commands only. \let\paragraphindent=\comment % Section fonts are the base font at magstep2, which produces % a size a bit more than 14 points in the default situation. \def\secheading #1#2#3{\secheadingi {#2.#3\enspace #1}} \def\plainsecheading #1{\secheadingi {#1}} \def\secheadingi #1{{\advance \secheadingskip by \parskip % \secheadingbreak}% {\secfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}% \ifdim \parskip<10pt \kern 10pt\kern -\parskip\fi \penalty 10000 } % Subsection fonts are the base font at magstep1, % which produces a size of 12 points. \def\subsecheading #1#2#3#4{\subsecheadingi {#2.#3.#4\enspace #1}} \def\subsecheadingi #1{{\advance \subsecheadingskip by \parskip % \subsecheadingbreak}% {\subsecfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}% \ifdim \parskip<10pt \kern 10pt\kern -\parskip\fi \penalty 10000 } \def\subsubsecfonts{\subsecfonts} % Maybe this should change: % Perhaps make sssec fonts scaled % magstep half \def\subsubsecheading #1#2#3#4#5{\subsubsecheadingi {#2.#3.#4.#5\enspace #1}} \def\subsubsecheadingi #1{{\advance \subsecheadingskip by \parskip % \subsecheadingbreak}% {\subsubsecfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}% \ifdim \parskip<10pt \kern 10pt\kern -\parskip\fi \penalty 10000} \message{toc printing,} % Finish up the main text and prepare to read what we've written % to \contentsfile. \newskip\contentsrightmargin \contentsrightmargin=1in \def\startcontents#1{% \pagealignmacro \immediate\closeout \contentsfile \ifnum \pageno>0 \pageno = -1 % Request roman numbered pages. \fi % Don't need to put `Contents' or `Short Contents' in the headline. % It is abundantly clear what they are. \unnumbchapmacro{#1}\def\thischapter{}% \begingroup % Set up to handle contents files properly. \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11 \raggedbottom % Worry more about breakpoints than the bottom. \advance\hsize by -\contentsrightmargin % Don't use the full line length. } % Normal (long) toc. \outer\def\contents{% \startcontents{Table of Contents}% \input \jobname.toc \endgroup \vfill \eject } % And just the chapters. \outer\def\summarycontents{% \startcontents{Short Contents}% % \let\chapentry = \shortchapentry \let\unnumbchapentry = \shortunnumberedentry % We want a true roman here for the page numbers. \secfonts \let\rm=\shortcontrm \let\bf=\shortcontbf \let\sl=\shortcontsl \rm \advance\baselineskip by 1pt % Open it up a little. \def\secentry ##1##2##3##4{} \def\unnumbsecentry ##1##2{} \def\subsecentry ##1##2##3##4##5{} \def\unnumbsubsecentry ##1##2{} \def\subsubsecentry ##1##2##3##4##5##6{} \def\unnumbsubsubsecentry ##1##2{} \input \jobname.toc \endgroup \vfill \eject } \let\shortcontents = \summarycontents % These macros generate individual entries in the table of contents. % The first argument is the chapter or section name. % The last argument is the page number. % The arguments in between are the chapter number, section number, ... % Chapter-level things, for both the long and short contents. \def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}} % See comments in \dochapentry re vbox and related settings \def\shortchapentry#1#2#3{% \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno{#3}}% } % Typeset the label for a chapter or appendix for the short contents. % The arg is, e.g. `Appendix A' for an appendix, or `3' for a chapter. % We could simplify the code here by writing out an \appendixentry % command in the toc file for appendices, instead of using \chapentry % for both, but it doesn't seem worth it. \setbox0 = \hbox{\shortcontrm Appendix } \newdimen\shortappendixwidth \shortappendixwidth = \wd0 \def\shortchaplabel#1{% % We typeset #1 in a box of constant width, regardless of the text of % #1, so the chapter titles will come out aligned. \setbox0 = \hbox{#1}% \dimen0 = \ifdim\wd0 > \shortappendixwidth \shortappendixwidth \else 0pt \fi % % This space should be plenty, since a single number is .5em, and the % widest letter (M) is 1em, at least in the Computer Modern fonts. % (This space doesn't include the extra space that gets added after % the label; that gets put in in \shortchapentry above.) \advance\dimen0 by 1.1em \hbox to \dimen0{#1\hfil}% } \def\unnumbchapentry#1#2{\dochapentry{#1}{#2}} \def\shortunnumberedentry#1#2{\tocentry{#1}{\doshortpageno{#2}}} % Sections. \def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}} \def\unnumbsecentry#1#2{\dosecentry{#1}{#2}} % Subsections. \def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}} \def\unnumbsubsecentry#1#2{\dosubsecentry{#1}{#2}} % And subsubsections. \def\subsubsecentry#1#2#3#4#5#6{% \dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}} \def\unnumbsubsubsecentry#1#2{\dosubsubsecentry{#1}{#2}} % This parameter controls the indentation of the various levels. \newdimen\tocindent \tocindent = 3pc % Now for the actual typesetting. In all these, #1 is the text and #2 is the % page number. % % If the toc has to be broken over pages, we would want to be at chapters % if at all possible; hence the \penalty. \def\dochapentry#1#2{% \penalty-300 \vskip\baselineskip \begingroup \chapentryfonts \tocentry{#1}{\dopageno{#2}}% \endgroup \nobreak\vskip .25\baselineskip } \def\dosecentry#1#2{\begingroup \secentryfonts \leftskip=\tocindent \tocentry{#1}{\dopageno{#2}}% \endgroup} \def\dosubsecentry#1#2{\begingroup \subsecentryfonts \leftskip=2\tocindent \tocentry{#1}{\dopageno{#2}}% \endgroup} \def\dosubsubsecentry#1#2{\begingroup \subsubsecentryfonts \leftskip=3\tocindent \tocentry{#1}{\dopageno{#2}}% \endgroup} % Final typesetting of a toc entry; we use the same \entry macro as for % the index entries, but we want to suppress hyphenation here. (We % can't do that in the \entry macro, since index entries might consist % of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.) % \def\tocentry#1#2{\begingroup \hyphenpenalty = 10000 \entry{#1}{#2}% \endgroup} % Space between chapter (or whatever) number and the title. \def\labelspace{\hskip1em \relax} \def\dopageno#1{{\rm #1}} \def\doshortpageno#1{{\rm #1}} \def\chapentryfonts{\secfonts \rm} \def\secentryfonts{\textfonts} \let\subsecentryfonts = \textfonts \let\subsubsecentryfonts = \textfonts \message{environments,} % Since these characters are used in examples, it should be an even number of % \tt widths. Each \tt character is 1en, so two makes it 1em. % Furthermore, these definitions must come after we define our fonts. \newbox\dblarrowbox \newbox\longdblarrowbox \newbox\pushcharbox \newbox\bullbox \newbox\equivbox \newbox\errorbox \let\ptexequiv = \equiv %{\tentt %\global\setbox\dblarrowbox = \hbox to 1em{\hfil$\Rightarrow$\hfil} %\global\setbox\longdblarrowbox = \hbox to 1em{\hfil$\mapsto$\hfil} %\global\setbox\pushcharbox = \hbox to 1em{\hfil$\dashv$\hfil} %\global\setbox\equivbox = \hbox to 1em{\hfil$\ptexequiv$\hfil} % Adapted from the manmac format (p.420 of TeXbook) %\global\setbox\bullbox = \hbox to 1em{\kern.15em\vrule height .75ex width .85ex % depth .1ex\hfil} %} \def\point{$\star$} \def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} \def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}} \def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} \def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}} % Adapted from the TeXbook's \boxit. {\tentt \global\dimen0 = 3em}% Width of the box. \dimen2 = .55pt % Thickness of rules % The text. (`r' is open on the right, `e' somewhat less so on the left.) \setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt} \global\setbox\errorbox=\hbox to \dimen0{\hfil \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. \advance\hsize by -2\dimen2 % Rules. \vbox{ \hrule height\dimen2 \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. \kern3pt\vrule width\dimen2}% Space to right. \hrule height\dimen2} \hfil} % The @error{} command. \def\error{\leavevmode\lower.7ex\copy\errorbox} % @tex ... @end tex escapes into raw Tex temporarily. % One exception: @ is still an escape character, so that @end tex works. % But \@ or @@ will get a plain tex @ character. \def\tex{\begingroup \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 \catcode `\^=7 \catcode `\_=8 \catcode `\~=13 \let~=\tie \catcode `\%=14 \catcode 43=12 \catcode`\"=12 \catcode`\==12 \catcode`\|=12 \catcode`\<=12 \catcode`\>=12 \escapechar=`\\ % \let\{=\ptexlbrace \let\}=\ptexrbrace \let\.=\ptexdot \let\*=\ptexstar \let\dots=\ptexdots \def\@{@}% \let\bullet=\ptexbullet \let\b=\ptexb \let\c=\ptexc \let\i=\ptexi \let\t=\ptext \let\l=\ptexl \let\L=\ptexL % \let\Etex=\endgroup} % Define @lisp ... @endlisp. % @lisp does a \begingroup so it can rebind things, % including the definition of @endlisp (which normally is erroneous). % Amount to narrow the margins by for @lisp. \newskip\lispnarrowing \lispnarrowing=0.4in % This is the definition that ^M gets inside @lisp % phr: changed space to \null, to avoid overfull hbox problems. {\obeyspaces% \gdef\lisppar{\null\endgraf}} % Make each space character in the input produce a normal interword % space in the output. Don't allow a line break at this space, as this % is used only in environments like @example, where each line of input % should produce a line of output anyway. % {\obeyspaces % \gdef\sepspaces{\obeyspaces\let =\tie}} % Define \obeyedspace to be our active space, whatever it is. This is % for use in \parsearg. {\sepspaces % \global\let\obeyedspace= } % This space is always present above and below environments. \newskip\envskipamount \envskipamount = 0pt % Make spacing and below environment symmetrical. \def\aboveenvbreak{{\advance\envskipamount by \parskip \endgraf \ifdim\lastskip<\envskipamount \removelastskip \penalty-50 \vskip\envskipamount \fi}} \let\afterenvbreak = \aboveenvbreak % \nonarrowing is a flag. If "set", @lisp etc don't narrow margins. \let\nonarrowing=\relax %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \cartouche: draw rectangle w/rounded corners around argument \font\circle=lcircle10 \newdimen\circthick \newdimen\cartouter\newdimen\cartinner \newskip\normbskip\newskip\normpskip\newskip\normlskip \circthick=\fontdimen8\circle % \def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth \def\ctr{{\hskip 6pt\circle\char'010}} \def\cbl{{\circle\char'012\hskip -6pt}} \def\cbr{{\hskip 6pt\circle\char'011}} \def\carttop{\hbox to \cartouter{\hskip\lskip \ctl\leaders\hrule height\circthick\hfil\ctr \hskip\rskip}} \def\cartbot{\hbox to \cartouter{\hskip\lskip \cbl\leaders\hrule height\circthick\hfil\cbr \hskip\rskip}} % \newskip\lskip\newskip\rskip \long\def\cartouche{% \begingroup \lskip=\leftskip \rskip=\rightskip \leftskip=0pt\rightskip=0pt %we want these *outside*. \cartinner=\hsize \advance\cartinner by-\lskip \advance\cartinner by-\rskip \cartouter=\hsize \advance\cartouter by 18pt % allow for 3pt kerns on either % side, and for 6pt waste from % each corner char \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip % Flag to tell @lisp, etc., not to narrow margin. \let\nonarrowing=\comment \vbox\bgroup \baselineskip=0pt\parskip=0pt\lineskip=0pt \carttop \hbox\bgroup \hskip\lskip \vrule\kern3pt \vbox\bgroup \hsize=\cartinner \kern3pt \begingroup \baselineskip=\normbskip \lineskip=\normlskip \parskip=\normpskip \vskip -\parskip \def\Ecartouche{% \endgroup \kern3pt \egroup \kern3pt\vrule \hskip\rskip \egroup \cartbot \egroup \endgroup }} % This macro is called at the beginning of all the @example variants, % inside a group. \def\nonfillstart{% \aboveenvbreak \inENV % This group ends at the end of the body \hfuzz = 12pt % Don't be fussy \sepspaces % Make spaces be word-separators rather than space tokens. \singlespace % single space lines \let\par = \lisppar % don't ignore blank lines \obeylines % each line of input is a line of output \parskip = 0pt \parindent = 0pt \emergencystretch = 0pt % don't try to avoid overfull boxes % @cartouche defines \nonarrowing to inhibit narrowing % at next level down. \ifx\nonarrowing\relax \advance \leftskip by \lispnarrowing \exdentamount=\lispnarrowing \let\exdent=\nofillexdent \let\nonarrowing=\relax \fi } \def\Elisp{\endgroup\afterenvbreak}% \def\lisp{\begingroup \nonfillstart \def\Elisp{\endgroup\afterenvbreak}% \tt \rawbackslash % output the \ character from the current font \gobble } % Define the \E... control sequence only if we are inside the % environment, so the error checking in \end will work. % % We must call \lisp last in the definition, since it reads the % return following the @example (or whatever) command. % \def\example{\begingroup \def\Eexample{\Elisp\endgroup}\lisp} \def\smallexample{\begingroup \def\Esmallexample{\Elisp\endgroup}\lisp} % Macro for 9 pt. examples, necessary to print with 5" lines. From % Pavel@xerox. This is not used for @smallexamples unless the % @smallbook command is given. % \def\smalllispx{\begingroup \nonfillstart \def\Esmalllisp{\endgroup\afterenvbreak}% % % Smaller interline space and fonts for small examples. \baselineskip 10pt \indexfonts \tt \rawbackslash % output the \ character from the current font \gobble } % This is @display; same as @lisp except use roman font. % \def\display{\begingroup \nonfillstart \def\Edisplay{\endgroup\afterenvbreak}% \gobble } % This is @format; same as @display except don't narrow margins. % \def\format{\begingroup \let\nonarrowing = t \nonfillstart \def\Eformat{\endgroup\afterenvbreak} \gobble } % @flushleft (same as @format) and @flushright. % \def\flushleft{\begingroup \let\nonarrowing = t \nonfillstart \def\Eflushleft{\endgroup\afterenvbreak}% \gobble } \def\flushright{\begingroup \let\nonarrowing = t \nonfillstart \def\Eflushright{\endgroup\afterenvbreak}% \advance\leftskip by 0pt plus 1fill \gobble} % @quotation does normal linebreaking and narrows the margins. % \def\quotation{% \begingroup\inENV %This group ends at the end of the @quotation body {\parskip=0pt % because we will skip by \parskip too, later \aboveenvbreak}% \singlespace \parindent=0pt \def\Equotation{\par\endgroup\afterenvbreak}% % @cartouche defines \nonarrowing to inhibit narrowing % at next level down. \ifx\nonarrowing\relax \advance \leftskip by \lispnarrowing \advance \rightskip by \lispnarrowing \exdentamount=\lispnarrowing \let\nonarrowing=\relax \fi} \message{defuns,} % Define formatter for defuns % First, allow user to change definition object font (\df) internally \def\setdeffont #1 {\csname DEF#1\endcsname} \newskip\defbodyindent \defbodyindent=.4in \newskip\defargsindent \defargsindent=50pt \newskip\deftypemargin \deftypemargin=12pt \newskip\deflastargmargin \deflastargmargin=18pt \newcount\parencount % define \functionparens, which makes ( and ) and & do special things. % \functionparens affects the group it is contained in. \def\activeparens{% \catcode`\(=\active \catcode`\)=\active \catcode`\&=\active \catcode`\[=\active \catcode`\]=\active} % Make control sequences which act like normal parenthesis chars. \let\lparen = ( \let\rparen = ) {\activeparens % Now, smart parens don't turn on until &foo (see \amprm) % Be sure that we always have a definition for `(', etc. For example, % if the fn name has parens in it, \boldbrax will not be in effect yet, % so TeX would otherwise complain about undefined control sequence. \global\let(=\lparen \global\let)=\rparen \global\let[=\lbrack \global\let]=\rbrack \gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 } \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} % Definitions of (, ) and & used in args for functions. % This is the definition of ( outside of all parentheses. \gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested % \global\advance\parencount by 1 } % % This is the definition of ( when already inside a level of parens. \gdef\opnested{\char`\(\global\advance\parencount by 1 } % \gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0. % also in that case restore the outer-level definition of (. \ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi \global\advance \parencount by -1 } % If we encounter &foo, then turn on ()-hacking afterwards \gdef\amprm#1 {{\rm\}\let(=\oprm \let)=\clrm\ } % \gdef\normalparens{\boldbrax\let&=\ampnr} } % End of definition inside \activeparens %% These parens (in \boldbrax) actually are a little bolder than the %% contained text. This is especially needed for [ and ] \def\opnr{{\sf\char`\(}} \def\clnr{{\sf\char`\)}} \def\ampnr{\&} \def\lbrb{{\bf\char`\[}} \def\rbrb{{\bf\char`\]}} % First, defname, which formats the header line itself. % #1 should be the function name. % #2 should be the type of definition, such as "Function". \def\defname #1#2{% % Get the values of \leftskip and \rightskip as they were % outside the @def... \dimen2=\leftskip \advance\dimen2 by -\defbodyindent \dimen3=\rightskip \advance\dimen3 by -\defbodyindent \noindent % \setbox0=\hbox{\hskip \deflastargmargin{\rm #2}\hskip \deftypemargin}% \dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line \dimen1=\hsize \advance \dimen1 by -\defargsindent %size for continuations \parshape 2 0in \dimen0 \defargsindent \dimen1 % % Now output arg 2 ("Function" or some such) % ending at \deftypemargin from the right margin, % but stuck inside a box of width 0 so it does not interfere with linebreaking {% Adjust \hsize to exclude the ambient margins, % so that \rightline will obey them. \advance \hsize by -\dimen2 \advance \hsize by -\dimen3 \rlap{\rightline{{\rm #2}\hskip \deftypemargin}}}% % Make all lines underfull and no complaints: \tolerance=10000 \hbadness=10000 \advance\leftskip by -\defbodyindent \exdentamount=\defbodyindent {\df #1}\enskip % Generate function name } % Actually process the body of a definition % #1 should be the terminating control sequence, such as \Edefun. % #2 should be the "another name" control sequence, such as \defunx. % #3 should be the control sequence that actually processes the header, % such as \defunheader. \def\defparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2{\begingroup\obeylines\activeparens\spacesplit#3}% \parindent=0in \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent \exdentamount=\defbodyindent \begingroup % \catcode 61=\active % \obeylines\activeparens\spacesplit#3} \def\defmethparsebody #1#2#3#4 {\begingroup\inENV % \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2##1 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}}}% \parindent=0in \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent \exdentamount=\defbodyindent \begingroup\obeylines\activeparens\spacesplit{#3{#4}}} \def\defopparsebody #1#2#3#4#5 {\begingroup\inENV % \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2##1 ##2 {\def#4{##1}% \begingroup\obeylines\activeparens\spacesplit{#3{##2}}}% \parindent=0in \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent \exdentamount=\defbodyindent \begingroup\obeylines\activeparens\spacesplit{#3{#5}}} % These parsing functions are similar to the preceding ones % except that they do not make parens into active characters. % These are used for "variables" since they have no arguments. \def\defvarparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2{\begingroup\obeylines\spacesplit#3}% \parindent=0in \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent \exdentamount=\defbodyindent \begingroup % \catcode 61=\active % \obeylines\spacesplit#3} \def\defvrparsebody #1#2#3#4 {\begingroup\inENV % \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2##1 {\begingroup\obeylines\spacesplit{#3{##1}}}% \parindent=0in \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent \exdentamount=\defbodyindent \begingroup\obeylines\spacesplit{#3{#4}}} % This seems to work right in all cases. \let\deftpparsebody=\defvrparsebody % This fails to work. When given `@deftp {Data Type} foo_t', % it thinks the type name is just `f'. %%% This is the same as all the others except for the last line. We need %%% to parse the arguments differently for @deftp, since the ``attributes'' %%% there are optional. %%% %%\def\deftpparsebody #1#2#3#4 {\begingroup\inENV % %%\medbreak % %%% Define the end token that this defining construct specifies %%% so that it will exit this group. %%\def#1{\endgraf\endgroup\medbreak}% %%\def#2##1 {\begingroup\obeylines\spacesplit{#3{##1}}}% %%\parindent=0in %%\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent %%\exdentamount=\defbodyindent %%\begingroup\obeylines\parsetpheaderline{#3{#4}}} %%{\obeylines % %% % Parse the type name and any attributes (field names, etc.). %% % #1 is the beginning of the macro call that will produce the output, %% % i.e., \deftpheader{CLASS}; this is passed from \deftpparsebody. %% % #2 is the type name, e.g., `struct termios'. %% % #3 is the (possibly empty) attribute list. %% % %% \gdef\parsetpheaderline#1#2#3^^M{% %% \endgroup % Started in \deftpparsebody. %% % %% % If the attribute list is in fact empty, there will be no space after %% % #2; so we can't put a space in our TeX parameter list. But if it %% % isn't empty, then #3 will begin with an unwanted space. %% \def\theargs{\ignorespaces #3}% %% % %% % Call the macro to produce the output. %% #1{#2}\theargs % %% }% %%} \def\defopvarparsebody #1#2#3#4#5 {\begingroup\inENV % \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2##1 ##2 {\def#4{##1}% \begingroup\obeylines\spacesplit{#3{##2}}}% \parindent=0in \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent \exdentamount=\defbodyindent \begingroup\obeylines\spacesplit{#3{#5}}} % Split up #2 at the first space token. % call #1 with two arguments: % the first is all of #2 before the space token, % the second is all of #2 after that space token. % If #2 contains no space token, all of it is passed as the first arg % and the second is passed as empty. {\obeylines \gdef\spacesplit#1#2^^M{\endgroup\spacesplitfoo{#1}#2 \relax\spacesplitfoo}% \long\gdef\spacesplitfoo#1#2 #3#4\spacesplitfoo{% \ifx\relax #3% #1{#2}{}\else #1{#2}{#3#4}\fi}} % So much for the things common to all kinds of definitions. % Define @defun. % First, define the processing that is wanted for arguments of \defun % Use this to expand the args and terminate the paragraph they make up \def\defunargs #1{\functionparens \sl % Expand, preventing hyphenation at `-' chars. % Note that groups don't affect changes in \hyphenchar. \hyphenchar\tensl=0 #1% \hyphenchar\tensl=45 \ifnum\parencount=0 \else \errmessage{unbalanced parens in @def arguments}\fi% \interlinepenalty=10000 \advance\rightskip by 0pt plus 1fil \endgraf\penalty 10000\vskip -\parskip\penalty 10000% } \def\deftypefunargs #1{% % Expand, preventing hyphenation at `-' chars. % Note that groups don't affect changes in \hyphenchar. \functionparens \code{#1}% \interlinepenalty=10000 \advance\rightskip by 0pt plus 1fil \endgraf\penalty 10000\vskip -\parskip\penalty 10000% } % Do complete processing of one @defun or @defunx line already parsed. % @deffn Command forward-char nchars \def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader} \def\deffnheader #1#2#3{\doind {fn}{\code{#2}}% \begingroup\defname {#2}{#1}\defunargs{#3}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @defun == @deffn Function \def\defun{\defparsebody\Edefun\defunx\defunheader} \def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{Function}% \defunargs {#2}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @deftypefun int foobar (int @var{foo}, float @var{bar}) \def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader} % #1 is the data type. #2 is the name and args. \def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax} % #1 is the data type, #2 the name, #3 the args. \def\deftypefunheaderx #1#2 #3\relax{% \doind {fn}{\code{#2}}% Make entry in function index \begingroup\defname {\code{#1} #2}{Function}% \deftypefunargs {#3}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar}) \def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader} % #1 is the classification. #2 is the data type. #3 is the name and args. \def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax} % #1 is the classification, #2 the data type, #3 the name, #4 the args. \def\deftypefnheaderx #1#2#3 #4\relax{% \doind {fn}{\code{#3}}% Make entry in function index \begingroup\defname {\code{#2} #3}{#1}% \deftypefunargs {#4}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @defmac == @deffn Macro \def\defmac{\defparsebody\Edefmac\defmacx\defmacheader} \def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{Macro}% \defunargs {#2}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @defspec == @deffn Special Form \def\defspec{\defparsebody\Edefspec\defspecx\defspecheader} \def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{Special Form}% \defunargs {#2}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % This definition is run if you use @defunx % anywhere other than immediately after a @defun or @defunx. \def\deffnx #1 {\errmessage{@deffnx in invalid context}} \def\defunx #1 {\errmessage{@defunx in invalid context}} \def\defmacx #1 {\errmessage{@defmacx in invalid context}} \def\defspecx #1 {\errmessage{@defspecx in invalid context}} \def\deftypefnx #1 {\errmessage{@deftypefnx in invalid context}} \def\deftypeunx #1 {\errmessage{@deftypeunx in invalid context}} % @defmethod, and so on % @defop {Funny Method} foo-class frobnicate argument \def\defop #1 {\def\defoptype{#1}% \defopparsebody\Edefop\defopx\defopheader\defoptype} \def\defopheader #1#2#3{% \dosubind {fn}{\code{#2}}{on #1}% Make entry in function index \begingroup\defname {#2}{\defoptype{} on #1}% \defunargs {#3}\endgroup % } % @defmethod == @defop Method \def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader} \def\defmethodheader #1#2#3{% \dosubind {fn}{\code{#2}}{on #1}% entry in function index \begingroup\defname {#2}{Method on #1}% \defunargs {#3}\endgroup % } % @defcv {Class Option} foo-class foo-flag \def\defcv #1 {\def\defcvtype{#1}% \defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype} \def\defcvarheader #1#2#3{% \dosubind {vr}{\code{#2}}{of #1}% Make entry in var index \begingroup\defname {#2}{\defcvtype{} of #1}% \defvarargs {#3}\endgroup % } % @defivar == @defcv {Instance Variable} \def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader} \def\defivarheader #1#2#3{% \dosubind {vr}{\code{#2}}{of #1}% Make entry in var index \begingroup\defname {#2}{Instance Variable of #1}% \defvarargs {#3}\endgroup % } % These definitions are run if you use @defmethodx, etc., % anywhere other than immediately after a @defmethod, etc. \def\defopx #1 {\errmessage{@defopx in invalid context}} \def\defmethodx #1 {\errmessage{@defmethodx in invalid context}} \def\defcvx #1 {\errmessage{@defcvx in invalid context}} \def\defivarx #1 {\errmessage{@defivarx in invalid context}} % Now @defvar % First, define the processing that is wanted for arguments of @defvar. % This is actually simple: just print them in roman. % This must expand the args and terminate the paragraph they make up \def\defvarargs #1{\normalparens #1% \interlinepenalty=10000 \endgraf\penalty 10000\vskip -\parskip\penalty 10000} % @defvr Counter foo-count \def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader} \def\defvrheader #1#2#3{\doind {vr}{\code{#2}}% \begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup} % @defvar == @defvr Variable \def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader} \def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index \begingroup\defname {#1}{Variable}% \defvarargs {#2}\endgroup % } % @defopt == @defvr {User Option} \def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader} \def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index \begingroup\defname {#1}{User Option}% \defvarargs {#2}\endgroup % } % @deftypevar int foobar \def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader} % #1 is the data type. #2 is the name. \def\deftypevarheader #1#2{% \doind {vr}{\code{#2}}% Make entry in variables index \begingroup\defname {\code{#1} #2}{Variable}% \interlinepenalty=10000 \endgraf\penalty 10000\vskip -\parskip\penalty 10000 \endgroup} % @deftypevr {Global Flag} int enable \def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader} \def\deftypevrheader #1#2#3{\doind {vr}{\code{#3}}% \begingroup\defname {\code{#2} #3}{#1} \interlinepenalty=10000 \endgraf\penalty 10000\vskip -\parskip\penalty 10000 \endgroup} % This definition is run if you use @defvarx % anywhere other than immediately after a @defvar or @defvarx. \def\defvrx #1 {\errmessage{@defvrx in invalid context}} \def\defvarx #1 {\errmessage{@defvarx in invalid context}} \def\defoptx #1 {\errmessage{@defoptx in invalid context}} \def\deftypevarx #1 {\errmessage{@deftypevarx in invalid context}} \def\deftypevrx #1 {\errmessage{@deftypevrx in invalid context}} % Now define @deftp % Args are printed in bold, a slight difference from @defvar. \def\deftpargs #1{\bf \defvarargs{#1}} % @deftp Class window height width ... \def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader} \def\deftpheader #1#2#3{\doind {tp}{\code{#2}}% \begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup} % This definition is run if you use @deftpx, etc % anywhere other than immediately after a @deftp, etc. \def\deftpx #1 {\errmessage{@deftpx in invalid context}} \message{cross reference,} % Define cross-reference macros \newwrite \auxfile \newif\ifhavexrefs % True if xref values are known. \newif\ifwarnedxrefs % True if we warned once that they aren't known. % \setref{foo} defines a cross-reference point named foo. \def\setref#1{% %\dosetq{#1-title}{Ytitle}% \dosetq{#1-pg}{Ypagenumber}% \dosetq{#1-snt}{Ysectionnumberandtype}} \def\unnumbsetref#1{% %\dosetq{#1-title}{Ytitle}% \dosetq{#1-pg}{Ypagenumber}% \dosetq{#1-snt}{Ynothing}} \def\appendixsetref#1{% %\dosetq{#1-title}{Ytitle}% \dosetq{#1-pg}{Ypagenumber}% \dosetq{#1-snt}{Yappendixletterandtype}} % \xref, \pxref, and \ref generate cross-references to specified points. % For \xrefX, #1 is the node name, #2 the name of the Info % cross-reference, #3 the printed node name, #4 the name of the Info % file, #5 the name of the printed manual. All but the node name can be % omitted. % \def\pxref#1{see \xrefX[#1,,,,,,,]} \def\xref#1{See \xrefX[#1,,,,,,,]} \def\ref#1{\xrefX[#1,,,,,,,]} \def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup% \def\printedmanual{\ignorespaces #5}% \def\printednodename{\ignorespaces #3}% % \setbox1=\hbox{\printedmanual}% \setbox0=\hbox{\printednodename}% \ifdim \wd0=0pt% \def\printednodename{\ignorespaces #1}% %%% Uncommment the following line to make the actual chapter or section title %%% appear inside the square brackets. %\def\printednodename{#1-title}% \fi% % % % If we use \unhbox0 and \unhbox1 to print the node names, TeX does % not insert empty discretionaries after hyphens, which means that it % will not find a line break at a hyphen in a node names. Since some % manuals are best written with fairly long node names, containing % hyphens, this is a loss. Therefore, we simply give the text of % the node name again, so it is as if TeX is seeing it for the first % time. \ifdim \wd1>0pt section ``\printednodename'' in \cite{\printedmanual}% \else% \turnoffactive% \refx{#1-snt}{} [\printednodename], page\tie\refx{#1-pg}{}% \fi \endgroup} % \dosetq is the interface for calls from other macros % Use \turnoffactive so that punctuation chars such as underscore % work in node names. \def\dosetq #1#2{{\let\folio=0 \turnoffactive% \edef\next{\write\auxfile{\internalsetq {#1}{#2}}}% \next}} % \internalsetq {foo}{page} expands into % CHARACTERS 'xrdef {foo}{...expansion of \Ypage...} % When the aux file is read, ' is the escape character \def\internalsetq #1#2{'xrdef {#1}{\csname #2\endcsname}} % Things to be expanded by \internalsetq \def\Ypagenumber{\folio} \def\Ytitle{\thischapter} \def\Ynothing{} \def\Ysectionnumberandtype{% \ifnum\secno=0 Chapter\xreftie\the\chapno % \else \ifnum \subsecno=0 Section\xreftie\the\chapno.\the\secno % \else \ifnum \subsubsecno=0 % Section\xreftie\the\chapno.\the\secno.\the\subsecno % \else % Section\xreftie\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno % \fi \fi \fi } \def\Yappendixletterandtype{% \ifnum\secno=0 Appendix\xreftie'char\the\appendixno{}% \else \ifnum \subsecno=0 Section\xreftie'char\the\appendixno.\the\secno % \else \ifnum \subsubsecno=0 % Section\xreftie'char\the\appendixno.\the\secno.\the\subsecno % \else % Section\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % \fi \fi \fi } \gdef\xreftie{'tie} % Use TeX 3.0's \inputlineno to get the line number, for better error % messages, but if we're using an old version of TeX, don't do anything. % \ifx\inputlineno\thisisundefined \let\linenumber = \empty % Non-3.0. \else \def\linenumber{\the\inputlineno:\space} \fi % Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. % If its value is nonempty, SUFFIX is output afterward. \def\refx#1#2{% \expandafter\ifx\csname X#1\endcsname\relax % If not defined, say something at least. $\langle$un\-de\-fined$\rangle$% \ifhavexrefs \message{\linenumber Undefined cross reference `#1'.}% \else \ifwarnedxrefs\else \global\warnedxrefstrue \message{Cross reference values unknown; you must run TeX again.}% \fi \fi \else % It's defined, so just use it. \csname X#1\endcsname \fi #2% Output the suffix in any case. } % Read the last existing aux file, if any. No error if none exists. % This is the macro invoked by entries in the aux file. \def\xrdef #1#2{ {\catcode`\'=\other\expandafter \gdef \csname X#1\endcsname {#2}}} \def\readauxfile{% \begingroup \catcode `\^^@=\other \catcode `\=\other \catcode `\=\other \catcode `\^^C=\other \catcode `\^^D=\other \catcode `\^^E=\other \catcode `\^^F=\other \catcode `\^^G=\other \catcode `\^^H=\other \catcode `\ =\other \catcode `\^^L=\other \catcode `\=\other \catcode `\=\other \catcode `\=\other \catcode `\=\other \catcode `\=\other \catcode `\=\other \catcode `\=\other \catcode `\=\other \catcode `\=\other \catcode `\=\other \catcode `\=\other \catcode `\=\other \catcode 26=\other \catcode `\^^[=\other \catcode `\^^\=\other \catcode `\^^]=\other \catcode `\^^^=\other \catcode `\^^_=\other \catcode `\@=\other \catcode `\^=\other \catcode `\~=\other \catcode `\[=\other \catcode `\]=\other \catcode`\"=\other \catcode`\_=\other \catcode`\|=\other \catcode`\<=\other \catcode`\>=\other \catcode `\$=\other \catcode `\#=\other \catcode `\&=\other % `\+ does not work, so use 43. \catcode 43=\other % the aux file uses ' as the escape. % Turn off \ as an escape so we do not lose on % entries which were dumped with control sequences in their names. % For example, 'xrdef {$\leq $-fun}{page ...} made by @defun ^^ % Reference to such entries still does not work the way one would wish, % but at least they do not bomb out when the aux file is read in. \catcode `\{=1 \catcode `\}=2 \catcode `\%=\other \catcode `\'=0 \catcode `\\=\other \openin 1 \jobname.aux \ifeof 1 \else \closein 1 \input \jobname.aux \global\havexrefstrue \global\warnedobstrue \fi % Open the new aux file. Tex will close it automatically at exit. \openout \auxfile=\jobname.aux \endgroup} % Footnotes. \newcount \footnoteno % The trailing space in the following definition for supereject is % vital for proper filling; pages come out unaligned when you do a % pagealignmacro call if that space before the closing brace is % removed. \def\supereject{\par\penalty -20000\footnoteno =0 } % @footnotestyle is meaningful for info output only.. \let\footnotestyle=\comment \let\ptexfootnote=\footnote {\catcode `\@=11 % % Auto-number footnotes. Otherwise like plain. \gdef\footnote{% \global\advance\footnoteno by \@ne \edef\thisfootno{$^{\the\footnoteno}$}% % % In case the footnote comes at the end of a sentence, preserve the % extra spacing after we do the footnote number. \let\@sf\empty \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\/\fi % % Remove inadvertent blank space before typesetting the footnote number. \unskip \thisfootno\@sf \footnotezzz }% % Don't bother with the trickery in plain.tex to not require the % footnote text as a parameter. Our footnotes don't need to be so general. % \long\gdef\footnotezzz#1{\insert\footins{% % We want to typeset this text as a normal paragraph, even if the % footnote reference occurs in (for example) a display environment. % So reset some parameters. \interlinepenalty\interfootnotelinepenalty \splittopskip\ht\strutbox % top baseline for broken footnotes \splitmaxdepth\dp\strutbox \floatingpenalty\@MM \leftskip\z@skip \rightskip\z@skip \spaceskip\z@skip \xspaceskip\z@skip \parindent\defaultparindent % % Hang the footnote text off the number. \hang \textindent{\thisfootno}% % % Don't crash into the line above the footnote text. Since this % expands into a box, it must come within the paragraph, lest it % provide a place where TeX can split the footnote. \footstrut #1\strut}% } }%end \catcode `\@=11 % Set the baselineskip to #1, and the lineskip and strut size % correspondingly. There is no deep meaning behind these magic numbers % used as factors; they just match (closely enough) what Knuth defined. % \def\lineskipfactor{.1} \def\strutheightpercent{.71} \def\strutdepthpercent{.29} % \def\setleading#1{% \baselineskip = #1\relax \normalbaselineskip = \baselineskip \lineskip = \lineskipfactor\baselineskip \setbox\strutbox =\hbox{% \vrule width0pt height\strutheightpercent\baselineskip depth \strutdepthpercent \baselineskip }% } % @| inserts a changebar to the left of the current line. It should % surround any changed text. This approach does *not* work if the % change spans more than two lines of output. To handle that, we would % have adopt a much more difficult approach (putting marks into the main % vertical list for the beginning and end of each change). % \def\|{% % \vadjust can only be used in horizontal mode. \leavevmode % % Append this vertical mode material after the current line in the output. \vadjust{% % We want to insert a rule with the height and depth of the current % leading; that is exactly what \strutbox is supposed to record. \vskip-\baselineskip % % \vadjust-items are inserted at the left edge of the type. So % the \llap here moves out into the left-hand margin. \llap{% % % For a thicker or thinner bar, change the `1pt'. \vrule height\baselineskip width1pt % % This is the space between the bar and the text. \hskip 12pt }% }% } % For a final copy, take out the rectangles % that mark overfull boxes (in case you have decided % that the text looks ok even though it passes the margin). % \def\finalout{\overfullrule=0pt} % End of control word definitions. \message{and turning on texinfo input format.} \def\openindices{% \newindex{cp}% \newcodeindex{fn}% \newcodeindex{vr}% \newcodeindex{tp}% \newcodeindex{ky}% \newcodeindex{pg}% } % Set some numeric style parameters, for 8.5 x 11 format. %\hsize = 6.5in \newdimen\defaultparindent \defaultparindent = 15pt \parindent = \defaultparindent \parskip 18pt plus 1pt \setleading{15pt} \advance\topskip by 1.2cm % Prevent underfull vbox error messages. \vbadness=10000 % Following George Bush, just get rid of widows and orphans. \widowpenalty=10000 \clubpenalty=10000 % Use TeX 3.0's \emergencystretch to help line breaking, but if we're % using an old version of TeX, don't do anything. We want the amount of % stretch added to depend on the line length, hence the dependence on % \hsize. This makes it come to about 9pt for the 8.5x11 format. % \ifx\emergencystretch\thisisundefined % Allow us to assign to \emergencystretch anyway. \def\emergencystretch{\dimen0}% \else \emergencystretch = \hsize \divide\emergencystretch by 45 \fi % Use @smallbook to reset parameters for 7x9.5 format (or else 7x9.25) \def\smallbook{ % These values for secheadingskip and subsecheadingskip are % experiments. RJC 7 Aug 1992 \global\secheadingskip = 17pt plus 6pt minus 3pt \global\subsecheadingskip = 14pt plus 6pt minus 3pt \global\lispnarrowing = 0.3in \setleading{12pt} \advance\topskip by -1cm \global\parskip 3pt plus 1pt \global\hsize = 5in \global\vsize=7.5in \global\tolerance=700 \global\hfuzz=1pt \global\contentsrightmargin=0pt \global\pagewidth=\hsize \global\pageheight=\vsize \global\let\smalllisp=\smalllispx \global\let\smallexample=\smalllispx \global\def\Esmallexample{\Esmalllisp} } % Use @afourpaper to print on European A4 paper. \def\afourpaper{ \global\tolerance=700 \global\hfuzz=1pt \setleading{12pt} \global\parskip 15pt plus 1pt \global\vsize= 53\baselineskip \advance\vsize by \topskip %\global\hsize= 5.85in % A4 wide 10pt \global\hsize= 6.5in \global\outerhsize=\hsize \global\advance\outerhsize by 0.5in \global\outervsize=\vsize \global\advance\outervsize by 0.6in \global\pagewidth=\hsize \global\pageheight=\vsize } % Define macros to output various characters with catcode for normal text. \catcode`\"=\other \catcode`\~=\other \catcode`\^=\other \catcode`\_=\other \catcode`\|=\other \catcode`\<=\other \catcode`\>=\other \catcode`\+=\other \def\normaldoublequote{"} \def\normaltilde{~} \def\normalcaret{^} \def\normalunderscore{_} \def\normalverticalbar{|} \def\normalless{<} \def\normalgreater{>} \def\normalplus{+} % This macro is used to make a character print one way in ttfont % where it can probably just be output, and another way in other fonts, % where something hairier probably needs to be done. % % #1 is what to print if we are indeed using \tt; #2 is what to print % otherwise. Since all the Computer Modern typewriter fonts have zero % interword stretch (and shrink), and it is reasonable to expect all % typewriter fonts to have this, we can check that font parameter. % \def\ifusingtt#1#2{\ifdim \fontdimen3\the\font=0pt #1\else #2\fi} % Turn off all special characters except @ % (and those which the user can use as if they were ordinary). % Most of these we simply print from the \tt font, but for some, we can % use math or other variants that look better in normal text. \catcode`\"=\active \def\activedoublequote{{\tt \char '042}} \let"=\activedoublequote \catcode`\~=\active \def~{{\tt \char '176}} \chardef\hat=`\^ \catcode`\^=\active \def^{{\tt \hat}} \catcode`\_=\active \def_{\ifusingtt\normalunderscore\_} % Subroutine for the previous macro. \def\_{\lvvmode \kern.06em \vbox{\hrule width.3em height.1ex}} % \lvvmode is equivalent in function to \leavevmode. % Using \leavevmode runs into trouble when written out to % an index file due to the expansion of \leavevmode into ``\unhbox % \voidb@x'' ---which looks to TeX like ``\unhbox \voidb\x'' due to our % magic tricks with @. \def\lvvmode{\vbox to 0pt{}} \catcode`\|=\active \def|{{\tt \char '174}} \chardef \less=`\< \catcode`\<=\active \def<{{\tt \less}} \chardef \gtr=`\> \catcode`\>=\active \def>{{\tt \gtr}} \catcode`\+=\active \def+{{\tt \char 43}} %\catcode 27=\active %\def^^[{$\diamondsuit$} % Used sometimes to turn off (effectively) the active characters % even after parsing them. \def\turnoffactive{\let"=\normaldoublequote \let~=\normaltilde \let^=\normalcaret \let_=\normalunderscore \let|=\normalverticalbar \let<=\normalless \let>=\normalgreater \let+=\normalplus} % Set up an active definition for =, but don't enable it most of the time. {\catcode`\==\active \global\def={{\tt \char 61}}} \catcode`\@=0 % \rawbackslashxx output one backslash character in current font \global\chardef\rawbackslashxx=`\\ %{\catcode`\\=\other %@gdef@rawbackslashxx{\}} % \rawbackslash redefines \ as input to do \rawbackslashxx. {\catcode`\\=\active @gdef@rawbackslash{@let\=@rawbackslashxx }} % \normalbackslash outputs one backslash in fixed width font. \def\normalbackslash{{\tt\rawbackslashxx}} % Say @foo, not \foo, in error messages. \escapechar=`\@ % \catcode 17=0 % Define control-q \catcode`\\=\active % If a .fmt file is being used, we don't want the `\input texinfo' to show up. % That is what \eatinput is for; after that, the `\' should revert to printing % a backslash. % @gdef@eatinput input texinfo{@fixbackslash} @global@let\ = @eatinput % On the other hand, perhaps the file did not have a `\input texinfo'. Then % the first `\{ in the file would cause an error. This macro tries to fix % that, assuming it is called before the first `\' could plausibly occur. % @gdef@fixbackslash{@ifx\@eatinput @let\ = @normalbackslash @fi} %% These look ok in all fonts, so just make them not special. The @rm below %% makes sure that the current font starts out as the newly loaded cmr10 @catcode`@$=@other @catcode`@%=@other @catcode`@&=@other @catcode`@#=@other @textfonts @rm @c Local variables: @c page-delimiter: "^\\\\message" @c End: lyskom-server-2.1.2/src/libraries/regex/doc/.cvsignore0000664000015100472110000000002506701512230016430 Makefile Makefile.in lyskom-server-2.1.2/src/libraries/regex/doc/include.awk0000664000015100472110000000120505314452713016570 # Assume `source' is set with -vsource=filename on the command line. # /^\[\[\[/ { inclusion = $2; # name of the thing to include. printing = 0; while ((getline line < source) > 0) { if (match (line, "\\[\\[\\[end " inclusion "\\]\\]\\]")) printing = 0; if (printing) print line; if (match (line,"\\[\\[\\[begin " inclusion "\\]\\]\\]")) printing = 1; } close (source); next; } { print } lyskom-server-2.1.2/src/libraries/regex/doc/regex.aux0000664000015100472110000001372005533104507016275 'xrdef {Overview-pg}{1} 'xrdef {Overview-snt}{Chapter'tie1} 'xrdef {Regular Expression Syntax-pg}{2} 'xrdef {Regular Expression Syntax-snt}{Chapter'tie2} 'xrdef {Syntax Bits-pg}{2} 'xrdef {Syntax Bits-snt}{Section'tie2.1} 'xrdef {Predefined Syntaxes-pg}{5} 'xrdef {Predefined Syntaxes-snt}{Section'tie2.2} 'xrdef {Collating Elements vs. Characters-pg}{6} 'xrdef {Collating Elements vs. Characters-snt}{Section'tie2.3} 'xrdef {The Backslash Character-pg}{7} 'xrdef {The Backslash Character-snt}{Section'tie2.4} 'xrdef {Common Operators-pg}{9} 'xrdef {Common Operators-snt}{Chapter'tie3} 'xrdef {Match-self Operator-pg}{9} 'xrdef {Match-self Operator-snt}{Section'tie3.1} 'xrdef {Match-any-character Operator-pg}{9} 'xrdef {Match-any-character Operator-snt}{Section'tie3.2} 'xrdef {Concatenation Operator-pg}{10} 'xrdef {Concatenation Operator-snt}{Section'tie3.3} 'xrdef {Repetition Operators-pg}{10} 'xrdef {Repetition Operators-snt}{Section'tie3.4} 'xrdef {Match-zero-or-more Operator-pg}{10} 'xrdef {Match-zero-or-more Operator-snt}{Section'tie3.4.1} 'xrdef {Match-one-or-more Operator-pg}{11} 'xrdef {Match-one-or-more Operator-snt}{Section'tie3.4.2} 'xrdef {Match-zero-or-one Operator-pg}{11} 'xrdef {Match-zero-or-one Operator-snt}{Section'tie3.4.3} 'xrdef {Interval Operators-pg}{12} 'xrdef {Interval Operators-snt}{Section'tie3.4.4} 'xrdef {Alternation Operator-pg}{13} 'xrdef {Alternation Operator-snt}{Section'tie3.5} 'xrdef {List Operators-pg}{13} 'xrdef {List Operators-snt}{Section'tie3.6} 'xrdef {Character Class Operators-pg}{14} 'xrdef {Character Class Operators-snt}{Section'tie3.6.1} 'xrdef {Range Operator-pg}{15} 'xrdef {Range Operator-snt}{Section'tie3.6.2} 'xrdef {Grouping Operators-pg}{16} 'xrdef {Grouping Operators-snt}{Section'tie3.7} 'xrdef {Back-reference Operator-pg}{17} 'xrdef {Back-reference Operator-snt}{Section'tie3.8} 'xrdef {Anchoring Operators-pg}{18} 'xrdef {Anchoring Operators-snt}{Section'tie3.9} 'xrdef {Match-beginning-of-line Operator-pg}{18} 'xrdef {Match-beginning-of-line Operator-snt}{Section'tie3.9.1} 'xrdef {Match-end-of-line Operator-pg}{18} 'xrdef {Match-end-of-line Operator-snt}{Section'tie3.9.2} 'xrdef {GNU Operators-pg}{20} 'xrdef {GNU Operators-snt}{Chapter'tie4} 'xrdef {Word Operators-pg}{20} 'xrdef {Word Operators-snt}{Section'tie4.1} 'xrdef {Non-Emacs Syntax Tables-pg}{20} 'xrdef {Non-Emacs Syntax Tables-snt}{Section'tie4.1.1} 'xrdef {Match-word-boundary Operator-pg}{20} 'xrdef {Match-word-boundary Operator-snt}{Section'tie4.1.2} 'xrdef {Match-within-word Operator-pg}{20} 'xrdef {Match-within-word Operator-snt}{Section'tie4.1.3} 'xrdef {Match-beginning-of-word Operator-pg}{21} 'xrdef {Match-beginning-of-word Operator-snt}{Section'tie4.1.4} 'xrdef {Match-end-of-word Operator-pg}{21} 'xrdef {Match-end-of-word Operator-snt}{Section'tie4.1.5} 'xrdef {Match-word-constituent Operator-pg}{21} 'xrdef {Match-word-constituent Operator-snt}{Section'tie4.1.6} 'xrdef {Match-non-word-constituent Operator-pg}{21} 'xrdef {Match-non-word-constituent Operator-snt}{Section'tie4.1.7} 'xrdef {Buffer Operators-pg}{21} 'xrdef {Buffer Operators-snt}{Section'tie4.2} 'xrdef {Match-beginning-of-buffer Operator-pg}{21} 'xrdef {Match-beginning-of-buffer Operator-snt}{Section'tie4.2.1} 'xrdef {Match-end-of-buffer Operator-pg}{21} 'xrdef {Match-end-of-buffer Operator-snt}{Section'tie4.2.2} 'xrdef {GNU Emacs Operators-pg}{22} 'xrdef {GNU Emacs Operators-snt}{Chapter'tie5} 'xrdef {Syntactic Class Operators-pg}{22} 'xrdef {Syntactic Class Operators-snt}{Section'tie5.1} 'xrdef {Emacs Syntax Tables-pg}{22} 'xrdef {Emacs Syntax Tables-snt}{Section'tie5.1.1} 'xrdef {Match-syntactic-class Operator-pg}{22} 'xrdef {Match-syntactic-class Operator-snt}{Section'tie5.1.2} 'xrdef {Match-not-syntactic-class Operator-pg}{22} 'xrdef {Match-not-syntactic-class Operator-snt}{Section'tie5.1.3} 'xrdef {What Gets Matched?-pg}{23} 'xrdef {What Gets Matched?-snt}{Chapter'tie6} 'xrdef {Programming with Regex-pg}{24} 'xrdef {Programming with Regex-snt}{Chapter'tie7} 'xrdef {GNU Regex Functions-pg}{24} 'xrdef {GNU Regex Functions-snt}{Section'tie7.1} 'xrdef {GNU Pattern Buffers-pg}{24} 'xrdef {GNU Pattern Buffers-snt}{Section'tie7.1.1} 'xrdef {GNU Regular Expression Compiling-pg}{26} 'xrdef {GNU Regular Expression Compiling-snt}{Section'tie7.1.2} 'xrdef {GNU Matching-pg}{27} 'xrdef {GNU Matching-snt}{Section'tie7.1.3} 'xrdef {GNU Searching-pg}{28} 'xrdef {GNU Searching-snt}{Section'tie7.1.4} 'xrdef {Matching/Searching with Split Data-pg}{29} 'xrdef {Matching/Searching with Split Data-snt}{Section'tie7.1.5} 'xrdef {Searching with Fastmaps-pg}{30} 'xrdef {Searching with Fastmaps-snt}{Section'tie7.1.6} 'xrdef {GNU Translate Tables-pg}{31} 'xrdef {GNU Translate Tables-snt}{Section'tie7.1.7} 'xrdef {Using Registers-pg}{32} 'xrdef {Using Registers-snt}{Section'tie7.1.8} 'xrdef {Freeing GNU Pattern Buffers-pg}{34} 'xrdef {Freeing GNU Pattern Buffers-snt}{Section'tie7.1.9} 'xrdef {POSIX Regex Functions-pg}{35} 'xrdef {POSIX Regex Functions-snt}{Section'tie7.2} 'xrdef {POSIX Pattern Buffers-pg}{35} 'xrdef {POSIX Pattern Buffers-snt}{Section'tie7.2.1} 'xrdef {POSIX Regular Expression Compiling-pg}{35} 'xrdef {POSIX Regular Expression Compiling-snt}{Section'tie7.2.2} 'xrdef {POSIX Matching-pg}{37} 'xrdef {POSIX Matching-snt}{Section'tie7.2.3} 'xrdef {Reporting Errors-pg}{38} 'xrdef {Reporting Errors-snt}{Section'tie7.2.4} 'xrdef {Using Byte Offsets-pg}{39} 'xrdef {Using Byte Offsets-snt}{Section'tie7.2.5} 'xrdef {Freeing POSIX Pattern Buffers-pg}{39} 'xrdef {Freeing POSIX Pattern Buffers-snt}{Section'tie7.2.6} 'xrdef {BSD Regex Functions-pg}{40} 'xrdef {BSD Regex Functions-snt}{Section'tie7.3} 'xrdef {BSD Regular Expression Compiling-pg}{40} 'xrdef {BSD Regular Expression Compiling-snt}{Section'tie7.3.1} 'xrdef {BSD Searching-pg}{40} 'xrdef {BSD Searching-snt}{Section'tie7.3.2} 'xrdef {Copying-pg}{42} 'xrdef {Copying-snt}{Appendix'tie'char65{}} 'xrdef {Copying-pg}{42} 'xrdef {Copying-snt}{} 'xrdef {Copying-pg}{43} 'xrdef {Copying-snt}{} 'xrdef {Copying-pg}{48} 'xrdef {Copying-snt}{} 'xrdef {Index-pg}{50} 'xrdef {Index-snt}{} lyskom-server-2.1.2/src/libraries/regex/doc/regex.cps0000664000015100472110000001322705533104514016265 \initial {$} \entry {\code {$}}{18} \initial {(} \entry {\code {(}}{16} \initial {)} \entry {\code {)}}{16} \initial {*} \entry {\samp {*}}{10} \initial {-} \entry {\samp {-}}{13} \initial {.} \entry {\samp {.}}{9} \initial {:} \entry {\samp {:]} in regex}{14} \initial {?} \entry {\samp {?}}{11} \initial {[} \entry {\samp {[}}{13} \entry {\samp {[:} in regex}{14} \entry {\samp {[{\tt\hat}}}{13} \initial {]} \entry {\samp {]}}{13} \initial {{\tt\char'173}} \entry {\samp {{\tt\char'173}}}{12} \initial {{\tt\char'174}} \entry {\code {{\tt\char'174}}}{13} \initial {{\tt\char'175}} \entry {\samp {{\tt\char'175}}}{12} \initial {{\tt\char43}} \entry {\samp {{\tt\char43}}}{11} \initial {{\tt\hat}} \entry {\samp {{\tt\hat}}}{13} \entry {\code {{\tt\hat}}}{18} \initial {{\tt\indexbackslash }} \entry {{\tt\indexbackslash }}{7} \entry {\samp {{\tt\indexbackslash }}}{13} \entry {\samp {{\tt\indexbackslash }'}}{21} \entry {\code {{\tt\indexbackslash }(}}{16} \entry {\code {{\tt\indexbackslash })}}{16} \entry {\samp {{\tt\indexbackslash }`}}{21} \entry {\samp {{\tt\indexbackslash }{\tt\char'173}}}{12} \entry {\code {{\tt\indexbackslash }{\tt\char'174}}}{13} \entry {\samp {{\tt\indexbackslash }{\tt\char'175}}}{12} \entry {\samp {{\tt\indexbackslash }{\tt\gtr}}}{21} \entry {\samp {{\tt\indexbackslash }{\tt\less}}}{21} \entry {\samp {{\tt\indexbackslash }b}}{20} \entry {\samp {{\tt\indexbackslash }B}}{20} \entry {\samp {{\tt\indexbackslash }s}}{22} \entry {\samp {{\tt\indexbackslash }S}}{22} \entry {\samp {{\tt\indexbackslash }w}}{21} \entry {\samp {{\tt\indexbackslash }W}}{21} \initial {A} \entry {\code {allocated \r {initialization}}}{26} \entry {alternation operator}{13} \entry {alternation operator and \samp {{\tt\hat}}}{18} \entry {anchoring}{18} \entry {anchors}{18} \entry {Awk}{5} \initial {B} \entry {back references}{17} \entry {backtracking}{10, 13} \entry {beginning-of-line operator}{18} \entry {bracket expression}{13} \entry {\code {buffer \r {field, set by \code {re{\_}compile{\_}pattern}}}}{27} \entry {\code {buffer \r {initialization}}}{26} \initial {C} \entry {character classes}{14} \initial {E} \entry {Egrep}{5} \entry {Emacs}{5} \entry {end-of-line operator}{18} \entry {\code {end\penalty 10000{\spaceskip = 0pt{} }\r {in\penalty 10000{\spaceskip = 0pt{} }\code {struct\penalty 10000{\spaceskip = 0pt{} }re_registers}}}}{32} \initial {F} \entry {\code {fastmap \r {initialization}}}{26} \entry {\code {fastmap{\_}accurate \r {field, set by \code {re{\_}compile{\_}pattern}}}}{27} \entry {fastmaps}{30} \initial {G} \entry {Grep}{5} \entry {grouping}{16} \initial {I} \entry {ignoring case}{35} \entry {interval expression}{12} \initial {M} \entry {matching list}{13} \entry {matching newline}{13} \entry {matching with GNU functions}{27} \initial {N} \entry {\code {newline{\_}anchor \r {field in pattern buffer}}}{18} \entry {nonmatching list}{13} \entry {\code {not{\_}bol \r {field in pattern buffer}}}{18} \entry {\code {num_regs\penalty 10000{\spaceskip = 0pt{} }\r {in\penalty 10000{\spaceskip = 0pt{} }\code {struct\penalty 10000{\spaceskip = 0pt{} }re_registers}}}}{32} \initial {O} \entry {open-group operator and \samp {{\tt\hat}}}{18} \entry {or operator}{13} \initial {P} \entry {parenthesizing}{16} \entry {pattern buffer initialization}{26} \entry {pattern buffer, definition of}{24} \entry {POSIX Awk}{5} \initial {R} \entry {\code {range \r {argument to \code {re{\_}search}}}}{28} \entry {\code {re_registers}}{32} \entry {\code {RE{\_}BACKSLASH{\_}ESCAPE{\_}IN{\_}LIST}}{3} \entry {\code {RE{\_}BK{\_}PLUS{\_}QM}}{3} \entry {\code {RE{\_}CHAR{\_}CLASSES}}{3} \entry {\code {RE{\_}CONTEXT{\_}INDEP{\_}ANCHORS}}{3} \entry {\code {RE{\_}CONTEXT{\_}INDEP{\_}ANCHORS \r {(and \samp {{\tt\hat}})}}}{18} \entry {\code {RE{\_}CONTEXT{\_}INDEP{\_}OPS}}{3} \entry {\code {RE{\_}CONTEXT{\_}INVALID{\_}OPS}}{3} \entry {\code {RE{\_}DOT{\_}NEWLINE}}{3} \entry {\code {RE{\_}DOT{\_}NOT{\_}NULL}}{4} \entry {\code {RE{\_}INTERVALS}}{4} \entry {\code {RE{\_}LIMITED{\_}OPS}}{4} \entry {\code {RE{\_}NEWLINE{\_}ALT}}{4} \entry {\code {RE{\_}NO{\_}BK{\_}BRACES}}{4} \entry {\code {RE{\_}NO{\_}BK{\_}PARENS}}{4} \entry {\code {RE{\_}NO{\_}BK{\_}REFS}}{4} \entry {\code {RE{\_}NO{\_}BK{\_}VBAR}}{4} \entry {\code {RE{\_}NO{\_}EMPTY{\_}RANGES}}{4} \entry {\code {re{\_}nsub \r {field, set by \code {re{\_}compile{\_}pattern}}}}{27} \entry {\code {re{\_}pattern{\_}buffer \r {definition}}}{24} \entry {\code {re{\_}syntax{\_}options \r {initialization}}}{26} \entry {\code {RE{\_}UNMATCHED{\_}RIGHT{\_}PAREN{\_}ORD}}{4} \entry {\code {REG{\_}EXTENDED}}{35} \entry {\code {REG{\_}ICASE}}{35} \entry {\code {REG{\_}NEWLINE}}{36} \entry {\code {REG{\_}NOSUB}}{35} \entry {\code {regex.c}}{1} \entry {\code {regex.h}}{1} \entry {regexp anchoring}{18} \entry {\code {regmatch{\_}t}}{39} \entry {\code {regs{\_}allocated}}{32} \entry {\code {REGS{\_}FIXED}}{33} \entry {\code {REGS{\_}REALLOCATE}}{32} \entry {\code {REGS{\_}UNALLOCATED}}{32} \entry {regular expressions, syntax of}{2} \initial {S} \entry {searching with GNU functions}{28} \entry {\code {start \r {argument to \code {re{\_}search}}}}{28} \entry {\code {start\penalty 10000{\spaceskip = 0pt{} }\r {in\penalty 10000{\spaceskip = 0pt{} }\code {struct\penalty 10000{\spaceskip = 0pt{} }re_registers}}}}{32} \entry {\code {struct re{\_}pattern{\_}buffer \r {definition}}}{24} \entry {subexpressions}{16} \entry {syntax bits}{2} \entry {\code {syntax \r {field, set by \code {re{\_}compile{\_}pattern}}}}{27} \entry {syntax initialization}{26} \entry {syntax of regular expressions}{2} \initial {T} \entry {\code {translate \r {initialization}}}{26} \initial {U} \entry {\code {used \r {field, set by \code {re{\_}compile{\_}pattern}}}}{27} \initial {W} \entry {word boundaries, matching}{20} lyskom-server-2.1.2/src/libraries/regex/doc/regex.info0000664000015100472110000035074405533104473016447 This is Info file regex.info, produced by Makeinfo-1.52 from the input file .././doc/regex.texi. This file documents the GNU regular expression library. Copyright (C) 1992, 1993 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the section entitled "GNU General Public License" is included exactly as in the original, and provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that the section entitled "GNU General Public License" may be included in a translation approved by the Free Software Foundation instead of in the original English.  File: regex.info, Node: Top, Next: Overview, Prev: (dir), Up: (dir) Regular Expression Library ************************** This manual documents how to program with the GNU regular expression library. This is edition 0.12a of the manual, 19 September 1992. The first part of this master menu lists the major nodes in this Info document, including the index. The rest of the menu lists all the lower level nodes in the document. * Menu: * Overview:: * Regular Expression Syntax:: * Common Operators:: * GNU Operators:: * GNU Emacs Operators:: * What Gets Matched?:: * Programming with Regex:: * Copying:: Copying and sharing Regex. * Index:: General index. -- The Detailed Node Listing -- Regular Expression Syntax * Syntax Bits:: * Predefined Syntaxes:: * Collating Elements vs. Characters:: * The Backslash Character:: Common Operators * Match-self Operator:: Ordinary characters. * Match-any-character Operator:: . * Concatenation Operator:: Juxtaposition. * Repetition Operators:: * + ? {} * Alternation Operator:: | * List Operators:: [...] [^...] * Grouping Operators:: (...) * Back-reference Operator:: \digit * Anchoring Operators:: ^ $ Repetition Operators * Match-zero-or-more Operator:: * * Match-one-or-more Operator:: + * Match-zero-or-one Operator:: ? * Interval Operators:: {} List Operators (`[' ... `]' and `[^' ... `]') * Character Class Operators:: [:class:] * Range Operator:: start-end Anchoring Operators * Match-beginning-of-line Operator:: ^ * Match-end-of-line Operator:: $ GNU Operators * Word Operators:: * Buffer Operators:: Word Operators * Non-Emacs Syntax Tables:: * Match-word-boundary Operator:: \b * Match-within-word Operator:: \B * Match-beginning-of-word Operator:: \< * Match-end-of-word Operator:: \> * Match-word-constituent Operator:: \w * Match-non-word-constituent Operator:: \W Buffer Operators * Match-beginning-of-buffer Operator:: \` * Match-end-of-buffer Operator:: \' GNU Emacs Operators * Syntactic Class Operators:: Syntactic Class Operators * Emacs Syntax Tables:: * Match-syntactic-class Operator:: \sCLASS * Match-not-syntactic-class Operator:: \SCLASS Programming with Regex * GNU Regex Functions:: * POSIX Regex Functions:: * BSD Regex Functions:: GNU Regex Functions * GNU Pattern Buffers:: The re_pattern_buffer type. * GNU Regular Expression Compiling:: re_compile_pattern () * GNU Matching:: re_match () * GNU Searching:: re_search () * Matching/Searching with Split Data:: re_match_2 (), re_search_2 () * Searching with Fastmaps:: re_compile_fastmap () * GNU Translate Tables:: The `translate' field. * Using Registers:: The re_registers type and related fns. * Freeing GNU Pattern Buffers:: regfree () POSIX Regex Functions * POSIX Pattern Buffers:: The regex_t type. * POSIX Regular Expression Compiling:: regcomp () * POSIX Matching:: regexec () * Reporting Errors:: regerror () * Using Byte Offsets:: The regmatch_t type. * Freeing POSIX Pattern Buffers:: regfree () BSD Regex Functions * BSD Regular Expression Compiling:: re_comp () * BSD Searching:: re_exec ()  File: regex.info, Node: Overview, Next: Regular Expression Syntax, Prev: Top, Up: Top Overview ******** A "regular expression" (or "regexp", or "pattern") is a text string that describes some (mathematical) set of strings. A regexp R "matches" a string S if S is in the set of strings described by R. Using the Regex library, you can: * see if a string matches a specified pattern as a whole, and * search within a string for a substring matching a specified pattern. Some regular expressions match only one string, i.e., the set they describe has only one member. For example, the regular expression `foo' matches the string `foo' and no others. Other regular expressions match more than one string, i.e., the set they describe has more than one member. For example, the regular expression `f*' matches the set of strings made up of any number (including zero) of `f's. As you can see, some characters in regular expressions match themselves (such as `f') and some don't (such as `*'); the ones that don't match themselves instead let you specify patterns that describe many different strings. To either match or search for a regular expression with the Regex library functions, you must first compile it with a Regex pattern compiling function. A "compiled pattern" is a regular expression converted to the internal format used by the library functions. Once you've compiled a pattern, you can use it for matching or searching any number of times. The Regex library consists of two source files: `regex.h' and `regex.c'. Regex provides three groups of functions with which you can operate on regular expressions. One group--the GNU group--is more powerful but not completely compatible with the other two, namely the POSIX and Berkeley UNIX groups; its interface was designed specifically for GNU. The other groups have the same interfaces as do the regular expression functions in POSIX and Berkeley UNIX. We wrote this chapter with programmers in mind, not users of programs--such as Emacs--that use Regex. We describe the Regex library in its entirety, not how to write regular expressions that a particular program understands.  File: regex.info, Node: Regular Expression Syntax, Next: Common Operators, Prev: Overview, Up: Top Regular Expression Syntax ************************* "Characters" are things you can type. "Operators" are things in a regular expression that match one or more characters. You compose regular expressions from operators, which in turn you specify using one or more characters. Most characters represent what we call the match-self operator, i.e., they match themselves; we call these characters "ordinary". Other characters represent either all or parts of fancier operators; e.g., `.' represents what we call the match-any-character operator (which, no surprise, matches (almost) any character); we call these characters "special". Two different things determine what characters represent what operators: 1. the regular expression syntax your program has told the Regex library to recognize, and 2. the context of the character in the regular expression. In the following sections, we describe these things in more detail. * Menu: * Syntax Bits:: * Predefined Syntaxes:: * Collating Elements vs. Characters:: * The Backslash Character::  File: regex.info, Node: Syntax Bits, Next: Predefined Syntaxes, Up: Regular Expression Syntax Syntax Bits =========== In any particular syntax for regular expressions, some characters are always special, others are sometimes special, and others are never special. The particular syntax that Regex recognizes for a given regular expression depends on the value in the `syntax' field of the pattern buffer of that regular expression. You get a pattern buffer by compiling a regular expression. *Note GNU Pattern Buffers::, and *Note POSIX Pattern Buffers::, for more information on pattern buffers. *Note GNU Regular Expression Compiling::, *Note POSIX Regular Expression Compiling::, and *Note BSD Regular Expression Compiling::, for more information on compiling. Regex considers the value of the `syntax' field to be a collection of bits; we refer to these bits as "syntax bits". In most cases, they affect what characters represent what operators. We describe the meanings of the operators to which we refer in *Note Common Operators::, *Note GNU Operators::, and *Note GNU Emacs Operators::. For reference, here is the complete list of syntax bits, in alphabetical order: `RE_BACKSLASH_ESCAPE_IN_LISTS' If this bit is set, then `\' inside a list (*note List Operators::. quotes (makes ordinary, if it's special) the following character; if this bit isn't set, then `\' is an ordinary character inside lists. (*Note The Backslash Character::, for what `\' does outside of lists.) `RE_BK_PLUS_QM' If this bit is set, then `\+' represents the match-one-or-more operator and `\?' represents the match-zero-or-more operator; if this bit isn't set, then `+' represents the match-one-or-more operator and `?' represents the match-zero-or-one operator. This bit is irrelevant if `RE_LIMITED_OPS' is set. `RE_CHAR_CLASSES' If this bit is set, then you can use character classes in lists; if this bit isn't set, then you can't. `RE_CONTEXT_INDEP_ANCHORS' If this bit is set, then `^' and `$' are special anywhere outside a list; if this bit isn't set, then these characters are special only in certain contexts. *Note Match-beginning-of-line Operator::, and *Note Match-end-of-line Operator::. `RE_CONTEXT_INDEP_OPS' If this bit is set, then certain characters are special anywhere outside a list; if this bit isn't set, then those characters are special only in some contexts and are ordinary elsewhere. Specifically, if this bit isn't set then `*', and (if the syntax bit `RE_LIMITED_OPS' isn't set) `+' and `?' (or `\+' and `\?', depending on the syntax bit `RE_BK_PLUS_QM') represent repetition operators only if they're not first in a regular expression or just after an open-group or alternation operator. The same holds for `{' (or `\{', depending on the syntax bit `RE_NO_BK_BRACES') if it is the beginning of a valid interval and the syntax bit `RE_INTERVALS' is set. `RE_CONTEXT_INVALID_OPS' If this bit is set, then repetition and alternation operators can't be in certain positions within a regular expression. Specifically, the regular expression is invalid if it has: * a repetition operator first in the regular expression or just after a match-beginning-of-line, open-group, or alternation operator; or * an alternation operator first or last in the regular expression, just before a match-end-of-line operator, or just after an alternation or open-group operator. If this bit isn't set, then you can put the characters representing the repetition and alternation characters anywhere in a regular expression. Whether or not they will in fact be operators in certain positions depends on other syntax bits. `RE_DOT_NEWLINE' If this bit is set, then the match-any-character operator matches a newline; if this bit isn't set, then it doesn't. `RE_DOT_NOT_NULL' If this bit is set, then the match-any-character operator doesn't match a null character; if this bit isn't set, then it does. `RE_INTERVALS' If this bit is set, then Regex recognizes interval operators; if this bit isn't set, then it doesn't. `RE_LIMITED_OPS' If this bit is set, then Regex doesn't recognize the match-one-or-more, match-zero-or-one or alternation operators; if this bit isn't set, then it does. `RE_NEWLINE_ALT' If this bit is set, then newline represents the alternation operator; if this bit isn't set, then newline is ordinary. `RE_NO_BK_BRACES' If this bit is set, then `{' represents the open-interval operator and `}' represents the close-interval operator; if this bit isn't set, then `\{' represents the open-interval operator and `\}' represents the close-interval operator. This bit is relevant only if `RE_INTERVALS' is set. `RE_NO_BK_PARENS' If this bit is set, then `(' represents the open-group operator and `)' represents the close-group operator; if this bit isn't set, then `\(' represents the open-group operator and `\)' represents the close-group operator. `RE_NO_BK_REFS' If this bit is set, then Regex doesn't recognize `\'DIGIT as the back reference operator; if this bit isn't set, then it does. `RE_NO_BK_VBAR' If this bit is set, then `|' represents the alternation operator; if this bit isn't set, then `\|' represents the alternation operator. This bit is irrelevant if `RE_LIMITED_OPS' is set. `RE_NO_EMPTY_RANGES' If this bit is set, then a regular expression with a range whose ending point collates lower than its starting point is invalid; if this bit isn't set, then Regex considers such a range to be empty. `RE_UNMATCHED_RIGHT_PAREN_ORD' If this bit is set and the regular expression has no matching open-group operator, then Regex considers what would otherwise be a close-group operator (based on how `RE_NO_BK_PARENS' is set) to match `)'.  File: regex.info, Node: Predefined Syntaxes, Next: Collating Elements vs. Characters, Prev: Syntax Bits, Up: Regular Expression Syntax Predefined Syntaxes =================== If you're programming with Regex, you can set a pattern buffer's (*note GNU Pattern Buffers::., and *Note POSIX Pattern Buffers::) `syntax' field either to an arbitrary combination of syntax bits (*note Syntax Bits::.) or else to the configurations defined by Regex. These configurations define the syntaxes used by certain programs--GNU Emacs, POSIX Awk, traditional Awk, Grep, Egrep--in addition to syntaxes for POSIX basic and extended regular expressions. The predefined syntaxes-taken directly from `regex.h'--are: #define RE_SYNTAX_EMACS 0 #define RE_SYNTAX_AWK \ (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \ | RE_NO_BK_PARENS | RE_NO_BK_REFS \ | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \ | RE_UNMATCHED_RIGHT_PAREN_ORD) #define RE_SYNTAX_POSIX_AWK \ (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS) #define RE_SYNTAX_GREP \ (RE_BK_PLUS_QM | RE_CHAR_CLASSES \ | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \ | RE_NEWLINE_ALT) #define RE_SYNTAX_EGREP \ (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \ | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \ | RE_NEWLINE_ALT | RE_NO_BK_PARENS \ | RE_NO_BK_VBAR) #define RE_SYNTAX_POSIX_EGREP \ (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES) /* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */ #define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC #define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC /* Syntax bits common to both basic and extended POSIX regex syntax. */ #define _RE_SYNTAX_POSIX_COMMON \ (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \ | RE_INTERVALS | RE_NO_EMPTY_RANGES) #define RE_SYNTAX_POSIX_BASIC \ (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM) /* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this isn't minimal, since other operators, such as \`, aren't disabled. */ #define RE_SYNTAX_POSIX_MINIMAL_BASIC \ (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS) #define RE_SYNTAX_POSIX_EXTENDED \ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \ | RE_NO_BK_PARENS | RE_NO_BK_VBAR \ | RE_UNMATCHED_RIGHT_PAREN_ORD) /* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */ #define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \ | RE_NO_BK_PARENS | RE_NO_BK_REFS \ | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD)  File: regex.info, Node: Collating Elements vs. Characters, Next: The Backslash Character, Prev: Predefined Syntaxes, Up: Regular Expression Syntax Collating Elements vs. Characters ================================= POSIX generalizes the notion of a character to that of a collating element. It defines a "collating element" to be "a sequence of one or more bytes defined in the current collating sequence as a unit of collation." This generalizes the notion of a character in two ways. First, a single character can map into two or more collating elements. For example, the German "es-zet" collates as the collating element `s' followed by another collating element `s'. Second, two or more characters can map into one collating element. For example, the Spanish `ll' collates after `l' and before `m'. Since POSIX's "collating element" preserves the essential idea of a "character," we use the latter, more familiar, term in this document.  File: regex.info, Node: The Backslash Character, Prev: Collating Elements vs. Characters, Up: Regular Expression Syntax The Backslash Character ======================= The `\' character has one of four different meanings, depending on the context in which you use it and what syntax bits are set (*note Syntax Bits::.). It can: 1) stand for itself, 2) quote the next character, 3) introduce an operator, or 4) do nothing. 1. It stands for itself inside a list (*note List Operators::.) if the syntax bit `RE_BACKSLASH_ESCAPE_IN_LISTS' is not set. For example, `[\]' would match `\'. 2. It quotes (makes ordinary, if it's special) the next character when you use it either: * outside a list,(1) or * inside a list and the syntax bit `RE_BACKSLASH_ESCAPE_IN_LISTS' is set. 3. It introduces an operator when followed by certain ordinary characters--sometimes only when certain syntax bits are set. See the cases `RE_BK_PLUS_QM', `RE_NO_BK_BRACES', `RE_NO_BK_VAR', `RE_NO_BK_PARENS', `RE_NO_BK_REF' in *Note Syntax Bits::. Also: * `\b' represents the match-word-boundary operator (*note Match-word-boundary Operator::.). * `\B' represents the match-within-word operator (*note Match-within-word Operator::.). * `\<' represents the match-beginning-of-word operator (*note Match-beginning-of-word Operator::.). * `\>' represents the match-end-of-word operator (*note Match-end-of-word Operator::.). * `\w' represents the match-word-constituent operator (*note Match-word-constituent Operator::.). * `\W' represents the match-non-word-constituent operator (*note Match-non-word-constituent Operator::.). * `\`' represents the match-beginning-of-buffer operator and `\'' represents the match-end-of-buffer operator (*note Buffer Operators::.). * If Regex was compiled with the C preprocessor symbol `emacs' defined, then `\sCLASS' represents the match-syntactic-class operator and `\SCLASS' represents the match-not-syntactic-class operator (*note Syntactic Class Operators::.). 4. In all other cases, Regex ignores `\'. For example, `\n' matches `n'. ---------- Footnotes ---------- (1) Sometimes you don't have to explicitly quote special characters to make them ordinary. For instance, most characters lose any special meaning inside a list (*note List Operators::.). In addition, if the syntax bits `RE_CONTEXT_INVALID_OPS' and `RE_CONTEXT_INDEP_OPS' aren't set, then (for historical reasons) the matcher considers special characters ordinary if they are in contexts where the operations they represent make no sense; for example, then the match-zero-or-more operator (represented by `*') matches itself in the regular expression `*foo' because there is no preceding expression on which it can operate. It is poor practice, however, to depend on this behavior; if you want a special character to be ordinary outside a list, it's better to always quote it, regardless.  File: regex.info, Node: Common Operators, Next: GNU Operators, Prev: Regular Expression Syntax, Up: Top Common Operators **************** You compose regular expressions from operators. In the following sections, we describe the regular expression operators specified by POSIX; GNU also uses these. Most operators have more than one representation as characters. *Note Regular Expression Syntax::, for what characters represent what operators under what circumstances. For most operators that can be represented in two ways, one representation is a single character and the other is that character preceded by `\'. For example, either `(' or `\(' represents the open-group operator. Which one does depends on the setting of a syntax bit, in this case `RE_NO_BK_PARENS'. Why is this so? Historical reasons dictate some of the varying representations, while POSIX dictates others. Finally, almost all characters lose any special meaning inside a list (*note List Operators::.). * Menu: * Match-self Operator:: Ordinary characters. * Match-any-character Operator:: . * Concatenation Operator:: Juxtaposition. * Repetition Operators:: * + ? {} * Alternation Operator:: | * List Operators:: [...] [^...] * Grouping Operators:: (...) * Back-reference Operator:: \digit * Anchoring Operators:: ^ $  File: regex.info, Node: Match-self Operator, Next: Match-any-character Operator, Up: Common Operators The Match-self Operator (ORDINARY CHARACTER) ============================================ This operator matches the character itself. All ordinary characters (*note Regular Expression Syntax::.) represent this operator. For example, `f' is always an ordinary character, so the regular expression `f' matches only the string `f'. In particular, it does *not* match the string `ff'.  File: regex.info, Node: Match-any-character Operator, Next: Concatenation Operator, Prev: Match-self Operator, Up: Common Operators The Match-any-character Operator (`.') ====================================== This operator matches any single printing or nonprinting character except it won't match a: newline if the syntax bit `RE_DOT_NEWLINE' isn't set. null if the syntax bit `RE_DOT_NOT_NULL' is set. The `.' (period) character represents this operator. For example, `a.b' matches any three-character string beginning with `a' and ending with `b'.  File: regex.info, Node: Concatenation Operator, Next: Repetition Operators, Prev: Match-any-character Operator, Up: Common Operators The Concatenation Operator ========================== This operator concatenates two regular expressions A and B. No character represents this operator; you simply put B after A. The result is a regular expression that will match a string if A matches its first part and B matches the rest. For example, `xy' (two match-self operators) matches `xy'.  File: regex.info, Node: Repetition Operators, Next: Alternation Operator, Prev: Concatenation Operator, Up: Common Operators Repetition Operators ==================== Repetition operators repeat the preceding regular expression a specified number of times. * Menu: * Match-zero-or-more Operator:: * * Match-one-or-more Operator:: + * Match-zero-or-one Operator:: ? * Interval Operators:: {}  File: regex.info, Node: Match-zero-or-more Operator, Next: Match-one-or-more Operator, Up: Repetition Operators The Match-zero-or-more Operator (`*') ------------------------------------- This operator repeats the smallest possible preceding regular expression as many times as necessary (including zero) to match the pattern. `*' represents this operator. For example, `o*' matches any string made up of zero or more `o's. Since this operator operates on the smallest preceding regular expression, `fo*' has a repeating `o', not a repeating `fo'. So, `fo*' matches `f', `fo', `foo', and so on. Since the match-zero-or-more operator is a suffix operator, it may be useless as such when no regular expression precedes it. This is the case when it: * is first in a regular expression, or * follows a match-beginning-of-line, open-group, or alternation operator. Three different things can happen in these cases: 1. If the syntax bit `RE_CONTEXT_INVALID_OPS' is set, then the regular expression is invalid. 2. If `RE_CONTEXT_INVALID_OPS' isn't set, but `RE_CONTEXT_INDEP_OPS' is, then `*' represents the match-zero-or-more operator (which then operates on the empty string). 3. Otherwise, `*' is ordinary. The matcher processes a match-zero-or-more operator by first matching as many repetitions of the smallest preceding regular expression as it can. Then it continues to match the rest of the pattern. If it can't match the rest of the pattern, it backtracks (as many times as necessary), each time discarding one of the matches until it can either match the entire pattern or be certain that it cannot get a match. For example, when matching `ca*ar' against `caaar', the matcher first matches all three `a's of the string with the `a*' of the regular expression. However, it cannot then match the final `ar' of the regular expression against the final `r' of the string. So it backtracks, discarding the match of the last `a' in the string. It can then match the remaining `ar'.  File: regex.info, Node: Match-one-or-more Operator, Next: Match-zero-or-one Operator, Prev: Match-zero-or-more Operator, Up: Repetition Operators The Match-one-or-more Operator (`+' or `\+') -------------------------------------------- If the syntax bit `RE_LIMITED_OPS' is set, then Regex doesn't recognize this operator. Otherwise, if the syntax bit `RE_BK_PLUS_QM' isn't set, then `+' represents this operator; if it is, then `\+' does. This operator is similar to the match-zero-or-more operator except that it repeats the preceding regular expression at least once; *note Match-zero-or-more Operator::., for what it operates on, how some syntax bits affect it, and how Regex backtracks to match it. For example, supposing that `+' represents the match-one-or-more operator; then `ca+r' matches, e.g., `car' and `caaaar', but not `cr'.  File: regex.info, Node: Match-zero-or-one Operator, Next: Interval Operators, Prev: Match-one-or-more Operator, Up: Repetition Operators The Match-zero-or-one Operator (`?' or `\?') -------------------------------------------- If the syntax bit `RE_LIMITED_OPS' is set, then Regex doesn't recognize this operator. Otherwise, if the syntax bit `RE_BK_PLUS_QM' isn't set, then `?' represents this operator; if it is, then `\?' does. This operator is similar to the match-zero-or-more operator except that it repeats the preceding regular expression once or not at all; *note Match-zero-or-more Operator::., to see what it operates on, how some syntax bits affect it, and how Regex backtracks to match it. For example, supposing that `?' represents the match-zero-or-one operator; then `ca?r' matches both `car' and `cr', but nothing else.  File: regex.info, Node: Interval Operators, Prev: Match-zero-or-one Operator, Up: Repetition Operators Interval Operators (`{' ... `}' or `\{' ... `\}') ------------------------------------------------- If the syntax bit `RE_INTERVALS' is set, then Regex recognizes "interval expressions". They repeat the smallest possible preceding regular expression a specified number of times. If the syntax bit `RE_NO_BK_BRACES' is set, `{' represents the "open-interval operator" and `}' represents the "close-interval operator" ; otherwise, `\{' and `\}' do. Specifically, supposing that `{' and `}' represent the open-interval and close-interval operators; then: `{COUNT}' matches exactly COUNT occurrences of the preceding regular expression. `{MIN,}' matches MIN or more occurrences of the preceding regular expression. `{MIN, MAX}' matches at least MIN but no more than MAX occurrences of the preceding regular expression. The interval expression (but not necessarily the regular expression that contains it) is invalid if: * MIN is greater than MAX, or * any of COUNT, MIN, or MAX are outside the range zero to `RE_DUP_MAX' (which symbol `regex.h' defines). If the interval expression is invalid and the syntax bit `RE_NO_BK_BRACES' is set, then Regex considers all the characters in the would-be interval to be ordinary. If that bit isn't set, then the regular expression is invalid. If the interval expression is valid but there is no preceding regular expression on which to operate, then if the syntax bit `RE_CONTEXT_INVALID_OPS' is set, the regular expression is invalid. If that bit isn't set, then Regex considers all the characters--other than backslashes, which it ignores--in the would-be interval to be ordinary.  File: regex.info, Node: Alternation Operator, Next: List Operators, Prev: Repetition Operators, Up: Common Operators The Alternation Operator (`|' or `\|') ====================================== If the syntax bit `RE_LIMITED_OPS' is set, then Regex doesn't recognize this operator. Otherwise, if the syntax bit `RE_NO_BK_VBAR' is set, then `|' represents this operator; otherwise, `\|' does. Alternatives match one of a choice of regular expressions: if you put the character(s) representing the alternation operator between any two regular expressions A and B, the result matches the union of the strings that A and B match. For example, supposing that `|' is the alternation operator, then `foo|bar|quux' would match any of `foo', `bar' or `quux'. The alternation operator operates on the *largest* possible surrounding regular expressions. (Put another way, it has the lowest precedence of any regular expression operator.) Thus, the only way you can delimit its arguments is to use grouping. For example, if `(' and `)' are the open and close-group operators, then `fo(o|b)ar' would match either `fooar' or `fobar'. (`foo|bar' would match `foo' or `bar'.) The matcher usually tries all combinations of alternatives so as to match the longest possible string. For example, when matching `(fooq|foo)*(qbarquux|bar)' against `fooqbarquux', it cannot take, say, the first ("depth-first") combination it could match, since then it would be content to match just `fooqbar'.  File: regex.info, Node: List Operators, Next: Grouping Operators, Prev: Alternation Operator, Up: Common Operators List Operators (`[' ... `]' and `[^' ... `]') ============================================= "Lists", also called "bracket expressions", are a set of one or more items. An "item" is a character, a character class expression, or a range expression. The syntax bits affect which kinds of items you can put in a list. We explain the last two items in subsections below. Empty lists are invalid. A "matching list" matches a single character represented by one of the list items. You form a matching list by enclosing one or more items within an "open-matching-list operator" (represented by `[') and a "close-list operator" (represented by `]'). For example, `[ab]' matches either `a' or `b'. `[ad]*' matches the empty string and any string composed of just `a's and `d's in any order. Regex considers invalid a regular expression with a `[' but no matching `]'. "Nonmatching lists" are similar to matching lists except that they match a single character *not* represented by one of the list items. You use an "open-nonmatching-list operator" (represented by `[^'(1)) instead of an open-matching-list operator to start a nonmatching list. For example, `[^ab]' matches any character except `a' or `b'. If the `posix_newline' field in the pattern buffer (*note GNU Pattern Buffers::. is set, then nonmatching lists do not match a newline. Most characters lose any special meaning inside a list. The special characters inside a list follow. `]' ends the list if it's not the first list item. So, if you want to make the `]' character a list item, you must put it first. `\' quotes the next character if the syntax bit `RE_BACKSLASH_ESCAPE_IN_LISTS' is set. `[:' represents the open-character-class operator (*note Character Class Operators::.) if the syntax bit `RE_CHAR_CLASSES' is set and what follows is a valid character class expression. `:]' represents the close-character-class operator if the syntax bit `RE_CHAR_CLASSES' is set and what precedes it is an open-character-class operator followed by a valid character class name. `-' represents the range operator (*note Range Operator::.) if it's not first or last in a list or the ending point of a range. All other characters are ordinary. For example, `[.*]' matches `.' and `*'. * Menu: * Character Class Operators:: [:class:] * Range Operator:: start-end ---------- Footnotes ---------- (1) Regex therefore doesn't consider the `^' to be the first character in the list. If you put a `^' character first in (what you think is) a matching list, you'll turn it into a nonmatching list.  File: regex.info, Node: Character Class Operators, Next: Range Operator, Up: List Operators Character Class Operators (`[:' ... `:]') ----------------------------------------- If the syntax bit `RE_CHARACTER_CLASSES' is set, then Regex recognizes character class expressions inside lists. A "character class expression" matches one character from a given class. You form a character class expression by putting a character class name between an "open-character-class operator" (represented by `[:') and a "close-character-class operator" (represented by `:]'). The character class names and their meanings are: `alnum' letters and digits `alpha' letters `blank' system-dependent; for GNU, a space or tab `cntrl' control characters (in the ASCII encoding, code 0177 and codes less than 040) `digit' digits `graph' same as `print' except omits space `lower' lowercase letters `print' printable characters (in the ASCII encoding, space tilde--codes 040 through 0176) `punct' neither control nor alphanumeric characters `space' space, carriage return, newline, vertical tab, and form feed `upper' uppercase letters `xdigit' hexadecimal digits: `0'-`9', `a'-`f', `A'-`F' These correspond to the definitions in the C library's `' facility. For example, `[:alpha:]' corresponds to the standard facility `isalpha'. Regex recognizes character class expressions only inside of lists; so `[[:alpha:]]' matches any letter, but `[:alpha:]' outside of a bracket expression and not followed by a repetition operator matches just itself.  File: regex.info, Node: Range Operator, Prev: Character Class Operators, Up: List Operators The Range Operator (`-') ------------------------ Regex recognizes "range expressions" inside a list. They represent those characters that fall between two elements in the current collating sequence. You form a range expression by putting a "range operator" between two characters.(1) `-' represents the range operator. For example, `a-f' within a list represents all the characters from `a' through `f' inclusively. If the syntax bit `RE_NO_EMPTY_RANGES' is set, then if the range's ending point collates less than its starting point, the range (and the regular expression containing it) is invalid. For example, the regular expression `[z-a]' would be invalid. If this bit isn't set, then Regex considers such a range to be empty. Since `-' represents the range operator, if you want to make a `-' character itself a list item, you must do one of the following: * Put the `-' either first or last in the list. * Include a range whose starting point collates strictly lower than `-' and whose ending point collates equal or higher. Unless a range is the first item in a list, a `-' can't be its starting point, but *can* be its ending point. That is because Regex considers `-' to be the range operator unless it is preceded by another `-'. For example, in the ASCII encoding, `)', `*', `+', `,', `-', `.', and `/' are contiguous characters in the collating sequence. You might think that `[)-+--/]' has two ranges: `)-+' and `--/'. Rather, it has the ranges `)-+' and `+--', plus the character `/', so it matches, e.g., `,', not `.'. * Put a range whose starting point is `-' first in the list. For example, `[-a-z]' matches a lowercase letter or a hyphen (in English, in ASCII). ---------- Footnotes ---------- (1) You can't use a character class for the starting or ending point of a range, since a character class is not a single character.  File: regex.info, Node: Grouping Operators, Next: Back-reference Operator, Prev: List Operators, Up: Common Operators Grouping Operators (`(' ... `)' or `\(' ... `\)') ================================================= A "group", also known as a "subexpression", consists of an "open-group operator", any number of other operators, and a "close-group operator". Regex treats this sequence as a unit, just as mathematics and programming languages treat a parenthesized expression as a unit. Therefore, using "groups", you can: * delimit the argument(s) to an alternation operator (*note Alternation Operator::.) or a repetition operator (*note Repetition Operators::.). * keep track of the indices of the substring that matched a given group. *Note Using Registers::, for a precise explanation. This lets you: * use the back-reference operator (*note Back-reference Operator::.). * use registers (*note Using Registers::.). If the syntax bit `RE_NO_BK_PARENS' is set, then `(' represents the open-group operator and `)' represents the close-group operator; otherwise, `\(' and `\)' do. If the syntax bit `RE_UNMATCHED_RIGHT_PAREN_ORD' is set and a close-group operator has no matching open-group operator, then Regex considers it to match `)'.  File: regex.info, Node: Back-reference Operator, Next: Anchoring Operators, Prev: Grouping Operators, Up: Common Operators The Back-reference Operator ("\"DIGIT) ====================================== If the syntax bit `RE_NO_BK_REF' isn't set, then Regex recognizes back references. A back reference matches a specified preceding group. The back reference operator is represented by `\DIGIT' anywhere after the end of a regular expression's DIGIT-th group (*note Grouping Operators::.). DIGIT must be between `1' and `9'. The matcher assigns numbers 1 through 9 to the first nine groups it encounters. By using one of `\1' through `\9' after the corresponding group's close-group operator, you can match a substring identical to the one that the group does. Back references match according to the following (in all examples below, `(' represents the open-group, `)' the close-group, `{' the open-interval and `}' the close-interval operator): * If the group matches a substring, the back reference matches an identical substring. For example, `(a)\1' matches `aa' and `(bana)na\1bo\1' matches `bananabanabobana'. Likewise, `(.*)\1' matches any (newline-free if the syntax bit `RE_DOT_NEWLINE' isn't set) string that is composed of two identical halves; the `(.*)' matches the first half and the `\1' matches the second half. * If the group matches more than once (as it might if followed by, e.g., a repetition operator), then the back reference matches the substring the group *last* matched. For example, `((a*)b)*\1\2' matches `aabababa'; first group 1 (the outer one) matches `aab' and group 2 (the inner one) matches `aa'. Then group 1 matches `ab' and group 2 matches `a'. So, `\1' matches `ab' and `\2' matches `a'. * If the group doesn't participate in a match, i.e., it is part of an alternative not taken or a repetition operator allows zero repetitions of it, then the back reference makes the whole match fail. For example, `(one()|two())-and-(three\2|four\3)' matches `one-and-three' and `two-and-four', but not `one-and-four' or `two-and-three'. For example, if the pattern matches `one-and-', then its group 2 matches the empty string and its group 3 doesn't participate in the match. So, if it then matches `four', then when it tries to back reference group 3--which it will attempt to do because `\3' follows the `four'--the match will fail because group 3 didn't participate in the match. You can use a back reference as an argument to a repetition operator. For example, `(a(b))\2*' matches `a' followed by two or more `b's. Similarly, `(a(b))\2{3}' matches `abbbb'. If there is no preceding DIGIT-th subexpression, the regular expression is invalid.  File: regex.info, Node: Anchoring Operators, Prev: Back-reference Operator, Up: Common Operators Anchoring Operators =================== These operators can constrain a pattern to match only at the beginning or end of the entire string or at the beginning or end of a line. * Menu: * Match-beginning-of-line Operator:: ^ * Match-end-of-line Operator:: $  File: regex.info, Node: Match-beginning-of-line Operator, Next: Match-end-of-line Operator, Up: Anchoring Operators The Match-beginning-of-line Operator (`^') ------------------------------------------ This operator can match the empty string either at the beginning of the string or after a newline character. Thus, it is said to "anchor" the pattern to the beginning of a line. In the cases following, `^' represents this operator. (Otherwise, `^' is ordinary.) * It (the `^') is first in the pattern, as in `^foo'. * The syntax bit `RE_CONTEXT_INDEP_ANCHORS' is set, and it is outside a bracket expression. * It follows an open-group or alternation operator, as in `a\(^b\)' and `a\|^b'. *Note Grouping Operators::, and *Note Alternation Operator::. These rules imply that some valid patterns containing `^' cannot be matched; for example, `foo^bar' if `RE_CONTEXT_INDEP_ANCHORS' is set. If the `not_bol' field is set in the pattern buffer (*note GNU Pattern Buffers::.), then `^' fails to match at the beginning of the string. *Note POSIX Matching::, for when you might find this useful. If the `newline_anchor' field is set in the pattern buffer, then `^' fails to match after a newline. This is useful when you do not regard the string to be matched as broken into lines.  File: regex.info, Node: Match-end-of-line Operator, Prev: Match-beginning-of-line Operator, Up: Anchoring Operators The Match-end-of-line Operator (`$') ------------------------------------ This operator can match the empty string either at the end of the string or before a newline character in the string. Thus, it is said to "anchor" the pattern to the end of a line. It is always represented by `$'. For example, `foo$' usually matches, e.g., `foo' and, e.g., the first three characters of `foo\nbar'. Its interaction with the syntax bits and pattern buffer fields is exactly the dual of `^''s; see the previous section. (That is, "beginning" becomes "end", "next" becomes "previous", and "after" becomes "before".)  File: regex.info, Node: GNU Operators, Next: GNU Emacs Operators, Prev: Common Operators, Up: Top GNU Operators ************* Following are operators that GNU defines (and POSIX doesn't). * Menu: * Word Operators:: * Buffer Operators::  File: regex.info, Node: Word Operators, Next: Buffer Operators, Up: GNU Operators Word Operators ============== The operators in this section require Regex to recognize parts of words. Regex uses a syntax table to determine whether or not a character is part of a word, i.e., whether or not it is "word-constituent". * Menu: * Non-Emacs Syntax Tables:: * Match-word-boundary Operator:: \b * Match-within-word Operator:: \B * Match-beginning-of-word Operator:: \< * Match-end-of-word Operator:: \> * Match-word-constituent Operator:: \w * Match-non-word-constituent Operator:: \W  File: regex.info, Node: Non-Emacs Syntax Tables, Next: Match-word-boundary Operator, Up: Word Operators Non-Emacs Syntax Tables ----------------------- A "syntax table" is an array indexed by the characters in your character set. In the ASCII encoding, therefore, a syntax table has 256 elements. Regex always uses a `char *' variable `re_syntax_table' as its syntax table. In some cases, it initializes this variable and in others it expects you to initialize it. * If Regex is compiled with the preprocessor symbols `emacs' and `SYNTAX_TABLE' both undefined, then Regex allocates `re_syntax_table' and initializes an element I either to `Sword' (which it defines) if I is a letter, number, or `_', or to zero if it's not. * If Regex is compiled with `emacs' undefined but `SYNTAX_TABLE' defined, then Regex expects you to define a `char *' variable `re_syntax_table' to be a valid syntax table. * *Note Emacs Syntax Tables::, for what happens when Regex is compiled with the preprocessor symbol `emacs' defined.  File: regex.info, Node: Match-word-boundary Operator, Next: Match-within-word Operator, Prev: Non-Emacs Syntax Tables, Up: Word Operators The Match-word-boundary Operator (`\b') --------------------------------------- This operator (represented by `\b') matches the empty string at either the beginning or the end of a word. For example, `\brat\b' matches the separate word `rat'.  File: regex.info, Node: Match-within-word Operator, Next: Match-beginning-of-word Operator, Prev: Match-word-boundary Operator, Up: Word Operators The Match-within-word Operator (`\B') ------------------------------------- This operator (represented by `\B') matches the empty string within a word. For example, `c\Brat\Be' matches `crate', but `dirty \Brat' doesn't match `dirty rat'.  File: regex.info, Node: Match-beginning-of-word Operator, Next: Match-end-of-word Operator, Prev: Match-within-word Operator, Up: Word Operators The Match-beginning-of-word Operator (`\<') ------------------------------------------- This operator (represented by `\<') matches the empty string at the beginning of a word.  File: regex.info, Node: Match-end-of-word Operator, Next: Match-word-constituent Operator, Prev: Match-beginning-of-word Operator, Up: Word Operators The Match-end-of-word Operator (`\>') ------------------------------------- This operator (represented by `\>') matches the empty string at the end of a word.  File: regex.info, Node: Match-word-constituent Operator, Next: Match-non-word-constituent Operator, Prev: Match-end-of-word Operator, Up: Word Operators The Match-word-constituent Operator (`\w') ------------------------------------------ This operator (represented by `\w') matches any word-constituent character.  File: regex.info, Node: Match-non-word-constituent Operator, Prev: Match-word-constituent Operator, Up: Word Operators The Match-non-word-constituent Operator (`\W') ---------------------------------------------- This operator (represented by `\W') matches any character that is not word-constituent.  File: regex.info, Node: Buffer Operators, Prev: Word Operators, Up: GNU Operators Buffer Operators ================ Following are operators which work on buffers. In Emacs, a "buffer" is, naturally, an Emacs buffer. For other programs, Regex considers the entire string to be matched as the buffer. * Menu: * Match-beginning-of-buffer Operator:: \` * Match-end-of-buffer Operator:: \'  File: regex.info, Node: Match-beginning-of-buffer Operator, Next: Match-end-of-buffer Operator, Up: Buffer Operators The Match-beginning-of-buffer Operator (`\`') --------------------------------------------- This operator (represented by `\`') matches the empty string at the beginning of the buffer.  File: regex.info, Node: Match-end-of-buffer Operator, Prev: Match-beginning-of-buffer Operator, Up: Buffer Operators The Match-end-of-buffer Operator (`\'') --------------------------------------- This operator (represented by `\'') matches the empty string at the end of the buffer.  File: regex.info, Node: GNU Emacs Operators, Next: What Gets Matched?, Prev: GNU Operators, Up: Top GNU Emacs Operators ******************* Following are operators that GNU defines (and POSIX doesn't) that you can use only when Regex is compiled with the preprocessor symbol `emacs' defined. * Menu: * Syntactic Class Operators::  File: regex.info, Node: Syntactic Class Operators, Up: GNU Emacs Operators Syntactic Class Operators ========================= The operators in this section require Regex to recognize the syntactic classes of characters. Regex uses a syntax table to determine this. * Menu: * Emacs Syntax Tables:: * Match-syntactic-class Operator:: \sCLASS * Match-not-syntactic-class Operator:: \SCLASS  File: regex.info, Node: Emacs Syntax Tables, Next: Match-syntactic-class Operator, Up: Syntactic Class Operators Emacs Syntax Tables ------------------- A "syntax table" is an array indexed by the characters in your character set. In the ASCII encoding, therefore, a syntax table has 256 elements. If Regex is compiled with the preprocessor symbol `emacs' defined, then Regex expects you to define and initialize the variable `re_syntax_table' to be an Emacs syntax table. Emacs' syntax tables are more complicated than Regex's own (*note Non-Emacs Syntax Tables::.). *Note Syntax: (emacs)Syntax, for a description of Emacs' syntax tables.  File: regex.info, Node: Match-syntactic-class Operator, Next: Match-not-syntactic-class Operator, Prev: Emacs Syntax Tables, Up: Syntactic Class Operators The Match-syntactic-class Operator (`\s'CLASS) ---------------------------------------------- This operator matches any character whose syntactic class is represented by a specified character. `\sCLASS' represents this operator where CLASS is the character representing the syntactic class you want. For example, `w' represents the syntactic class of word-constituent characters, so `\sw' matches any word-constituent character.  File: regex.info, Node: Match-not-syntactic-class Operator, Prev: Match-syntactic-class Operator, Up: Syntactic Class Operators The Match-not-syntactic-class Operator (`\S'CLASS) -------------------------------------------------- This operator is similar to the match-syntactic-class operator except that it matches any character whose syntactic class is *not* represented by the specified character. `\SCLASS' represents this operator. For example, `w' represents the syntactic class of word-constituent characters, so `\Sw' matches any character that is not word-constituent.  File: regex.info, Node: What Gets Matched?, Next: Programming with Regex, Prev: GNU Emacs Operators, Up: Top What Gets Matched? ****************** Regex usually matches strings according to the "leftmost longest" rule; that is, it chooses the longest of the leftmost matches. This does not mean that for a regular expression containing subexpressions that it simply chooses the longest match for each subexpression, left to right; the overall match must also be the longest possible one. For example, `(ac*)(c*d[ac]*)\1' matches `acdacaaa', not `acdac', as it would if it were to choose the longest match for the first subexpression.  File: regex.info, Node: Programming with Regex, Next: Copying, Prev: What Gets Matched?, Up: Top Programming with Regex ********************** Here we describe how you use the Regex data structures and functions in C programs. Regex has three interfaces: one designed for GNU, one compatible with POSIX and one compatible with Berkeley UNIX. * Menu: * GNU Regex Functions:: * POSIX Regex Functions:: * BSD Regex Functions::  File: regex.info, Node: GNU Regex Functions, Next: POSIX Regex Functions, Up: Programming with Regex GNU Regex Functions =================== If you're writing code that doesn't need to be compatible with either POSIX or Berkeley UNIX, you can use these functions. They provide more options than the other interfaces. * Menu: * GNU Pattern Buffers:: The re_pattern_buffer type. * GNU Regular Expression Compiling:: re_compile_pattern () * GNU Matching:: re_match () * GNU Searching:: re_search () * Matching/Searching with Split Data:: re_match_2 (), re_search_2 () * Searching with Fastmaps:: re_compile_fastmap () * GNU Translate Tables:: The `translate' field. * Using Registers:: The re_registers type and related fns. * Freeing GNU Pattern Buffers:: regfree ()  File: regex.info, Node: GNU Pattern Buffers, Next: GNU Regular Expression Compiling, Up: GNU Regex Functions GNU Pattern Buffers ------------------- To compile, match, or search for a given regular expression, you must supply a pattern buffer. A "pattern buffer" holds one compiled regular expression.(1) You can have several different pattern buffers simultaneously, each holding a compiled pattern for a different regular expression. `regex.h' defines the pattern buffer `struct' as follows: /* Space that holds the compiled pattern. It is declared as `unsigned char *' because its elements are sometimes used as array indexes. */ unsigned char *buffer; /* Number of bytes to which `buffer' points. */ unsigned long allocated; /* Number of bytes actually used in `buffer'. */ unsigned long used; /* Syntax setting with which the pattern was compiled. */ reg_syntax_t syntax; /* Pointer to a fastmap, if any, otherwise zero. re_search uses the fastmap, if there is one, to skip over impossible starting points for matches. */ char *fastmap; /* Either a translate table to apply to all characters before comparing them, or zero for no translation. The translation is applied to a pattern when it is compiled and to a string when it is matched. */ char *translate; /* Number of subexpressions found by the compiler. */ size_t re_nsub; /* Zero if this pattern cannot match the empty string, one else. Well, in truth it's used only in `re_search_2', to see whether or not we should use the fastmap, so we don't set this absolutely perfectly; see `re_compile_fastmap' (the `duplicate' case). */ unsigned can_be_null : 1; /* If REGS_UNALLOCATED, allocate space in the `regs' structure for `max (RE_NREGS, re_nsub + 1)' groups. If REGS_REALLOCATE, reallocate space if necessary. If REGS_FIXED, use what's there. */ #define REGS_UNALLOCATED 0 #define REGS_REALLOCATE 1 #define REGS_FIXED 2 unsigned regs_allocated : 2; /* Set to zero when `regex_compile' compiles a pattern; set to one by `re_compile_fastmap' if it updates the fastmap. */ unsigned fastmap_accurate : 1; /* If set, `re_match_2' does not return information about subexpressions. */ unsigned no_sub : 1; /* If set, a beginning-of-line anchor doesn't match at the beginning of the string. */ unsigned not_bol : 1; /* Similarly for an end-of-line anchor. */ unsigned not_eol : 1; /* If true, an anchor at a newline matches. */ unsigned newline_anchor : 1; ---------- Footnotes ---------- (1) Regular expressions are also referred to as "patterns," hence the name "pattern buffer."  File: regex.info, Node: GNU Regular Expression Compiling, Next: GNU Matching, Prev: GNU Pattern Buffers, Up: GNU Regex Functions GNU Regular Expression Compiling -------------------------------- In GNU, you can both match and search for a given regular expression. To do either, you must first compile it in a pattern buffer (*note GNU Pattern Buffers::.). Regular expressions match according to the syntax with which they were compiled; with GNU, you indicate what syntax you want by setting the variable `re_syntax_options' (declared in `regex.h' and defined in `regex.c') before calling the compiling function, `re_compile_pattern' (see below). *Note Syntax Bits::, and *Note Predefined Syntaxes::. You can change the value of `re_syntax_options' at any time. Usually, however, you set its value once and then never change it. `re_compile_pattern' takes a pattern buffer as an argument. You must initialize the following fields: `translate initialization' `translate' Initialize this to point to a translate table if you want one, or to zero if you don't. We explain translate tables in *Note GNU Translate Tables::. `fastmap' Initialize this to nonzero if you want a fastmap, or to zero if you don't. `buffer' `allocated' If you want `re_compile_pattern' to allocate memory for the compiled pattern, set both of these to zero. If you have an existing block of memory (allocated with `malloc') you want Regex to use, set `buffer' to its address and `allocated' to its size (in bytes). `re_compile_pattern' uses `realloc' to extend the space for the compiled pattern as necessary. To compile a pattern buffer, use: char * re_compile_pattern (const char *REGEX, const int REGEX_SIZE, struct re_pattern_buffer *PATTERN_BUFFER) REGEX is the regular expression's address, REGEX_SIZE is its length, and PATTERN_BUFFER is the pattern buffer's address. If `re_compile_pattern' successfully compiles the regular expression, it returns zero and sets `*PATTERN_BUFFER' to the compiled pattern. It sets the pattern buffer's fields as follows: `buffer' to the compiled pattern. `used' to the number of bytes the compiled pattern in `buffer' occupies. `syntax' to the current value of `re_syntax_options'. `re_nsub' to the number of subexpressions in REGEX. `fastmap_accurate' to zero on the theory that the pattern you're compiling is different than the one previously compiled into `buffer'; in that case (since you can't make a fastmap without a compiled pattern), `fastmap' would either contain an incompatible fastmap, or nothing at all. If `re_compile_pattern' can't compile REGEX, it returns an error string corresponding to one of the errors listed in *Note POSIX Regular Expression Compiling::.  File: regex.info, Node: GNU Matching, Next: GNU Searching, Prev: GNU Regular Expression Compiling, Up: GNU Regex Functions GNU Matching ------------ Matching the GNU way means trying to match as much of a string as possible starting at a position within it you specify. Once you've compiled a pattern into a pattern buffer (*note GNU Regular Expression Compiling::.), you can ask the matcher to match that pattern against a string using: int re_match (struct re_pattern_buffer *PATTERN_BUFFER, const char *STRING, const int SIZE, const int START, struct re_registers *REGS) PATTERN_BUFFER is the address of a pattern buffer containing a compiled pattern. STRING is the string you want to match; it can contain newline and null characters. SIZE is the length of that string. START is the string index at which you want to begin matching; the first character of STRING is at index zero. *Note Using Registers::, for a explanation of REGS; you can safely pass zero. `re_match' matches the regular expression in PATTERN_BUFFER against the string STRING according to the syntax in PATTERN_BUFFERS's `syntax' field. (*Note GNU Regular Expression Compiling::, for how to set it.) The function returns -1 if the compiled pattern does not match any part of STRING and -2 if an internal error happens; otherwise, it returns how many (possibly zero) characters of STRING the pattern matched. An example: suppose PATTERN_BUFFER points to a pattern buffer containing the compiled pattern for `a*', and STRING points to `aaaaab' (whereupon SIZE should be 6). Then if START is 2, `re_match' returns 3, i.e., `a*' would have matched the last three `a's in STRING. If START is 0, `re_match' returns 5, i.e., `a*' would have matched all the `a's in STRING. If START is either 5 or 6, it returns zero. If START is not between zero and SIZE, then `re_match' returns -1.  File: regex.info, Node: GNU Searching, Next: Matching/Searching with Split Data, Prev: GNU Matching, Up: GNU Regex Functions GNU Searching ------------- "Searching" means trying to match starting at successive positions within a string. The function `re_search' does this. Before calling `re_search', you must compile your regular expression. *Note GNU Regular Expression Compiling::. Here is the function declaration: int re_search (struct re_pattern_buffer *PATTERN_BUFFER, const char *STRING, const int SIZE, const int START, const int RANGE, struct re_registers *REGS) whose arguments are the same as those to `re_match' (*note GNU Matching::.) except that the two arguments START and RANGE replace `re_match''s argument START. If RANGE is positive, then `re_search' attempts a match starting first at index START, then at START + 1 if that fails, and so on, up to START + RANGE; if RANGE is negative, then it attempts a match starting first at index START, then at START -1 if that fails, and so on. If START is not between zero and SIZE, then `re_search' returns -1. When RANGE is positive, `re_search' adjusts RANGE so that START + RANGE - 1 is between zero and SIZE, if necessary; that way it won't search outside of STRING. Similarly, when RANGE is negative, `re_search' adjusts RANGE so that START + RANGE + 1 is between zero and SIZE, if necessary. If the `fastmap' field of PATTERN_BUFFER is zero, `re_search' matches starting at consecutive positions; otherwise, it uses `fastmap' to make the search more efficient. *Note Searching with Fastmaps::. If no match is found, `re_search' returns -1. If a match is found, it returns the index where the match began. If an internal error happens, it returns -2.  File: regex.info, Node: Matching/Searching with Split Data, Next: Searching with Fastmaps, Prev: GNU Searching, Up: GNU Regex Functions Matching and Searching with Split Data -------------------------------------- Using the functions `re_match_2' and `re_search_2', you can match or search in data that is divided into two strings. The function: int re_match_2 (struct re_pattern_buffer *BUFFER, const char *STRING1, const int SIZE1, const char *STRING2, const int SIZE2, const int START, struct re_registers *REGS, const int STOP) is similar to `re_match' (*note GNU Matching::.) except that you pass *two* data strings and sizes, and an index STOP beyond which you don't want the matcher to try matching. As with `re_match', if it succeeds, `re_match_2' returns how many characters of STRING it matched. Regard STRING1 and STRING2 as concatenated when you set the arguments START and STOP and use the contents of REGS; `re_match_2' never returns a value larger than SIZE1 + SIZE2. The function: int re_search_2 (struct re_pattern_buffer *BUFFER, const char *STRING1, const int SIZE1, const char *STRING2, const int SIZE2, const int START, const int RANGE, struct re_registers *REGS, const int STOP) is similarly related to `re_search'.  File: regex.info, Node: Searching with Fastmaps, Next: GNU Translate Tables, Prev: Matching/Searching with Split Data, Up: GNU Regex Functions Searching with Fastmaps ----------------------- If you're searching through a long string, you should use a fastmap. Without one, the searcher tries to match at consecutive positions in the string. Generally, most of the characters in the string could not start a match. It takes much longer to try matching at a given position in the string than it does to check in a table whether or not the character at that position could start a match. A "fastmap" is such a table. More specifically, a fastmap is an array indexed by the characters in your character set. Under the ASCII encoding, therefore, a fastmap has 256 elements. If you want the searcher to use a fastmap with a given pattern buffer, you must allocate the array and assign the array's address to the pattern buffer's `fastmap' field. You either can compile the fastmap yourself or have `re_search' do it for you; when `fastmap' is nonzero, it automatically compiles a fastmap the first time you search using a particular compiled pattern. To compile a fastmap yourself, use: int re_compile_fastmap (struct re_pattern_buffer *PATTERN_BUFFER) PATTERN_BUFFER is the address of a pattern buffer. If the character C could start a match for the pattern, `re_compile_fastmap' makes `PATTERN_BUFFER->fastmap[C]' nonzero. It returns 0 if it can compile a fastmap and -2 if there is an internal error. For example, if `|' is the alternation operator and PATTERN_BUFFER holds the compiled pattern for `a|b', then `re_compile_fastmap' sets `fastmap['a']' and `fastmap['b']' (and no others). `re_search' uses a fastmap as it moves along in the string: it checks the string's characters until it finds one that's in the fastmap. Then it tries matching at that character. If the match fails, it repeats the process. So, by using a fastmap, `re_search' doesn't waste time trying to match at positions in the string that couldn't start a match. If you don't want `re_search' to use a fastmap, store zero in the `fastmap' field of the pattern buffer before calling `re_search'. Once you've initialized a pattern buffer's `fastmap' field, you need never do so again--even if you compile a new pattern in it--provided the way the field is set still reflects whether or not you want a fastmap. `re_search' will still either do nothing if `fastmap' is null or, if it isn't, compile a new fastmap for the new pattern.  File: regex.info, Node: GNU Translate Tables, Next: Using Registers, Prev: Searching with Fastmaps, Up: GNU Regex Functions GNU Translate Tables -------------------- If you set the `translate' field of a pattern buffer to a translate table, then the GNU Regex functions to which you've passed that pattern buffer use it to apply a simple transformation to all the regular expression and string characters at which they look. A "translate table" is an array indexed by the characters in your character set. Under the ASCII encoding, therefore, a translate table has 256 elements. The array's elements are also characters in your character set. When the Regex functions see a character C, they use `translate[C]' in its place, with one exception: the character after a `\' is not translated. (This ensures that, the operators, e.g., `\B' and `\b', are always distinguishable.) For example, a table that maps all lowercase letters to the corresponding uppercase ones would cause the matcher to ignore differences in case.(1) Such a table would map all characters except lowercase letters to themselves, and lowercase letters to the corresponding uppercase ones. Under the ASCII encoding, here's how you could initialize such a table (we'll call it `case_fold'): for (i = 0; i < 256; i++) case_fold[i] = i; for (i = 'a'; i <= 'z'; i++) case_fold[i] = i - ('a' - 'A'); You tell Regex to use a translate table on a given pattern buffer by assigning that table's address to the `translate' field of that buffer. If you don't want Regex to do any translation, put zero into this field. You'll get weird results if you change the table's contents anytime between compiling the pattern buffer, compiling its fastmap, and matching or searching with the pattern buffer. ---------- Footnotes ---------- (1) A table that maps all uppercase letters to the corresponding lowercase ones would work just as well for this purpose.  File: regex.info, Node: Using Registers, Next: Freeing GNU Pattern Buffers, Prev: GNU Translate Tables, Up: GNU Regex Functions Using Registers --------------- A group in a regular expression can match a (posssibly empty) substring of the string that regular expression as a whole matched. The matcher remembers the beginning and end of the substring matched by each group. To find out what they matched, pass a nonzero REGS argument to a GNU matching or searching function (*note GNU Matching::. and *Note GNU Searching::), i.e., the address of a structure of this type, as defined in `regex.h': struct re_registers { unsigned num_regs; regoff_t *start; regoff_t *end; }; Except for (possibly) the NUM_REGS'th element (see below), the Ith element of the `start' and `end' arrays records information about the Ith group in the pattern. (They're declared as C pointers, but this is only because not all C compilers accept zero-length arrays; conceptually, it is simplest to think of them as arrays.) The `start' and `end' arrays are allocated in various ways, depending on the value of the `regs_allocated' field in the pattern buffer passed to the matcher. The simplest and perhaps most useful is to let the matcher (re)allocate enough space to record information for all the groups in the regular expression. If `regs_allocated' is `REGS_UNALLOCATED', the matcher allocates 1 + RE_NSUB (another field in the pattern buffer; *note GNU Pattern Buffers::.). The extra element is set to -1, and sets `regs_allocated' to `REGS_REALLOCATE'. Then on subsequent calls with the same pattern buffer and REGS arguments, the matcher reallocates more space if necessary. It would perhaps be more logical to make the `regs_allocated' field part of the `re_registers' structure, instead of part of the pattern buffer. But in that case the caller would be forced to initialize the structure before passing it. Much existing code doesn't do this initialization, and it's arguably better to avoid it anyway. `re_compile_pattern' sets `regs_allocated' to `REGS_UNALLOCATED', so if you use the GNU regular expression functions, you get this behavior by default. xx document re_set_registers POSIX, on the other hand, requires a different interface: the caller is supposed to pass in a fixed-length array which the matcher fills. Therefore, if `regs_allocated' is `REGS_FIXED' the matcher simply fills that array. The following examples illustrate the information recorded in the `re_registers' structure. (In all of them, `(' represents the open-group and `)' the close-group operator. The first character in the string STRING is at index 0.) * If the regular expression has an I-th group not contained within another group that matches a substring of STRING, then the function sets `REGS->start[I]' to the index in STRING where the substring matched by the I-th group begins, and `REGS->end[I]' to the index just beyond that substring's end. The function sets `REGS->start[0]' and `REGS->end[0]' to analogous information about the entire pattern. For example, when you match `((a)(b))' against `ab', you get: * 0 in `REGS->start[0]' and 2 in `REGS->end[0]' * 0 in `REGS->start[1]' and 2 in `REGS->end[1]' * 0 in `REGS->start[2]' and 1 in `REGS->end[2]' * 1 in `REGS->start[3]' and 2 in `REGS->end[3]' * If a group matches more than once (as it might if followed by, e.g., a repetition operator), then the function reports the information about what the group *last* matched. For example, when you match the pattern `(a)*' against the string `aa', you get: * 0 in `REGS->start[0]' and 2 in `REGS->end[0]' * 1 in `REGS->start[1]' and 2 in `REGS->end[1]' * If the I-th group does not participate in a successful match, e.g., it is an alternative not taken or a repetition operator allows zero repetitions of it, then the function sets `REGS->start[I]' and `REGS->end[I]' to -1. For example, when you match the pattern `(a)*b' against the string `b', you get: * 0 in `REGS->start[0]' and 1 in `REGS->end[0]' * -1 in `REGS->start[1]' and -1 in `REGS->end[1]' * If the I-th group matches a zero-length string, then the function sets `REGS->start[I]' and `REGS->end[I]' to the index just beyond that zero-length string. For example, when you match the pattern `(a*)b' against the string `b', you get: * 0 in `REGS->start[0]' and 1 in `REGS->end[0]' * 0 in `REGS->start[1]' and 0 in `REGS->end[1]' * If an I-th group contains a J-th group in turn not contained within any other group within group I and the function reports a match of the I-th group, then it records in `REGS->start[J]' and `REGS->end[J]' the last match (if it matched) of the J-th group. For example, when you match the pattern `((a*)b)*' against the string `abb', group 2 last matches the empty string, so you get what it previously matched: * 0 in `REGS->start[0]' and 3 in `REGS->end[0]' * 2 in `REGS->start[1]' and 3 in `REGS->end[1]' * 2 in `REGS->start[2]' and 2 in `REGS->end[2]' When you match the pattern `((a)*b)*' against the string `abb', group 2 doesn't participate in the last match, so you get: * 0 in `REGS->start[0]' and 3 in `REGS->end[0]' * 2 in `REGS->start[1]' and 3 in `REGS->end[1]' * 0 in `REGS->start[2]' and 1 in `REGS->end[2]' * If an I-th group contains a J-th group in turn not contained within any other group within group I and the function sets `REGS->start[I]' and `REGS->end[I]' to -1, then it also sets `REGS->start[J]' and `REGS->end[J]' to -1. For example, when you match the pattern `((a)*b)*c' against the string `c', you get: * 0 in `REGS->start[0]' and 1 in `REGS->end[0]' * -1 in `REGS->start[1]' and -1 in `REGS->end[1]' * -1 in `REGS->start[2]' and -1 in `REGS->end[2]'  File: regex.info, Node: Freeing GNU Pattern Buffers, Prev: Using Registers, Up: GNU Regex Functions Freeing GNU Pattern Buffers --------------------------- To free any allocated fields of a pattern buffer, you can use the POSIX function described in *Note Freeing POSIX Pattern Buffers::, since the type `regex_t'--the type for POSIX pattern buffers--is equivalent to the type `re_pattern_buffer'. After freeing a pattern buffer, you need to again compile a regular expression in it (*note GNU Regular Expression Compiling::.) before passing it to a matching or searching function.  File: regex.info, Node: POSIX Regex Functions, Next: BSD Regex Functions, Prev: GNU Regex Functions, Up: Programming with Regex POSIX Regex Functions ===================== If you're writing code that has to be POSIX compatible, you'll need to use these functions. Their interfaces are as specified by POSIX, draft 1003.2/D11.2. * Menu: * POSIX Pattern Buffers:: The regex_t type. * POSIX Regular Expression Compiling:: regcomp () * POSIX Matching:: regexec () * Reporting Errors:: regerror () * Using Byte Offsets:: The regmatch_t type. * Freeing POSIX Pattern Buffers:: regfree ()  File: regex.info, Node: POSIX Pattern Buffers, Next: POSIX Regular Expression Compiling, Up: POSIX Regex Functions POSIX Pattern Buffers --------------------- To compile or match a given regular expression the POSIX way, you must supply a pattern buffer exactly the way you do for GNU (*note GNU Pattern Buffers::.). POSIX pattern buffers have type `regex_t', which is equivalent to the GNU pattern buffer type `re_pattern_buffer'.  File: regex.info, Node: POSIX Regular Expression Compiling, Next: POSIX Matching, Prev: POSIX Pattern Buffers, Up: POSIX Regex Functions POSIX Regular Expression Compiling ---------------------------------- With POSIX, you can only search for a given regular expression; you can't match it. To do this, you must first compile it in a pattern buffer, using `regcomp'. To compile a pattern buffer, use: int regcomp (regex_t *PREG, const char *REGEX, int CFLAGS) PREG is the initialized pattern buffer's address, REGEX is the regular expression's address, and CFLAGS is the compilation flags, which Regex considers as a collection of bits. Here are the valid bits, as defined in `regex.h': `REG_EXTENDED' says to use POSIX Extended Regular Expression syntax; if this isn't set, then says to use POSIX Basic Regular Expression syntax. `regcomp' sets PREG's `syntax' field accordingly. `REG_ICASE' says to ignore case; `regcomp' sets PREG's `translate' field to a translate table which ignores case, replacing anything you've put there before. `REG_NOSUB' says to set PREG's `no_sub' field; *note POSIX Matching::., for what this means. `REG_NEWLINE' says that a: * match-any-character operator (*note Match-any-character Operator::.) doesn't match a newline. * nonmatching list not containing a newline (*note List Operators::.) matches a newline. * match-beginning-of-line operator (*note Match-beginning-of-line Operator::.) matches the empty string immediately after a newline, regardless of how `REG_NOTBOL' is set (*note POSIX Matching::., for an explanation of `REG_NOTBOL'). * match-end-of-line operator (*note Match-beginning-of-line Operator::.) matches the empty string immediately before a newline, regardless of how `REG_NOTEOL' is set (*note POSIX Matching::., for an explanation of `REG_NOTEOL'). If `regcomp' successfully compiles the regular expression, it returns zero and sets `*PATTERN_BUFFER' to the compiled pattern. Except for `syntax' (which it sets as explained above), it also sets the same fields the same way as does the GNU compiling function (*note GNU Regular Expression Compiling::.). If `regcomp' can't compile the regular expression, it returns one of the error codes listed here. (Except when noted differently, the syntax of in all examples below is basic regular expression syntax.) `REG_BADRPT' For example, the consecutive repetition operators `**' in `a**' are invalid. As another example, if the syntax is extended regular expression syntax, then the repetition operator `*' with nothing on which to operate in `*' is invalid. `REG_BADBR' For example, the COUNT `-1' in `a\{-1' is invalid. `REG_EBRACE' For example, `a\{1' is missing a close-interval operator. `REG_EBRACK' For example, `[a' is missing a close-list operator. `REG_ERANGE' For example, the range ending point `z' that collates lower than does its starting point `a' in `[z-a]' is invalid. Also, the range with the character class `[:alpha:]' as its starting point in `[[:alpha:]-|]'. `REG_ECTYPE' For example, the character class name `foo' in `[[:foo:]' is invalid. `REG_EPAREN' For example, `a\)' is missing an open-group operator and `\(a' is missing a close-group operator. `REG_ESUBREG' For example, the back reference `\2' that refers to a nonexistent subexpression in `\(a\)\2' is invalid. `REG_EEND' Returned when a regular expression causes no other more specific error. `REG_EESCAPE' For example, the trailing backslash `\' in `a\' is invalid, as is the one in `\'. `REG_BADPAT' For example, in the extended regular expression syntax, the empty group `()' in `a()b' is invalid. `REG_ESIZE' Returned when a regular expression needs a pattern buffer larger than 65536 bytes. `REG_ESPACE' Returned when a regular expression makes Regex to run out of memory.  File: regex.info, Node: POSIX Matching, Next: Reporting Errors, Prev: POSIX Regular Expression Compiling, Up: POSIX Regex Functions POSIX Matching -------------- Matching the POSIX way means trying to match a null-terminated string starting at its first character. Once you've compiled a pattern into a pattern buffer (*note POSIX Regular Expression Compiling::.), you can ask the matcher to match that pattern against a string using: int regexec (const regex_t *PREG, const char *STRING, size_t NMATCH, regmatch_t PMATCH[], int EFLAGS) PREG is the address of a pattern buffer for a compiled pattern. STRING is the string you want to match. *Note Using Byte Offsets::, for an explanation of PMATCH. If you pass zero for NMATCH or you compiled PREG with the compilation flag `REG_NOSUB' set, then `regexec' will ignore PMATCH; otherwise, you must allocate it to have at least NMATCH elements. `regexec' will record NMATCH byte offsets in PMATCH, and set to -1 any unused elements up to PMATCH`[NMATCH]' - 1. EFLAGS specifies "execution flags"--namely, the two bits `REG_NOTBOL' and `REG_NOTEOL' (defined in `regex.h'). If you set `REG_NOTBOL', then the match-beginning-of-line operator (*note Match-beginning-of-line Operator::.) always fails to match. This lets you match against pieces of a line, as you would need to if, say, searching for repeated instances of a given pattern in a line; it would work correctly for patterns both with and without match-beginning-of-line operators. `REG_NOTEOL' works analogously for the match-end-of-line operator (*note Match-end-of-line Operator::.); it exists for symmetry. `regexec' tries to find a match for PREG in STRING according to the syntax in PREG's `syntax' field. (*Note POSIX Regular Expression Compiling::, for how to set it.) The function returns zero if the compiled pattern matches STRING and `REG_NOMATCH' (defined in `regex.h') if it doesn't.  File: regex.info, Node: Reporting Errors, Next: Using Byte Offsets, Prev: POSIX Matching, Up: POSIX Regex Functions Reporting Errors ---------------- If either `regcomp' or `regexec' fail, they return a nonzero error code, the possibilities for which are defined in `regex.h'. *Note POSIX Regular Expression Compiling::, and *Note POSIX Matching::, for what these codes mean. To get an error string corresponding to these codes, you can use: size_t regerror (int ERRCODE, const regex_t *PREG, char *ERRBUF, size_t ERRBUF_SIZE) ERRCODE is an error code, PREG is the address of the pattern buffer which provoked the error, ERRBUF is the error buffer, and ERRBUF_SIZE is ERRBUF's size. `regerror' returns the size in bytes of the error string corresponding to ERRCODE (including its terminating null). If ERRBUF and ERRBUF_SIZE are nonzero, it also returns in ERRBUF the first ERRBUF_SIZE - 1 characters of the error string, followed by a null. eRRBUF_SIZE must be a nonnegative number less than or equal to the size in bytes of ERRBUF. You can call `regerror' with a null ERRBUF and a zero ERRBUF_SIZE to determine how large ERRBUF need be to accommodate `regerror''s error string.  File: regex.info, Node: Using Byte Offsets, Next: Freeing POSIX Pattern Buffers, Prev: Reporting Errors, Up: POSIX Regex Functions Using Byte Offsets ------------------ In POSIX, variables of type `regmatch_t' hold analogous information, but are not identical to, GNU's registers (*note Using Registers::.). To get information about registers in POSIX, pass to `regexec' a nonzero PMATCH of type `regmatch_t', i.e., the address of a structure of this type, defined in `regex.h': typedef struct { regoff_t rm_so; regoff_t rm_eo; } regmatch_t; When reading in *Note Using Registers::, about how the matching function stores the information into the registers, substitute PMATCH for REGS, `PMATCH[I]->rm_so' for `REGS->start[I]' and `PMATCH[I]->rm_eo' for `REGS->end[I]'.  File: regex.info, Node: Freeing POSIX Pattern Buffers, Prev: Using Byte Offsets, Up: POSIX Regex Functions Freeing POSIX Pattern Buffers ----------------------------- To free any allocated fields of a pattern buffer, use: void regfree (regex_t *PREG) PREG is the pattern buffer whose allocated fields you want freed. `regfree' also sets PREG's `allocated' and `used' fields to zero. After freeing a pattern buffer, you need to again compile a regular expression in it (*note POSIX Regular Expression Compiling::.) before passing it to the matching function (*note POSIX Matching::.).  File: regex.info, Node: BSD Regex Functions, Prev: POSIX Regex Functions, Up: Programming with Regex BSD Regex Functions =================== If you're writing code that has to be Berkeley UNIX compatible, you'll need to use these functions whose interfaces are the same as those in Berkeley UNIX. * Menu: * BSD Regular Expression Compiling:: re_comp () * BSD Searching:: re_exec ()  File: regex.info, Node: BSD Regular Expression Compiling, Next: BSD Searching, Up: BSD Regex Functions BSD Regular Expression Compiling -------------------------------- With Berkeley UNIX, you can only search for a given regular expression; you can't match one. To search for it, you must first compile it. Before you compile it, you must indicate the regular expression syntax you want it compiled according to by setting the variable `re_syntax_options' (declared in `regex.h' to some syntax (*note Regular Expression Syntax::.). To compile a regular expression use: char * re_comp (char *REGEX) REGEX is the address of a null-terminated regular expression. `re_comp' uses an internal pattern buffer, so you can use only the most recently compiled pattern buffer. This means that if you want to use a given regular expression that you've already compiled--but it isn't the latest one you've compiled--you'll have to recompile it. If you call `re_comp' with the null string (*not* the empty string) as the argument, it doesn't change the contents of the pattern buffer. If `re_comp' successfully compiles the regular expression, it returns zero. If it can't compile the regular expression, it returns an error string. `re_comp''s error messages are identical to those of `re_compile_pattern' (*note GNU Regular Expression Compiling::.).  File: regex.info, Node: BSD Searching, Prev: BSD Regular Expression Compiling, Up: BSD Regex Functions BSD Searching ------------- Searching the Berkeley UNIX way means searching in a string starting at its first character and trying successive positions within it to find a match. Once you've compiled a pattern using `re_comp' (*note BSD Regular Expression Compiling::.), you can ask Regex to search for that pattern in a string using: int re_exec (char *STRING) STRING is the address of the null-terminated string in which you want to search. `re_exec' returns either 1 for success or 0 for failure. It automatically uses a GNU fastmap (*note Searching with Fastmaps::.).  File: regex.info, Node: Copying, Next: Index, Prev: Programming with Regex, Up: Top GNU GENERAL PUBLIC LICENSE ************************** Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble ======== The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 1. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 2. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 3. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a. You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b. You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c. If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 4. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a. Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b. Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c. Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 5. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 6. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 7. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 8. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 9. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 10. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 11. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 12. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 13. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs ======================================================= If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES. Copyright (C) 19YY NAME OF AUTHOR 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 2 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, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19YY NAME OF AUTHOR Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. SIGNATURE OF TY COON, 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License.  File: regex.info, Node: Index, Prev: Copying, Up: Top Index ***** * Menu: * $: Match-end-of-line Operator. * (: Grouping Operators. * ): Grouping Operators. * *: Match-zero-or-more Operator. * +: Match-one-or-more Operator. * -: List Operators. * .: Match-any-character Operator. * :] in regex: Character Class Operators. * ?: Match-zero-or-one Operator. * {: Interval Operators. * }: Interval Operators. * [: in regex: Character Class Operators. * [^: List Operators. * [: List Operators. * \': Match-end-of-buffer Operator. * \<: Match-beginning-of-word Operator. * \>: Match-end-of-word Operator. * \{: Interval Operators. * \}: Interval Operators. * \b: Match-word-boundary Operator. * \B: Match-within-word Operator. * \s: Match-syntactic-class Operator. * \S: Match-not-syntactic-class Operator. * \w: Match-word-constituent Operator. * \W: Match-non-word-constituent Operator. * \`: Match-beginning-of-buffer Operator. * \: List Operators. * ]: List Operators. * ^: List Operators. * allocated initialization: GNU Regular Expression Compiling. * alternation operator: Alternation Operator. * alternation operator and ^: Match-beginning-of-line Operator. * anchoring: Anchoring Operators. * anchors: Match-end-of-line Operator. * anchors: Match-beginning-of-line Operator. * Awk: Predefined Syntaxes. * back references: Back-reference Operator. * backtracking: Match-zero-or-more Operator. * backtracking: Alternation Operator. * beginning-of-line operator: Match-beginning-of-line Operator. * bracket expression: List Operators. * buffer field, set by re_compile_pattern: GNU Regular Expression Compiling. * buffer initialization: GNU Regular Expression Compiling. * character classes: Character Class Operators. * Egrep: Predefined Syntaxes. * Emacs: Predefined Syntaxes. * end in struct re_registers: Using Registers. * end-of-line operator: Match-end-of-line Operator. * fastmap initialization: GNU Regular Expression Compiling. * fastmaps: Searching with Fastmaps. * fastmap_accurate field, set by re_compile_pattern: GNU Regular Expression Compiling. * Grep: Predefined Syntaxes. * grouping: Grouping Operators. * ignoring case: POSIX Regular Expression Compiling. * interval expression: Interval Operators. * matching list: List Operators. * matching newline: List Operators. * matching with GNU functions: GNU Matching. * newline_anchor field in pattern buffer: Match-beginning-of-line Operator. * nonmatching list: List Operators. * not_bol field in pattern buffer: Match-beginning-of-line Operator. * num_regs in struct re_registers: Using Registers. * open-group operator and ^: Match-beginning-of-line Operator. * or operator: Alternation Operator. * parenthesizing: Grouping Operators. * pattern buffer initialization: GNU Regular Expression Compiling. * pattern buffer, definition of: GNU Pattern Buffers. * POSIX Awk: Predefined Syntaxes. * range argument to re_search: GNU Searching. * regex.c: Overview. * regex.h: Overview. * regexp anchoring: Anchoring Operators. * regmatch_t: Using Byte Offsets. * regs_allocated: Using Registers. * REGS_FIXED: Using Registers. * REGS_REALLOCATE: Using Registers. * REGS_UNALLOCATED: Using Registers. * regular expressions, syntax of: Regular Expression Syntax. * REG_EXTENDED: POSIX Regular Expression Compiling. * REG_ICASE: POSIX Regular Expression Compiling. * REG_NEWLINE: POSIX Regular Expression Compiling. * REG_NOSUB: POSIX Regular Expression Compiling. * RE_BACKSLASH_ESCAPE_IN_LIST: Syntax Bits. * RE_BK_PLUS_QM: Syntax Bits. * RE_CHAR_CLASSES: Syntax Bits. * RE_CONTEXT_INDEP_ANCHORS: Syntax Bits. * RE_CONTEXT_INDEP_ANCHORS (and ^): Match-beginning-of-line Operator. * RE_CONTEXT_INDEP_OPS: Syntax Bits. * RE_CONTEXT_INVALID_OPS: Syntax Bits. * RE_DOT_NEWLINE: Syntax Bits. * RE_DOT_NOT_NULL: Syntax Bits. * RE_INTERVALS: Syntax Bits. * RE_LIMITED_OPS: Syntax Bits. * RE_NEWLINE_ALT: Syntax Bits. * RE_NO_BK_BRACES: Syntax Bits. * RE_NO_BK_PARENS: Syntax Bits. * RE_NO_BK_REFS: Syntax Bits. * RE_NO_BK_VBAR: Syntax Bits. * RE_NO_EMPTY_RANGES: Syntax Bits. * re_nsub field, set by re_compile_pattern: GNU Regular Expression Compiling. * re_pattern_buffer definition: GNU Pattern Buffers. * re_registers: Using Registers. * re_syntax_options initialization: GNU Regular Expression Compiling. * RE_UNMATCHED_RIGHT_PAREN_ORD: Syntax Bits. * searching with GNU functions: GNU Searching. * start argument to re_search: GNU Searching. * start in struct re_registers: Using Registers. * struct re_pattern_buffer definition: GNU Pattern Buffers. * subexpressions: Grouping Operators. * syntax field, set by re_compile_pattern: GNU Regular Expression Compiling. * syntax bits: Syntax Bits. * syntax initialization: GNU Regular Expression Compiling. * syntax of regular expressions: Regular Expression Syntax. * translate initialization: GNU Regular Expression Compiling. * used field, set by re_compile_pattern: GNU Regular Expression Compiling. * word boundaries, matching: Match-word-boundary Operator. * \: The Backslash Character. * \(: Grouping Operators. * \): Grouping Operators. * \|: Alternation Operator. * ^: Match-beginning-of-line Operator. * |: Alternation Operator.  Tag Table: Node: Top1064 Node: Overview4562 Node: Regular Expression Syntax6746 Node: Syntax Bits7916 Node: Predefined Syntaxes14018 Node: Collating Elements vs. Characters17872 Node: The Backslash Character18835 Node: Common Operators21992 Node: Match-self Operator23445 Node: Match-any-character Operator23941 Node: Concatenation Operator24520 Node: Repetition Operators25017 Node: Match-zero-or-more Operator25436 Node: Match-one-or-more Operator27483 Node: Match-zero-or-one Operator28341 Node: Interval Operators29196 Node: Alternation Operator30991 Node: List Operators32489 Node: Character Class Operators35272 Node: Range Operator36901 Node: Grouping Operators38930 Node: Back-reference Operator40251 Node: Anchoring Operators43073 Node: Match-beginning-of-line Operator43447 Node: Match-end-of-line Operator44779 Node: GNU Operators45518 Node: Word Operators45767 Node: Non-Emacs Syntax Tables46391 Node: Match-word-boundary Operator47465 Node: Match-within-word Operator47858 Node: Match-beginning-of-word Operator48255 Node: Match-end-of-word Operator48588 Node: Match-word-constituent Operator48908 Node: Match-non-word-constituent Operator49234 Node: Buffer Operators49545 Node: Match-beginning-of-buffer Operator49952 Node: Match-end-of-buffer Operator50264 Node: GNU Emacs Operators50558 Node: Syntactic Class Operators50901 Node: Emacs Syntax Tables51307 Node: Match-syntactic-class Operator51963 Node: Match-not-syntactic-class Operator52560 Node: What Gets Matched?53150 Node: Programming with Regex53799 Node: GNU Regex Functions54237 Node: GNU Pattern Buffers55078 Node: GNU Regular Expression Compiling58303 Node: GNU Matching61181 Node: GNU Searching63101 Node: Matching/Searching with Split Data64913 Node: Searching with Fastmaps66369 Node: GNU Translate Tables68921 Node: Using Registers70892 Node: Freeing GNU Pattern Buffers77000 Node: POSIX Regex Functions77593 Node: POSIX Pattern Buffers78266 Node: POSIX Regular Expression Compiling78709 Node: POSIX Matching82836 Node: Reporting Errors84791 Node: Using Byte Offsets86048 Node: Freeing POSIX Pattern Buffers86861 Node: BSD Regex Functions87467 Node: BSD Regular Expression Compiling87886 Node: BSD Searching89258 Node: Copying89960 Node: Index109122  End Tag Table lyskom-server-2.1.2/src/libraries/regex/doc/regex.texi0000664000015100472110000035160005533104413016447 \input texinfo @c %**start of header @setfilename regex.info @settitle Regex @c %**end of header @c \\{fill-paragraph} works better (for me, anyway) if the text in the @c source file isn't indented. @paragraphindent 2 @c Define a new index for our magic constants. @defcodeindex cn @c Put everything in one index (arbitrarily chosen to be the concept index). @syncodeindex cn cp @syncodeindex ky cp @syncodeindex pg cp @syncodeindex tp cp @syncodeindex vr cp @c Here is what we use in the Info `dir' file: @c * Regex: (regex). Regular expression library. @ifinfo This file documents the GNU regular expression library. Copyright (C) 1992, 1993 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. @ignore Permission is granted to process this file through TeX and print the results, provided the printed document carries a copying permission notice identical to this one except for the removal of this paragraph (this paragraph not being relevant to the printed manual). @end ignore Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the section entitled ``GNU General Public License'' is included exactly as in the original, and provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that the section entitled ``GNU General Public License'' may be included in a translation approved by the Free Software Foundation instead of in the original English. @end ifinfo @titlepage @title Regex @subtitle edition 0.12a @subtitle 19 September 1992 @author Kathryn A. Hargreaves @author Karl Berry @page @vskip 0pt plus 1filll Copyright @copyright{} 1992 Free Software Foundation. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the section entitled ``GNU General Public License'' is included exactly as in the original, and provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that the section entitled ``GNU General Public License'' may be included in a translation approved by the Free Software Foundation instead of in the original English. @end titlepage @ifinfo @node Top, Overview, (dir), (dir) @top Regular Expression Library This manual documents how to program with the GNU regular expression library. This is edition 0.12a of the manual, 19 September 1992. The first part of this master menu lists the major nodes in this Info document, including the index. The rest of the menu lists all the lower level nodes in the document. @menu * Overview:: * Regular Expression Syntax:: * Common Operators:: * GNU Operators:: * GNU Emacs Operators:: * What Gets Matched?:: * Programming with Regex:: * Copying:: Copying and sharing Regex. * Index:: General index. --- The Detailed Node Listing --- Regular Expression Syntax * Syntax Bits:: * Predefined Syntaxes:: * Collating Elements vs. Characters:: * The Backslash Character:: Common Operators * Match-self Operator:: Ordinary characters. * Match-any-character Operator:: . * Concatenation Operator:: Juxtaposition. * Repetition Operators:: * + ? @{@} * Alternation Operator:: | * List Operators:: [...] [^...] * Grouping Operators:: (...) * Back-reference Operator:: \digit * Anchoring Operators:: ^ $ Repetition Operators * Match-zero-or-more Operator:: * * Match-one-or-more Operator:: + * Match-zero-or-one Operator:: ? * Interval Operators:: @{@} List Operators (@code{[} @dots{} @code{]} and @code{[^} @dots{} @code{]}) * Character Class Operators:: [:class:] * Range Operator:: start-end Anchoring Operators * Match-beginning-of-line Operator:: ^ * Match-end-of-line Operator:: $ GNU Operators * Word Operators:: * Buffer Operators:: Word Operators * Non-Emacs Syntax Tables:: * Match-word-boundary Operator:: \b * Match-within-word Operator:: \B * Match-beginning-of-word Operator:: \< * Match-end-of-word Operator:: \> * Match-word-constituent Operator:: \w * Match-non-word-constituent Operator:: \W Buffer Operators * Match-beginning-of-buffer Operator:: \` * Match-end-of-buffer Operator:: \' GNU Emacs Operators * Syntactic Class Operators:: Syntactic Class Operators * Emacs Syntax Tables:: * Match-syntactic-class Operator:: \sCLASS * Match-not-syntactic-class Operator:: \SCLASS Programming with Regex * GNU Regex Functions:: * POSIX Regex Functions:: * BSD Regex Functions:: GNU Regex Functions * GNU Pattern Buffers:: The re_pattern_buffer type. * GNU Regular Expression Compiling:: re_compile_pattern () * GNU Matching:: re_match () * GNU Searching:: re_search () * Matching/Searching with Split Data:: re_match_2 (), re_search_2 () * Searching with Fastmaps:: re_compile_fastmap () * GNU Translate Tables:: The `translate' field. * Using Registers:: The re_registers type and related fns. * Freeing GNU Pattern Buffers:: regfree () POSIX Regex Functions * POSIX Pattern Buffers:: The regex_t type. * POSIX Regular Expression Compiling:: regcomp () * POSIX Matching:: regexec () * Reporting Errors:: regerror () * Using Byte Offsets:: The regmatch_t type. * Freeing POSIX Pattern Buffers:: regfree () BSD Regex Functions * BSD Regular Expression Compiling:: re_comp () * BSD Searching:: re_exec () @end menu @end ifinfo @node Overview, Regular Expression Syntax, Top, Top @chapter Overview A @dfn{regular expression} (or @dfn{regexp}, or @dfn{pattern}) is a text string that describes some (mathematical) set of strings. A regexp @var{r} @dfn{matches} a string @var{s} if @var{s} is in the set of strings described by @var{r}. Using the Regex library, you can: @itemize @bullet @item see if a string matches a specified pattern as a whole, and @item search within a string for a substring matching a specified pattern. @end itemize Some regular expressions match only one string, i.e., the set they describe has only one member. For example, the regular expression @samp{foo} matches the string @samp{foo} and no others. Other regular expressions match more than one string, i.e., the set they describe has more than one member. For example, the regular expression @samp{f*} matches the set of strings made up of any number (including zero) of @samp{f}s. As you can see, some characters in regular expressions match themselves (such as @samp{f}) and some don't (such as @samp{*}); the ones that don't match themselves instead let you specify patterns that describe many different strings. To either match or search for a regular expression with the Regex library functions, you must first compile it with a Regex pattern compiling function. A @dfn{compiled pattern} is a regular expression converted to the internal format used by the library functions. Once you've compiled a pattern, you can use it for matching or searching any number of times. The Regex library consists of two source files: @file{regex.h} and @file{regex.c}. @pindex regex.h @pindex regex.c Regex provides three groups of functions with which you can operate on regular expressions. One group---the @sc{gnu} group---is more powerful but not completely compatible with the other two, namely the @sc{posix} and Berkeley @sc{unix} groups; its interface was designed specifically for @sc{gnu}. The other groups have the same interfaces as do the regular expression functions in @sc{posix} and Berkeley @sc{unix}. We wrote this chapter with programmers in mind, not users of programs---such as Emacs---that use Regex. We describe the Regex library in its entirety, not how to write regular expressions that a particular program understands. @node Regular Expression Syntax, Common Operators, Overview, Top @chapter Regular Expression Syntax @cindex regular expressions, syntax of @cindex syntax of regular expressions @dfn{Characters} are things you can type. @dfn{Operators} are things in a regular expression that match one or more characters. You compose regular expressions from operators, which in turn you specify using one or more characters. Most characters represent what we call the match-self operator, i.e., they match themselves; we call these characters @dfn{ordinary}. Other characters represent either all or parts of fancier operators; e.g., @samp{.} represents what we call the match-any-character operator (which, no surprise, matches (almost) any character); we call these characters @dfn{special}. Two different things determine what characters represent what operators: @enumerate @item the regular expression syntax your program has told the Regex library to recognize, and @item the context of the character in the regular expression. @end enumerate In the following sections, we describe these things in more detail. @menu * Syntax Bits:: * Predefined Syntaxes:: * Collating Elements vs. Characters:: * The Backslash Character:: @end menu @node Syntax Bits, Predefined Syntaxes, , Regular Expression Syntax @section Syntax Bits @cindex syntax bits In any particular syntax for regular expressions, some characters are always special, others are sometimes special, and others are never special. The particular syntax that Regex recognizes for a given regular expression depends on the value in the @code{syntax} field of the pattern buffer of that regular expression. You get a pattern buffer by compiling a regular expression. @xref{GNU Pattern Buffers}, and @ref{POSIX Pattern Buffers}, for more information on pattern buffers. @xref{GNU Regular Expression Compiling}, @ref{POSIX Regular Expression Compiling}, and @ref{BSD Regular Expression Compiling}, for more information on compiling. Regex considers the value of the @code{syntax} field to be a collection of bits; we refer to these bits as @dfn{syntax bits}. In most cases, they affect what characters represent what operators. We describe the meanings of the operators to which we refer in @ref{Common Operators}, @ref{GNU Operators}, and @ref{GNU Emacs Operators}. For reference, here is the complete list of syntax bits, in alphabetical order: @table @code @cnindex RE_BACKSLASH_ESCAPE_IN_LIST @item RE_BACKSLASH_ESCAPE_IN_LISTS If this bit is set, then @samp{\} inside a list (@pxref{List Operators} quotes (makes ordinary, if it's special) the following character; if this bit isn't set, then @samp{\} is an ordinary character inside lists. (@xref{The Backslash Character}, for what `\' does outside of lists.) @cnindex RE_BK_PLUS_QM @item RE_BK_PLUS_QM If this bit is set, then @samp{\+} represents the match-one-or-more operator and @samp{\?} represents the match-zero-or-more operator; if this bit isn't set, then @samp{+} represents the match-one-or-more operator and @samp{?} represents the match-zero-or-one operator. This bit is irrelevant if @code{RE_LIMITED_OPS} is set. @cnindex RE_CHAR_CLASSES @item RE_CHAR_CLASSES If this bit is set, then you can use character classes in lists; if this bit isn't set, then you can't. @cnindex RE_CONTEXT_INDEP_ANCHORS @item RE_CONTEXT_INDEP_ANCHORS If this bit is set, then @samp{^} and @samp{$} are special anywhere outside a list; if this bit isn't set, then these characters are special only in certain contexts. @xref{Match-beginning-of-line Operator}, and @ref{Match-end-of-line Operator}. @cnindex RE_CONTEXT_INDEP_OPS @item RE_CONTEXT_INDEP_OPS If this bit is set, then certain characters are special anywhere outside a list; if this bit isn't set, then those characters are special only in some contexts and are ordinary elsewhere. Specifically, if this bit isn't set then @samp{*}, and (if the syntax bit @code{RE_LIMITED_OPS} isn't set) @samp{+} and @samp{?} (or @samp{\+} and @samp{\?}, depending on the syntax bit @code{RE_BK_PLUS_QM}) represent repetition operators only if they're not first in a regular expression or just after an open-group or alternation operator. The same holds for @samp{@{} (or @samp{\@{}, depending on the syntax bit @code{RE_NO_BK_BRACES}) if it is the beginning of a valid interval and the syntax bit @code{RE_INTERVALS} is set. @cnindex RE_CONTEXT_INVALID_OPS @item RE_CONTEXT_INVALID_OPS If this bit is set, then repetition and alternation operators can't be in certain positions within a regular expression. Specifically, the regular expression is invalid if it has: @itemize @bullet @item a repetition operator first in the regular expression or just after a match-beginning-of-line, open-group, or alternation operator; or @item an alternation operator first or last in the regular expression, just before a match-end-of-line operator, or just after an alternation or open-group operator. @end itemize If this bit isn't set, then you can put the characters representing the repetition and alternation characters anywhere in a regular expression. Whether or not they will in fact be operators in certain positions depends on other syntax bits. @cnindex RE_DOT_NEWLINE @item RE_DOT_NEWLINE If this bit is set, then the match-any-character operator matches a newline; if this bit isn't set, then it doesn't. @cnindex RE_DOT_NOT_NULL @item RE_DOT_NOT_NULL If this bit is set, then the match-any-character operator doesn't match a null character; if this bit isn't set, then it does. @cnindex RE_INTERVALS @item RE_INTERVALS If this bit is set, then Regex recognizes interval operators; if this bit isn't set, then it doesn't. @cnindex RE_LIMITED_OPS @item RE_LIMITED_OPS If this bit is set, then Regex doesn't recognize the match-one-or-more, match-zero-or-one or alternation operators; if this bit isn't set, then it does. @cnindex RE_NEWLINE_ALT @item RE_NEWLINE_ALT If this bit is set, then newline represents the alternation operator; if this bit isn't set, then newline is ordinary. @cnindex RE_NO_BK_BRACES @item RE_NO_BK_BRACES If this bit is set, then @samp{@{} represents the open-interval operator and @samp{@}} represents the close-interval operator; if this bit isn't set, then @samp{\@{} represents the open-interval operator and @samp{\@}} represents the close-interval operator. This bit is relevant only if @code{RE_INTERVALS} is set. @cnindex RE_NO_BK_PARENS @item RE_NO_BK_PARENS If this bit is set, then @samp{(} represents the open-group operator and @samp{)} represents the close-group operator; if this bit isn't set, then @samp{\(} represents the open-group operator and @samp{\)} represents the close-group operator. @cnindex RE_NO_BK_REFS @item RE_NO_BK_REFS If this bit is set, then Regex doesn't recognize @samp{\}@var{digit} as the back reference operator; if this bit isn't set, then it does. @cnindex RE_NO_BK_VBAR @item RE_NO_BK_VBAR If this bit is set, then @samp{|} represents the alternation operator; if this bit isn't set, then @samp{\|} represents the alternation operator. This bit is irrelevant if @code{RE_LIMITED_OPS} is set. @cnindex RE_NO_EMPTY_RANGES @item RE_NO_EMPTY_RANGES If this bit is set, then a regular expression with a range whose ending point collates lower than its starting point is invalid; if this bit isn't set, then Regex considers such a range to be empty. @cnindex RE_UNMATCHED_RIGHT_PAREN_ORD @item RE_UNMATCHED_RIGHT_PAREN_ORD If this bit is set and the regular expression has no matching open-group operator, then Regex considers what would otherwise be a close-group operator (based on how @code{RE_NO_BK_PARENS} is set) to match @samp{)}. @end table @node Predefined Syntaxes, Collating Elements vs. Characters, Syntax Bits, Regular Expression Syntax @section Predefined Syntaxes If you're programming with Regex, you can set a pattern buffer's (@pxref{GNU Pattern Buffers}, and @ref{POSIX Pattern Buffers}) @code{syntax} field either to an arbitrary combination of syntax bits (@pxref{Syntax Bits}) or else to the configurations defined by Regex. These configurations define the syntaxes used by certain programs---@sc{gnu} Emacs, @cindex Emacs @sc{posix} Awk, @cindex POSIX Awk traditional Awk, @cindex Awk Grep, @cindex Grep @cindex Egrep Egrep---in addition to syntaxes for @sc{posix} basic and extended regular expressions. The predefined syntaxes--taken directly from @file{regex.h}---are: @example #define RE_SYNTAX_EMACS 0 #define RE_SYNTAX_AWK \ (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \ | RE_NO_BK_PARENS | RE_NO_BK_REFS \ | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \ | RE_UNMATCHED_RIGHT_PAREN_ORD) #define RE_SYNTAX_POSIX_AWK \ (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS) #define RE_SYNTAX_GREP \ (RE_BK_PLUS_QM | RE_CHAR_CLASSES \ | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \ | RE_NEWLINE_ALT) #define RE_SYNTAX_EGREP \ (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \ | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \ | RE_NEWLINE_ALT | RE_NO_BK_PARENS \ | RE_NO_BK_VBAR) #define RE_SYNTAX_POSIX_EGREP \ (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES) /* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */ #define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC #define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC /* Syntax bits common to both basic and extended POSIX regex syntax. */ #define _RE_SYNTAX_POSIX_COMMON \ (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \ | RE_INTERVALS | RE_NO_EMPTY_RANGES) #define RE_SYNTAX_POSIX_BASIC \ (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM) /* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this isn't minimal, since other operators, such as \`, aren't disabled. */ #define RE_SYNTAX_POSIX_MINIMAL_BASIC \ (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS) #define RE_SYNTAX_POSIX_EXTENDED \ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \ | RE_NO_BK_PARENS | RE_NO_BK_VBAR \ | RE_UNMATCHED_RIGHT_PAREN_ORD) /* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */ #define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \ | RE_NO_BK_PARENS | RE_NO_BK_REFS \ | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD) @end example @node Collating Elements vs. Characters, The Backslash Character, Predefined Syntaxes, Regular Expression Syntax @section Collating Elements vs.@: Characters @sc{posix} generalizes the notion of a character to that of a collating element. It defines a @dfn{collating element} to be ``a sequence of one or more bytes defined in the current collating sequence as a unit of collation.'' This generalizes the notion of a character in two ways. First, a single character can map into two or more collating elements. For example, the German @tex `\ss' @end tex @ifinfo ``es-zet'' @end ifinfo collates as the collating element @samp{s} followed by another collating element @samp{s}. Second, two or more characters can map into one collating element. For example, the Spanish @samp{ll} collates after @samp{l} and before @samp{m}. Since @sc{posix}'s ``collating element'' preserves the essential idea of a ``character,'' we use the latter, more familiar, term in this document. @node The Backslash Character, , Collating Elements vs. Characters, Regular Expression Syntax @section The Backslash Character @cindex \ The @samp{\} character has one of four different meanings, depending on the context in which you use it and what syntax bits are set (@pxref{Syntax Bits}). It can: 1) stand for itself, 2) quote the next character, 3) introduce an operator, or 4) do nothing. @enumerate @item It stands for itself inside a list (@pxref{List Operators}) if the syntax bit @code{RE_BACKSLASH_ESCAPE_IN_LISTS} is not set. For example, @samp{[\]} would match @samp{\}. @item It quotes (makes ordinary, if it's special) the next character when you use it either: @itemize @bullet @item outside a list,@footnote{Sometimes you don't have to explicitly quote special characters to make them ordinary. For instance, most characters lose any special meaning inside a list (@pxref{List Operators}). In addition, if the syntax bits @code{RE_CONTEXT_INVALID_OPS} and @code{RE_CONTEXT_INDEP_OPS} aren't set, then (for historical reasons) the matcher considers special characters ordinary if they are in contexts where the operations they represent make no sense; for example, then the match-zero-or-more operator (represented by @samp{*}) matches itself in the regular expression @samp{*foo} because there is no preceding expression on which it can operate. It is poor practice, however, to depend on this behavior; if you want a special character to be ordinary outside a list, it's better to always quote it, regardless.} or @item inside a list and the syntax bit @code{RE_BACKSLASH_ESCAPE_IN_LISTS} is set. @end itemize @item It introduces an operator when followed by certain ordinary characters---sometimes only when certain syntax bits are set. See the cases @code{RE_BK_PLUS_QM}, @code{RE_NO_BK_BRACES}, @code{RE_NO_BK_VAR}, @code{RE_NO_BK_PARENS}, @code{RE_NO_BK_REF} in @ref{Syntax Bits}. Also: @itemize @bullet @item @samp{\b} represents the match-word-boundary operator (@pxref{Match-word-boundary Operator}). @item @samp{\B} represents the match-within-word operator (@pxref{Match-within-word Operator}). @item @samp{\<} represents the match-beginning-of-word operator @* (@pxref{Match-beginning-of-word Operator}). @item @samp{\>} represents the match-end-of-word operator (@pxref{Match-end-of-word Operator}). @item @samp{\w} represents the match-word-constituent operator (@pxref{Match-word-constituent Operator}). @item @samp{\W} represents the match-non-word-constituent operator (@pxref{Match-non-word-constituent Operator}). @item @samp{\`} represents the match-beginning-of-buffer operator and @samp{\'} represents the match-end-of-buffer operator (@pxref{Buffer Operators}). @item If Regex was compiled with the C preprocessor symbol @code{emacs} defined, then @samp{\s@var{class}} represents the match-syntactic-class operator and @samp{\S@var{class}} represents the match-not-syntactic-class operator (@pxref{Syntactic Class Operators}). @end itemize @item In all other cases, Regex ignores @samp{\}. For example, @samp{\n} matches @samp{n}. @end enumerate @node Common Operators, GNU Operators, Regular Expression Syntax, Top @chapter Common Operators You compose regular expressions from operators. In the following sections, we describe the regular expression operators specified by @sc{posix}; @sc{gnu} also uses these. Most operators have more than one representation as characters. @xref{Regular Expression Syntax}, for what characters represent what operators under what circumstances. For most operators that can be represented in two ways, one representation is a single character and the other is that character preceded by @samp{\}. For example, either @samp{(} or @samp{\(} represents the open-group operator. Which one does depends on the setting of a syntax bit, in this case @code{RE_NO_BK_PARENS}. Why is this so? Historical reasons dictate some of the varying representations, while @sc{posix} dictates others. Finally, almost all characters lose any special meaning inside a list (@pxref{List Operators}). @menu * Match-self Operator:: Ordinary characters. * Match-any-character Operator:: . * Concatenation Operator:: Juxtaposition. * Repetition Operators:: * + ? @{@} * Alternation Operator:: | * List Operators:: [...] [^...] * Grouping Operators:: (...) * Back-reference Operator:: \digit * Anchoring Operators:: ^ $ @end menu @node Match-self Operator, Match-any-character Operator, , Common Operators @section The Match-self Operator (@var{ordinary character}) This operator matches the character itself. All ordinary characters (@pxref{Regular Expression Syntax}) represent this operator. For example, @samp{f} is always an ordinary character, so the regular expression @samp{f} matches only the string @samp{f}. In particular, it does @emph{not} match the string @samp{ff}. @node Match-any-character Operator, Concatenation Operator, Match-self Operator, Common Operators @section The Match-any-character Operator (@code{.}) @cindex @samp{.} This operator matches any single printing or nonprinting character except it won't match a: @table @asis @item newline if the syntax bit @code{RE_DOT_NEWLINE} isn't set. @item null if the syntax bit @code{RE_DOT_NOT_NULL} is set. @end table The @samp{.} (period) character represents this operator. For example, @samp{a.b} matches any three-character string beginning with @samp{a} and ending with @samp{b}. @node Concatenation Operator, Repetition Operators, Match-any-character Operator, Common Operators @section The Concatenation Operator This operator concatenates two regular expressions @var{a} and @var{b}. No character represents this operator; you simply put @var{b} after @var{a}. The result is a regular expression that will match a string if @var{a} matches its first part and @var{b} matches the rest. For example, @samp{xy} (two match-self operators) matches @samp{xy}. @node Repetition Operators, Alternation Operator, Concatenation Operator, Common Operators @section Repetition Operators Repetition operators repeat the preceding regular expression a specified number of times. @menu * Match-zero-or-more Operator:: * * Match-one-or-more Operator:: + * Match-zero-or-one Operator:: ? * Interval Operators:: @{@} @end menu @node Match-zero-or-more Operator, Match-one-or-more Operator, , Repetition Operators @subsection The Match-zero-or-more Operator (@code{*}) @cindex @samp{*} This operator repeats the smallest possible preceding regular expression as many times as necessary (including zero) to match the pattern. @samp{*} represents this operator. For example, @samp{o*} matches any string made up of zero or more @samp{o}s. Since this operator operates on the smallest preceding regular expression, @samp{fo*} has a repeating @samp{o}, not a repeating @samp{fo}. So, @samp{fo*} matches @samp{f}, @samp{fo}, @samp{foo}, and so on. Since the match-zero-or-more operator is a suffix operator, it may be useless as such when no regular expression precedes it. This is the case when it: @itemize @bullet @item is first in a regular expression, or @item follows a match-beginning-of-line, open-group, or alternation operator. @end itemize @noindent Three different things can happen in these cases: @enumerate @item If the syntax bit @code{RE_CONTEXT_INVALID_OPS} is set, then the regular expression is invalid. @item If @code{RE_CONTEXT_INVALID_OPS} isn't set, but @code{RE_CONTEXT_INDEP_OPS} is, then @samp{*} represents the match-zero-or-more operator (which then operates on the empty string). @item Otherwise, @samp{*} is ordinary. @end enumerate @cindex backtracking The matcher processes a match-zero-or-more operator by first matching as many repetitions of the smallest preceding regular expression as it can. Then it continues to match the rest of the pattern. If it can't match the rest of the pattern, it backtracks (as many times as necessary), each time discarding one of the matches until it can either match the entire pattern or be certain that it cannot get a match. For example, when matching @samp{ca*ar} against @samp{caaar}, the matcher first matches all three @samp{a}s of the string with the @samp{a*} of the regular expression. However, it cannot then match the final @samp{ar} of the regular expression against the final @samp{r} of the string. So it backtracks, discarding the match of the last @samp{a} in the string. It can then match the remaining @samp{ar}. @node Match-one-or-more Operator, Match-zero-or-one Operator, Match-zero-or-more Operator, Repetition Operators @subsection The Match-one-or-more Operator (@code{+} or @code{\+}) @cindex @samp{+} If the syntax bit @code{RE_LIMITED_OPS} is set, then Regex doesn't recognize this operator. Otherwise, if the syntax bit @code{RE_BK_PLUS_QM} isn't set, then @samp{+} represents this operator; if it is, then @samp{\+} does. This operator is similar to the match-zero-or-more operator except that it repeats the preceding regular expression at least once; @pxref{Match-zero-or-more Operator}, for what it operates on, how some syntax bits affect it, and how Regex backtracks to match it. For example, supposing that @samp{+} represents the match-one-or-more operator; then @samp{ca+r} matches, e.g., @samp{car} and @samp{caaaar}, but not @samp{cr}. @node Match-zero-or-one Operator, Interval Operators, Match-one-or-more Operator, Repetition Operators @subsection The Match-zero-or-one Operator (@code{?} or @code{\?}) @cindex @samp{?} If the syntax bit @code{RE_LIMITED_OPS} is set, then Regex doesn't recognize this operator. Otherwise, if the syntax bit @code{RE_BK_PLUS_QM} isn't set, then @samp{?} represents this operator; if it is, then @samp{\?} does. This operator is similar to the match-zero-or-more operator except that it repeats the preceding regular expression once or not at all; @pxref{Match-zero-or-more Operator}, to see what it operates on, how some syntax bits affect it, and how Regex backtracks to match it. For example, supposing that @samp{?} represents the match-zero-or-one operator; then @samp{ca?r} matches both @samp{car} and @samp{cr}, but nothing else. @node Interval Operators, , Match-zero-or-one Operator, Repetition Operators @subsection Interval Operators (@code{@{} @dots{} @code{@}} or @code{\@{} @dots{} @code{\@}}) @cindex interval expression @cindex @samp{@{} @cindex @samp{@}} @cindex @samp{\@{} @cindex @samp{\@}} If the syntax bit @code{RE_INTERVALS} is set, then Regex recognizes @dfn{interval expressions}. They repeat the smallest possible preceding regular expression a specified number of times. If the syntax bit @code{RE_NO_BK_BRACES} is set, @samp{@{} represents the @dfn{open-interval operator} and @samp{@}} represents the @dfn{close-interval operator} ; otherwise, @samp{\@{} and @samp{\@}} do. Specifically, supposing that @samp{@{} and @samp{@}} represent the open-interval and close-interval operators; then: @table @code @item @{@var{count}@} matches exactly @var{count} occurrences of the preceding regular expression. @item @{@var{min,}@} matches @var{min} or more occurrences of the preceding regular expression. @item @{@var{min, max}@} matches at least @var{min} but no more than @var{max} occurrences of the preceding regular expression. @end table The interval expression (but not necessarily the regular expression that contains it) is invalid if: @itemize @bullet @item @var{min} is greater than @var{max}, or @item any of @var{count}, @var{min}, or @var{max} are outside the range zero to @code{RE_DUP_MAX} (which symbol @file{regex.h} defines). @end itemize If the interval expression is invalid and the syntax bit @code{RE_NO_BK_BRACES} is set, then Regex considers all the characters in the would-be interval to be ordinary. If that bit isn't set, then the regular expression is invalid. If the interval expression is valid but there is no preceding regular expression on which to operate, then if the syntax bit @code{RE_CONTEXT_INVALID_OPS} is set, the regular expression is invalid. If that bit isn't set, then Regex considers all the characters---other than backslashes, which it ignores---in the would-be interval to be ordinary. @node Alternation Operator, List Operators, Repetition Operators, Common Operators @section The Alternation Operator (@code{|} or @code{\|}) @kindex | @kindex \| @cindex alternation operator @cindex or operator If the syntax bit @code{RE_LIMITED_OPS} is set, then Regex doesn't recognize this operator. Otherwise, if the syntax bit @code{RE_NO_BK_VBAR} is set, then @samp{|} represents this operator; otherwise, @samp{\|} does. Alternatives match one of a choice of regular expressions: if you put the character(s) representing the alternation operator between any two regular expressions @var{a} and @var{b}, the result matches the union of the strings that @var{a} and @var{b} match. For example, supposing that @samp{|} is the alternation operator, then @samp{foo|bar|quux} would match any of @samp{foo}, @samp{bar} or @samp{quux}. @ignore @c Nobody needs to disallow empty alternatives any more. If the syntax bit @code{RE_NO_EMPTY_ALTS} is set, then if either of the regular expressions @var{a} or @var{b} is empty, the regular expression is invalid. More precisely, if this syntax bit is set, then the alternation operator can't: @itemize @bullet @item be first or last in a regular expression; @item follow either another alternation operator or an open-group operator (@pxref{Grouping Operators}); or @item precede a close-group operator. @end itemize @noindent For example, supposing @samp{(} and @samp{)} represent the open and close-group operators, then @samp{|foo}, @samp{foo|}, @samp{foo||bar}, @samp{foo(|bar)}, and @samp{(foo|)bar} would all be invalid. @end ignore The alternation operator operates on the @emph{largest} possible surrounding regular expressions. (Put another way, it has the lowest precedence of any regular expression operator.) Thus, the only way you can delimit its arguments is to use grouping. For example, if @samp{(} and @samp{)} are the open and close-group operators, then @samp{fo(o|b)ar} would match either @samp{fooar} or @samp{fobar}. (@samp{foo|bar} would match @samp{foo} or @samp{bar}.) @cindex backtracking The matcher usually tries all combinations of alternatives so as to match the longest possible string. For example, when matching @samp{(fooq|foo)*(qbarquux|bar)} against @samp{fooqbarquux}, it cannot take, say, the first (``depth-first'') combination it could match, since then it would be content to match just @samp{fooqbar}. @comment xx something about leftmost-longest @node List Operators, Grouping Operators, Alternation Operator, Common Operators @section List Operators (@code{[} @dots{} @code{]} and @code{[^} @dots{} @code{]}) @cindex matching list @cindex @samp{[} @cindex @samp{]} @cindex @samp{^} @cindex @samp{-} @cindex @samp{\} @cindex @samp{[^} @cindex nonmatching list @cindex matching newline @cindex bracket expression @dfn{Lists}, also called @dfn{bracket expressions}, are a set of one or more items. An @dfn{item} is a character, @ignore (These get added when they get implemented.) a collating symbol, an equivalence class expression, @end ignore a character class expression, or a range expression. The syntax bits affect which kinds of items you can put in a list. We explain the last two items in subsections below. Empty lists are invalid. A @dfn{matching list} matches a single character represented by one of the list items. You form a matching list by enclosing one or more items within an @dfn{open-matching-list operator} (represented by @samp{[}) and a @dfn{close-list operator} (represented by @samp{]}). For example, @samp{[ab]} matches either @samp{a} or @samp{b}. @samp{[ad]*} matches the empty string and any string composed of just @samp{a}s and @samp{d}s in any order. Regex considers invalid a regular expression with a @samp{[} but no matching @samp{]}. @dfn{Nonmatching lists} are similar to matching lists except that they match a single character @emph{not} represented by one of the list items. You use an @dfn{open-nonmatching-list operator} (represented by @samp{[^}@footnote{Regex therefore doesn't consider the @samp{^} to be the first character in the list. If you put a @samp{^} character first in (what you think is) a matching list, you'll turn it into a nonmatching list.}) instead of an open-matching-list operator to start a nonmatching list. For example, @samp{[^ab]} matches any character except @samp{a} or @samp{b}. If the @code{posix_newline} field in the pattern buffer (@pxref{GNU Pattern Buffers} is set, then nonmatching lists do not match a newline. Most characters lose any special meaning inside a list. The special characters inside a list follow. @table @samp @item ] ends the list if it's not the first list item. So, if you want to make the @samp{]} character a list item, you must put it first. @item \ quotes the next character if the syntax bit @code{RE_BACKSLASH_ESCAPE_IN_LISTS} is set. @ignore Put these in if they get implemented. @item [. represents the open-collating-symbol operator (@pxref{Collating Symbol Operators}). @item .] represents the close-collating-symbol operator. @item [= represents the open-equivalence-class operator (@pxref{Equivalence Class Operators}). @item =] represents the close-equivalence-class operator. @end ignore @item [: represents the open-character-class operator (@pxref{Character Class Operators}) if the syntax bit @code{RE_CHAR_CLASSES} is set and what follows is a valid character class expression. @item :] represents the close-character-class operator if the syntax bit @code{RE_CHAR_CLASSES} is set and what precedes it is an open-character-class operator followed by a valid character class name. @item - represents the range operator (@pxref{Range Operator}) if it's not first or last in a list or the ending point of a range. @end table @noindent All other characters are ordinary. For example, @samp{[.*]} matches @samp{.} and @samp{*}. @menu * Character Class Operators:: [:class:] * Range Operator:: start-end @end menu @ignore (If collating symbols and equivalence class expressions get implemented, then add this.) node Collating Symbol Operators subsubsection Collating Symbol Operators (@code{[.} @dots{} @code{.]}) If the syntax bit @code{XX} is set, then you can represent collating symbols inside lists. You form a @dfn{collating symbol} by putting a collating element between an @dfn{open-collating-symbol operator} and an @dfn{close-collating-symbol operator}. @samp{[.} represents the open-collating-symbol operator and @samp{.]} represents the close-collating-symbol operator. For example, if @samp{ll} is a collating element, then @samp{[[.ll.]]} would match @samp{ll}. node Equivalence Class Operators subsubsection Equivalence Class Operators (@code{[=} @dots{} @code{=]}) @cindex equivalence class expression in regex @cindex @samp{[=} in regex @cindex @samp{=]} in regex If the syntax bit @code{XX} is set, then Regex recognizes equivalence class expressions inside lists. A @dfn{equivalence class expression} is a set of collating elements which all belong to the same equivalence class. You form an equivalence class expression by putting a collating element between an @dfn{open-equivalence-class operator} and a @dfn{close-equivalence-class operator}. @samp{[=} represents the open-equivalence-class operator and @samp{=]} represents the close-equivalence-class operator. For example, if @samp{a} and @samp{A} were an equivalence class, then both @samp{[[=a=]]} and @samp{[[=A=]]} would match both @samp{a} and @samp{A}. If the collating element in an equivalence class expression isn't part of an equivalence class, then the matcher considers the equivalence class expression to be a collating symbol. @end ignore @node Character Class Operators, Range Operator, , List Operators @subsection Character Class Operators (@code{[:} @dots{} @code{:]}) @cindex character classes @cindex @samp{[:} in regex @cindex @samp{:]} in regex If the syntax bit @code{RE_CHARACTER_CLASSES} is set, then Regex recognizes character class expressions inside lists. A @dfn{character class expression} matches one character from a given class. You form a character class expression by putting a character class name between an @dfn{open-character-class operator} (represented by @samp{[:}) and a @dfn{close-character-class operator} (represented by @samp{:]}). The character class names and their meanings are: @table @code @item alnum letters and digits @item alpha letters @item blank system-dependent; for @sc{gnu}, a space or tab @item cntrl control characters (in the @sc{ascii} encoding, code 0177 and codes less than 040) @item digit digits @item graph same as @code{print} except omits space @item lower lowercase letters @item print printable characters (in the @sc{ascii} encoding, space tilde---codes 040 through 0176) @item punct neither control nor alphanumeric characters @item space space, carriage return, newline, vertical tab, and form feed @item upper uppercase letters @item xdigit hexadecimal digits: @code{0}--@code{9}, @code{a}--@code{f}, @code{A}--@code{F} @end table @noindent These correspond to the definitions in the C library's @file{} facility. For example, @samp{[:alpha:]} corresponds to the standard facility @code{isalpha}. Regex recognizes character class expressions only inside of lists; so @samp{[[:alpha:]]} matches any letter, but @samp{[:alpha:]} outside of a bracket expression and not followed by a repetition operator matches just itself. @node Range Operator, , Character Class Operators, List Operators @subsection The Range Operator (@code{-}) Regex recognizes @dfn{range expressions} inside a list. They represent those characters that fall between two elements in the current collating sequence. You form a range expression by putting a @dfn{range operator} between two @ignore (If these get implemented, then substitute this for ``characters.'') of any of the following: characters, collating elements, collating symbols, and equivalence class expressions. The starting point of the range and the ending point of the range don't have to be the same kind of item, e.g., the starting point could be a collating element and the ending point could be an equivalence class expression. If a range's ending point is an equivalence class, then all the collating elements in that class will be in the range. @end ignore characters.@footnote{You can't use a character class for the starting or ending point of a range, since a character class is not a single character.} @samp{-} represents the range operator. For example, @samp{a-f} within a list represents all the characters from @samp{a} through @samp{f} inclusively. If the syntax bit @code{RE_NO_EMPTY_RANGES} is set, then if the range's ending point collates less than its starting point, the range (and the regular expression containing it) is invalid. For example, the regular expression @samp{[z-a]} would be invalid. If this bit isn't set, then Regex considers such a range to be empty. Since @samp{-} represents the range operator, if you want to make a @samp{-} character itself a list item, you must do one of the following: @itemize @bullet @item Put the @samp{-} either first or last in the list. @item Include a range whose starting point collates strictly lower than @samp{-} and whose ending point collates equal or higher. Unless a range is the first item in a list, a @samp{-} can't be its starting point, but @emph{can} be its ending point. That is because Regex considers @samp{-} to be the range operator unless it is preceded by another @samp{-}. For example, in the @sc{ascii} encoding, @samp{)}, @samp{*}, @samp{+}, @samp{,}, @samp{-}, @samp{.}, and @samp{/} are contiguous characters in the collating sequence. You might think that @samp{[)-+--/]} has two ranges: @samp{)-+} and @samp{--/}. Rather, it has the ranges @samp{)-+} and @samp{+--}, plus the character @samp{/}, so it matches, e.g., @samp{,}, not @samp{.}. @item Put a range whose starting point is @samp{-} first in the list. @end itemize For example, @samp{[-a-z]} matches a lowercase letter or a hyphen (in English, in @sc{ascii}). @node Grouping Operators, Back-reference Operator, List Operators, Common Operators @section Grouping Operators (@code{(} @dots{} @code{)} or @code{\(} @dots{} @code{\)}) @kindex ( @kindex ) @kindex \( @kindex \) @cindex grouping @cindex subexpressions @cindex parenthesizing A @dfn{group}, also known as a @dfn{subexpression}, consists of an @dfn{open-group operator}, any number of other operators, and a @dfn{close-group operator}. Regex treats this sequence as a unit, just as mathematics and programming languages treat a parenthesized expression as a unit. Therefore, using @dfn{groups}, you can: @itemize @bullet @item delimit the argument(s) to an alternation operator (@pxref{Alternation Operator}) or a repetition operator (@pxref{Repetition Operators}). @item keep track of the indices of the substring that matched a given group. @xref{Using Registers}, for a precise explanation. This lets you: @itemize @bullet @item use the back-reference operator (@pxref{Back-reference Operator}). @item use registers (@pxref{Using Registers}). @end itemize @end itemize If the syntax bit @code{RE_NO_BK_PARENS} is set, then @samp{(} represents the open-group operator and @samp{)} represents the close-group operator; otherwise, @samp{\(} and @samp{\)} do. If the syntax bit @code{RE_UNMATCHED_RIGHT_PAREN_ORD} is set and a close-group operator has no matching open-group operator, then Regex considers it to match @samp{)}. @node Back-reference Operator, Anchoring Operators, Grouping Operators, Common Operators @section The Back-reference Operator (@dfn{\}@var{digit}) @cindex back references If the syntax bit @code{RE_NO_BK_REF} isn't set, then Regex recognizes back references. A back reference matches a specified preceding group. The back reference operator is represented by @samp{\@var{digit}} anywhere after the end of a regular expression's @w{@var{digit}-th} group (@pxref{Grouping Operators}). @var{digit} must be between @samp{1} and @samp{9}. The matcher assigns numbers 1 through 9 to the first nine groups it encounters. By using one of @samp{\1} through @samp{\9} after the corresponding group's close-group operator, you can match a substring identical to the one that the group does. Back references match according to the following (in all examples below, @samp{(} represents the open-group, @samp{)} the close-group, @samp{@{} the open-interval and @samp{@}} the close-interval operator): @itemize @bullet @item If the group matches a substring, the back reference matches an identical substring. For example, @samp{(a)\1} matches @samp{aa} and @samp{(bana)na\1bo\1} matches @samp{bananabanabobana}. Likewise, @samp{(.*)\1} matches any (newline-free if the syntax bit @code{RE_DOT_NEWLINE} isn't set) string that is composed of two identical halves; the @samp{(.*)} matches the first half and the @samp{\1} matches the second half. @item If the group matches more than once (as it might if followed by, e.g., a repetition operator), then the back reference matches the substring the group @emph{last} matched. For example, @samp{((a*)b)*\1\2} matches @samp{aabababa}; first @w{group 1} (the outer one) matches @samp{aab} and @w{group 2} (the inner one) matches @samp{aa}. Then @w{group 1} matches @samp{ab} and @w{group 2} matches @samp{a}. So, @samp{\1} matches @samp{ab} and @samp{\2} matches @samp{a}. @item If the group doesn't participate in a match, i.e., it is part of an alternative not taken or a repetition operator allows zero repetitions of it, then the back reference makes the whole match fail. For example, @samp{(one()|two())-and-(three\2|four\3)} matches @samp{one-and-three} and @samp{two-and-four}, but not @samp{one-and-four} or @samp{two-and-three}. For example, if the pattern matches @samp{one-and-}, then its @w{group 2} matches the empty string and its @w{group 3} doesn't participate in the match. So, if it then matches @samp{four}, then when it tries to back reference @w{group 3}---which it will attempt to do because @samp{\3} follows the @samp{four}---the match will fail because @w{group 3} didn't participate in the match. @end itemize You can use a back reference as an argument to a repetition operator. For example, @samp{(a(b))\2*} matches @samp{a} followed by two or more @samp{b}s. Similarly, @samp{(a(b))\2@{3@}} matches @samp{abbbb}. If there is no preceding @w{@var{digit}-th} subexpression, the regular expression is invalid. @node Anchoring Operators, , Back-reference Operator, Common Operators @section Anchoring Operators @cindex anchoring @cindex regexp anchoring These operators can constrain a pattern to match only at the beginning or end of the entire string or at the beginning or end of a line. @menu * Match-beginning-of-line Operator:: ^ * Match-end-of-line Operator:: $ @end menu @node Match-beginning-of-line Operator, Match-end-of-line Operator, , Anchoring Operators @subsection The Match-beginning-of-line Operator (@code{^}) @kindex ^ @cindex beginning-of-line operator @cindex anchors This operator can match the empty string either at the beginning of the string or after a newline character. Thus, it is said to @dfn{anchor} the pattern to the beginning of a line. In the cases following, @samp{^} represents this operator. (Otherwise, @samp{^} is ordinary.) @itemize @bullet @item It (the @samp{^}) is first in the pattern, as in @samp{^foo}. @cnindex RE_CONTEXT_INDEP_ANCHORS @r{(and @samp{^})} @item The syntax bit @code{RE_CONTEXT_INDEP_ANCHORS} is set, and it is outside a bracket expression. @cindex open-group operator and @samp{^} @cindex alternation operator and @samp{^} @item It follows an open-group or alternation operator, as in @samp{a\(^b\)} and @samp{a\|^b}. @xref{Grouping Operators}, and @ref{Alternation Operator}. @end itemize These rules imply that some valid patterns containing @samp{^} cannot be matched; for example, @samp{foo^bar} if @code{RE_CONTEXT_INDEP_ANCHORS} is set. @vindex not_bol @r{field in pattern buffer} If the @code{not_bol} field is set in the pattern buffer (@pxref{GNU Pattern Buffers}), then @samp{^} fails to match at the beginning of the string. @xref{POSIX Matching}, for when you might find this useful. @vindex newline_anchor @r{field in pattern buffer} If the @code{newline_anchor} field is set in the pattern buffer, then @samp{^} fails to match after a newline. This is useful when you do not regard the string to be matched as broken into lines. @node Match-end-of-line Operator, , Match-beginning-of-line Operator, Anchoring Operators @subsection The Match-end-of-line Operator (@code{$}) @kindex $ @cindex end-of-line operator @cindex anchors This operator can match the empty string either at the end of the string or before a newline character in the string. Thus, it is said to @dfn{anchor} the pattern to the end of a line. It is always represented by @samp{$}. For example, @samp{foo$} usually matches, e.g., @samp{foo} and, e.g., the first three characters of @samp{foo\nbar}. Its interaction with the syntax bits and pattern buffer fields is exactly the dual of @samp{^}'s; see the previous section. (That is, ``beginning'' becomes ``end'', ``next'' becomes ``previous'', and ``after'' becomes ``before''.) @node GNU Operators, GNU Emacs Operators, Common Operators, Top @chapter GNU Operators Following are operators that @sc{gnu} defines (and @sc{posix} doesn't). @menu * Word Operators:: * Buffer Operators:: @end menu @node Word Operators, Buffer Operators, , GNU Operators @section Word Operators The operators in this section require Regex to recognize parts of words. Regex uses a syntax table to determine whether or not a character is part of a word, i.e., whether or not it is @dfn{word-constituent}. @menu * Non-Emacs Syntax Tables:: * Match-word-boundary Operator:: \b * Match-within-word Operator:: \B * Match-beginning-of-word Operator:: \< * Match-end-of-word Operator:: \> * Match-word-constituent Operator:: \w * Match-non-word-constituent Operator:: \W @end menu @node Non-Emacs Syntax Tables, Match-word-boundary Operator, , Word Operators @subsection Non-Emacs Syntax Tables A @dfn{syntax table} is an array indexed by the characters in your character set. In the @sc{ascii} encoding, therefore, a syntax table has 256 elements. Regex always uses a @code{char *} variable @code{re_syntax_table} as its syntax table. In some cases, it initializes this variable and in others it expects you to initialize it. @itemize @bullet @item If Regex is compiled with the preprocessor symbols @code{emacs} and @code{SYNTAX_TABLE} both undefined, then Regex allocates @code{re_syntax_table} and initializes an element @var{i} either to @code{Sword} (which it defines) if @var{i} is a letter, number, or @samp{_}, or to zero if it's not. @item If Regex is compiled with @code{emacs} undefined but @code{SYNTAX_TABLE} defined, then Regex expects you to define a @code{char *} variable @code{re_syntax_table} to be a valid syntax table. @item @xref{Emacs Syntax Tables}, for what happens when Regex is compiled with the preprocessor symbol @code{emacs} defined. @end itemize @node Match-word-boundary Operator, Match-within-word Operator, Non-Emacs Syntax Tables, Word Operators @subsection The Match-word-boundary Operator (@code{\b}) @cindex @samp{\b} @cindex word boundaries, matching This operator (represented by @samp{\b}) matches the empty string at either the beginning or the end of a word. For example, @samp{\brat\b} matches the separate word @samp{rat}. @node Match-within-word Operator, Match-beginning-of-word Operator, Match-word-boundary Operator, Word Operators @subsection The Match-within-word Operator (@code{\B}) @cindex @samp{\B} This operator (represented by @samp{\B}) matches the empty string within a word. For example, @samp{c\Brat\Be} matches @samp{crate}, but @samp{dirty \Brat} doesn't match @samp{dirty rat}. @node Match-beginning-of-word Operator, Match-end-of-word Operator, Match-within-word Operator, Word Operators @subsection The Match-beginning-of-word Operator (@code{\<}) @cindex @samp{\<} This operator (represented by @samp{\<}) matches the empty string at the beginning of a word. @node Match-end-of-word Operator, Match-word-constituent Operator, Match-beginning-of-word Operator, Word Operators @subsection The Match-end-of-word Operator (@code{\>}) @cindex @samp{\>} This operator (represented by @samp{\>}) matches the empty string at the end of a word. @node Match-word-constituent Operator, Match-non-word-constituent Operator, Match-end-of-word Operator, Word Operators @subsection The Match-word-constituent Operator (@code{\w}) @cindex @samp{\w} This operator (represented by @samp{\w}) matches any word-constituent character. @node Match-non-word-constituent Operator, , Match-word-constituent Operator, Word Operators @subsection The Match-non-word-constituent Operator (@code{\W}) @cindex @samp{\W} This operator (represented by @samp{\W}) matches any character that is not word-constituent. @node Buffer Operators, , Word Operators, GNU Operators @section Buffer Operators Following are operators which work on buffers. In Emacs, a @dfn{buffer} is, naturally, an Emacs buffer. For other programs, Regex considers the entire string to be matched as the buffer. @menu * Match-beginning-of-buffer Operator:: \` * Match-end-of-buffer Operator:: \' @end menu @node Match-beginning-of-buffer Operator, Match-end-of-buffer Operator, , Buffer Operators @subsection The Match-beginning-of-buffer Operator (@code{\`}) @cindex @samp{\`} This operator (represented by @samp{\`}) matches the empty string at the beginning of the buffer. @node Match-end-of-buffer Operator, , Match-beginning-of-buffer Operator, Buffer Operators @subsection The Match-end-of-buffer Operator (@code{\'}) @cindex @samp{\'} This operator (represented by @samp{\'}) matches the empty string at the end of the buffer. @node GNU Emacs Operators, What Gets Matched?, GNU Operators, Top @chapter GNU Emacs Operators Following are operators that @sc{gnu} defines (and @sc{posix} doesn't) that you can use only when Regex is compiled with the preprocessor symbol @code{emacs} defined. @menu * Syntactic Class Operators:: @end menu @node Syntactic Class Operators, , , GNU Emacs Operators @section Syntactic Class Operators The operators in this section require Regex to recognize the syntactic classes of characters. Regex uses a syntax table to determine this. @menu * Emacs Syntax Tables:: * Match-syntactic-class Operator:: \sCLASS * Match-not-syntactic-class Operator:: \SCLASS @end menu @node Emacs Syntax Tables, Match-syntactic-class Operator, , Syntactic Class Operators @subsection Emacs Syntax Tables A @dfn{syntax table} is an array indexed by the characters in your character set. In the @sc{ascii} encoding, therefore, a syntax table has 256 elements. If Regex is compiled with the preprocessor symbol @code{emacs} defined, then Regex expects you to define and initialize the variable @code{re_syntax_table} to be an Emacs syntax table. Emacs' syntax tables are more complicated than Regex's own (@pxref{Non-Emacs Syntax Tables}). @xref{Syntax, , Syntax, emacs, The GNU Emacs User's Manual}, for a description of Emacs' syntax tables. @node Match-syntactic-class Operator, Match-not-syntactic-class Operator, Emacs Syntax Tables, Syntactic Class Operators @subsection The Match-syntactic-class Operator (@code{\s}@var{class}) @cindex @samp{\s} This operator matches any character whose syntactic class is represented by a specified character. @samp{\s@var{class}} represents this operator where @var{class} is the character representing the syntactic class you want. For example, @samp{w} represents the syntactic class of word-constituent characters, so @samp{\sw} matches any word-constituent character. @node Match-not-syntactic-class Operator, , Match-syntactic-class Operator, Syntactic Class Operators @subsection The Match-not-syntactic-class Operator (@code{\S}@var{class}) @cindex @samp{\S} This operator is similar to the match-syntactic-class operator except that it matches any character whose syntactic class is @emph{not} represented by the specified character. @samp{\S@var{class}} represents this operator. For example, @samp{w} represents the syntactic class of word-constituent characters, so @samp{\Sw} matches any character that is not word-constituent. @node What Gets Matched?, Programming with Regex, GNU Emacs Operators, Top @chapter What Gets Matched? Regex usually matches strings according to the ``leftmost longest'' rule; that is, it chooses the longest of the leftmost matches. This does not mean that for a regular expression containing subexpressions that it simply chooses the longest match for each subexpression, left to right; the overall match must also be the longest possible one. For example, @samp{(ac*)(c*d[ac]*)\1} matches @samp{acdacaaa}, not @samp{acdac}, as it would if it were to choose the longest match for the first subexpression. @node Programming with Regex, Copying, What Gets Matched?, Top @chapter Programming with Regex Here we describe how you use the Regex data structures and functions in C programs. Regex has three interfaces: one designed for @sc{gnu}, one compatible with @sc{posix} and one compatible with Berkeley @sc{unix}. @menu * GNU Regex Functions:: * POSIX Regex Functions:: * BSD Regex Functions:: @end menu @node GNU Regex Functions, POSIX Regex Functions, , Programming with Regex @section GNU Regex Functions If you're writing code that doesn't need to be compatible with either @sc{posix} or Berkeley @sc{unix}, you can use these functions. They provide more options than the other interfaces. @menu * GNU Pattern Buffers:: The re_pattern_buffer type. * GNU Regular Expression Compiling:: re_compile_pattern () * GNU Matching:: re_match () * GNU Searching:: re_search () * Matching/Searching with Split Data:: re_match_2 (), re_search_2 () * Searching with Fastmaps:: re_compile_fastmap () * GNU Translate Tables:: The `translate' field. * Using Registers:: The re_registers type and related fns. * Freeing GNU Pattern Buffers:: regfree () @end menu @node GNU Pattern Buffers, GNU Regular Expression Compiling, , GNU Regex Functions @subsection GNU Pattern Buffers @cindex pattern buffer, definition of @tindex re_pattern_buffer @r{definition} @tindex struct re_pattern_buffer @r{definition} To compile, match, or search for a given regular expression, you must supply a pattern buffer. A @dfn{pattern buffer} holds one compiled regular expression.@footnote{Regular expressions are also referred to as ``patterns,'' hence the name ``pattern buffer.''} You can have several different pattern buffers simultaneously, each holding a compiled pattern for a different regular expression. @file{regex.h} defines the pattern buffer @code{struct} as follows: @example /* Space that holds the compiled pattern. It is declared as `unsigned char *' because its elements are sometimes used as array indexes. */ unsigned char *buffer; /* Number of bytes to which `buffer' points. */ unsigned long allocated; /* Number of bytes actually used in `buffer'. */ unsigned long used; /* Syntax setting with which the pattern was compiled. */ reg_syntax_t syntax; /* Pointer to a fastmap, if any, otherwise zero. re_search uses the fastmap, if there is one, to skip over impossible starting points for matches. */ char *fastmap; /* Either a translate table to apply to all characters before comparing them, or zero for no translation. The translation is applied to a pattern when it is compiled and to a string when it is matched. */ char *translate; /* Number of subexpressions found by the compiler. */ size_t re_nsub; /* Zero if this pattern cannot match the empty string, one else. Well, in truth it's used only in `re_search_2', to see whether or not we should use the fastmap, so we don't set this absolutely perfectly; see `re_compile_fastmap' (the `duplicate' case). */ unsigned can_be_null : 1; /* If REGS_UNALLOCATED, allocate space in the `regs' structure for `max (RE_NREGS, re_nsub + 1)' groups. If REGS_REALLOCATE, reallocate space if necessary. If REGS_FIXED, use what's there. */ #define REGS_UNALLOCATED 0 #define REGS_REALLOCATE 1 #define REGS_FIXED 2 unsigned regs_allocated : 2; /* Set to zero when `regex_compile' compiles a pattern; set to one by `re_compile_fastmap' if it updates the fastmap. */ unsigned fastmap_accurate : 1; /* If set, `re_match_2' does not return information about subexpressions. */ unsigned no_sub : 1; /* If set, a beginning-of-line anchor doesn't match at the beginning of the string. */ unsigned not_bol : 1; /* Similarly for an end-of-line anchor. */ unsigned not_eol : 1; /* If true, an anchor at a newline matches. */ unsigned newline_anchor : 1; @end example @node GNU Regular Expression Compiling, GNU Matching, GNU Pattern Buffers, GNU Regex Functions @subsection GNU Regular Expression Compiling In @sc{gnu}, you can both match and search for a given regular expression. To do either, you must first compile it in a pattern buffer (@pxref{GNU Pattern Buffers}). @cindex syntax initialization @vindex re_syntax_options @r{initialization} Regular expressions match according to the syntax with which they were compiled; with @sc{gnu}, you indicate what syntax you want by setting the variable @code{re_syntax_options} (declared in @file{regex.h} and defined in @file{regex.c}) before calling the compiling function, @code{re_compile_pattern} (see below). @xref{Syntax Bits}, and @ref{Predefined Syntaxes}. You can change the value of @code{re_syntax_options} at any time. Usually, however, you set its value once and then never change it. @cindex pattern buffer initialization @code{re_compile_pattern} takes a pattern buffer as an argument. You must initialize the following fields: @table @code @item translate @r{initialization} @item translate @vindex translate @r{initialization} Initialize this to point to a translate table if you want one, or to zero if you don't. We explain translate tables in @ref{GNU Translate Tables}. @item fastmap @vindex fastmap @r{initialization} Initialize this to nonzero if you want a fastmap, or to zero if you don't. @item buffer @itemx allocated @vindex buffer @r{initialization} @vindex allocated @r{initialization} @findex malloc If you want @code{re_compile_pattern} to allocate memory for the compiled pattern, set both of these to zero. If you have an existing block of memory (allocated with @code{malloc}) you want Regex to use, set @code{buffer} to its address and @code{allocated} to its size (in bytes). @code{re_compile_pattern} uses @code{realloc} to extend the space for the compiled pattern as necessary. @end table To compile a pattern buffer, use: @findex re_compile_pattern @example char * re_compile_pattern (const char *@var{regex}, const int @var{regex_size}, struct re_pattern_buffer *@var{pattern_buffer}) @end example @noindent @var{regex} is the regular expression's address, @var{regex_size} is its length, and @var{pattern_buffer} is the pattern buffer's address. If @code{re_compile_pattern} successfully compiles the regular expression, it returns zero and sets @code{*@var{pattern_buffer}} to the compiled pattern. It sets the pattern buffer's fields as follows: @table @code @item buffer @vindex buffer @r{field, set by @code{re_compile_pattern}} to the compiled pattern. @item used @vindex used @r{field, set by @code{re_compile_pattern}} to the number of bytes the compiled pattern in @code{buffer} occupies. @item syntax @vindex syntax @r{field, set by @code{re_compile_pattern}} to the current value of @code{re_syntax_options}. @item re_nsub @vindex re_nsub @r{field, set by @code{re_compile_pattern}} to the number of subexpressions in @var{regex}. @item fastmap_accurate @vindex fastmap_accurate @r{field, set by @code{re_compile_pattern}} to zero on the theory that the pattern you're compiling is different than the one previously compiled into @code{buffer}; in that case (since you can't make a fastmap without a compiled pattern), @code{fastmap} would either contain an incompatible fastmap, or nothing at all. @c xx what else? @end table If @code{re_compile_pattern} can't compile @var{regex}, it returns an error string corresponding to one of the errors listed in @ref{POSIX Regular Expression Compiling}. @node GNU Matching, GNU Searching, GNU Regular Expression Compiling, GNU Regex Functions @subsection GNU Matching @cindex matching with GNU functions Matching the @sc{gnu} way means trying to match as much of a string as possible starting at a position within it you specify. Once you've compiled a pattern into a pattern buffer (@pxref{GNU Regular Expression Compiling}), you can ask the matcher to match that pattern against a string using: @findex re_match @example int re_match (struct re_pattern_buffer *@var{pattern_buffer}, const char *@var{string}, const int @var{size}, const int @var{start}, struct re_registers *@var{regs}) @end example @noindent @var{pattern_buffer} is the address of a pattern buffer containing a compiled pattern. @var{string} is the string you want to match; it can contain newline and null characters. @var{size} is the length of that string. @var{start} is the string index at which you want to begin matching; the first character of @var{string} is at index zero. @xref{Using Registers}, for a explanation of @var{regs}; you can safely pass zero. @code{re_match} matches the regular expression in @var{pattern_buffer} against the string @var{string} according to the syntax in @var{pattern_buffers}'s @code{syntax} field. (@xref{GNU Regular Expression Compiling}, for how to set it.) The function returns @math{-1} if the compiled pattern does not match any part of @var{string} and @math{-2} if an internal error happens; otherwise, it returns how many (possibly zero) characters of @var{string} the pattern matched. An example: suppose @var{pattern_buffer} points to a pattern buffer containing the compiled pattern for @samp{a*}, and @var{string} points to @samp{aaaaab} (whereupon @var{size} should be 6). Then if @var{start} is 2, @code{re_match} returns 3, i.e., @samp{a*} would have matched the last three @samp{a}s in @var{string}. If @var{start} is 0, @code{re_match} returns 5, i.e., @samp{a*} would have matched all the @samp{a}s in @var{string}. If @var{start} is either 5 or 6, it returns zero. If @var{start} is not between zero and @var{size}, then @code{re_match} returns @math{-1}. @node GNU Searching, Matching/Searching with Split Data, GNU Matching, GNU Regex Functions @subsection GNU Searching @cindex searching with GNU functions @dfn{Searching} means trying to match starting at successive positions within a string. The function @code{re_search} does this. Before calling @code{re_search}, you must compile your regular expression. @xref{GNU Regular Expression Compiling}. Here is the function declaration: @findex re_search @example int re_search (struct re_pattern_buffer *@var{pattern_buffer}, const char *@var{string}, const int @var{size}, const int @var{start}, const int @var{range}, struct re_registers *@var{regs}) @end example @noindent @vindex start @r{argument to @code{re_search}} @vindex range @r{argument to @code{re_search}} whose arguments are the same as those to @code{re_match} (@pxref{GNU Matching}) except that the two arguments @var{start} and @var{range} replace @code{re_match}'s argument @var{start}. If @var{range} is positive, then @code{re_search} attempts a match starting first at index @var{start}, then at @math{@var{start} + 1} if that fails, and so on, up to @math{@var{start} + @var{range}}; if @var{range} is negative, then it attempts a match starting first at index @var{start}, then at @math{@var{start} -1} if that fails, and so on. If @var{start} is not between zero and @var{size}, then @code{re_search} returns @math{-1}. When @var{range} is positive, @code{re_search} adjusts @var{range} so that @math{@var{start} + @var{range} - 1} is between zero and @var{size}, if necessary; that way it won't search outside of @var{string}. Similarly, when @var{range} is negative, @code{re_search} adjusts @var{range} so that @math{@var{start} + @var{range} + 1} is between zero and @var{size}, if necessary. If the @code{fastmap} field of @var{pattern_buffer} is zero, @code{re_search} matches starting at consecutive positions; otherwise, it uses @code{fastmap} to make the search more efficient. @xref{Searching with Fastmaps}. If no match is found, @code{re_search} returns @math{-1}. If a match is found, it returns the index where the match began. If an internal error happens, it returns @math{-2}. @node Matching/Searching with Split Data, Searching with Fastmaps, GNU Searching, GNU Regex Functions @subsection Matching and Searching with Split Data Using the functions @code{re_match_2} and @code{re_search_2}, you can match or search in data that is divided into two strings. The function: @findex re_match_2 @example int re_match_2 (struct re_pattern_buffer *@var{buffer}, const char *@var{string1}, const int @var{size1}, const char *@var{string2}, const int @var{size2}, const int @var{start}, struct re_registers *@var{regs}, const int @var{stop}) @end example @noindent is similar to @code{re_match} (@pxref{GNU Matching}) except that you pass @emph{two} data strings and sizes, and an index @var{stop} beyond which you don't want the matcher to try matching. As with @code{re_match}, if it succeeds, @code{re_match_2} returns how many characters of @var{string} it matched. Regard @var{string1} and @var{string2} as concatenated when you set the arguments @var{start} and @var{stop} and use the contents of @var{regs}; @code{re_match_2} never returns a value larger than @math{@var{size1} + @var{size2}}. The function: @findex re_search_2 @example int re_search_2 (struct re_pattern_buffer *@var{buffer}, const char *@var{string1}, const int @var{size1}, const char *@var{string2}, const int @var{size2}, const int @var{start}, const int @var{range}, struct re_registers *@var{regs}, const int @var{stop}) @end example @noindent is similarly related to @code{re_search}. @node Searching with Fastmaps, GNU Translate Tables, Matching/Searching with Split Data, GNU Regex Functions @subsection Searching with Fastmaps @cindex fastmaps If you're searching through a long string, you should use a fastmap. Without one, the searcher tries to match at consecutive positions in the string. Generally, most of the characters in the string could not start a match. It takes much longer to try matching at a given position in the string than it does to check in a table whether or not the character at that position could start a match. A @dfn{fastmap} is such a table. More specifically, a fastmap is an array indexed by the characters in your character set. Under the @sc{ascii} encoding, therefore, a fastmap has 256 elements. If you want the searcher to use a fastmap with a given pattern buffer, you must allocate the array and assign the array's address to the pattern buffer's @code{fastmap} field. You either can compile the fastmap yourself or have @code{re_search} do it for you; when @code{fastmap} is nonzero, it automatically compiles a fastmap the first time you search using a particular compiled pattern. To compile a fastmap yourself, use: @findex re_compile_fastmap @example int re_compile_fastmap (struct re_pattern_buffer *@var{pattern_buffer}) @end example @noindent @var{pattern_buffer} is the address of a pattern buffer. If the character @var{c} could start a match for the pattern, @code{re_compile_fastmap} makes @code{@var{pattern_buffer}->fastmap[@var{c}]} nonzero. It returns @math{0} if it can compile a fastmap and @math{-2} if there is an internal error. For example, if @samp{|} is the alternation operator and @var{pattern_buffer} holds the compiled pattern for @samp{a|b}, then @code{re_compile_fastmap} sets @code{fastmap['a']} and @code{fastmap['b']} (and no others). @code{re_search} uses a fastmap as it moves along in the string: it checks the string's characters until it finds one that's in the fastmap. Then it tries matching at that character. If the match fails, it repeats the process. So, by using a fastmap, @code{re_search} doesn't waste time trying to match at positions in the string that couldn't start a match. If you don't want @code{re_search} to use a fastmap, store zero in the @code{fastmap} field of the pattern buffer before calling @code{re_search}. Once you've initialized a pattern buffer's @code{fastmap} field, you need never do so again---even if you compile a new pattern in it---provided the way the field is set still reflects whether or not you want a fastmap. @code{re_search} will still either do nothing if @code{fastmap} is null or, if it isn't, compile a new fastmap for the new pattern. @node GNU Translate Tables, Using Registers, Searching with Fastmaps, GNU Regex Functions @subsection GNU Translate Tables If you set the @code{translate} field of a pattern buffer to a translate table, then the @sc{gnu} Regex functions to which you've passed that pattern buffer use it to apply a simple transformation to all the regular expression and string characters at which they look. A @dfn{translate table} is an array indexed by the characters in your character set. Under the @sc{ascii} encoding, therefore, a translate table has 256 elements. The array's elements are also characters in your character set. When the Regex functions see a character @var{c}, they use @code{translate[@var{c}]} in its place, with one exception: the character after a @samp{\} is not translated. (This ensures that, the operators, e.g., @samp{\B} and @samp{\b}, are always distinguishable.) For example, a table that maps all lowercase letters to the corresponding uppercase ones would cause the matcher to ignore differences in case.@footnote{A table that maps all uppercase letters to the corresponding lowercase ones would work just as well for this purpose.} Such a table would map all characters except lowercase letters to themselves, and lowercase letters to the corresponding uppercase ones. Under the @sc{ascii} encoding, here's how you could initialize such a table (we'll call it @code{case_fold}): @example for (i = 0; i < 256; i++) case_fold[i] = i; for (i = 'a'; i <= 'z'; i++) case_fold[i] = i - ('a' - 'A'); @end example You tell Regex to use a translate table on a given pattern buffer by assigning that table's address to the @code{translate} field of that buffer. If you don't want Regex to do any translation, put zero into this field. You'll get weird results if you change the table's contents anytime between compiling the pattern buffer, compiling its fastmap, and matching or searching with the pattern buffer. @node Using Registers, Freeing GNU Pattern Buffers, GNU Translate Tables, GNU Regex Functions @subsection Using Registers A group in a regular expression can match a (posssibly empty) substring of the string that regular expression as a whole matched. The matcher remembers the beginning and end of the substring matched by each group. To find out what they matched, pass a nonzero @var{regs} argument to a @sc{gnu} matching or searching function (@pxref{GNU Matching} and @ref{GNU Searching}), i.e., the address of a structure of this type, as defined in @file{regex.h}: @c We don't bother to include this directly from regex.h, @c since it changes so rarely. @example @tindex re_registers @vindex num_regs @r{in @code{struct re_registers}} @vindex start @r{in @code{struct re_registers}} @vindex end @r{in @code{struct re_registers}} struct re_registers @{ unsigned num_regs; regoff_t *start; regoff_t *end; @}; @end example Except for (possibly) the @var{num_regs}'th element (see below), the @var{i}th element of the @code{start} and @code{end} arrays records information about the @var{i}th group in the pattern. (They're declared as C pointers, but this is only because not all C compilers accept zero-length arrays; conceptually, it is simplest to think of them as arrays.) The @code{start} and @code{end} arrays are allocated in various ways, depending on the value of the @code{regs_allocated} @vindex regs_allocated field in the pattern buffer passed to the matcher. The simplest and perhaps most useful is to let the matcher (re)allocate enough space to record information for all the groups in the regular expression. If @code{regs_allocated} is @code{REGS_UNALLOCATED}, @vindex REGS_UNALLOCATED the matcher allocates @math{1 + @var{re_nsub}} (another field in the pattern buffer; @pxref{GNU Pattern Buffers}). The extra element is set to @math{-1}, and sets @code{regs_allocated} to @code{REGS_REALLOCATE}. @vindex REGS_REALLOCATE Then on subsequent calls with the same pattern buffer and @var{regs} arguments, the matcher reallocates more space if necessary. It would perhaps be more logical to make the @code{regs_allocated} field part of the @code{re_registers} structure, instead of part of the pattern buffer. But in that case the caller would be forced to initialize the structure before passing it. Much existing code doesn't do this initialization, and it's arguably better to avoid it anyway. @code{re_compile_pattern} sets @code{regs_allocated} to @code{REGS_UNALLOCATED}, so if you use the GNU regular expression functions, you get this behavior by default. xx document re_set_registers @sc{posix}, on the other hand, requires a different interface: the caller is supposed to pass in a fixed-length array which the matcher fills. Therefore, if @code{regs_allocated} is @code{REGS_FIXED} @vindex REGS_FIXED the matcher simply fills that array. The following examples illustrate the information recorded in the @code{re_registers} structure. (In all of them, @samp{(} represents the open-group and @samp{)} the close-group operator. The first character in the string @var{string} is at index 0.) @c xx i'm not sure this is all true anymore. @itemize @bullet @item If the regular expression has an @w{@var{i}-th} group not contained within another group that matches a substring of @var{string}, then the function sets @code{@w{@var{regs}->}start[@var{i}]} to the index in @var{string} where the substring matched by the @w{@var{i}-th} group begins, and @code{@w{@var{regs}->}end[@var{i}]} to the index just beyond that substring's end. The function sets @code{@w{@var{regs}->}start[0]} and @code{@w{@var{regs}->}end[0]} to analogous information about the entire pattern. For example, when you match @samp{((a)(b))} against @samp{ab}, you get: @itemize @item 0 in @code{@w{@var{regs}->}start[0]} and 2 in @code{@w{@var{regs}->}end[0]} @item 0 in @code{@w{@var{regs}->}start[1]} and 2 in @code{@w{@var{regs}->}end[1]} @item 0 in @code{@w{@var{regs}->}start[2]} and 1 in @code{@w{@var{regs}->}end[2]} @item 1 in @code{@w{@var{regs}->}start[3]} and 2 in @code{@w{@var{regs}->}end[3]} @end itemize @item If a group matches more than once (as it might if followed by, e.g., a repetition operator), then the function reports the information about what the group @emph{last} matched. For example, when you match the pattern @samp{(a)*} against the string @samp{aa}, you get: @itemize @item 0 in @code{@w{@var{regs}->}start[0]} and 2 in @code{@w{@var{regs}->}end[0]} @item 1 in @code{@w{@var{regs}->}start[1]} and 2 in @code{@w{@var{regs}->}end[1]} @end itemize @item If the @w{@var{i}-th} group does not participate in a successful match, e.g., it is an alternative not taken or a repetition operator allows zero repetitions of it, then the function sets @code{@w{@var{regs}->}start[@var{i}]} and @code{@w{@var{regs}->}end[@var{i}]} to @math{-1}. For example, when you match the pattern @samp{(a)*b} against the string @samp{b}, you get: @itemize @item 0 in @code{@w{@var{regs}->}start[0]} and 1 in @code{@w{@var{regs}->}end[0]} @item @math{-1} in @code{@w{@var{regs}->}start[1]} and @math{-1} in @code{@w{@var{regs}->}end[1]} @end itemize @item If the @w{@var{i}-th} group matches a zero-length string, then the function sets @code{@w{@var{regs}->}start[@var{i}]} and @code{@w{@var{regs}->}end[@var{i}]} to the index just beyond that zero-length string. For example, when you match the pattern @samp{(a*)b} against the string @samp{b}, you get: @itemize @item 0 in @code{@w{@var{regs}->}start[0]} and 1 in @code{@w{@var{regs}->}end[0]} @item 0 in @code{@w{@var{regs}->}start[1]} and 0 in @code{@w{@var{regs}->}end[1]} @end itemize @ignore The function sets @code{@w{@var{regs}->}start[0]} and @code{@w{@var{regs}->}end[0]} to analogous information about the entire pattern. For example, when you match the pattern @samp{(a*)} against the empty string, you get: @itemize @item 0 in @code{@w{@var{regs}->}start[0]} and 0 in @code{@w{@var{regs}->}end[0]} @item 0 in @code{@w{@var{regs}->}start[1]} and 0 in @code{@w{@var{regs}->}end[1]} @end itemize @end ignore @item If an @w{@var{i}-th} group contains a @w{@var{j}-th} group in turn not contained within any other group within group @var{i} and the function reports a match of the @w{@var{i}-th} group, then it records in @code{@w{@var{regs}->}start[@var{j}]} and @code{@w{@var{regs}->}end[@var{j}]} the last match (if it matched) of the @w{@var{j}-th} group. For example, when you match the pattern @samp{((a*)b)*} against the string @samp{abb}, @w{group 2} last matches the empty string, so you get what it previously matched: @itemize @item 0 in @code{@w{@var{regs}->}start[0]} and 3 in @code{@w{@var{regs}->}end[0]} @item 2 in @code{@w{@var{regs}->}start[1]} and 3 in @code{@w{@var{regs}->}end[1]} @item 2 in @code{@w{@var{regs}->}start[2]} and 2 in @code{@w{@var{regs}->}end[2]} @end itemize When you match the pattern @samp{((a)*b)*} against the string @samp{abb}, @w{group 2} doesn't participate in the last match, so you get: @itemize @item 0 in @code{@w{@var{regs}->}start[0]} and 3 in @code{@w{@var{regs}->}end[0]} @item 2 in @code{@w{@var{regs}->}start[1]} and 3 in @code{@w{@var{regs}->}end[1]} @item 0 in @code{@w{@var{regs}->}start[2]} and 1 in @code{@w{@var{regs}->}end[2]} @end itemize @item If an @w{@var{i}-th} group contains a @w{@var{j}-th} group in turn not contained within any other group within group @var{i} and the function sets @code{@w{@var{regs}->}start[@var{i}]} and @code{@w{@var{regs}->}end[@var{i}]} to @math{-1}, then it also sets @code{@w{@var{regs}->}start[@var{j}]} and @code{@w{@var{regs}->}end[@var{j}]} to @math{-1}. For example, when you match the pattern @samp{((a)*b)*c} against the string @samp{c}, you get: @itemize @item 0 in @code{@w{@var{regs}->}start[0]} and 1 in @code{@w{@var{regs}->}end[0]} @item @math{-1} in @code{@w{@var{regs}->}start[1]} and @math{-1} in @code{@w{@var{regs}->}end[1]} @item @math{-1} in @code{@w{@var{regs}->}start[2]} and @math{-1} in @code{@w{@var{regs}->}end[2]} @end itemize @end itemize @node Freeing GNU Pattern Buffers, , Using Registers, GNU Regex Functions @subsection Freeing GNU Pattern Buffers To free any allocated fields of a pattern buffer, you can use the @sc{posix} function described in @ref{Freeing POSIX Pattern Buffers}, since the type @code{regex_t}---the type for @sc{posix} pattern buffers---is equivalent to the type @code{re_pattern_buffer}. After freeing a pattern buffer, you need to again compile a regular expression in it (@pxref{GNU Regular Expression Compiling}) before passing it to a matching or searching function. @node POSIX Regex Functions, BSD Regex Functions, GNU Regex Functions, Programming with Regex @section POSIX Regex Functions If you're writing code that has to be @sc{posix} compatible, you'll need to use these functions. Their interfaces are as specified by @sc{posix}, draft 1003.2/D11.2. @menu * POSIX Pattern Buffers:: The regex_t type. * POSIX Regular Expression Compiling:: regcomp () * POSIX Matching:: regexec () * Reporting Errors:: regerror () * Using Byte Offsets:: The regmatch_t type. * Freeing POSIX Pattern Buffers:: regfree () @end menu @node POSIX Pattern Buffers, POSIX Regular Expression Compiling, , POSIX Regex Functions @subsection POSIX Pattern Buffers To compile or match a given regular expression the @sc{posix} way, you must supply a pattern buffer exactly the way you do for @sc{gnu} (@pxref{GNU Pattern Buffers}). @sc{posix} pattern buffers have type @code{regex_t}, which is equivalent to the @sc{gnu} pattern buffer type @code{re_pattern_buffer}. @node POSIX Regular Expression Compiling, POSIX Matching, POSIX Pattern Buffers, POSIX Regex Functions @subsection POSIX Regular Expression Compiling With @sc{posix}, you can only search for a given regular expression; you can't match it. To do this, you must first compile it in a pattern buffer, using @code{regcomp}. @ignore Before calling @code{regcomp}, you must initialize this pattern buffer as you do for @sc{gnu} (@pxref{GNU Regular Expression Compiling}). See below, however, for how to choose a syntax with which to compile. @end ignore To compile a pattern buffer, use: @findex regcomp @example int regcomp (regex_t *@var{preg}, const char *@var{regex}, int @var{cflags}) @end example @noindent @var{preg} is the initialized pattern buffer's address, @var{regex} is the regular expression's address, and @var{cflags} is the compilation flags, which Regex considers as a collection of bits. Here are the valid bits, as defined in @file{regex.h}: @table @code @item REG_EXTENDED @vindex REG_EXTENDED says to use @sc{posix} Extended Regular Expression syntax; if this isn't set, then says to use @sc{posix} Basic Regular Expression syntax. @code{regcomp} sets @var{preg}'s @code{syntax} field accordingly. @item REG_ICASE @vindex REG_ICASE @cindex ignoring case says to ignore case; @code{regcomp} sets @var{preg}'s @code{translate} field to a translate table which ignores case, replacing anything you've put there before. @item REG_NOSUB @vindex REG_NOSUB says to set @var{preg}'s @code{no_sub} field; @pxref{POSIX Matching}, for what this means. @item REG_NEWLINE @vindex REG_NEWLINE says that a: @itemize @bullet @item match-any-character operator (@pxref{Match-any-character Operator}) doesn't match a newline. @item nonmatching list not containing a newline (@pxref{List Operators}) matches a newline. @item match-beginning-of-line operator (@pxref{Match-beginning-of-line Operator}) matches the empty string immediately after a newline, regardless of how @code{REG_NOTBOL} is set (@pxref{POSIX Matching}, for an explanation of @code{REG_NOTBOL}). @item match-end-of-line operator (@pxref{Match-beginning-of-line Operator}) matches the empty string immediately before a newline, regardless of how @code{REG_NOTEOL} is set (@pxref{POSIX Matching}, for an explanation of @code{REG_NOTEOL}). @end itemize @end table If @code{regcomp} successfully compiles the regular expression, it returns zero and sets @code{*@var{pattern_buffer}} to the compiled pattern. Except for @code{syntax} (which it sets as explained above), it also sets the same fields the same way as does the @sc{gnu} compiling function (@pxref{GNU Regular Expression Compiling}). If @code{regcomp} can't compile the regular expression, it returns one of the error codes listed here. (Except when noted differently, the syntax of in all examples below is basic regular expression syntax.) @table @code @comment repetitions @item REG_BADRPT For example, the consecutive repetition operators @samp{**} in @samp{a**} are invalid. As another example, if the syntax is extended regular expression syntax, then the repetition operator @samp{*} with nothing on which to operate in @samp{*} is invalid. @item REG_BADBR For example, the @var{count} @samp{-1} in @samp{a\@{-1} is invalid. @item REG_EBRACE For example, @samp{a\@{1} is missing a close-interval operator. @comment lists @item REG_EBRACK For example, @samp{[a} is missing a close-list operator. @item REG_ERANGE For example, the range ending point @samp{z} that collates lower than does its starting point @samp{a} in @samp{[z-a]} is invalid. Also, the range with the character class @samp{[:alpha:]} as its starting point in @samp{[[:alpha:]-|]}. @item REG_ECTYPE For example, the character class name @samp{foo} in @samp{[[:foo:]} is invalid. @comment groups @item REG_EPAREN For example, @samp{a\)} is missing an open-group operator and @samp{\(a} is missing a close-group operator. @item REG_ESUBREG For example, the back reference @samp{\2} that refers to a nonexistent subexpression in @samp{\(a\)\2} is invalid. @comment unfinished business @item REG_EEND Returned when a regular expression causes no other more specific error. @item REG_EESCAPE For example, the trailing backslash @samp{\} in @samp{a\} is invalid, as is the one in @samp{\}. @comment kitchen sink @item REG_BADPAT For example, in the extended regular expression syntax, the empty group @samp{()} in @samp{a()b} is invalid. @comment internal @item REG_ESIZE Returned when a regular expression needs a pattern buffer larger than 65536 bytes. @item REG_ESPACE Returned when a regular expression makes Regex to run out of memory. @end table @node POSIX Matching, Reporting Errors, POSIX Regular Expression Compiling, POSIX Regex Functions @subsection POSIX Matching Matching the @sc{posix} way means trying to match a null-terminated string starting at its first character. Once you've compiled a pattern into a pattern buffer (@pxref{POSIX Regular Expression Compiling}), you can ask the matcher to match that pattern against a string using: @findex regexec @example int regexec (const regex_t *@var{preg}, const char *@var{string}, size_t @var{nmatch}, regmatch_t @var{pmatch}[], int @var{eflags}) @end example @noindent @var{preg} is the address of a pattern buffer for a compiled pattern. @var{string} is the string you want to match. @xref{Using Byte Offsets}, for an explanation of @var{pmatch}. If you pass zero for @var{nmatch} or you compiled @var{preg} with the compilation flag @code{REG_NOSUB} set, then @code{regexec} will ignore @var{pmatch}; otherwise, you must allocate it to have at least @var{nmatch} elements. @code{regexec} will record @var{nmatch} byte offsets in @var{pmatch}, and set to @math{-1} any unused elements up to @math{@var{pmatch}@code{[@var{nmatch}]} - 1}. @var{eflags} specifies @dfn{execution flags}---namely, the two bits @code{REG_NOTBOL} and @code{REG_NOTEOL} (defined in @file{regex.h}). If you set @code{REG_NOTBOL}, then the match-beginning-of-line operator (@pxref{Match-beginning-of-line Operator}) always fails to match. This lets you match against pieces of a line, as you would need to if, say, searching for repeated instances of a given pattern in a line; it would work correctly for patterns both with and without match-beginning-of-line operators. @code{REG_NOTEOL} works analogously for the match-end-of-line operator (@pxref{Match-end-of-line Operator}); it exists for symmetry. @code{regexec} tries to find a match for @var{preg} in @var{string} according to the syntax in @var{preg}'s @code{syntax} field. (@xref{POSIX Regular Expression Compiling}, for how to set it.) The function returns zero if the compiled pattern matches @var{string} and @code{REG_NOMATCH} (defined in @file{regex.h}) if it doesn't. @node Reporting Errors, Using Byte Offsets, POSIX Matching, POSIX Regex Functions @subsection Reporting Errors If either @code{regcomp} or @code{regexec} fail, they return a nonzero error code, the possibilities for which are defined in @file{regex.h}. @xref{POSIX Regular Expression Compiling}, and @ref{POSIX Matching}, for what these codes mean. To get an error string corresponding to these codes, you can use: @findex regerror @example size_t regerror (int @var{errcode}, const regex_t *@var{preg}, char *@var{errbuf}, size_t @var{errbuf_size}) @end example @noindent @var{errcode} is an error code, @var{preg} is the address of the pattern buffer which provoked the error, @var{errbuf} is the error buffer, and @var{errbuf_size} is @var{errbuf}'s size. @code{regerror} returns the size in bytes of the error string corresponding to @var{errcode} (including its terminating null). If @var{errbuf} and @var{errbuf_size} are nonzero, it also returns in @var{errbuf} the first @math{@var{errbuf_size} - 1} characters of the error string, followed by a null. @var{errbuf_size} must be a nonnegative number less than or equal to the size in bytes of @var{errbuf}. You can call @code{regerror} with a null @var{errbuf} and a zero @var{errbuf_size} to determine how large @var{errbuf} need be to accommodate @code{regerror}'s error string. @node Using Byte Offsets, Freeing POSIX Pattern Buffers, Reporting Errors, POSIX Regex Functions @subsection Using Byte Offsets In @sc{posix}, variables of type @code{regmatch_t} hold analogous information, but are not identical to, @sc{gnu}'s registers (@pxref{Using Registers}). To get information about registers in @sc{posix}, pass to @code{regexec} a nonzero @var{pmatch} of type @code{regmatch_t}, i.e., the address of a structure of this type, defined in @file{regex.h}: @tindex regmatch_t @example typedef struct @{ regoff_t rm_so; regoff_t rm_eo; @} regmatch_t; @end example When reading in @ref{Using Registers}, about how the matching function stores the information into the registers, substitute @var{pmatch} for @var{regs}, @code{@w{@var{pmatch}[@var{i}]->}rm_so} for @code{@w{@var{regs}->}start[@var{i}]} and @code{@w{@var{pmatch}[@var{i}]->}rm_eo} for @code{@w{@var{regs}->}end[@var{i}]}. @node Freeing POSIX Pattern Buffers, , Using Byte Offsets, POSIX Regex Functions @subsection Freeing POSIX Pattern Buffers To free any allocated fields of a pattern buffer, use: @findex regfree @example void regfree (regex_t *@var{preg}) @end example @noindent @var{preg} is the pattern buffer whose allocated fields you want freed. @code{regfree} also sets @var{preg}'s @code{allocated} and @code{used} fields to zero. After freeing a pattern buffer, you need to again compile a regular expression in it (@pxref{POSIX Regular Expression Compiling}) before passing it to the matching function (@pxref{POSIX Matching}). @node BSD Regex Functions, , POSIX Regex Functions, Programming with Regex @section BSD Regex Functions If you're writing code that has to be Berkeley @sc{unix} compatible, you'll need to use these functions whose interfaces are the same as those in Berkeley @sc{unix}. @menu * BSD Regular Expression Compiling:: re_comp () * BSD Searching:: re_exec () @end menu @node BSD Regular Expression Compiling, BSD Searching, , BSD Regex Functions @subsection BSD Regular Expression Compiling With Berkeley @sc{unix}, you can only search for a given regular expression; you can't match one. To search for it, you must first compile it. Before you compile it, you must indicate the regular expression syntax you want it compiled according to by setting the variable @code{re_syntax_options} (declared in @file{regex.h} to some syntax (@pxref{Regular Expression Syntax}). To compile a regular expression use: @findex re_comp @example char * re_comp (char *@var{regex}) @end example @noindent @var{regex} is the address of a null-terminated regular expression. @code{re_comp} uses an internal pattern buffer, so you can use only the most recently compiled pattern buffer. This means that if you want to use a given regular expression that you've already compiled---but it isn't the latest one you've compiled---you'll have to recompile it. If you call @code{re_comp} with the null string (@emph{not} the empty string) as the argument, it doesn't change the contents of the pattern buffer. If @code{re_comp} successfully compiles the regular expression, it returns zero. If it can't compile the regular expression, it returns an error string. @code{re_comp}'s error messages are identical to those of @code{re_compile_pattern} (@pxref{GNU Regular Expression Compiling}). @node BSD Searching, , BSD Regular Expression Compiling, BSD Regex Functions @subsection BSD Searching Searching the Berkeley @sc{unix} way means searching in a string starting at its first character and trying successive positions within it to find a match. Once you've compiled a pattern using @code{re_comp} (@pxref{BSD Regular Expression Compiling}), you can ask Regex to search for that pattern in a string using: @findex re_exec @example int re_exec (char *@var{string}) @end example @noindent @var{string} is the address of the null-terminated string in which you want to search. @code{re_exec} returns either 1 for success or 0 for failure. It automatically uses a @sc{gnu} fastmap (@pxref{Searching with Fastmaps}). @node Copying, Index, Programming with Regex, Top @appendix GNU GENERAL PUBLIC LICENSE @center Version 2, June 1991 @display Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @end display @unnumberedsec Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software---to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. @iftex @unnumberedsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION @end iftex @ifinfo @center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION @end ifinfo @enumerate @item This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The ``Program'', below, refers to any such program or work, and a ``work based on the Program'' means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term ``modification''.) Each licensee is addressed as ``you''. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. @item You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. @item You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: @enumerate a @item You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. @item You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. @item If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) @end enumerate These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. @item You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: @enumerate a @item Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, @item Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, @item Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) @end enumerate The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. @item You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. @item You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. @item Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. @item If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. @item If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. @item The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and ``any later version'', you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. @item If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. @iftex @heading NO WARRANTY @end iftex @ifinfo @center NO WARRANTY @end ifinfo @item BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM ``AS IS'' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. @item IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. @end enumerate @iftex @heading END OF TERMS AND CONDITIONS @end iftex @ifinfo @center END OF TERMS AND CONDITIONS @end ifinfo @page @unnumberedsec Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the ``copyright'' line and a pointer to where the full notice is found. @smallexample @var{one line to give the program's name and a brief idea of what it does.} Copyright (C) 19@var{yy} @var{name of author} 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 2 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, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. @end smallexample Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: @smallexample Gnomovision version 69, Copyright (C) 19@var{yy} @var{name of author} Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. @end smallexample The hypothetical commands @samp{show w} and @samp{show c} should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than @samp{show w} and @samp{show c}; they could even be mouse-clicks or menu items---whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a ``copyright disclaimer'' for the program, if necessary. Here is a sample; alter the names: @example Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. @var{signature of Ty Coon}, 1 April 1989 Ty Coon, President of Vice @end example This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. @node Index, , Copying, Top @unnumbered Index @printindex cp @contents @bye lyskom-server-2.1.2/src/libraries/regex/doc/xregex.texi0000664000015100472110000033655205533104432016651 \input texinfo @c %**start of header @setfilename regex.info @settitle Regex @c %**end of header @c \\{fill-paragraph} works better (for me, anyway) if the text in the @c source file isn't indented. @paragraphindent 2 @c Define a new index for our magic constants. @defcodeindex cn @c Put everything in one index (arbitrarily chosen to be the concept index). @syncodeindex cn cp @syncodeindex ky cp @syncodeindex pg cp @syncodeindex tp cp @syncodeindex vr cp @c Here is what we use in the Info `dir' file: @c * Regex: (regex). Regular expression library. @ifinfo This file documents the GNU regular expression library. Copyright (C) 1992, 1993 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. @ignore Permission is granted to process this file through TeX and print the results, provided the printed document carries a copying permission notice identical to this one except for the removal of this paragraph (this paragraph not being relevant to the printed manual). @end ignore Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the section entitled ``GNU General Public License'' is included exactly as in the original, and provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that the section entitled ``GNU General Public License'' may be included in a translation approved by the Free Software Foundation instead of in the original English. @end ifinfo @titlepage @title Regex @subtitle edition 0.12a @subtitle 19 September 1992 @author Kathryn A. Hargreaves @author Karl Berry @page @vskip 0pt plus 1filll Copyright @copyright{} 1992 Free Software Foundation. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the section entitled ``GNU General Public License'' is included exactly as in the original, and provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that the section entitled ``GNU General Public License'' may be included in a translation approved by the Free Software Foundation instead of in the original English. @end titlepage @ifinfo @node Top, Overview, (dir), (dir) @top Regular Expression Library This manual documents how to program with the GNU regular expression library. This is edition 0.12a of the manual, 19 September 1992. The first part of this master menu lists the major nodes in this Info document, including the index. The rest of the menu lists all the lower level nodes in the document. @menu * Overview:: * Regular Expression Syntax:: * Common Operators:: * GNU Operators:: * GNU Emacs Operators:: * What Gets Matched?:: * Programming with Regex:: * Copying:: Copying and sharing Regex. * Index:: General index. --- The Detailed Node Listing --- Regular Expression Syntax * Syntax Bits:: * Predefined Syntaxes:: * Collating Elements vs. Characters:: * The Backslash Character:: Common Operators * Match-self Operator:: Ordinary characters. * Match-any-character Operator:: . * Concatenation Operator:: Juxtaposition. * Repetition Operators:: * + ? @{@} * Alternation Operator:: | * List Operators:: [...] [^...] * Grouping Operators:: (...) * Back-reference Operator:: \digit * Anchoring Operators:: ^ $ Repetition Operators * Match-zero-or-more Operator:: * * Match-one-or-more Operator:: + * Match-zero-or-one Operator:: ? * Interval Operators:: @{@} List Operators (@code{[} @dots{} @code{]} and @code{[^} @dots{} @code{]}) * Character Class Operators:: [:class:] * Range Operator:: start-end Anchoring Operators * Match-beginning-of-line Operator:: ^ * Match-end-of-line Operator:: $ GNU Operators * Word Operators:: * Buffer Operators:: Word Operators * Non-Emacs Syntax Tables:: * Match-word-boundary Operator:: \b * Match-within-word Operator:: \B * Match-beginning-of-word Operator:: \< * Match-end-of-word Operator:: \> * Match-word-constituent Operator:: \w * Match-non-word-constituent Operator:: \W Buffer Operators * Match-beginning-of-buffer Operator:: \` * Match-end-of-buffer Operator:: \' GNU Emacs Operators * Syntactic Class Operators:: Syntactic Class Operators * Emacs Syntax Tables:: * Match-syntactic-class Operator:: \sCLASS * Match-not-syntactic-class Operator:: \SCLASS Programming with Regex * GNU Regex Functions:: * POSIX Regex Functions:: * BSD Regex Functions:: GNU Regex Functions * GNU Pattern Buffers:: The re_pattern_buffer type. * GNU Regular Expression Compiling:: re_compile_pattern () * GNU Matching:: re_match () * GNU Searching:: re_search () * Matching/Searching with Split Data:: re_match_2 (), re_search_2 () * Searching with Fastmaps:: re_compile_fastmap () * GNU Translate Tables:: The `translate' field. * Using Registers:: The re_registers type and related fns. * Freeing GNU Pattern Buffers:: regfree () POSIX Regex Functions * POSIX Pattern Buffers:: The regex_t type. * POSIX Regular Expression Compiling:: regcomp () * POSIX Matching:: regexec () * Reporting Errors:: regerror () * Using Byte Offsets:: The regmatch_t type. * Freeing POSIX Pattern Buffers:: regfree () BSD Regex Functions * BSD Regular Expression Compiling:: re_comp () * BSD Searching:: re_exec () @end menu @end ifinfo @node Overview, Regular Expression Syntax, Top, Top @chapter Overview A @dfn{regular expression} (or @dfn{regexp}, or @dfn{pattern}) is a text string that describes some (mathematical) set of strings. A regexp @var{r} @dfn{matches} a string @var{s} if @var{s} is in the set of strings described by @var{r}. Using the Regex library, you can: @itemize @bullet @item see if a string matches a specified pattern as a whole, and @item search within a string for a substring matching a specified pattern. @end itemize Some regular expressions match only one string, i.e., the set they describe has only one member. For example, the regular expression @samp{foo} matches the string @samp{foo} and no others. Other regular expressions match more than one string, i.e., the set they describe has more than one member. For example, the regular expression @samp{f*} matches the set of strings made up of any number (including zero) of @samp{f}s. As you can see, some characters in regular expressions match themselves (such as @samp{f}) and some don't (such as @samp{*}); the ones that don't match themselves instead let you specify patterns that describe many different strings. To either match or search for a regular expression with the Regex library functions, you must first compile it with a Regex pattern compiling function. A @dfn{compiled pattern} is a regular expression converted to the internal format used by the library functions. Once you've compiled a pattern, you can use it for matching or searching any number of times. The Regex library consists of two source files: @file{regex.h} and @file{regex.c}. @pindex regex.h @pindex regex.c Regex provides three groups of functions with which you can operate on regular expressions. One group---the @sc{gnu} group---is more powerful but not completely compatible with the other two, namely the @sc{posix} and Berkeley @sc{unix} groups; its interface was designed specifically for @sc{gnu}. The other groups have the same interfaces as do the regular expression functions in @sc{posix} and Berkeley @sc{unix}. We wrote this chapter with programmers in mind, not users of programs---such as Emacs---that use Regex. We describe the Regex library in its entirety, not how to write regular expressions that a particular program understands. @node Regular Expression Syntax, Common Operators, Overview, Top @chapter Regular Expression Syntax @cindex regular expressions, syntax of @cindex syntax of regular expressions @dfn{Characters} are things you can type. @dfn{Operators} are things in a regular expression that match one or more characters. You compose regular expressions from operators, which in turn you specify using one or more characters. Most characters represent what we call the match-self operator, i.e., they match themselves; we call these characters @dfn{ordinary}. Other characters represent either all or parts of fancier operators; e.g., @samp{.} represents what we call the match-any-character operator (which, no surprise, matches (almost) any character); we call these characters @dfn{special}. Two different things determine what characters represent what operators: @enumerate @item the regular expression syntax your program has told the Regex library to recognize, and @item the context of the character in the regular expression. @end enumerate In the following sections, we describe these things in more detail. @menu * Syntax Bits:: * Predefined Syntaxes:: * Collating Elements vs. Characters:: * The Backslash Character:: @end menu @node Syntax Bits, Predefined Syntaxes, , Regular Expression Syntax @section Syntax Bits @cindex syntax bits In any particular syntax for regular expressions, some characters are always special, others are sometimes special, and others are never special. The particular syntax that Regex recognizes for a given regular expression depends on the value in the @code{syntax} field of the pattern buffer of that regular expression. You get a pattern buffer by compiling a regular expression. @xref{GNU Pattern Buffers}, and @ref{POSIX Pattern Buffers}, for more information on pattern buffers. @xref{GNU Regular Expression Compiling}, @ref{POSIX Regular Expression Compiling}, and @ref{BSD Regular Expression Compiling}, for more information on compiling. Regex considers the value of the @code{syntax} field to be a collection of bits; we refer to these bits as @dfn{syntax bits}. In most cases, they affect what characters represent what operators. We describe the meanings of the operators to which we refer in @ref{Common Operators}, @ref{GNU Operators}, and @ref{GNU Emacs Operators}. For reference, here is the complete list of syntax bits, in alphabetical order: @table @code @cnindex RE_BACKSLASH_ESCAPE_IN_LIST @item RE_BACKSLASH_ESCAPE_IN_LISTS If this bit is set, then @samp{\} inside a list (@pxref{List Operators} quotes (makes ordinary, if it's special) the following character; if this bit isn't set, then @samp{\} is an ordinary character inside lists. (@xref{The Backslash Character}, for what `\' does outside of lists.) @cnindex RE_BK_PLUS_QM @item RE_BK_PLUS_QM If this bit is set, then @samp{\+} represents the match-one-or-more operator and @samp{\?} represents the match-zero-or-more operator; if this bit isn't set, then @samp{+} represents the match-one-or-more operator and @samp{?} represents the match-zero-or-one operator. This bit is irrelevant if @code{RE_LIMITED_OPS} is set. @cnindex RE_CHAR_CLASSES @item RE_CHAR_CLASSES If this bit is set, then you can use character classes in lists; if this bit isn't set, then you can't. @cnindex RE_CONTEXT_INDEP_ANCHORS @item RE_CONTEXT_INDEP_ANCHORS If this bit is set, then @samp{^} and @samp{$} are special anywhere outside a list; if this bit isn't set, then these characters are special only in certain contexts. @xref{Match-beginning-of-line Operator}, and @ref{Match-end-of-line Operator}. @cnindex RE_CONTEXT_INDEP_OPS @item RE_CONTEXT_INDEP_OPS If this bit is set, then certain characters are special anywhere outside a list; if this bit isn't set, then those characters are special only in some contexts and are ordinary elsewhere. Specifically, if this bit isn't set then @samp{*}, and (if the syntax bit @code{RE_LIMITED_OPS} isn't set) @samp{+} and @samp{?} (or @samp{\+} and @samp{\?}, depending on the syntax bit @code{RE_BK_PLUS_QM}) represent repetition operators only if they're not first in a regular expression or just after an open-group or alternation operator. The same holds for @samp{@{} (or @samp{\@{}, depending on the syntax bit @code{RE_NO_BK_BRACES}) if it is the beginning of a valid interval and the syntax bit @code{RE_INTERVALS} is set. @cnindex RE_CONTEXT_INVALID_OPS @item RE_CONTEXT_INVALID_OPS If this bit is set, then repetition and alternation operators can't be in certain positions within a regular expression. Specifically, the regular expression is invalid if it has: @itemize @bullet @item a repetition operator first in the regular expression or just after a match-beginning-of-line, open-group, or alternation operator; or @item an alternation operator first or last in the regular expression, just before a match-end-of-line operator, or just after an alternation or open-group operator. @end itemize If this bit isn't set, then you can put the characters representing the repetition and alternation characters anywhere in a regular expression. Whether or not they will in fact be operators in certain positions depends on other syntax bits. @cnindex RE_DOT_NEWLINE @item RE_DOT_NEWLINE If this bit is set, then the match-any-character operator matches a newline; if this bit isn't set, then it doesn't. @cnindex RE_DOT_NOT_NULL @item RE_DOT_NOT_NULL If this bit is set, then the match-any-character operator doesn't match a null character; if this bit isn't set, then it does. @cnindex RE_INTERVALS @item RE_INTERVALS If this bit is set, then Regex recognizes interval operators; if this bit isn't set, then it doesn't. @cnindex RE_LIMITED_OPS @item RE_LIMITED_OPS If this bit is set, then Regex doesn't recognize the match-one-or-more, match-zero-or-one or alternation operators; if this bit isn't set, then it does. @cnindex RE_NEWLINE_ALT @item RE_NEWLINE_ALT If this bit is set, then newline represents the alternation operator; if this bit isn't set, then newline is ordinary. @cnindex RE_NO_BK_BRACES @item RE_NO_BK_BRACES If this bit is set, then @samp{@{} represents the open-interval operator and @samp{@}} represents the close-interval operator; if this bit isn't set, then @samp{\@{} represents the open-interval operator and @samp{\@}} represents the close-interval operator. This bit is relevant only if @code{RE_INTERVALS} is set. @cnindex RE_NO_BK_PARENS @item RE_NO_BK_PARENS If this bit is set, then @samp{(} represents the open-group operator and @samp{)} represents the close-group operator; if this bit isn't set, then @samp{\(} represents the open-group operator and @samp{\)} represents the close-group operator. @cnindex RE_NO_BK_REFS @item RE_NO_BK_REFS If this bit is set, then Regex doesn't recognize @samp{\}@var{digit} as the back reference operator; if this bit isn't set, then it does. @cnindex RE_NO_BK_VBAR @item RE_NO_BK_VBAR If this bit is set, then @samp{|} represents the alternation operator; if this bit isn't set, then @samp{\|} represents the alternation operator. This bit is irrelevant if @code{RE_LIMITED_OPS} is set. @cnindex RE_NO_EMPTY_RANGES @item RE_NO_EMPTY_RANGES If this bit is set, then a regular expression with a range whose ending point collates lower than its starting point is invalid; if this bit isn't set, then Regex considers such a range to be empty. @cnindex RE_UNMATCHED_RIGHT_PAREN_ORD @item RE_UNMATCHED_RIGHT_PAREN_ORD If this bit is set and the regular expression has no matching open-group operator, then Regex considers what would otherwise be a close-group operator (based on how @code{RE_NO_BK_PARENS} is set) to match @samp{)}. @end table @node Predefined Syntaxes, Collating Elements vs. Characters, Syntax Bits, Regular Expression Syntax @section Predefined Syntaxes If you're programming with Regex, you can set a pattern buffer's (@pxref{GNU Pattern Buffers}, and @ref{POSIX Pattern Buffers}) @code{syntax} field either to an arbitrary combination of syntax bits (@pxref{Syntax Bits}) or else to the configurations defined by Regex. These configurations define the syntaxes used by certain programs---@sc{gnu} Emacs, @cindex Emacs @sc{posix} Awk, @cindex POSIX Awk traditional Awk, @cindex Awk Grep, @cindex Grep @cindex Egrep Egrep---in addition to syntaxes for @sc{posix} basic and extended regular expressions. The predefined syntaxes--taken directly from @file{regex.h}---are: @example [[[ syntaxes ]]] @end example @node Collating Elements vs. Characters, The Backslash Character, Predefined Syntaxes, Regular Expression Syntax @section Collating Elements vs.@: Characters @sc{posix} generalizes the notion of a character to that of a collating element. It defines a @dfn{collating element} to be ``a sequence of one or more bytes defined in the current collating sequence as a unit of collation.'' This generalizes the notion of a character in two ways. First, a single character can map into two or more collating elements. For example, the German @tex `\ss' @end tex @ifinfo ``es-zet'' @end ifinfo collates as the collating element @samp{s} followed by another collating element @samp{s}. Second, two or more characters can map into one collating element. For example, the Spanish @samp{ll} collates after @samp{l} and before @samp{m}. Since @sc{posix}'s ``collating element'' preserves the essential idea of a ``character,'' we use the latter, more familiar, term in this document. @node The Backslash Character, , Collating Elements vs. Characters, Regular Expression Syntax @section The Backslash Character @cindex \ The @samp{\} character has one of four different meanings, depending on the context in which you use it and what syntax bits are set (@pxref{Syntax Bits}). It can: 1) stand for itself, 2) quote the next character, 3) introduce an operator, or 4) do nothing. @enumerate @item It stands for itself inside a list (@pxref{List Operators}) if the syntax bit @code{RE_BACKSLASH_ESCAPE_IN_LISTS} is not set. For example, @samp{[\]} would match @samp{\}. @item It quotes (makes ordinary, if it's special) the next character when you use it either: @itemize @bullet @item outside a list,@footnote{Sometimes you don't have to explicitly quote special characters to make them ordinary. For instance, most characters lose any special meaning inside a list (@pxref{List Operators}). In addition, if the syntax bits @code{RE_CONTEXT_INVALID_OPS} and @code{RE_CONTEXT_INDEP_OPS} aren't set, then (for historical reasons) the matcher considers special characters ordinary if they are in contexts where the operations they represent make no sense; for example, then the match-zero-or-more operator (represented by @samp{*}) matches itself in the regular expression @samp{*foo} because there is no preceding expression on which it can operate. It is poor practice, however, to depend on this behavior; if you want a special character to be ordinary outside a list, it's better to always quote it, regardless.} or @item inside a list and the syntax bit @code{RE_BACKSLASH_ESCAPE_IN_LISTS} is set. @end itemize @item It introduces an operator when followed by certain ordinary characters---sometimes only when certain syntax bits are set. See the cases @code{RE_BK_PLUS_QM}, @code{RE_NO_BK_BRACES}, @code{RE_NO_BK_VAR}, @code{RE_NO_BK_PARENS}, @code{RE_NO_BK_REF} in @ref{Syntax Bits}. Also: @itemize @bullet @item @samp{\b} represents the match-word-boundary operator (@pxref{Match-word-boundary Operator}). @item @samp{\B} represents the match-within-word operator (@pxref{Match-within-word Operator}). @item @samp{\<} represents the match-beginning-of-word operator @* (@pxref{Match-beginning-of-word Operator}). @item @samp{\>} represents the match-end-of-word operator (@pxref{Match-end-of-word Operator}). @item @samp{\w} represents the match-word-constituent operator (@pxref{Match-word-constituent Operator}). @item @samp{\W} represents the match-non-word-constituent operator (@pxref{Match-non-word-constituent Operator}). @item @samp{\`} represents the match-beginning-of-buffer operator and @samp{\'} represents the match-end-of-buffer operator (@pxref{Buffer Operators}). @item If Regex was compiled with the C preprocessor symbol @code{emacs} defined, then @samp{\s@var{class}} represents the match-syntactic-class operator and @samp{\S@var{class}} represents the match-not-syntactic-class operator (@pxref{Syntactic Class Operators}). @end itemize @item In all other cases, Regex ignores @samp{\}. For example, @samp{\n} matches @samp{n}. @end enumerate @node Common Operators, GNU Operators, Regular Expression Syntax, Top @chapter Common Operators You compose regular expressions from operators. In the following sections, we describe the regular expression operators specified by @sc{posix}; @sc{gnu} also uses these. Most operators have more than one representation as characters. @xref{Regular Expression Syntax}, for what characters represent what operators under what circumstances. For most operators that can be represented in two ways, one representation is a single character and the other is that character preceded by @samp{\}. For example, either @samp{(} or @samp{\(} represents the open-group operator. Which one does depends on the setting of a syntax bit, in this case @code{RE_NO_BK_PARENS}. Why is this so? Historical reasons dictate some of the varying representations, while @sc{posix} dictates others. Finally, almost all characters lose any special meaning inside a list (@pxref{List Operators}). @menu * Match-self Operator:: Ordinary characters. * Match-any-character Operator:: . * Concatenation Operator:: Juxtaposition. * Repetition Operators:: * + ? @{@} * Alternation Operator:: | * List Operators:: [...] [^...] * Grouping Operators:: (...) * Back-reference Operator:: \digit * Anchoring Operators:: ^ $ @end menu @node Match-self Operator, Match-any-character Operator, , Common Operators @section The Match-self Operator (@var{ordinary character}) This operator matches the character itself. All ordinary characters (@pxref{Regular Expression Syntax}) represent this operator. For example, @samp{f} is always an ordinary character, so the regular expression @samp{f} matches only the string @samp{f}. In particular, it does @emph{not} match the string @samp{ff}. @node Match-any-character Operator, Concatenation Operator, Match-self Operator, Common Operators @section The Match-any-character Operator (@code{.}) @cindex @samp{.} This operator matches any single printing or nonprinting character except it won't match a: @table @asis @item newline if the syntax bit @code{RE_DOT_NEWLINE} isn't set. @item null if the syntax bit @code{RE_DOT_NOT_NULL} is set. @end table The @samp{.} (period) character represents this operator. For example, @samp{a.b} matches any three-character string beginning with @samp{a} and ending with @samp{b}. @node Concatenation Operator, Repetition Operators, Match-any-character Operator, Common Operators @section The Concatenation Operator This operator concatenates two regular expressions @var{a} and @var{b}. No character represents this operator; you simply put @var{b} after @var{a}. The result is a regular expression that will match a string if @var{a} matches its first part and @var{b} matches the rest. For example, @samp{xy} (two match-self operators) matches @samp{xy}. @node Repetition Operators, Alternation Operator, Concatenation Operator, Common Operators @section Repetition Operators Repetition operators repeat the preceding regular expression a specified number of times. @menu * Match-zero-or-more Operator:: * * Match-one-or-more Operator:: + * Match-zero-or-one Operator:: ? * Interval Operators:: @{@} @end menu @node Match-zero-or-more Operator, Match-one-or-more Operator, , Repetition Operators @subsection The Match-zero-or-more Operator (@code{*}) @cindex @samp{*} This operator repeats the smallest possible preceding regular expression as many times as necessary (including zero) to match the pattern. @samp{*} represents this operator. For example, @samp{o*} matches any string made up of zero or more @samp{o}s. Since this operator operates on the smallest preceding regular expression, @samp{fo*} has a repeating @samp{o}, not a repeating @samp{fo}. So, @samp{fo*} matches @samp{f}, @samp{fo}, @samp{foo}, and so on. Since the match-zero-or-more operator is a suffix operator, it may be useless as such when no regular expression precedes it. This is the case when it: @itemize @bullet @item is first in a regular expression, or @item follows a match-beginning-of-line, open-group, or alternation operator. @end itemize @noindent Three different things can happen in these cases: @enumerate @item If the syntax bit @code{RE_CONTEXT_INVALID_OPS} is set, then the regular expression is invalid. @item If @code{RE_CONTEXT_INVALID_OPS} isn't set, but @code{RE_CONTEXT_INDEP_OPS} is, then @samp{*} represents the match-zero-or-more operator (which then operates on the empty string). @item Otherwise, @samp{*} is ordinary. @end enumerate @cindex backtracking The matcher processes a match-zero-or-more operator by first matching as many repetitions of the smallest preceding regular expression as it can. Then it continues to match the rest of the pattern. If it can't match the rest of the pattern, it backtracks (as many times as necessary), each time discarding one of the matches until it can either match the entire pattern or be certain that it cannot get a match. For example, when matching @samp{ca*ar} against @samp{caaar}, the matcher first matches all three @samp{a}s of the string with the @samp{a*} of the regular expression. However, it cannot then match the final @samp{ar} of the regular expression against the final @samp{r} of the string. So it backtracks, discarding the match of the last @samp{a} in the string. It can then match the remaining @samp{ar}. @node Match-one-or-more Operator, Match-zero-or-one Operator, Match-zero-or-more Operator, Repetition Operators @subsection The Match-one-or-more Operator (@code{+} or @code{\+}) @cindex @samp{+} If the syntax bit @code{RE_LIMITED_OPS} is set, then Regex doesn't recognize this operator. Otherwise, if the syntax bit @code{RE_BK_PLUS_QM} isn't set, then @samp{+} represents this operator; if it is, then @samp{\+} does. This operator is similar to the match-zero-or-more operator except that it repeats the preceding regular expression at least once; @pxref{Match-zero-or-more Operator}, for what it operates on, how some syntax bits affect it, and how Regex backtracks to match it. For example, supposing that @samp{+} represents the match-one-or-more operator; then @samp{ca+r} matches, e.g., @samp{car} and @samp{caaaar}, but not @samp{cr}. @node Match-zero-or-one Operator, Interval Operators, Match-one-or-more Operator, Repetition Operators @subsection The Match-zero-or-one Operator (@code{?} or @code{\?}) @cindex @samp{?} If the syntax bit @code{RE_LIMITED_OPS} is set, then Regex doesn't recognize this operator. Otherwise, if the syntax bit @code{RE_BK_PLUS_QM} isn't set, then @samp{?} represents this operator; if it is, then @samp{\?} does. This operator is similar to the match-zero-or-more operator except that it repeats the preceding regular expression once or not at all; @pxref{Match-zero-or-more Operator}, to see what it operates on, how some syntax bits affect it, and how Regex backtracks to match it. For example, supposing that @samp{?} represents the match-zero-or-one operator; then @samp{ca?r} matches both @samp{car} and @samp{cr}, but nothing else. @node Interval Operators, , Match-zero-or-one Operator, Repetition Operators @subsection Interval Operators (@code{@{} @dots{} @code{@}} or @code{\@{} @dots{} @code{\@}}) @cindex interval expression @cindex @samp{@{} @cindex @samp{@}} @cindex @samp{\@{} @cindex @samp{\@}} If the syntax bit @code{RE_INTERVALS} is set, then Regex recognizes @dfn{interval expressions}. They repeat the smallest possible preceding regular expression a specified number of times. If the syntax bit @code{RE_NO_BK_BRACES} is set, @samp{@{} represents the @dfn{open-interval operator} and @samp{@}} represents the @dfn{close-interval operator} ; otherwise, @samp{\@{} and @samp{\@}} do. Specifically, supposing that @samp{@{} and @samp{@}} represent the open-interval and close-interval operators; then: @table @code @item @{@var{count}@} matches exactly @var{count} occurrences of the preceding regular expression. @item @{@var{min,}@} matches @var{min} or more occurrences of the preceding regular expression. @item @{@var{min, max}@} matches at least @var{min} but no more than @var{max} occurrences of the preceding regular expression. @end table The interval expression (but not necessarily the regular expression that contains it) is invalid if: @itemize @bullet @item @var{min} is greater than @var{max}, or @item any of @var{count}, @var{min}, or @var{max} are outside the range zero to @code{RE_DUP_MAX} (which symbol @file{regex.h} defines). @end itemize If the interval expression is invalid and the syntax bit @code{RE_NO_BK_BRACES} is set, then Regex considers all the characters in the would-be interval to be ordinary. If that bit isn't set, then the regular expression is invalid. If the interval expression is valid but there is no preceding regular expression on which to operate, then if the syntax bit @code{RE_CONTEXT_INVALID_OPS} is set, the regular expression is invalid. If that bit isn't set, then Regex considers all the characters---other than backslashes, which it ignores---in the would-be interval to be ordinary. @node Alternation Operator, List Operators, Repetition Operators, Common Operators @section The Alternation Operator (@code{|} or @code{\|}) @kindex | @kindex \| @cindex alternation operator @cindex or operator If the syntax bit @code{RE_LIMITED_OPS} is set, then Regex doesn't recognize this operator. Otherwise, if the syntax bit @code{RE_NO_BK_VBAR} is set, then @samp{|} represents this operator; otherwise, @samp{\|} does. Alternatives match one of a choice of regular expressions: if you put the character(s) representing the alternation operator between any two regular expressions @var{a} and @var{b}, the result matches the union of the strings that @var{a} and @var{b} match. For example, supposing that @samp{|} is the alternation operator, then @samp{foo|bar|quux} would match any of @samp{foo}, @samp{bar} or @samp{quux}. @ignore @c Nobody needs to disallow empty alternatives any more. If the syntax bit @code{RE_NO_EMPTY_ALTS} is set, then if either of the regular expressions @var{a} or @var{b} is empty, the regular expression is invalid. More precisely, if this syntax bit is set, then the alternation operator can't: @itemize @bullet @item be first or last in a regular expression; @item follow either another alternation operator or an open-group operator (@pxref{Grouping Operators}); or @item precede a close-group operator. @end itemize @noindent For example, supposing @samp{(} and @samp{)} represent the open and close-group operators, then @samp{|foo}, @samp{foo|}, @samp{foo||bar}, @samp{foo(|bar)}, and @samp{(foo|)bar} would all be invalid. @end ignore The alternation operator operates on the @emph{largest} possible surrounding regular expressions. (Put another way, it has the lowest precedence of any regular expression operator.) Thus, the only way you can delimit its arguments is to use grouping. For example, if @samp{(} and @samp{)} are the open and close-group operators, then @samp{fo(o|b)ar} would match either @samp{fooar} or @samp{fobar}. (@samp{foo|bar} would match @samp{foo} or @samp{bar}.) @cindex backtracking The matcher usually tries all combinations of alternatives so as to match the longest possible string. For example, when matching @samp{(fooq|foo)*(qbarquux|bar)} against @samp{fooqbarquux}, it cannot take, say, the first (``depth-first'') combination it could match, since then it would be content to match just @samp{fooqbar}. @comment xx something about leftmost-longest @node List Operators, Grouping Operators, Alternation Operator, Common Operators @section List Operators (@code{[} @dots{} @code{]} and @code{[^} @dots{} @code{]}) @cindex matching list @cindex @samp{[} @cindex @samp{]} @cindex @samp{^} @cindex @samp{-} @cindex @samp{\} @cindex @samp{[^} @cindex nonmatching list @cindex matching newline @cindex bracket expression @dfn{Lists}, also called @dfn{bracket expressions}, are a set of one or more items. An @dfn{item} is a character, @ignore (These get added when they get implemented.) a collating symbol, an equivalence class expression, @end ignore a character class expression, or a range expression. The syntax bits affect which kinds of items you can put in a list. We explain the last two items in subsections below. Empty lists are invalid. A @dfn{matching list} matches a single character represented by one of the list items. You form a matching list by enclosing one or more items within an @dfn{open-matching-list operator} (represented by @samp{[}) and a @dfn{close-list operator} (represented by @samp{]}). For example, @samp{[ab]} matches either @samp{a} or @samp{b}. @samp{[ad]*} matches the empty string and any string composed of just @samp{a}s and @samp{d}s in any order. Regex considers invalid a regular expression with a @samp{[} but no matching @samp{]}. @dfn{Nonmatching lists} are similar to matching lists except that they match a single character @emph{not} represented by one of the list items. You use an @dfn{open-nonmatching-list operator} (represented by @samp{[^}@footnote{Regex therefore doesn't consider the @samp{^} to be the first character in the list. If you put a @samp{^} character first in (what you think is) a matching list, you'll turn it into a nonmatching list.}) instead of an open-matching-list operator to start a nonmatching list. For example, @samp{[^ab]} matches any character except @samp{a} or @samp{b}. If the @code{posix_newline} field in the pattern buffer (@pxref{GNU Pattern Buffers} is set, then nonmatching lists do not match a newline. Most characters lose any special meaning inside a list. The special characters inside a list follow. @table @samp @item ] ends the list if it's not the first list item. So, if you want to make the @samp{]} character a list item, you must put it first. @item \ quotes the next character if the syntax bit @code{RE_BACKSLASH_ESCAPE_IN_LISTS} is set. @ignore Put these in if they get implemented. @item [. represents the open-collating-symbol operator (@pxref{Collating Symbol Operators}). @item .] represents the close-collating-symbol operator. @item [= represents the open-equivalence-class operator (@pxref{Equivalence Class Operators}). @item =] represents the close-equivalence-class operator. @end ignore @item [: represents the open-character-class operator (@pxref{Character Class Operators}) if the syntax bit @code{RE_CHAR_CLASSES} is set and what follows is a valid character class expression. @item :] represents the close-character-class operator if the syntax bit @code{RE_CHAR_CLASSES} is set and what precedes it is an open-character-class operator followed by a valid character class name. @item - represents the range operator (@pxref{Range Operator}) if it's not first or last in a list or the ending point of a range. @end table @noindent All other characters are ordinary. For example, @samp{[.*]} matches @samp{.} and @samp{*}. @menu * Character Class Operators:: [:class:] * Range Operator:: start-end @end menu @ignore (If collating symbols and equivalence class expressions get implemented, then add this.) node Collating Symbol Operators subsubsection Collating Symbol Operators (@code{[.} @dots{} @code{.]}) If the syntax bit @code{XX} is set, then you can represent collating symbols inside lists. You form a @dfn{collating symbol} by putting a collating element between an @dfn{open-collating-symbol operator} and an @dfn{close-collating-symbol operator}. @samp{[.} represents the open-collating-symbol operator and @samp{.]} represents the close-collating-symbol operator. For example, if @samp{ll} is a collating element, then @samp{[[.ll.]]} would match @samp{ll}. node Equivalence Class Operators subsubsection Equivalence Class Operators (@code{[=} @dots{} @code{=]}) @cindex equivalence class expression in regex @cindex @samp{[=} in regex @cindex @samp{=]} in regex If the syntax bit @code{XX} is set, then Regex recognizes equivalence class expressions inside lists. A @dfn{equivalence class expression} is a set of collating elements which all belong to the same equivalence class. You form an equivalence class expression by putting a collating element between an @dfn{open-equivalence-class operator} and a @dfn{close-equivalence-class operator}. @samp{[=} represents the open-equivalence-class operator and @samp{=]} represents the close-equivalence-class operator. For example, if @samp{a} and @samp{A} were an equivalence class, then both @samp{[[=a=]]} and @samp{[[=A=]]} would match both @samp{a} and @samp{A}. If the collating element in an equivalence class expression isn't part of an equivalence class, then the matcher considers the equivalence class expression to be a collating symbol. @end ignore @node Character Class Operators, Range Operator, , List Operators @subsection Character Class Operators (@code{[:} @dots{} @code{:]}) @cindex character classes @cindex @samp{[:} in regex @cindex @samp{:]} in regex If the syntax bit @code{RE_CHARACTER_CLASSES} is set, then Regex recognizes character class expressions inside lists. A @dfn{character class expression} matches one character from a given class. You form a character class expression by putting a character class name between an @dfn{open-character-class operator} (represented by @samp{[:}) and a @dfn{close-character-class operator} (represented by @samp{:]}). The character class names and their meanings are: @table @code @item alnum letters and digits @item alpha letters @item blank system-dependent; for @sc{gnu}, a space or tab @item cntrl control characters (in the @sc{ascii} encoding, code 0177 and codes less than 040) @item digit digits @item graph same as @code{print} except omits space @item lower lowercase letters @item print printable characters (in the @sc{ascii} encoding, space tilde---codes 040 through 0176) @item punct neither control nor alphanumeric characters @item space space, carriage return, newline, vertical tab, and form feed @item upper uppercase letters @item xdigit hexadecimal digits: @code{0}--@code{9}, @code{a}--@code{f}, @code{A}--@code{F} @end table @noindent These correspond to the definitions in the C library's @file{} facility. For example, @samp{[:alpha:]} corresponds to the standard facility @code{isalpha}. Regex recognizes character class expressions only inside of lists; so @samp{[[:alpha:]]} matches any letter, but @samp{[:alpha:]} outside of a bracket expression and not followed by a repetition operator matches just itself. @node Range Operator, , Character Class Operators, List Operators @subsection The Range Operator (@code{-}) Regex recognizes @dfn{range expressions} inside a list. They represent those characters that fall between two elements in the current collating sequence. You form a range expression by putting a @dfn{range operator} between two @ignore (If these get implemented, then substitute this for ``characters.'') of any of the following: characters, collating elements, collating symbols, and equivalence class expressions. The starting point of the range and the ending point of the range don't have to be the same kind of item, e.g., the starting point could be a collating element and the ending point could be an equivalence class expression. If a range's ending point is an equivalence class, then all the collating elements in that class will be in the range. @end ignore characters.@footnote{You can't use a character class for the starting or ending point of a range, since a character class is not a single character.} @samp{-} represents the range operator. For example, @samp{a-f} within a list represents all the characters from @samp{a} through @samp{f} inclusively. If the syntax bit @code{RE_NO_EMPTY_RANGES} is set, then if the range's ending point collates less than its starting point, the range (and the regular expression containing it) is invalid. For example, the regular expression @samp{[z-a]} would be invalid. If this bit isn't set, then Regex considers such a range to be empty. Since @samp{-} represents the range operator, if you want to make a @samp{-} character itself a list item, you must do one of the following: @itemize @bullet @item Put the @samp{-} either first or last in the list. @item Include a range whose starting point collates strictly lower than @samp{-} and whose ending point collates equal or higher. Unless a range is the first item in a list, a @samp{-} can't be its starting point, but @emph{can} be its ending point. That is because Regex considers @samp{-} to be the range operator unless it is preceded by another @samp{-}. For example, in the @sc{ascii} encoding, @samp{)}, @samp{*}, @samp{+}, @samp{,}, @samp{-}, @samp{.}, and @samp{/} are contiguous characters in the collating sequence. You might think that @samp{[)-+--/]} has two ranges: @samp{)-+} and @samp{--/}. Rather, it has the ranges @samp{)-+} and @samp{+--}, plus the character @samp{/}, so it matches, e.g., @samp{,}, not @samp{.}. @item Put a range whose starting point is @samp{-} first in the list. @end itemize For example, @samp{[-a-z]} matches a lowercase letter or a hyphen (in English, in @sc{ascii}). @node Grouping Operators, Back-reference Operator, List Operators, Common Operators @section Grouping Operators (@code{(} @dots{} @code{)} or @code{\(} @dots{} @code{\)}) @kindex ( @kindex ) @kindex \( @kindex \) @cindex grouping @cindex subexpressions @cindex parenthesizing A @dfn{group}, also known as a @dfn{subexpression}, consists of an @dfn{open-group operator}, any number of other operators, and a @dfn{close-group operator}. Regex treats this sequence as a unit, just as mathematics and programming languages treat a parenthesized expression as a unit. Therefore, using @dfn{groups}, you can: @itemize @bullet @item delimit the argument(s) to an alternation operator (@pxref{Alternation Operator}) or a repetition operator (@pxref{Repetition Operators}). @item keep track of the indices of the substring that matched a given group. @xref{Using Registers}, for a precise explanation. This lets you: @itemize @bullet @item use the back-reference operator (@pxref{Back-reference Operator}). @item use registers (@pxref{Using Registers}). @end itemize @end itemize If the syntax bit @code{RE_NO_BK_PARENS} is set, then @samp{(} represents the open-group operator and @samp{)} represents the close-group operator; otherwise, @samp{\(} and @samp{\)} do. If the syntax bit @code{RE_UNMATCHED_RIGHT_PAREN_ORD} is set and a close-group operator has no matching open-group operator, then Regex considers it to match @samp{)}. @node Back-reference Operator, Anchoring Operators, Grouping Operators, Common Operators @section The Back-reference Operator (@dfn{\}@var{digit}) @cindex back references If the syntax bit @code{RE_NO_BK_REF} isn't set, then Regex recognizes back references. A back reference matches a specified preceding group. The back reference operator is represented by @samp{\@var{digit}} anywhere after the end of a regular expression's @w{@var{digit}-th} group (@pxref{Grouping Operators}). @var{digit} must be between @samp{1} and @samp{9}. The matcher assigns numbers 1 through 9 to the first nine groups it encounters. By using one of @samp{\1} through @samp{\9} after the corresponding group's close-group operator, you can match a substring identical to the one that the group does. Back references match according to the following (in all examples below, @samp{(} represents the open-group, @samp{)} the close-group, @samp{@{} the open-interval and @samp{@}} the close-interval operator): @itemize @bullet @item If the group matches a substring, the back reference matches an identical substring. For example, @samp{(a)\1} matches @samp{aa} and @samp{(bana)na\1bo\1} matches @samp{bananabanabobana}. Likewise, @samp{(.*)\1} matches any (newline-free if the syntax bit @code{RE_DOT_NEWLINE} isn't set) string that is composed of two identical halves; the @samp{(.*)} matches the first half and the @samp{\1} matches the second half. @item If the group matches more than once (as it might if followed by, e.g., a repetition operator), then the back reference matches the substring the group @emph{last} matched. For example, @samp{((a*)b)*\1\2} matches @samp{aabababa}; first @w{group 1} (the outer one) matches @samp{aab} and @w{group 2} (the inner one) matches @samp{aa}. Then @w{group 1} matches @samp{ab} and @w{group 2} matches @samp{a}. So, @samp{\1} matches @samp{ab} and @samp{\2} matches @samp{a}. @item If the group doesn't participate in a match, i.e., it is part of an alternative not taken or a repetition operator allows zero repetitions of it, then the back reference makes the whole match fail. For example, @samp{(one()|two())-and-(three\2|four\3)} matches @samp{one-and-three} and @samp{two-and-four}, but not @samp{one-and-four} or @samp{two-and-three}. For example, if the pattern matches @samp{one-and-}, then its @w{group 2} matches the empty string and its @w{group 3} doesn't participate in the match. So, if it then matches @samp{four}, then when it tries to back reference @w{group 3}---which it will attempt to do because @samp{\3} follows the @samp{four}---the match will fail because @w{group 3} didn't participate in the match. @end itemize You can use a back reference as an argument to a repetition operator. For example, @samp{(a(b))\2*} matches @samp{a} followed by two or more @samp{b}s. Similarly, @samp{(a(b))\2@{3@}} matches @samp{abbbb}. If there is no preceding @w{@var{digit}-th} subexpression, the regular expression is invalid. @node Anchoring Operators, , Back-reference Operator, Common Operators @section Anchoring Operators @cindex anchoring @cindex regexp anchoring These operators can constrain a pattern to match only at the beginning or end of the entire string or at the beginning or end of a line. @menu * Match-beginning-of-line Operator:: ^ * Match-end-of-line Operator:: $ @end menu @node Match-beginning-of-line Operator, Match-end-of-line Operator, , Anchoring Operators @subsection The Match-beginning-of-line Operator (@code{^}) @kindex ^ @cindex beginning-of-line operator @cindex anchors This operator can match the empty string either at the beginning of the string or after a newline character. Thus, it is said to @dfn{anchor} the pattern to the beginning of a line. In the cases following, @samp{^} represents this operator. (Otherwise, @samp{^} is ordinary.) @itemize @bullet @item It (the @samp{^}) is first in the pattern, as in @samp{^foo}. @cnindex RE_CONTEXT_INDEP_ANCHORS @r{(and @samp{^})} @item The syntax bit @code{RE_CONTEXT_INDEP_ANCHORS} is set, and it is outside a bracket expression. @cindex open-group operator and @samp{^} @cindex alternation operator and @samp{^} @item It follows an open-group or alternation operator, as in @samp{a\(^b\)} and @samp{a\|^b}. @xref{Grouping Operators}, and @ref{Alternation Operator}. @end itemize These rules imply that some valid patterns containing @samp{^} cannot be matched; for example, @samp{foo^bar} if @code{RE_CONTEXT_INDEP_ANCHORS} is set. @vindex not_bol @r{field in pattern buffer} If the @code{not_bol} field is set in the pattern buffer (@pxref{GNU Pattern Buffers}), then @samp{^} fails to match at the beginning of the string. @xref{POSIX Matching}, for when you might find this useful. @vindex newline_anchor @r{field in pattern buffer} If the @code{newline_anchor} field is set in the pattern buffer, then @samp{^} fails to match after a newline. This is useful when you do not regard the string to be matched as broken into lines. @node Match-end-of-line Operator, , Match-beginning-of-line Operator, Anchoring Operators @subsection The Match-end-of-line Operator (@code{$}) @kindex $ @cindex end-of-line operator @cindex anchors This operator can match the empty string either at the end of the string or before a newline character in the string. Thus, it is said to @dfn{anchor} the pattern to the end of a line. It is always represented by @samp{$}. For example, @samp{foo$} usually matches, e.g., @samp{foo} and, e.g., the first three characters of @samp{foo\nbar}. Its interaction with the syntax bits and pattern buffer fields is exactly the dual of @samp{^}'s; see the previous section. (That is, ``beginning'' becomes ``end'', ``next'' becomes ``previous'', and ``after'' becomes ``before''.) @node GNU Operators, GNU Emacs Operators, Common Operators, Top @chapter GNU Operators Following are operators that @sc{gnu} defines (and @sc{posix} doesn't). @menu * Word Operators:: * Buffer Operators:: @end menu @node Word Operators, Buffer Operators, , GNU Operators @section Word Operators The operators in this section require Regex to recognize parts of words. Regex uses a syntax table to determine whether or not a character is part of a word, i.e., whether or not it is @dfn{word-constituent}. @menu * Non-Emacs Syntax Tables:: * Match-word-boundary Operator:: \b * Match-within-word Operator:: \B * Match-beginning-of-word Operator:: \< * Match-end-of-word Operator:: \> * Match-word-constituent Operator:: \w * Match-non-word-constituent Operator:: \W @end menu @node Non-Emacs Syntax Tables, Match-word-boundary Operator, , Word Operators @subsection Non-Emacs Syntax Tables A @dfn{syntax table} is an array indexed by the characters in your character set. In the @sc{ascii} encoding, therefore, a syntax table has 256 elements. Regex always uses a @code{char *} variable @code{re_syntax_table} as its syntax table. In some cases, it initializes this variable and in others it expects you to initialize it. @itemize @bullet @item If Regex is compiled with the preprocessor symbols @code{emacs} and @code{SYNTAX_TABLE} both undefined, then Regex allocates @code{re_syntax_table} and initializes an element @var{i} either to @code{Sword} (which it defines) if @var{i} is a letter, number, or @samp{_}, or to zero if it's not. @item If Regex is compiled with @code{emacs} undefined but @code{SYNTAX_TABLE} defined, then Regex expects you to define a @code{char *} variable @code{re_syntax_table} to be a valid syntax table. @item @xref{Emacs Syntax Tables}, for what happens when Regex is compiled with the preprocessor symbol @code{emacs} defined. @end itemize @node Match-word-boundary Operator, Match-within-word Operator, Non-Emacs Syntax Tables, Word Operators @subsection The Match-word-boundary Operator (@code{\b}) @cindex @samp{\b} @cindex word boundaries, matching This operator (represented by @samp{\b}) matches the empty string at either the beginning or the end of a word. For example, @samp{\brat\b} matches the separate word @samp{rat}. @node Match-within-word Operator, Match-beginning-of-word Operator, Match-word-boundary Operator, Word Operators @subsection The Match-within-word Operator (@code{\B}) @cindex @samp{\B} This operator (represented by @samp{\B}) matches the empty string within a word. For example, @samp{c\Brat\Be} matches @samp{crate}, but @samp{dirty \Brat} doesn't match @samp{dirty rat}. @node Match-beginning-of-word Operator, Match-end-of-word Operator, Match-within-word Operator, Word Operators @subsection The Match-beginning-of-word Operator (@code{\<}) @cindex @samp{\<} This operator (represented by @samp{\<}) matches the empty string at the beginning of a word. @node Match-end-of-word Operator, Match-word-constituent Operator, Match-beginning-of-word Operator, Word Operators @subsection The Match-end-of-word Operator (@code{\>}) @cindex @samp{\>} This operator (represented by @samp{\>}) matches the empty string at the end of a word. @node Match-word-constituent Operator, Match-non-word-constituent Operator, Match-end-of-word Operator, Word Operators @subsection The Match-word-constituent Operator (@code{\w}) @cindex @samp{\w} This operator (represented by @samp{\w}) matches any word-constituent character. @node Match-non-word-constituent Operator, , Match-word-constituent Operator, Word Operators @subsection The Match-non-word-constituent Operator (@code{\W}) @cindex @samp{\W} This operator (represented by @samp{\W}) matches any character that is not word-constituent. @node Buffer Operators, , Word Operators, GNU Operators @section Buffer Operators Following are operators which work on buffers. In Emacs, a @dfn{buffer} is, naturally, an Emacs buffer. For other programs, Regex considers the entire string to be matched as the buffer. @menu * Match-beginning-of-buffer Operator:: \` * Match-end-of-buffer Operator:: \' @end menu @node Match-beginning-of-buffer Operator, Match-end-of-buffer Operator, , Buffer Operators @subsection The Match-beginning-of-buffer Operator (@code{\`}) @cindex @samp{\`} This operator (represented by @samp{\`}) matches the empty string at the beginning of the buffer. @node Match-end-of-buffer Operator, , Match-beginning-of-buffer Operator, Buffer Operators @subsection The Match-end-of-buffer Operator (@code{\'}) @cindex @samp{\'} This operator (represented by @samp{\'}) matches the empty string at the end of the buffer. @node GNU Emacs Operators, What Gets Matched?, GNU Operators, Top @chapter GNU Emacs Operators Following are operators that @sc{gnu} defines (and @sc{posix} doesn't) that you can use only when Regex is compiled with the preprocessor symbol @code{emacs} defined. @menu * Syntactic Class Operators:: @end menu @node Syntactic Class Operators, , , GNU Emacs Operators @section Syntactic Class Operators The operators in this section require Regex to recognize the syntactic classes of characters. Regex uses a syntax table to determine this. @menu * Emacs Syntax Tables:: * Match-syntactic-class Operator:: \sCLASS * Match-not-syntactic-class Operator:: \SCLASS @end menu @node Emacs Syntax Tables, Match-syntactic-class Operator, , Syntactic Class Operators @subsection Emacs Syntax Tables A @dfn{syntax table} is an array indexed by the characters in your character set. In the @sc{ascii} encoding, therefore, a syntax table has 256 elements. If Regex is compiled with the preprocessor symbol @code{emacs} defined, then Regex expects you to define and initialize the variable @code{re_syntax_table} to be an Emacs syntax table. Emacs' syntax tables are more complicated than Regex's own (@pxref{Non-Emacs Syntax Tables}). @xref{Syntax, , Syntax, emacs, The GNU Emacs User's Manual}, for a description of Emacs' syntax tables. @node Match-syntactic-class Operator, Match-not-syntactic-class Operator, Emacs Syntax Tables, Syntactic Class Operators @subsection The Match-syntactic-class Operator (@code{\s}@var{class}) @cindex @samp{\s} This operator matches any character whose syntactic class is represented by a specified character. @samp{\s@var{class}} represents this operator where @var{class} is the character representing the syntactic class you want. For example, @samp{w} represents the syntactic class of word-constituent characters, so @samp{\sw} matches any word-constituent character. @node Match-not-syntactic-class Operator, , Match-syntactic-class Operator, Syntactic Class Operators @subsection The Match-not-syntactic-class Operator (@code{\S}@var{class}) @cindex @samp{\S} This operator is similar to the match-syntactic-class operator except that it matches any character whose syntactic class is @emph{not} represented by the specified character. @samp{\S@var{class}} represents this operator. For example, @samp{w} represents the syntactic class of word-constituent characters, so @samp{\Sw} matches any character that is not word-constituent. @node What Gets Matched?, Programming with Regex, GNU Emacs Operators, Top @chapter What Gets Matched? Regex usually matches strings according to the ``leftmost longest'' rule; that is, it chooses the longest of the leftmost matches. This does not mean that for a regular expression containing subexpressions that it simply chooses the longest match for each subexpression, left to right; the overall match must also be the longest possible one. For example, @samp{(ac*)(c*d[ac]*)\1} matches @samp{acdacaaa}, not @samp{acdac}, as it would if it were to choose the longest match for the first subexpression. @node Programming with Regex, Copying, What Gets Matched?, Top @chapter Programming with Regex Here we describe how you use the Regex data structures and functions in C programs. Regex has three interfaces: one designed for @sc{gnu}, one compatible with @sc{posix} and one compatible with Berkeley @sc{unix}. @menu * GNU Regex Functions:: * POSIX Regex Functions:: * BSD Regex Functions:: @end menu @node GNU Regex Functions, POSIX Regex Functions, , Programming with Regex @section GNU Regex Functions If you're writing code that doesn't need to be compatible with either @sc{posix} or Berkeley @sc{unix}, you can use these functions. They provide more options than the other interfaces. @menu * GNU Pattern Buffers:: The re_pattern_buffer type. * GNU Regular Expression Compiling:: re_compile_pattern () * GNU Matching:: re_match () * GNU Searching:: re_search () * Matching/Searching with Split Data:: re_match_2 (), re_search_2 () * Searching with Fastmaps:: re_compile_fastmap () * GNU Translate Tables:: The `translate' field. * Using Registers:: The re_registers type and related fns. * Freeing GNU Pattern Buffers:: regfree () @end menu @node GNU Pattern Buffers, GNU Regular Expression Compiling, , GNU Regex Functions @subsection GNU Pattern Buffers @cindex pattern buffer, definition of @tindex re_pattern_buffer @r{definition} @tindex struct re_pattern_buffer @r{definition} To compile, match, or search for a given regular expression, you must supply a pattern buffer. A @dfn{pattern buffer} holds one compiled regular expression.@footnote{Regular expressions are also referred to as ``patterns,'' hence the name ``pattern buffer.''} You can have several different pattern buffers simultaneously, each holding a compiled pattern for a different regular expression. @file{regex.h} defines the pattern buffer @code{struct} as follows: @example [[[ pattern_buffer ]]] @end example @node GNU Regular Expression Compiling, GNU Matching, GNU Pattern Buffers, GNU Regex Functions @subsection GNU Regular Expression Compiling In @sc{gnu}, you can both match and search for a given regular expression. To do either, you must first compile it in a pattern buffer (@pxref{GNU Pattern Buffers}). @cindex syntax initialization @vindex re_syntax_options @r{initialization} Regular expressions match according to the syntax with which they were compiled; with @sc{gnu}, you indicate what syntax you want by setting the variable @code{re_syntax_options} (declared in @file{regex.h} and defined in @file{regex.c}) before calling the compiling function, @code{re_compile_pattern} (see below). @xref{Syntax Bits}, and @ref{Predefined Syntaxes}. You can change the value of @code{re_syntax_options} at any time. Usually, however, you set its value once and then never change it. @cindex pattern buffer initialization @code{re_compile_pattern} takes a pattern buffer as an argument. You must initialize the following fields: @table @code @item translate @r{initialization} @item translate @vindex translate @r{initialization} Initialize this to point to a translate table if you want one, or to zero if you don't. We explain translate tables in @ref{GNU Translate Tables}. @item fastmap @vindex fastmap @r{initialization} Initialize this to nonzero if you want a fastmap, or to zero if you don't. @item buffer @itemx allocated @vindex buffer @r{initialization} @vindex allocated @r{initialization} @findex malloc If you want @code{re_compile_pattern} to allocate memory for the compiled pattern, set both of these to zero. If you have an existing block of memory (allocated with @code{malloc}) you want Regex to use, set @code{buffer} to its address and @code{allocated} to its size (in bytes). @code{re_compile_pattern} uses @code{realloc} to extend the space for the compiled pattern as necessary. @end table To compile a pattern buffer, use: @findex re_compile_pattern @example char * re_compile_pattern (const char *@var{regex}, const int @var{regex_size}, struct re_pattern_buffer *@var{pattern_buffer}) @end example @noindent @var{regex} is the regular expression's address, @var{regex_size} is its length, and @var{pattern_buffer} is the pattern buffer's address. If @code{re_compile_pattern} successfully compiles the regular expression, it returns zero and sets @code{*@var{pattern_buffer}} to the compiled pattern. It sets the pattern buffer's fields as follows: @table @code @item buffer @vindex buffer @r{field, set by @code{re_compile_pattern}} to the compiled pattern. @item used @vindex used @r{field, set by @code{re_compile_pattern}} to the number of bytes the compiled pattern in @code{buffer} occupies. @item syntax @vindex syntax @r{field, set by @code{re_compile_pattern}} to the current value of @code{re_syntax_options}. @item re_nsub @vindex re_nsub @r{field, set by @code{re_compile_pattern}} to the number of subexpressions in @var{regex}. @item fastmap_accurate @vindex fastmap_accurate @r{field, set by @code{re_compile_pattern}} to zero on the theory that the pattern you're compiling is different than the one previously compiled into @code{buffer}; in that case (since you can't make a fastmap without a compiled pattern), @code{fastmap} would either contain an incompatible fastmap, or nothing at all. @c xx what else? @end table If @code{re_compile_pattern} can't compile @var{regex}, it returns an error string corresponding to one of the errors listed in @ref{POSIX Regular Expression Compiling}. @node GNU Matching, GNU Searching, GNU Regular Expression Compiling, GNU Regex Functions @subsection GNU Matching @cindex matching with GNU functions Matching the @sc{gnu} way means trying to match as much of a string as possible starting at a position within it you specify. Once you've compiled a pattern into a pattern buffer (@pxref{GNU Regular Expression Compiling}), you can ask the matcher to match that pattern against a string using: @findex re_match @example int re_match (struct re_pattern_buffer *@var{pattern_buffer}, const char *@var{string}, const int @var{size}, const int @var{start}, struct re_registers *@var{regs}) @end example @noindent @var{pattern_buffer} is the address of a pattern buffer containing a compiled pattern. @var{string} is the string you want to match; it can contain newline and null characters. @var{size} is the length of that string. @var{start} is the string index at which you want to begin matching; the first character of @var{string} is at index zero. @xref{Using Registers}, for a explanation of @var{regs}; you can safely pass zero. @code{re_match} matches the regular expression in @var{pattern_buffer} against the string @var{string} according to the syntax in @var{pattern_buffers}'s @code{syntax} field. (@xref{GNU Regular Expression Compiling}, for how to set it.) The function returns @math{-1} if the compiled pattern does not match any part of @var{string} and @math{-2} if an internal error happens; otherwise, it returns how many (possibly zero) characters of @var{string} the pattern matched. An example: suppose @var{pattern_buffer} points to a pattern buffer containing the compiled pattern for @samp{a*}, and @var{string} points to @samp{aaaaab} (whereupon @var{size} should be 6). Then if @var{start} is 2, @code{re_match} returns 3, i.e., @samp{a*} would have matched the last three @samp{a}s in @var{string}. If @var{start} is 0, @code{re_match} returns 5, i.e., @samp{a*} would have matched all the @samp{a}s in @var{string}. If @var{start} is either 5 or 6, it returns zero. If @var{start} is not between zero and @var{size}, then @code{re_match} returns @math{-1}. @node GNU Searching, Matching/Searching with Split Data, GNU Matching, GNU Regex Functions @subsection GNU Searching @cindex searching with GNU functions @dfn{Searching} means trying to match starting at successive positions within a string. The function @code{re_search} does this. Before calling @code{re_search}, you must compile your regular expression. @xref{GNU Regular Expression Compiling}. Here is the function declaration: @findex re_search @example int re_search (struct re_pattern_buffer *@var{pattern_buffer}, const char *@var{string}, const int @var{size}, const int @var{start}, const int @var{range}, struct re_registers *@var{regs}) @end example @noindent @vindex start @r{argument to @code{re_search}} @vindex range @r{argument to @code{re_search}} whose arguments are the same as those to @code{re_match} (@pxref{GNU Matching}) except that the two arguments @var{start} and @var{range} replace @code{re_match}'s argument @var{start}. If @var{range} is positive, then @code{re_search} attempts a match starting first at index @var{start}, then at @math{@var{start} + 1} if that fails, and so on, up to @math{@var{start} + @var{range}}; if @var{range} is negative, then it attempts a match starting first at index @var{start}, then at @math{@var{start} -1} if that fails, and so on. If @var{start} is not between zero and @var{size}, then @code{re_search} returns @math{-1}. When @var{range} is positive, @code{re_search} adjusts @var{range} so that @math{@var{start} + @var{range} - 1} is between zero and @var{size}, if necessary; that way it won't search outside of @var{string}. Similarly, when @var{range} is negative, @code{re_search} adjusts @var{range} so that @math{@var{start} + @var{range} + 1} is between zero and @var{size}, if necessary. If the @code{fastmap} field of @var{pattern_buffer} is zero, @code{re_search} matches starting at consecutive positions; otherwise, it uses @code{fastmap} to make the search more efficient. @xref{Searching with Fastmaps}. If no match is found, @code{re_search} returns @math{-1}. If a match is found, it returns the index where the match began. If an internal error happens, it returns @math{-2}. @node Matching/Searching with Split Data, Searching with Fastmaps, GNU Searching, GNU Regex Functions @subsection Matching and Searching with Split Data Using the functions @code{re_match_2} and @code{re_search_2}, you can match or search in data that is divided into two strings. The function: @findex re_match_2 @example int re_match_2 (struct re_pattern_buffer *@var{buffer}, const char *@var{string1}, const int @var{size1}, const char *@var{string2}, const int @var{size2}, const int @var{start}, struct re_registers *@var{regs}, const int @var{stop}) @end example @noindent is similar to @code{re_match} (@pxref{GNU Matching}) except that you pass @emph{two} data strings and sizes, and an index @var{stop} beyond which you don't want the matcher to try matching. As with @code{re_match}, if it succeeds, @code{re_match_2} returns how many characters of @var{string} it matched. Regard @var{string1} and @var{string2} as concatenated when you set the arguments @var{start} and @var{stop} and use the contents of @var{regs}; @code{re_match_2} never returns a value larger than @math{@var{size1} + @var{size2}}. The function: @findex re_search_2 @example int re_search_2 (struct re_pattern_buffer *@var{buffer}, const char *@var{string1}, const int @var{size1}, const char *@var{string2}, const int @var{size2}, const int @var{start}, const int @var{range}, struct re_registers *@var{regs}, const int @var{stop}) @end example @noindent is similarly related to @code{re_search}. @node Searching with Fastmaps, GNU Translate Tables, Matching/Searching with Split Data, GNU Regex Functions @subsection Searching with Fastmaps @cindex fastmaps If you're searching through a long string, you should use a fastmap. Without one, the searcher tries to match at consecutive positions in the string. Generally, most of the characters in the string could not start a match. It takes much longer to try matching at a given position in the string than it does to check in a table whether or not the character at that position could start a match. A @dfn{fastmap} is such a table. More specifically, a fastmap is an array indexed by the characters in your character set. Under the @sc{ascii} encoding, therefore, a fastmap has 256 elements. If you want the searcher to use a fastmap with a given pattern buffer, you must allocate the array and assign the array's address to the pattern buffer's @code{fastmap} field. You either can compile the fastmap yourself or have @code{re_search} do it for you; when @code{fastmap} is nonzero, it automatically compiles a fastmap the first time you search using a particular compiled pattern. To compile a fastmap yourself, use: @findex re_compile_fastmap @example int re_compile_fastmap (struct re_pattern_buffer *@var{pattern_buffer}) @end example @noindent @var{pattern_buffer} is the address of a pattern buffer. If the character @var{c} could start a match for the pattern, @code{re_compile_fastmap} makes @code{@var{pattern_buffer}->fastmap[@var{c}]} nonzero. It returns @math{0} if it can compile a fastmap and @math{-2} if there is an internal error. For example, if @samp{|} is the alternation operator and @var{pattern_buffer} holds the compiled pattern for @samp{a|b}, then @code{re_compile_fastmap} sets @code{fastmap['a']} and @code{fastmap['b']} (and no others). @code{re_search} uses a fastmap as it moves along in the string: it checks the string's characters until it finds one that's in the fastmap. Then it tries matching at that character. If the match fails, it repeats the process. So, by using a fastmap, @code{re_search} doesn't waste time trying to match at positions in the string that couldn't start a match. If you don't want @code{re_search} to use a fastmap, store zero in the @code{fastmap} field of the pattern buffer before calling @code{re_search}. Once you've initialized a pattern buffer's @code{fastmap} field, you need never do so again---even if you compile a new pattern in it---provided the way the field is set still reflects whether or not you want a fastmap. @code{re_search} will still either do nothing if @code{fastmap} is null or, if it isn't, compile a new fastmap for the new pattern. @node GNU Translate Tables, Using Registers, Searching with Fastmaps, GNU Regex Functions @subsection GNU Translate Tables If you set the @code{translate} field of a pattern buffer to a translate table, then the @sc{gnu} Regex functions to which you've passed that pattern buffer use it to apply a simple transformation to all the regular expression and string characters at which they look. A @dfn{translate table} is an array indexed by the characters in your character set. Under the @sc{ascii} encoding, therefore, a translate table has 256 elements. The array's elements are also characters in your character set. When the Regex functions see a character @var{c}, they use @code{translate[@var{c}]} in its place, with one exception: the character after a @samp{\} is not translated. (This ensures that, the operators, e.g., @samp{\B} and @samp{\b}, are always distinguishable.) For example, a table that maps all lowercase letters to the corresponding uppercase ones would cause the matcher to ignore differences in case.@footnote{A table that maps all uppercase letters to the corresponding lowercase ones would work just as well for this purpose.} Such a table would map all characters except lowercase letters to themselves, and lowercase letters to the corresponding uppercase ones. Under the @sc{ascii} encoding, here's how you could initialize such a table (we'll call it @code{case_fold}): @example for (i = 0; i < 256; i++) case_fold[i] = i; for (i = 'a'; i <= 'z'; i++) case_fold[i] = i - ('a' - 'A'); @end example You tell Regex to use a translate table on a given pattern buffer by assigning that table's address to the @code{translate} field of that buffer. If you don't want Regex to do any translation, put zero into this field. You'll get weird results if you change the table's contents anytime between compiling the pattern buffer, compiling its fastmap, and matching or searching with the pattern buffer. @node Using Registers, Freeing GNU Pattern Buffers, GNU Translate Tables, GNU Regex Functions @subsection Using Registers A group in a regular expression can match a (posssibly empty) substring of the string that regular expression as a whole matched. The matcher remembers the beginning and end of the substring matched by each group. To find out what they matched, pass a nonzero @var{regs} argument to a @sc{gnu} matching or searching function (@pxref{GNU Matching} and @ref{GNU Searching}), i.e., the address of a structure of this type, as defined in @file{regex.h}: @c We don't bother to include this directly from regex.h, @c since it changes so rarely. @example @tindex re_registers @vindex num_regs @r{in @code{struct re_registers}} @vindex start @r{in @code{struct re_registers}} @vindex end @r{in @code{struct re_registers}} struct re_registers @{ unsigned num_regs; regoff_t *start; regoff_t *end; @}; @end example Except for (possibly) the @var{num_regs}'th element (see below), the @var{i}th element of the @code{start} and @code{end} arrays records information about the @var{i}th group in the pattern. (They're declared as C pointers, but this is only because not all C compilers accept zero-length arrays; conceptually, it is simplest to think of them as arrays.) The @code{start} and @code{end} arrays are allocated in various ways, depending on the value of the @code{regs_allocated} @vindex regs_allocated field in the pattern buffer passed to the matcher. The simplest and perhaps most useful is to let the matcher (re)allocate enough space to record information for all the groups in the regular expression. If @code{regs_allocated} is @code{REGS_UNALLOCATED}, @vindex REGS_UNALLOCATED the matcher allocates @math{1 + @var{re_nsub}} (another field in the pattern buffer; @pxref{GNU Pattern Buffers}). The extra element is set to @math{-1}, and sets @code{regs_allocated} to @code{REGS_REALLOCATE}. @vindex REGS_REALLOCATE Then on subsequent calls with the same pattern buffer and @var{regs} arguments, the matcher reallocates more space if necessary. It would perhaps be more logical to make the @code{regs_allocated} field part of the @code{re_registers} structure, instead of part of the pattern buffer. But in that case the caller would be forced to initialize the structure before passing it. Much existing code doesn't do this initialization, and it's arguably better to avoid it anyway. @code{re_compile_pattern} sets @code{regs_allocated} to @code{REGS_UNALLOCATED}, so if you use the GNU regular expression functions, you get this behavior by default. xx document re_set_registers @sc{posix}, on the other hand, requires a different interface: the caller is supposed to pass in a fixed-length array which the matcher fills. Therefore, if @code{regs_allocated} is @code{REGS_FIXED} @vindex REGS_FIXED the matcher simply fills that array. The following examples illustrate the information recorded in the @code{re_registers} structure. (In all of them, @samp{(} represents the open-group and @samp{)} the close-group operator. The first character in the string @var{string} is at index 0.) @c xx i'm not sure this is all true anymore. @itemize @bullet @item If the regular expression has an @w{@var{i}-th} group not contained within another group that matches a substring of @var{string}, then the function sets @code{@w{@var{regs}->}start[@var{i}]} to the index in @var{string} where the substring matched by the @w{@var{i}-th} group begins, and @code{@w{@var{regs}->}end[@var{i}]} to the index just beyond that substring's end. The function sets @code{@w{@var{regs}->}start[0]} and @code{@w{@var{regs}->}end[0]} to analogous information about the entire pattern. For example, when you match @samp{((a)(b))} against @samp{ab}, you get: @itemize @item 0 in @code{@w{@var{regs}->}start[0]} and 2 in @code{@w{@var{regs}->}end[0]} @item 0 in @code{@w{@var{regs}->}start[1]} and 2 in @code{@w{@var{regs}->}end[1]} @item 0 in @code{@w{@var{regs}->}start[2]} and 1 in @code{@w{@var{regs}->}end[2]} @item 1 in @code{@w{@var{regs}->}start[3]} and 2 in @code{@w{@var{regs}->}end[3]} @end itemize @item If a group matches more than once (as it might if followed by, e.g., a repetition operator), then the function reports the information about what the group @emph{last} matched. For example, when you match the pattern @samp{(a)*} against the string @samp{aa}, you get: @itemize @item 0 in @code{@w{@var{regs}->}start[0]} and 2 in @code{@w{@var{regs}->}end[0]} @item 1 in @code{@w{@var{regs}->}start[1]} and 2 in @code{@w{@var{regs}->}end[1]} @end itemize @item If the @w{@var{i}-th} group does not participate in a successful match, e.g., it is an alternative not taken or a repetition operator allows zero repetitions of it, then the function sets @code{@w{@var{regs}->}start[@var{i}]} and @code{@w{@var{regs}->}end[@var{i}]} to @math{-1}. For example, when you match the pattern @samp{(a)*b} against the string @samp{b}, you get: @itemize @item 0 in @code{@w{@var{regs}->}start[0]} and 1 in @code{@w{@var{regs}->}end[0]} @item @math{-1} in @code{@w{@var{regs}->}start[1]} and @math{-1} in @code{@w{@var{regs}->}end[1]} @end itemize @item If the @w{@var{i}-th} group matches a zero-length string, then the function sets @code{@w{@var{regs}->}start[@var{i}]} and @code{@w{@var{regs}->}end[@var{i}]} to the index just beyond that zero-length string. For example, when you match the pattern @samp{(a*)b} against the string @samp{b}, you get: @itemize @item 0 in @code{@w{@var{regs}->}start[0]} and 1 in @code{@w{@var{regs}->}end[0]} @item 0 in @code{@w{@var{regs}->}start[1]} and 0 in @code{@w{@var{regs}->}end[1]} @end itemize @ignore The function sets @code{@w{@var{regs}->}start[0]} and @code{@w{@var{regs}->}end[0]} to analogous information about the entire pattern. For example, when you match the pattern @samp{(a*)} against the empty string, you get: @itemize @item 0 in @code{@w{@var{regs}->}start[0]} and 0 in @code{@w{@var{regs}->}end[0]} @item 0 in @code{@w{@var{regs}->}start[1]} and 0 in @code{@w{@var{regs}->}end[1]} @end itemize @end ignore @item If an @w{@var{i}-th} group contains a @w{@var{j}-th} group in turn not contained within any other group within group @var{i} and the function reports a match of the @w{@var{i}-th} group, then it records in @code{@w{@var{regs}->}start[@var{j}]} and @code{@w{@var{regs}->}end[@var{j}]} the last match (if it matched) of the @w{@var{j}-th} group. For example, when you match the pattern @samp{((a*)b)*} against the string @samp{abb}, @w{group 2} last matches the empty string, so you get what it previously matched: @itemize @item 0 in @code{@w{@var{regs}->}start[0]} and 3 in @code{@w{@var{regs}->}end[0]} @item 2 in @code{@w{@var{regs}->}start[1]} and 3 in @code{@w{@var{regs}->}end[1]} @item 2 in @code{@w{@var{regs}->}start[2]} and 2 in @code{@w{@var{regs}->}end[2]} @end itemize When you match the pattern @samp{((a)*b)*} against the string @samp{abb}, @w{group 2} doesn't participate in the last match, so you get: @itemize @item 0 in @code{@w{@var{regs}->}start[0]} and 3 in @code{@w{@var{regs}->}end[0]} @item 2 in @code{@w{@var{regs}->}start[1]} and 3 in @code{@w{@var{regs}->}end[1]} @item 0 in @code{@w{@var{regs}->}start[2]} and 1 in @code{@w{@var{regs}->}end[2]} @end itemize @item If an @w{@var{i}-th} group contains a @w{@var{j}-th} group in turn not contained within any other group within group @var{i} and the function sets @code{@w{@var{regs}->}start[@var{i}]} and @code{@w{@var{regs}->}end[@var{i}]} to @math{-1}, then it also sets @code{@w{@var{regs}->}start[@var{j}]} and @code{@w{@var{regs}->}end[@var{j}]} to @math{-1}. For example, when you match the pattern @samp{((a)*b)*c} against the string @samp{c}, you get: @itemize @item 0 in @code{@w{@var{regs}->}start[0]} and 1 in @code{@w{@var{regs}->}end[0]} @item @math{-1} in @code{@w{@var{regs}->}start[1]} and @math{-1} in @code{@w{@var{regs}->}end[1]} @item @math{-1} in @code{@w{@var{regs}->}start[2]} and @math{-1} in @code{@w{@var{regs}->}end[2]} @end itemize @end itemize @node Freeing GNU Pattern Buffers, , Using Registers, GNU Regex Functions @subsection Freeing GNU Pattern Buffers To free any allocated fields of a pattern buffer, you can use the @sc{posix} function described in @ref{Freeing POSIX Pattern Buffers}, since the type @code{regex_t}---the type for @sc{posix} pattern buffers---is equivalent to the type @code{re_pattern_buffer}. After freeing a pattern buffer, you need to again compile a regular expression in it (@pxref{GNU Regular Expression Compiling}) before passing it to a matching or searching function. @node POSIX Regex Functions, BSD Regex Functions, GNU Regex Functions, Programming with Regex @section POSIX Regex Functions If you're writing code that has to be @sc{posix} compatible, you'll need to use these functions. Their interfaces are as specified by @sc{posix}, draft 1003.2/D11.2. @menu * POSIX Pattern Buffers:: The regex_t type. * POSIX Regular Expression Compiling:: regcomp () * POSIX Matching:: regexec () * Reporting Errors:: regerror () * Using Byte Offsets:: The regmatch_t type. * Freeing POSIX Pattern Buffers:: regfree () @end menu @node POSIX Pattern Buffers, POSIX Regular Expression Compiling, , POSIX Regex Functions @subsection POSIX Pattern Buffers To compile or match a given regular expression the @sc{posix} way, you must supply a pattern buffer exactly the way you do for @sc{gnu} (@pxref{GNU Pattern Buffers}). @sc{posix} pattern buffers have type @code{regex_t}, which is equivalent to the @sc{gnu} pattern buffer type @code{re_pattern_buffer}. @node POSIX Regular Expression Compiling, POSIX Matching, POSIX Pattern Buffers, POSIX Regex Functions @subsection POSIX Regular Expression Compiling With @sc{posix}, you can only search for a given regular expression; you can't match it. To do this, you must first compile it in a pattern buffer, using @code{regcomp}. @ignore Before calling @code{regcomp}, you must initialize this pattern buffer as you do for @sc{gnu} (@pxref{GNU Regular Expression Compiling}). See below, however, for how to choose a syntax with which to compile. @end ignore To compile a pattern buffer, use: @findex regcomp @example int regcomp (regex_t *@var{preg}, const char *@var{regex}, int @var{cflags}) @end example @noindent @var{preg} is the initialized pattern buffer's address, @var{regex} is the regular expression's address, and @var{cflags} is the compilation flags, which Regex considers as a collection of bits. Here are the valid bits, as defined in @file{regex.h}: @table @code @item REG_EXTENDED @vindex REG_EXTENDED says to use @sc{posix} Extended Regular Expression syntax; if this isn't set, then says to use @sc{posix} Basic Regular Expression syntax. @code{regcomp} sets @var{preg}'s @code{syntax} field accordingly. @item REG_ICASE @vindex REG_ICASE @cindex ignoring case says to ignore case; @code{regcomp} sets @var{preg}'s @code{translate} field to a translate table which ignores case, replacing anything you've put there before. @item REG_NOSUB @vindex REG_NOSUB says to set @var{preg}'s @code{no_sub} field; @pxref{POSIX Matching}, for what this means. @item REG_NEWLINE @vindex REG_NEWLINE says that a: @itemize @bullet @item match-any-character operator (@pxref{Match-any-character Operator}) doesn't match a newline. @item nonmatching list not containing a newline (@pxref{List Operators}) matches a newline. @item match-beginning-of-line operator (@pxref{Match-beginning-of-line Operator}) matches the empty string immediately after a newline, regardless of how @code{REG_NOTBOL} is set (@pxref{POSIX Matching}, for an explanation of @code{REG_NOTBOL}). @item match-end-of-line operator (@pxref{Match-beginning-of-line Operator}) matches the empty string immediately before a newline, regardless of how @code{REG_NOTEOL} is set (@pxref{POSIX Matching}, for an explanation of @code{REG_NOTEOL}). @end itemize @end table If @code{regcomp} successfully compiles the regular expression, it returns zero and sets @code{*@var{pattern_buffer}} to the compiled pattern. Except for @code{syntax} (which it sets as explained above), it also sets the same fields the same way as does the @sc{gnu} compiling function (@pxref{GNU Regular Expression Compiling}). If @code{regcomp} can't compile the regular expression, it returns one of the error codes listed here. (Except when noted differently, the syntax of in all examples below is basic regular expression syntax.) @table @code @comment repetitions @item REG_BADRPT For example, the consecutive repetition operators @samp{**} in @samp{a**} are invalid. As another example, if the syntax is extended regular expression syntax, then the repetition operator @samp{*} with nothing on which to operate in @samp{*} is invalid. @item REG_BADBR For example, the @var{count} @samp{-1} in @samp{a\@{-1} is invalid. @item REG_EBRACE For example, @samp{a\@{1} is missing a close-interval operator. @comment lists @item REG_EBRACK For example, @samp{[a} is missing a close-list operator. @item REG_ERANGE For example, the range ending point @samp{z} that collates lower than does its starting point @samp{a} in @samp{[z-a]} is invalid. Also, the range with the character class @samp{[:alpha:]} as its starting point in @samp{[[:alpha:]-|]}. @item REG_ECTYPE For example, the character class name @samp{foo} in @samp{[[:foo:]} is invalid. @comment groups @item REG_EPAREN For example, @samp{a\)} is missing an open-group operator and @samp{\(a} is missing a close-group operator. @item REG_ESUBREG For example, the back reference @samp{\2} that refers to a nonexistent subexpression in @samp{\(a\)\2} is invalid. @comment unfinished business @item REG_EEND Returned when a regular expression causes no other more specific error. @item REG_EESCAPE For example, the trailing backslash @samp{\} in @samp{a\} is invalid, as is the one in @samp{\}. @comment kitchen sink @item REG_BADPAT For example, in the extended regular expression syntax, the empty group @samp{()} in @samp{a()b} is invalid. @comment internal @item REG_ESIZE Returned when a regular expression needs a pattern buffer larger than 65536 bytes. @item REG_ESPACE Returned when a regular expression makes Regex to run out of memory. @end table @node POSIX Matching, Reporting Errors, POSIX Regular Expression Compiling, POSIX Regex Functions @subsection POSIX Matching Matching the @sc{posix} way means trying to match a null-terminated string starting at its first character. Once you've compiled a pattern into a pattern buffer (@pxref{POSIX Regular Expression Compiling}), you can ask the matcher to match that pattern against a string using: @findex regexec @example int regexec (const regex_t *@var{preg}, const char *@var{string}, size_t @var{nmatch}, regmatch_t @var{pmatch}[], int @var{eflags}) @end example @noindent @var{preg} is the address of a pattern buffer for a compiled pattern. @var{string} is the string you want to match. @xref{Using Byte Offsets}, for an explanation of @var{pmatch}. If you pass zero for @var{nmatch} or you compiled @var{preg} with the compilation flag @code{REG_NOSUB} set, then @code{regexec} will ignore @var{pmatch}; otherwise, you must allocate it to have at least @var{nmatch} elements. @code{regexec} will record @var{nmatch} byte offsets in @var{pmatch}, and set to @math{-1} any unused elements up to @math{@var{pmatch}@code{[@var{nmatch}]} - 1}. @var{eflags} specifies @dfn{execution flags}---namely, the two bits @code{REG_NOTBOL} and @code{REG_NOTEOL} (defined in @file{regex.h}). If you set @code{REG_NOTBOL}, then the match-beginning-of-line operator (@pxref{Match-beginning-of-line Operator}) always fails to match. This lets you match against pieces of a line, as you would need to if, say, searching for repeated instances of a given pattern in a line; it would work correctly for patterns both with and without match-beginning-of-line operators. @code{REG_NOTEOL} works analogously for the match-end-of-line operator (@pxref{Match-end-of-line Operator}); it exists for symmetry. @code{regexec} tries to find a match for @var{preg} in @var{string} according to the syntax in @var{preg}'s @code{syntax} field. (@xref{POSIX Regular Expression Compiling}, for how to set it.) The function returns zero if the compiled pattern matches @var{string} and @code{REG_NOMATCH} (defined in @file{regex.h}) if it doesn't. @node Reporting Errors, Using Byte Offsets, POSIX Matching, POSIX Regex Functions @subsection Reporting Errors If either @code{regcomp} or @code{regexec} fail, they return a nonzero error code, the possibilities for which are defined in @file{regex.h}. @xref{POSIX Regular Expression Compiling}, and @ref{POSIX Matching}, for what these codes mean. To get an error string corresponding to these codes, you can use: @findex regerror @example size_t regerror (int @var{errcode}, const regex_t *@var{preg}, char *@var{errbuf}, size_t @var{errbuf_size}) @end example @noindent @var{errcode} is an error code, @var{preg} is the address of the pattern buffer which provoked the error, @var{errbuf} is the error buffer, and @var{errbuf_size} is @var{errbuf}'s size. @code{regerror} returns the size in bytes of the error string corresponding to @var{errcode} (including its terminating null). If @var{errbuf} and @var{errbuf_size} are nonzero, it also returns in @var{errbuf} the first @math{@var{errbuf_size} - 1} characters of the error string, followed by a null. @var{errbuf_size} must be a nonnegative number less than or equal to the size in bytes of @var{errbuf}. You can call @code{regerror} with a null @var{errbuf} and a zero @var{errbuf_size} to determine how large @var{errbuf} need be to accommodate @code{regerror}'s error string. @node Using Byte Offsets, Freeing POSIX Pattern Buffers, Reporting Errors, POSIX Regex Functions @subsection Using Byte Offsets In @sc{posix}, variables of type @code{regmatch_t} hold analogous information, but are not identical to, @sc{gnu}'s registers (@pxref{Using Registers}). To get information about registers in @sc{posix}, pass to @code{regexec} a nonzero @var{pmatch} of type @code{regmatch_t}, i.e., the address of a structure of this type, defined in @file{regex.h}: @tindex regmatch_t @example typedef struct @{ regoff_t rm_so; regoff_t rm_eo; @} regmatch_t; @end example When reading in @ref{Using Registers}, about how the matching function stores the information into the registers, substitute @var{pmatch} for @var{regs}, @code{@w{@var{pmatch}[@var{i}]->}rm_so} for @code{@w{@var{regs}->}start[@var{i}]} and @code{@w{@var{pmatch}[@var{i}]->}rm_eo} for @code{@w{@var{regs}->}end[@var{i}]}. @node Freeing POSIX Pattern Buffers, , Using Byte Offsets, POSIX Regex Functions @subsection Freeing POSIX Pattern Buffers To free any allocated fields of a pattern buffer, use: @findex regfree @example void regfree (regex_t *@var{preg}) @end example @noindent @var{preg} is the pattern buffer whose allocated fields you want freed. @code{regfree} also sets @var{preg}'s @code{allocated} and @code{used} fields to zero. After freeing a pattern buffer, you need to again compile a regular expression in it (@pxref{POSIX Regular Expression Compiling}) before passing it to the matching function (@pxref{POSIX Matching}). @node BSD Regex Functions, , POSIX Regex Functions, Programming with Regex @section BSD Regex Functions If you're writing code that has to be Berkeley @sc{unix} compatible, you'll need to use these functions whose interfaces are the same as those in Berkeley @sc{unix}. @menu * BSD Regular Expression Compiling:: re_comp () * BSD Searching:: re_exec () @end menu @node BSD Regular Expression Compiling, BSD Searching, , BSD Regex Functions @subsection BSD Regular Expression Compiling With Berkeley @sc{unix}, you can only search for a given regular expression; you can't match one. To search for it, you must first compile it. Before you compile it, you must indicate the regular expression syntax you want it compiled according to by setting the variable @code{re_syntax_options} (declared in @file{regex.h} to some syntax (@pxref{Regular Expression Syntax}). To compile a regular expression use: @findex re_comp @example char * re_comp (char *@var{regex}) @end example @noindent @var{regex} is the address of a null-terminated regular expression. @code{re_comp} uses an internal pattern buffer, so you can use only the most recently compiled pattern buffer. This means that if you want to use a given regular expression that you've already compiled---but it isn't the latest one you've compiled---you'll have to recompile it. If you call @code{re_comp} with the null string (@emph{not} the empty string) as the argument, it doesn't change the contents of the pattern buffer. If @code{re_comp} successfully compiles the regular expression, it returns zero. If it can't compile the regular expression, it returns an error string. @code{re_comp}'s error messages are identical to those of @code{re_compile_pattern} (@pxref{GNU Regular Expression Compiling}). @node BSD Searching, , BSD Regular Expression Compiling, BSD Regex Functions @subsection BSD Searching Searching the Berkeley @sc{unix} way means searching in a string starting at its first character and trying successive positions within it to find a match. Once you've compiled a pattern using @code{re_comp} (@pxref{BSD Regular Expression Compiling}), you can ask Regex to search for that pattern in a string using: @findex re_exec @example int re_exec (char *@var{string}) @end example @noindent @var{string} is the address of the null-terminated string in which you want to search. @code{re_exec} returns either 1 for success or 0 for failure. It automatically uses a @sc{gnu} fastmap (@pxref{Searching with Fastmaps}). @node Copying, Index, Programming with Regex, Top @appendix GNU GENERAL PUBLIC LICENSE @center Version 2, June 1991 @display Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @end display @unnumberedsec Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software---to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. @iftex @unnumberedsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION @end iftex @ifinfo @center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION @end ifinfo @enumerate @item This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The ``Program'', below, refers to any such program or work, and a ``work based on the Program'' means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term ``modification''.) Each licensee is addressed as ``you''. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. @item You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. @item You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: @enumerate a @item You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. @item You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. @item If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) @end enumerate These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. @item You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: @enumerate a @item Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, @item Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, @item Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) @end enumerate The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. @item You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. @item You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. @item Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. @item If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. @item If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. @item The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and ``any later version'', you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. @item If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. @iftex @heading NO WARRANTY @end iftex @ifinfo @center NO WARRANTY @end ifinfo @item BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM ``AS IS'' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. @item IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. @end enumerate @iftex @heading END OF TERMS AND CONDITIONS @end iftex @ifinfo @center END OF TERMS AND CONDITIONS @end ifinfo @page @unnumberedsec Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the ``copyright'' line and a pointer to where the full notice is found. @smallexample @var{one line to give the program's name and a brief idea of what it does.} Copyright (C) 19@var{yy} @var{name of author} 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 2 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, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. @end smallexample Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: @smallexample Gnomovision version 69, Copyright (C) 19@var{yy} @var{name of author} Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. @end smallexample The hypothetical commands @samp{show w} and @samp{show c} should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than @samp{show w} and @samp{show c}; they could even be mouse-clicks or menu items---whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a ``copyright disclaimer'' for the program, if necessary. Here is a sample; alter the names: @example Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. @var{signature of Ty Coon}, 1 April 1989 Ty Coon, President of Vice @end example This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. @node Index, , Copying, Top @unnumbered Index @printindex cp @contents @bye lyskom-server-2.1.2/src/libraries/regex/test/0000777000015100472110000000000007723710335014742 5lyskom-server-2.1.2/src/libraries/regex/test/ChangeLog0000664000015100472110000000524306701512275016434 1999-04-03 Per Cederqvist * Makefile.am: New file. Sun Oct 10 12:35:44 1993 Per Cederqvist (ceder@lysator.liu.se) * Makefile.in (Makefile): Removed the target, since it was broken in the LysKOM environment. Thu Mar 25 21:23:43 1993 Jim Blandy (jimb@totoro.cs.oberlin.edu) * debugmalloc.c: #include , and remove declaration of memcpy. Sun Dec 13 20:59:32 1992 Jim Blandy (jimb@totoro.cs.oberlin.edu) * tregress.c (test_regress): Add regression test for matching "[a-a]" against "a" with the upcase translation map. * iregex.c (print_regs): Don't print a newline after the register contents. (main): Instead, write out newlines here after printing match and search results; this way, we get a newline whether or not the pattern matched. Fri Dec 11 03:30:50 1992 Jim Blandy (jimb@totoro.cs.oberlin.edu) * tregress.c (test_regress): Add new test to catch bug fixed by change to regex.c today. * Makefile.in (dregex.o): Depend on `../regex.[ch]', not `regex.[ch]'. Sun Nov 15 07:51:40 1992 Karl Berry (karl@cs.umb.edu) * debugmalloc.c (memcpy): Declare; also, include . * psx-interf.c (fill_pmatch): Declare offsets as `regoff_t' instead of `off_t'. Thu Nov 12 11:29:58 1992 Karl Berry (karl@cs.umb.edu) * iregex.c (main): Remove unused variable `c'; initialize the char array in C code; only call print_regs if the match and search succeeded. (strlen): Declare. * tregress.c (test_regress): Bug from enami. Tue Nov 10 10:36:53 1992 Karl Berry (karl@cs.umb.edu) * tregress.c (test_regress): Remove Emacs 19 diff bug from rms, as it was never the right thing to test anyway, and the test itself had bugs in it. Mon Nov 9 10:09:40 1992 Karl Berry (karl@cs.umb.edu) * tregress.c (test_regress): Bug from meyering. Thu Sep 24 10:48:34 1992 Karl Berry (karl@cs.umb.edu) * Makefile.in: avoid $< (except in implicit rule). Sat Sep 19 15:38:29 1992 Karl Berry (karl@hayley) * Makefile.in (TAGS): include regex.c and regex.h. Wed Sep 16 09:29:27 1992 Karl Berry (karl@hayley) * xmalloc.c (xmalloc): use char *, not void *, as some compilers bomb out on the latter. * Makefile.in (LOADLIBES): use LIBS instead, as that what's Autoconf wants to define. * other.c: remove tests for ^/$ around newlines. Tue Sep 15 11:01:15 1992 Karl Berry (karl@hayley) * fileregex.c (main): call re_search_2 instead of re_search. * Makefile.in (regex.o): make target dregex.o, so VPATH doesn't find ../regex.o. Sun Sep 13 06:50:03 1992 Karl Berry (karl@hayley) * Created. lyskom-server-2.1.2/src/libraries/regex/test/Makefile.am0000664000015100472110000000266007717413243016721 # $Id: Makefile.am,v 1.2 2003/08/16 11:29:04 ceder Exp $ # Copyright (C) 1998 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Distribute the files that are present in the regex distribution. # Nothing here gets installed et c when part of the lyskomd distribution. EXTRA_DIST = .cvsignore ChangeLog alloca.c bsd-interf.c \ debugmalloc.c emacsmalloc.c fileregex.c g++malloc.c \ getpagesize.h iregex.c main.c malloc-test.c other.c \ printchar.c psx-basic.c psx-extend.c psx-generic.c \ psx-group.c psx-interf.c psx-interv.c regexcpp.sed \ syntax.skel test.c test.h tregress.c upcase.c xmalloc.c lyskom-server-2.1.2/src/libraries/regex/test/Makefile.in0000664000015100472110000002105107723707426016733 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # $Id: Makefile.am,v 1.2 2003/08/16 11:29:04 ceder Exp $ # Copyright (C) 1998 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../../../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEBUG_CALLS = @DEBUG_CALLS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EFENCE = @EFENCE@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FLEX = @FLEX@ HAVE_PYTHON_FALSE = @HAVE_PYTHON_FALSE@ HAVE_PYTHON_TRUE = @HAVE_PYTHON_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSURE = @INSURE@ LANGUAGE_SUFFIX = @LANGUAGE_SUFFIX@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ SED = @SED@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRACED_ALLOCATIONS = @TRACED_ALLOCATIONS@ U = @U@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ YACC = @YACC@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ # Distribute the files that are present in the regex distribution. # Nothing here gets installed et c when part of the lyskomd distribution. EXTRA_DIST = .cvsignore ChangeLog alloca.c bsd-interf.c \ debugmalloc.c emacsmalloc.c fileregex.c g++malloc.c \ getpagesize.h iregex.c main.c malloc-test.c other.c \ printchar.c psx-basic.c psx-extend.c psx-generic.c \ psx-group.c psx-interf.c psx-interv.c regexcpp.sed \ syntax.skel test.c test.h tregress.c upcase.c xmalloc.c subdir = src/libraries/regex/test ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = DIST_SOURCES = DIST_COMMON = ChangeLog Makefile.am Makefile.in all: all-am .SUFFIXES: $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/libraries/regex/test/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) uninstall-info-am: tags: TAGS TAGS: ctags: CTAGS CTAGS: DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = ../../../.. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am info info-am install \ install-am install-data install-data-am install-exec \ install-exec-am install-info install-info-am install-man \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \ uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/src/libraries/regex/test/.cvsignore0000664000015100472110000000002506701512237016651 Makefile Makefile.in lyskom-server-2.1.2/src/libraries/regex/test/alloca.c0000664000015100472110000001231705314452716016263 /* alloca -- (mostly) portable public-domain implementation -- D A Gwyn last edit: 86/05/30 rms include config.h, since on VMS it renames some symbols. Use xmalloc instead of malloc. This implementation of the PWB library alloca() function, which is used to allocate space off the run-time stack so that it is automatically reclaimed upon procedure exit, was inspired by discussions with J. Q. Johnson of Cornell. It should work under any C implementation that uses an actual procedure stack (as opposed to a linked list of frames). There are some preprocessor constants that can be defined when compiling for your specific system, for improved efficiency; however, the defaults should be okay. The general concept of this implementation is to keep track of all alloca()-allocated blocks, and reclaim any that are found to be deeper in the stack than the current invocation. This heuristic does not reclaim storage as soon as it becomes invalid, but it will do so eventually. As a special case, alloca(0) reclaims storage without allocating any. It is a good idea to use alloca(0) in your main control loop, etc. to force garbage collection. */ #ifndef lint static char SCCSid[] = "@(#)alloca.c 1.1"; /* for the "what" utility */ #endif #ifdef emacs #include "config.h" #ifdef static /* actually, only want this if static is defined as "" -- this is for usg, in which emacs must undefine static in order to make unexec workable */ #ifndef STACK_DIRECTION you lose -- must know STACK_DIRECTION at compile-time #endif /* STACK_DIRECTION undefined */ #endif /* static */ #endif /* emacs */ #ifndef alloca /* If compiling with GCC, this file's not needed. */ #ifdef __STDC__ typedef void *pointer; /* generic pointer type */ #else typedef char *pointer; /* generic pointer type */ #endif #define NULL 0 /* null pointer constant */ extern void free(); extern pointer xmalloc(); /* Define STACK_DIRECTION if you know the direction of stack growth for your system; otherwise it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #ifndef STACK_DIRECTION #define STACK_DIRECTION 0 /* direction unknown */ #endif #if STACK_DIRECTION != 0 #define STACK_DIR STACK_DIRECTION /* known at compile-time */ #else /* STACK_DIRECTION == 0; need run-time code */ static int stack_dir; /* 1 or -1 once known */ #define STACK_DIR stack_dir static void find_stack_direction (/* void */) { static char *addr = NULL; /* address of first `dummy', once known */ auto char dummy; /* to get stack address */ if (addr == NULL) { /* initial entry */ addr = &dummy; find_stack_direction (); /* recurse once */ } else /* second entry */ if (&dummy > addr) stack_dir = 1; /* stack grew upward */ else stack_dir = -1; /* stack grew downward */ } #endif /* STACK_DIRECTION == 0 */ /* An "alloca header" is used to: (a) chain together all alloca()ed blocks; (b) keep track of stack depth. It is very important that sizeof(header) agree with malloc() alignment chunk size. The following default should work okay. */ #ifndef ALIGN_SIZE #define ALIGN_SIZE sizeof(double) #endif typedef union hdr { char align[ALIGN_SIZE]; /* to force sizeof(header) */ struct { union hdr *next; /* for chaining headers */ char *deep; /* for stack depth measure */ } h; } header; /* alloca( size ) returns a pointer to at least `size' bytes of storage which will be automatically reclaimed upon exit from the procedure that called alloca(). Originally, this space was supposed to be taken from the current stack frame of the caller, but that method cannot be made to work for some implementations of C, for example under Gould's UTX/32. */ static header *last_alloca_header = NULL; /* -> last alloca header */ pointer alloca (size) /* returns pointer to storage */ unsigned size; /* # bytes to allocate */ { auto char probe; /* probes stack depth: */ register char *depth = &probe; #if STACK_DIRECTION == 0 if (STACK_DIR == 0) /* unknown growth direction */ find_stack_direction (); #endif /* Reclaim garbage, defined as all alloca()ed storage that was allocated from deeper in the stack than currently. */ { register header *hp; /* traverses linked list */ for (hp = last_alloca_header; hp != NULL;) if ((STACK_DIR > 0 && hp->h.deep > depth) || (STACK_DIR < 0 && hp->h.deep < depth)) { register header *np = hp->h.next; free ((pointer) hp); /* collect garbage */ hp = np; /* -> next header */ } else break; /* rest are not deeper */ last_alloca_header = hp; /* -> last valid storage */ } if (size == 0) return NULL; /* no allocation required */ /* Allocate combined header + user data storage. */ { register pointer new = xmalloc (sizeof (header) + size); /* address of header */ ((header *)new)->h.next = last_alloca_header; ((header *)new)->h.deep = depth; last_alloca_header = (header *)new; /* User storage begins just after header. */ return (pointer)((char *)new + sizeof(header)); } } #endif /* no alloca */ lyskom-server-2.1.2/src/libraries/regex/test/bsd-interf.c0000664000015100472110000000147005314452716017063 /* bsd-interf.c: test BSD interface. */ #ifndef _POSIX_SOURCE /* whole file */ #include "test.h" void test_berk_search (pattern, string) const char *pattern; char *string; { const char *return_value = re_comp (pattern); if (return_value != 0) { printf ("This didn't compile: `%s'.\n", pattern); printf (" The error message was: `%s'.\n", return_value); } else if (test_should_match && re_exec (string) != strlen (string)) { printf ("Should have matched but didn't:\n"); printf (" The pattern was: %s.\n", pattern); if (string) printf (" The string was: `%s'.'n", string); else printf (" The string was empty.\n"); } } void test_bsd_interface () { test_berk_search ("a", "ab"); } #endif /* _POSIX_SOURCE */ lyskom-server-2.1.2/src/libraries/regex/test/debugmalloc.c0000664000015100472110000001334705533104542017304 /* debugmalloc.c: a malloc for debugging purposes. */ #include #include #include static unsigned trace = 0; #define TRACE(s) if (trace) fprintf (stderr, "%s", s) #define TRACE1(s, e1) if (trace) fprintf (stderr, s, e1) #define TRACE2(s, e1, e2) if (trace) fprintf (stderr, s, e1, e2) #define TRACE3(s, e1, e2, e3) if (trace) fprintf (stderr, s, e1, e2, e3) #define TRACE4(s, e1, e2, e3, e4) \ if (trace) fprintf (stderr, s, e1, e2, e3, e4) typedef char *address; /* Wrap our calls to sbrk. */ address xsbrk (incr) int incr; { extern char *sbrk (); address ret = sbrk (incr); if (ret == (address) -1) { perror ("sbrk"); /* Actually, we should return NULL, not quit. */ abort (); } return ret; } typedef struct chunk_struct { /* This is the size (in bytes) that has actually been actually allocated, not the size that the user requested. */ unsigned alloc_size; /* This is the size the user requested. */ unsigned user_size; /* Points to the next block in one of the lists. */ struct chunk_struct *next; /* Now comes the user's memory. */ address user_mem; /* After the user's memory is a constant. */ } *chunk; #define MALLOC_OVERHEAD 16 /* We might play around with the `user_size' field, but the amount of memory that is actually available in the chunk is always the size allocated minus the overhead. */ #define USER_ALLOC(c) ((c)->alloc_size - MALLOC_OVERHEAD) /* Given a pointer to a malloc-allocated block, the beginning of the chunk should always be MALLOC_OVERHEAD - 4 bytes back, since the only overhead after the user memory is the constant. */ chunk mem_to_chunk (mem) address mem; { return (chunk) (mem - (MALLOC_OVERHEAD - 4)); } /* The other direction is even easier, since the user's memory starts at the `user_mem' member in the chunk. */ address chunk_to_mem (c) chunk c; { return (address) &(c->user_mem); } /* We keep both all the allocated chunks and all the free chunks on lists. Since we put the next pointers in the chunk structure, we don't need a separate chunk_list structure. */ chunk alloc_list = NULL, free_list = NULL; /* We always append the new chunk at the beginning of the list. */ void chunk_insert (chunk_list, new_c) chunk *chunk_list; chunk new_c; { chunk c = *chunk_list; /* old beginning of list */ TRACE3 (" Inserting 0x%x at the beginning of 0x%x, before 0x%x.\n", new_c, chunk_list, c); *chunk_list = new_c; new_c->next = c; } /* Thus, removing an element means we have to search until we find it. Have to delete before we insert, since insertion changes the next pointer, which we need to put it on the other list. */ void chunk_delete (chunk_list, dead_c) chunk *chunk_list; chunk dead_c; { chunk c = *chunk_list; chunk prev_c = NULL; TRACE2 (" Deleting 0x%x from 0x%x:", dead_c, chunk_list); while (c != dead_c && c != NULL) { TRACE1 (" 0x%x", c); prev_c = c; c = c->next; } if (c == NULL) { fprintf (stderr, "Chunk at 0x%x not found on list.\n", dead_c); abort (); } if (prev_c == NULL) { TRACE1 (".\n Setting head to 0x%x.\n", c->next); *chunk_list = c->next; } else { TRACE2 (".\n Linking next(0x%x) to 0x%x.\n", prev_c, c->next); prev_c->next = c->next; } } /* See if a list is hunky-dory. */ void validate_list (chunk_list) chunk *chunk_list; { chunk c; TRACE1 (" Validating list at 0x%x:", chunk_list); for (c = *chunk_list; c != NULL; c = c->next) { assert (c->user_size < c->alloc_size); assert (memcmp (chunk_to_mem (c) + c->user_size, "Karl", 4)); TRACE2 (" 0x%x/%d", c, c->user_size); } TRACE (".\n"); } /* See if we have a free chunk of a given size. We'll take the first one that is big enough. */ chunk free_list_available (needed) unsigned needed; { chunk c; TRACE1 (" Checking free list for %d bytes:", needed); if (free_list == NULL) { return NULL; } c = free_list; while (c != NULL && USER_ALLOC (c) < needed) { TRACE2 (" 0x%x/%d", c, USER_ALLOC (c)); c = c->next; } TRACE1 ("\n Returning 0x%x.\n", c); return c; } address malloc (n) unsigned n; { address new_mem; chunk c; TRACE1 ("Mallocing %d bytes.\n", n); validate_list (&free_list); validate_list (&alloc_list); c = free_list_available (n); if (c == NULL) { /* Nothing suitable on free list. Allocate a new chunk. */ TRACE (" not on free list.\n"); c = (chunk) xsbrk (n + MALLOC_OVERHEAD); c->alloc_size = n + MALLOC_OVERHEAD; } else { /* Found something on free list. Don't split it, just use as is. */ TRACE (" found on free list.\n"); chunk_delete (&free_list, c); } /* If we took this from the free list, then the user size might be different now, and consequently the constant at the end might be in the wrong place. */ c->user_size = n; new_mem = chunk_to_mem (c); memcpy (new_mem + n, "Karl", 4); chunk_insert (&alloc_list, c); TRACE2 ("Malloc returning 0x%x (chunk 0x%x).\n", new_mem, c); return new_mem; } address realloc (mem, n) address mem; unsigned n; { void free (); chunk c = mem_to_chunk (mem); address new_mem; TRACE3 ("Reallocing %d bytes at 0x%x (chunk 0x%x).\n", n, mem, c); new_mem = malloc (n); memcpy (new_mem, mem, c->user_size); free (mem); return new_mem; } void free (mem) address mem; { chunk c = mem_to_chunk (mem); TRACE2 ("Freeing memory at 0x%x (chunk at 0x%x).\n", mem, c); validate_list (&free_list); validate_list (&alloc_list); chunk_delete (&alloc_list, c); chunk_insert (&free_list, c); } lyskom-server-2.1.2/src/libraries/regex/test/emacsmalloc.c0000664000015100472110000005160305314452717017312 /* dynamic memory allocation for GNU. Copyright (C) 1985, 1987 Free Software Foundation, Inc. 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 1, 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, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. In other words, you are welcome to use, share and improve this program. You are forbidden to forbid anyone else to use, share and improve what you give them. Help stamp out software-hoarding! */ /* * @(#)nmalloc.c 1 (Caltech) 2/21/82 * * U of M Modified: 20 Jun 1983 ACT: strange hacks for Emacs * * Nov 1983, Mike@BRL, Added support for 4.1C/4.2 BSD. * * This is a very fast storage allocator. It allocates blocks of a small * number of different sizes, and keeps free lists of each size. Blocks * that don't exactly fit are passed up to the next larger size. In this * implementation, the available sizes are (2^n)-4 (or -16) bytes long. * This is designed for use in a program that uses vast quantities of * memory, but bombs when it runs out. To make it a little better, it * warns the user when he starts to get near the end. * * June 84, ACT: modified rcheck code to check the range given to malloc, * rather than the range determined by the 2-power used. * * Jan 85, RMS: calls malloc_warning to issue warning on nearly full. * No longer Emacs-specific; can serve as all-purpose malloc for GNU. * You should call malloc_init to reinitialize after loading dumped Emacs. * Call malloc_stats to get info on memory stats if MSTATS turned on. * realloc knows how to return same block given, just changing its size, * if the power of 2 is correct. */ /* * nextf[i] is the pointer to the next free block of size 2^(i+3). The * smallest allocatable block is 8 bytes. The overhead information will * go in the first int of the block, and the returned pointer will point * to the second. * #ifdef MSTATS * nmalloc[i] is the difference between the number of mallocs and frees * for a given block size. #endif MSTATS */ #ifdef emacs /* config.h specifies which kind of system this is. */ #include "config.h" #include #else /* Determine which kind of system this is. */ #include #include #include #define bcopy(s,d,n) memcpy ((d), (s), (n)) #define bcmp(s1,s2,n) memcmp ((s1), (s2), (n)) #define bzero(s,n) memset ((s), 0, (n)) #ifndef SIGTSTP #ifndef VMS #ifndef USG #define USG #endif #endif /* not VMS */ #else /* SIGTSTP */ #ifdef SIGIO #define BSD4_2 #endif /* SIGIO */ #endif /* SIGTSTP */ #endif /* not emacs */ /* Define getpagesize () if the system does not. */ #include "getpagesize.h" #ifdef BSD #ifdef BSD4_1 #include /* warn the user when near the end */ #else /* if 4.2 or newer */ #include #include #endif /* if 4.2 or newer */ #endif #ifdef VMS #include "vlimit.h" #endif extern char *start_of_data (); #ifdef BSD #ifndef DATA_SEG_BITS #define start_of_data() &etext #endif #endif #ifndef emacs #define start_of_data() &etext #endif #define ISALLOC ((char) 0xf7) /* magic byte that implies allocation */ #define ISFREE ((char) 0x54) /* magic byte that implies free block */ /* this is for error checking only */ #define ISMEMALIGN ((char) 0xd6) /* Stored before the value returned by memalign, with the rest of the word being the distance to the true beginning of the block. */ extern char etext; /* These two are for user programs to look at, when they are interested. */ unsigned int malloc_sbrk_used; /* amount of data space used now */ unsigned int malloc_sbrk_unused; /* amount more we can have */ /* start of data space; can be changed by calling init_malloc */ static char *data_space_start; #ifdef MSTATS static int nmalloc[30]; static int nmal, nfre; #endif /* MSTATS */ /* If range checking is not turned on, all we have is a flag indicating whether memory is allocated, an index in nextf[], and a size field; to realloc() memory we copy either size bytes or 1<<(index+3) bytes depending on whether the former can hold the exact size (given the value of 'index'). If range checking is on, we always need to know how much space is allocated, so the 'size' field is never used. */ struct mhead { char mh_alloc; /* ISALLOC or ISFREE */ char mh_index; /* index in nextf[] */ /* Remainder are valid only when block is allocated */ unsigned short mh_size; /* size, if < 0x10000 */ #ifdef rcheck unsigned mh_nbytes; /* number of bytes allocated */ int mh_magic4; /* should be == MAGIC4 */ #endif /* rcheck */ }; /* Access free-list pointer of a block. It is stored at block + 4. This is not a field in the mhead structure because we want sizeof (struct mhead) to describe the overhead for when the block is in use, and we do not want the free-list pointer to count in that. */ #define CHAIN(a) \ (*(struct mhead **) (sizeof (char *) + (char *) (a))) #ifdef rcheck /* To implement range checking, we write magic values in at the beginning and end of each allocated block, and make sure they are undisturbed whenever a free or a realloc occurs. */ /* Written in each of the 4 bytes following the block's real space */ #define MAGIC1 0x55 /* Written in the 4 bytes before the block's real space */ #define MAGIC4 0x55555555 #define ASSERT(p) if (!(p)) botch("p"); else #define EXTRA 4 /* 4 bytes extra for MAGIC1s */ #else #define ASSERT(p) if (!(p)) abort (); else #define EXTRA 0 #endif /* rcheck */ /* nextf[i] is free list of blocks of size 2**(i + 3) */ static struct mhead *nextf[30]; /* busy[i] is nonzero while allocation of block size i is in progress. */ static char busy[30]; /* Number of bytes of writable memory we can expect to be able to get */ static unsigned int lim_data; /* Level number of warnings already issued. 0 -- no warnings issued. 1 -- 75% warning already issued. 2 -- 85% warning already issued. */ static int warnlevel; /* Function to call to issue a warning; 0 means don't issue them. */ static void (*warnfunction) (); /* nonzero once initial bunch of free blocks made */ static int gotpool; char *_malloc_base; static void getpool (); /* Cause reinitialization based on job parameters; also declare where the end of pure storage is. */ void malloc_init (start, warnfun) char *start; void (*warnfun) (); { if (start) data_space_start = start; lim_data = 0; warnlevel = 0; warnfunction = warnfun; } /* Return the maximum size to which MEM can be realloc'd without actually requiring copying. */ int malloc_usable_size (mem) char *mem; { struct mhead *p = (struct mhead *) (mem - ((sizeof (struct mhead) + 7) & ~7)); int blocksize = 8 << p->mh_index; return blocksize - sizeof (struct mhead) - EXTRA; } static void morecore (nu) /* ask system for more memory */ register int nu; /* size index to get more of */ { char *sbrk (); register char *cp; register int nblks; register unsigned int siz; int oldmask; #ifdef BSD #ifndef BSD4_1 int newmask = -1; /* Blocking these signals interferes with debugging, at least on BSD on the HP 9000/300. */ #ifdef SIGTRAP newmask &= ~(1 << SIGTRAP); #endif #ifdef SIGILL newmask &= ~(1 << SIGILL); #endif #ifdef SIGTSTP newmask &= ~(1 << SIGTSTP); #endif #ifdef SIGSTOP newmask &= ~(1 << SIGSTOP); #endif oldmask = sigsetmask (newmask); #endif #endif if (!data_space_start) { data_space_start = start_of_data (); } if (lim_data == 0) get_lim_data (); /* On initial startup, get two blocks of each size up to 1k bytes */ if (!gotpool) { getpool (); getpool (); gotpool = 1; } /* Find current end of memory and issue warning if getting near max */ #ifndef VMS /* Maximum virtual memory on VMS is difficult to calculate since it * depends on several dynmacially changing things. Also, alignment * isn't that important. That is why much of the code here is ifdef'ed * out for VMS systems. */ cp = sbrk (0); siz = cp - data_space_start; if (warnfunction) switch (warnlevel) { case 0: if (siz > (lim_data / 4) * 3) { warnlevel++; (*warnfunction) ("Warning: past 75% of memory limit"); } break; case 1: if (siz > (lim_data / 20) * 17) { warnlevel++; (*warnfunction) ("Warning: past 85% of memory limit"); } break; case 2: if (siz > (lim_data / 20) * 19) { warnlevel++; (*warnfunction) ("Warning: past 95% of memory limit"); } break; } if ((int) cp & 0x3ff) /* land on 1K boundaries */ sbrk (1024 - ((int) cp & 0x3ff)); #endif /* not VMS */ /* Take at least 2k, and figure out how many blocks of the desired size we're about to get */ nblks = 1; if ((siz = nu) < 8) nblks = 1 << ((siz = 8) - nu); if ((cp = sbrk (1 << (siz + 3))) == (char *) -1) { #ifdef BSD #ifndef BSD4_1 sigsetmask (oldmask); #endif #endif return; /* no more room! */ } malloc_sbrk_used = siz; malloc_sbrk_unused = lim_data - siz; #ifndef VMS if ((int) cp & 7) { /* shouldn't happen, but just in case */ cp = (char *) (((int) cp + 8) & ~7); nblks--; } #endif /* not VMS */ /* save new header and link the nblks blocks together */ nextf[nu] = (struct mhead *) cp; siz = 1 << (nu + 3); while (1) { ((struct mhead *) cp) -> mh_alloc = ISFREE; ((struct mhead *) cp) -> mh_index = nu; if (--nblks <= 0) break; CHAIN ((struct mhead *) cp) = (struct mhead *) (cp + siz); cp += siz; } CHAIN ((struct mhead *) cp) = 0; #ifdef BSD #ifndef BSD4_1 sigsetmask (oldmask); #endif #endif } static void getpool () { register int nu; char * sbrk (); register char *cp = sbrk (0); if ((int) cp & 0x3ff) /* land on 1K boundaries */ sbrk (1024 - ((int) cp & 0x3ff)); /* Record address of start of space allocated by malloc. */ if (_malloc_base == 0) _malloc_base = cp; /* Get 2k of storage */ cp = sbrk (04000); if (cp == (char *) -1) return; /* Divide it into an initial 8-word block plus one block of size 2**nu for nu = 3 ... 10. */ CHAIN (cp) = nextf[0]; nextf[0] = (struct mhead *) cp; ((struct mhead *) cp) -> mh_alloc = ISFREE; ((struct mhead *) cp) -> mh_index = 0; cp += 8; for (nu = 0; nu < 7; nu++) { CHAIN (cp) = nextf[nu]; nextf[nu] = (struct mhead *) cp; ((struct mhead *) cp) -> mh_alloc = ISFREE; ((struct mhead *) cp) -> mh_index = nu; cp += 8 << nu; } } char * malloc (n) /* get a block */ unsigned n; { register struct mhead *p; register unsigned int nbytes; register int nunits = 0; /* Figure out how many bytes are required, rounding up to the nearest multiple of 8, then figure out which nestf[] area to use. Both the beginning of the header and the beginning of the block should be on an eight byte boundary. */ nbytes = (n + ((sizeof *p + 7) & ~7) + EXTRA + 7) & ~7; { register unsigned int shiftr = (nbytes - 1) >> 2; while (shiftr >>= 1) nunits++; } /* In case this is reentrant use of malloc from signal handler, pick a block size that no other malloc level is currently trying to allocate. That's the easiest harmless way not to interfere with the other level of execution. */ while (busy[nunits]) nunits++; busy[nunits] = 1; /* If there are no blocks of the appropriate size, go get some */ /* COULD SPLIT UP A LARGER BLOCK HERE ... ACT */ if (nextf[nunits] == 0) morecore (nunits); /* Get one block off the list, and set the new list head */ if ((p = nextf[nunits]) == 0) { busy[nunits] = 0; return 0; } nextf[nunits] = CHAIN (p); busy[nunits] = 0; /* Check for free block clobbered */ /* If not for this check, we would gobble a clobbered free chain ptr */ /* and bomb out on the NEXT allocate of this size block */ if (p -> mh_alloc != ISFREE || p -> mh_index != nunits) #ifdef rcheck botch ("block on free list clobbered"); #else /* not rcheck */ abort (); #endif /* not rcheck */ /* Fill in the info, and if range checking, set up the magic numbers */ p -> mh_alloc = ISALLOC; #ifdef rcheck p -> mh_nbytes = n; p -> mh_magic4 = MAGIC4; { /* Get the location n after the beginning of the user's space. */ register char *m = (char *) p + ((sizeof *p + 7) & ~7) + n; *m++ = MAGIC1, *m++ = MAGIC1, *m++ = MAGIC1, *m = MAGIC1; } #else /* not rcheck */ p -> mh_size = n; #endif /* not rcheck */ #ifdef MSTATS nmalloc[nunits]++; nmal++; #endif /* MSTATS */ return (char *) p + ((sizeof *p + 7) & ~7); } free (mem) char *mem; { register struct mhead *p; { register char *ap = mem; if (ap == 0) return; p = (struct mhead *) (ap - ((sizeof *p + 7) & ~7)); if (p -> mh_alloc == ISMEMALIGN) { ap -= p->mh_size; p = (struct mhead *) (ap - ((sizeof *p + 7) & ~7)); } #ifndef rcheck if (p -> mh_alloc != ISALLOC) abort (); #else rcheck if (p -> mh_alloc != ISALLOC) { if (p -> mh_alloc == ISFREE) botch ("free: Called with already freed block argument\n"); else botch ("free: Called with bad argument\n"); } ASSERT (p -> mh_magic4 == MAGIC4); ap += p -> mh_nbytes; ASSERT (*ap++ == MAGIC1); ASSERT (*ap++ == MAGIC1); ASSERT (*ap++ == MAGIC1); ASSERT (*ap == MAGIC1); #endif /* rcheck */ } { register int nunits = p -> mh_index; ASSERT (nunits <= 29); p -> mh_alloc = ISFREE; /* Protect against signal handlers calling malloc. */ busy[nunits] = 1; /* Put this block on the free list. */ CHAIN (p) = nextf[nunits]; nextf[nunits] = p; busy[nunits] = 0; #ifdef MSTATS nmalloc[nunits]--; nfre++; #endif /* MSTATS */ } } char * realloc (mem, n) char *mem; register unsigned n; { register struct mhead *p; register unsigned int tocopy; register unsigned int nbytes; register int nunits; if (mem == 0) return malloc (n); p = (struct mhead *) (mem - ((sizeof *p + 7) & ~7)); nunits = p -> mh_index; ASSERT (p -> mh_alloc == ISALLOC); #ifdef rcheck ASSERT (p -> mh_magic4 == MAGIC4); { register char *m = mem + (tocopy = p -> mh_nbytes); ASSERT (*m++ == MAGIC1); ASSERT (*m++ == MAGIC1); ASSERT (*m++ == MAGIC1); ASSERT (*m == MAGIC1); } #else /* not rcheck */ if (p -> mh_index >= 13) tocopy = (1 << (p -> mh_index + 3)) - ((sizeof *p + 7) & ~7); else tocopy = p -> mh_size; #endif /* not rcheck */ /* See if desired size rounds to same power of 2 as actual size. */ nbytes = (n + ((sizeof *p + 7) & ~7) + EXTRA + 7) & ~7; /* If ok, use the same block, just marking its size as changed. */ if (nbytes > (4 << nunits) && nbytes <= (8 << nunits)) { #ifdef rcheck register char *m = mem + tocopy; *m++ = 0; *m++ = 0; *m++ = 0; *m++ = 0; p-> mh_nbytes = n; m = mem + n; *m++ = MAGIC1; *m++ = MAGIC1; *m++ = MAGIC1; *m++ = MAGIC1; #else /* not rcheck */ p -> mh_size = n; #endif /* not rcheck */ return mem; } if (n < tocopy) tocopy = n; { register char *new; if ((new = malloc (n)) == 0) return 0; bcopy (mem, new, tocopy); free (mem); return new; } } /* This is in case something linked with Emacs calls calloc. */ char * calloc (num, size) unsigned num, size; { register char *mem; num *= size; mem = malloc (num); if (mem != 0) bzero (mem, num); return mem; } #ifndef VMS char * memalign (alignment, size) unsigned alignment, size; { register char *ptr = malloc (size + alignment); register char *aligned; register struct mhead *p; if (ptr == 0) return 0; /* If entire block has the desired alignment, just accept it. */ if (((int) ptr & (alignment - 1)) == 0) return ptr; /* Otherwise, get address of byte in the block that has that alignment. */ aligned = (char *) (((int) ptr + alignment - 1) & -alignment); /* Store a suitable indication of how to free the block, so that free can find the true beginning of it. */ p = (struct mhead *) (aligned - ((7 + sizeof (struct mhead)) & ~7)); p -> mh_size = aligned - ptr; p -> mh_alloc = ISMEMALIGN; return aligned; } #ifndef HPUX /* This runs into trouble with getpagesize on HPUX. Patching out seems cleaner than the ugly fix needed. */ char * valloc (size) { return memalign (getpagesize (), size); } #endif /* not HPUX */ #endif /* not VMS */ #ifdef MSTATS /* Return statistics describing allocation of blocks of size 2**n. */ struct mstats_value { int blocksize; int nfree; int nused; }; struct mstats_value malloc_stats (size) int size; { struct mstats_value v; register int i; register struct mhead *p; v.nfree = 0; if (size < 0 || size >= 30) { v.blocksize = 0; v.nused = 0; return v; } v.blocksize = 1 << (size + 3); v.nused = nmalloc[size]; for (p = nextf[size]; p; p = CHAIN (p)) v.nfree++; return v; } int malloc_mem_used () { int i; int size_used; size_used = 0; for (i = 0; i < 30; i++) { int allocation_size = 1 << (i + 3); struct mhead *p; size_used += nmalloc[i] * allocation_size; } return size_used; } int malloc_mem_free () { int i; int size_unused; size_unused = 0; for (i = 0; i < 30; i++) { int allocation_size = 1 << (i + 3); struct mhead *p; for (p = nextf[i]; p ; p = CHAIN (p)) size_unused += allocation_size; } return size_unused; } #endif /* MSTATS */ /* * This function returns the total number of bytes that the process * will be allowed to allocate via the sbrk(2) system call. On * BSD systems this is the total space allocatable to stack and * data. On USG systems this is the data space only. */ #ifdef USG get_lim_data () { extern long ulimit (); #ifdef ULIMIT_BREAK_VALUE lim_data = ULIMIT_BREAK_VALUE; #else lim_data = ulimit (3, 0); #endif lim_data -= (long) data_space_start; } #else /* not USG */ #if defined (BSD4_1) || defined (VMS) get_lim_data () { lim_data = vlimit (LIM_DATA, -1); } #else /* not BSD4_1 and not VMS */ get_lim_data () { struct rlimit XXrlimit; getrlimit (RLIMIT_DATA, &XXrlimit); #ifdef RLIM_INFINITY lim_data = XXrlimit.rlim_cur & RLIM_INFINITY; /* soft limit */ #else lim_data = XXrlimit.rlim_cur; /* soft limit */ #endif } #endif /* not BSD4_1 and not VMS */ #endif /* not USG */ #ifdef VMS /* There is a problem when dumping and restoring things on VMS. Calls * to SBRK don't necessarily result in contiguous allocation. Dumping * doesn't work when it isn't. Therefore, we make the initial * allocation contiguous by allocating a big chunk, and do SBRKs from * there. Once Emacs has dumped there is no reason to continue * contiguous allocation, malloc doesn't depend on it. * * There is a further problem of using brk and sbrk while using VMS C * run time library routines malloc, calloc, etc. The documentation * says that this is a no-no, although I'm not sure why this would be * a problem. In any case, we remove the necessity to call brk and * sbrk, by calling calloc (to assure zero filled data) rather than * sbrk. * * VMS_ALLOCATION_SIZE is the size of the allocation array. This * should be larger than the malloc size before dumping. Making this * too large will result in the startup procedure slowing down since * it will require more space and time to map it in. * * The value for VMS_ALLOCATION_SIZE in the following define was determined * by running emacs linked (and a large allocation) with the debugger and * looking to see how much storage was used. The allocation was 201 pages, * so I rounded it up to a power of two. */ #ifndef VMS_ALLOCATION_SIZE #define VMS_ALLOCATION_SIZE (512*256) #endif /* Use VMS RTL definitions */ #undef sbrk #undef brk #undef malloc int vms_out_initial = 0; char vms_initial_buffer[VMS_ALLOCATION_SIZE]; static char *vms_current_brk = &vms_initial_buffer; static char *vms_end_brk = &vms_initial_buffer[VMS_ALLOCATION_SIZE-1]; #include char * sys_sbrk (incr) int incr; { char *sbrk(), *temp, *ptr; if (vms_out_initial) { /* out of initial allocation... */ if (!(temp = malloc (incr))) temp = (char *) -1; } else { /* otherwise, go out of our area */ ptr = vms_current_brk + incr; /* new current_brk */ if (ptr <= vms_end_brk) { temp = vms_current_brk; vms_current_brk = ptr; } else { vms_out_initial = 1; /* mark as out of initial allocation */ if (!(temp = malloc (incr))) temp = (char *) -1; } } return temp; } #endif /* VMS */ lyskom-server-2.1.2/src/libraries/regex/test/fileregex.c0000664000015100472110000000317605533104552017000 #include #include #include "regex.h" #define BYTEWIDTH 8 /* Sorry, but this is just a test program. */ #define LINE_MAX 500 int main (argc, argv) int argc; char *argv[]; { FILE *f; char *filename; char pat[500]; /* Sorry for that maximum size, too. */ char line[LINE_MAX]; struct re_pattern_buffer buf; char fastmap[(1 << BYTEWIDTH)]; const char *compile_ret; unsigned lineno = 1; unsigned nfound = 0; /* Actually, it might be useful to allow the data file to be standard input, and to specify the pattern on the command line. */ if (argc != 2) { fprintf (stderr, "Usage: %s .\n", argv[0]); exit (1); } filename = argv[1]; f = fopen (filename, "r"); if (f == NULL) perror (filename); buf.allocated = 0; buf.buffer = NULL; buf.fastmap = fastmap; printf ("Pattern = ", pat); gets (pat); if (feof (stdin)) { putchar ('\n'); exit (0); } compile_ret = re_compile_pattern (pat, strlen (pat), &buf); if (compile_ret != NULL) { fprintf (stderr, "%s: %s\n", pat, compile_ret); exit (1); } while (fgets (line, LINE_MAX, f) != NULL) { size_t len = strlen (line); struct re_registers regs; int search_ret = re_search_2 (&buf, NULL, 0, line, len, 0, len, ®s, len); if (search_ret == -2) { fprintf (stderr, "%s:%d: re_search failed.\n", filename, lineno); exit (1); } nfound += search_ret != -1; lineno++; } printf ("Matches found: %u (out of %u lines).\n", nfound, lineno - 1); return 0; } lyskom-server-2.1.2/src/libraries/regex/test/g++malloc.c0000664000015100472110000010363305314452720016571 #define inline /* Copyright (C) 1989 Free Software Foundation written by Doug Lea (dl@oswego.edu) This file is part of GNU CC. GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. No author or distributor accepts responsibility to anyone for the consequences of using it or for whether it serves any particular purpose or works at all, unless he says so in writing. Refer to the GNU CC General Public License for full details. Everyone is granted permission to copy, modify and redistribute GNU CC, but only under the conditions described in the GNU CC General Public License. A copy of this license is supposed to have been given to you along with GNU CC so you can know your rights and responsibilities. It should be in a file named COPYING. Among other things, the copyright notice and this notice must be preserved on all copies. */ #ifndef NO_LIBGXX_MALLOC /* ignore whole file otherwise */ /* compile with -DMALLOC_STATS to collect statistics */ /* collecting statistics slows down malloc by at least 15% */ #ifdef MALLOC_STATS #define UPDATE_STATS(ARGS) {ARGS;} #else #define UPDATE_STATS(ARGS) #endif /* History Tue Jan 16 04:54:27 1990 Doug Lea (dl at g.oswego.edu) version 1 released in libg++ Sun Jan 21 05:52:47 1990 Doug Lea (dl at g.oswego.edu) bins are now own struct for, sanity. new victim search strategy: scan up and consolidate. Both faster and less fragmentation. refined when to scan bins for consolidation, via consollink, etc. realloc: always try to expand chunk, avoiding some fragmentation. changed a few inlines into macros hardwired SBRK_UNIT to 4096 for uniformity across systems Tue Mar 20 14:18:23 1990 Doug Lea (dl at g.oswego.edu) calloc and cfree now correctly parameterized. Sun Apr 1 10:00:48 1990 Doug Lea (dl at g.oswego.edu) added memalign and valloc. Sun Jun 24 05:46:48 1990 Doug Lea (dl at g.oswego.edu) #include gepagesize.h only ifndef sun cache pagesize after first call Wed Jul 25 08:35:19 1990 Doug Lea (dl at g.oswego.edu) No longer rely on a `designated victim': 1. It sometimes caused splits of large chunks when smaller ones would do, leading to bad worst-case fragmentation. 2. Scanning through the av array fast anyway, so the overhead isn't worth it. To compensate, several other minor changes: 1. Unusable chunks are checked for consolidation during searches inside bins, better distributing chunks across bins. 2. Chunks are returned when found in malloc_find_space, rather than finishing cleaning everything up, to avoid wasted iterations due to (1). */ /* A version of malloc/free/realloc tuned for C++ applications. Here's what you probably want to know first: In various tests, this appears to be about as fast as, and usually substantially less memory-wasteful than BSD/GNUemacs malloc. Generally, it is slower (by perhaps 20%) than bsd-style malloc only when bsd malloc would waste a great deal of space in fragmented blocks, which this malloc recovers; or when, by chance or design, nearly all requests are near the bsd malloc power-of-2 allocation bin boundaries, and as many chunks are used as are allocated. It uses more space than bsd malloc only when, again by chance or design, only bsdmalloc bin-sized requests are malloced, or when little dynamic space is malloced, since this malloc may grab larger chunks from the system at a time than bsd. In other words, this malloc seems generally superior to bsd except perhaps for programs that are specially tuned to deal with bsdmalloc's characteristics. But even here, the performance differences are slight. This malloc, like any other, is a compromised design. Chunks of memory are maintained using a `boundary tag' method as described in e.g., Knuth or Standish. This means that the size of the chunk is stored both in the front of the chunk and at the end. This makes consolidating fragmented chunks into bigger chunks very fast. The size field is also used to hold bits representing whether a chunk is free or in use. Malloced chunks have space overhead of 8 bytes: The preceding and trailing size fields. When they are freed, the list pointer fields are also needed. Available chunks are kept in doubly linked lists. The lists are maintained in an array of bins using a power-of-two method, except that instead of 32 bins (one for each 1 << i), there are 128: each power of two is split in quarters. The use of very fine bin sizes closely approximates the use of one bin per actually used size, without necessitating the overhead of locating such bins. It is especially desirable in common C++ applications where large numbers of identically-sized blocks are malloced/freed in some dynamic manner, and then later are all freed. The finer bin sizes make finding blocks fast, with little wasted overallocation. The consolidation methods ensure that once the collection of blocks is no longer useful, fragments are gathered into bigger chunks awaiting new roles. The bins av[i] serve as heads of the lists. Bins contain a dummy header for the chunk lists, and a `dirty' field used to indicate whether the list may need to be scanned for consolidation. On allocation, the bin corresponding to the request size is scanned, and if there is a chunk with size >= requested, it is split, if too big, and used. Chunks on the list which are too small are examined for consolidation during this traversal. If no chunk exists in the list bigger bins are scanned in search of a victim. If no victim can be found, then smaller bins are examined for consolidation in order to construct a victim. Finally, if consolidation fails to come up with a usable chunk, more space is obtained from the system. After a split, the remainder is placed on the back of the appropriate bin list. (All freed chunks are placed on fronts of lists. All remaindered or consolidated chunks are placed on the rear. Correspondingly, searching within a bin starts at the front, but finding victims is from the back. All of this approximates the effect of having 2 kinds of lists per bin: returned chunks vs unallocated chunks, but without the overhead of maintaining 2 lists.) Deallocation (free) consists only of placing the chunk on a list. Reallocation proceeds in the usual way. If a chunk can be extended, it is, else a malloc-copy-free sequence is taken. memalign requests more than enough space from malloc, finds a spot within that chunk that meets the alignment request, and then possibly frees the leading and trailing space. Overreliance on memalign is a sure way to fragment space. Some other implementation matters: 8 byte alignment is currently hardwired into the design. Calling memalign will return a chunk that is both 8-byte aligned, and meets the requested alignment. The basic overhead of a used chunk is 8 bytes: 4 at the front and 4 at the end. When a chunk is free, 8 additional bytes are needed for free list pointers. Thus, the minimum allocatable size is 16 bytes. The existence of front and back overhead permits some reasonably effective fence-bashing checks: The front and back fields must be identical. This is checked only within free() and realloc(). The checks are fast enough to be made non-optional. The overwriting of parts of freed memory with the freelist pointers can also be very effective (albeit in an annoying way) in helping users track down dangling pointers. User overwriting of freed space will often result in crashes within malloc or free. These routines are also tuned to C++ in that free(0) is a noop and a failed malloc automatically calls (*new_handler)(). malloc(0) returns a pointer to something of the minimum allocatable size. Additional memory is gathered from the system (via sbrk) in a way that allows chunks obtained across different sbrk calls to be consolidated, but does not require contiguous memory: Thus, it should be safe to intersperse mallocs with other sbrk calls. This malloc is NOT designed to work in multiprocessing applications. No semaphores or other concurrency control are provided to ensure that multiple malloc or free calls don't run at the same time, which could be disasterous. VERY heavy use of inlines is made, for clarity. If this malloc is ported via a compiler without inlining capabilities, all inlines should be transformed into macros -- making them non-inline makes malloc at least twice as slow. */ /* preliminaries */ #ifdef __cplusplus #include #else #include "//usr/include/stdio.h" /* needed for error reporting */ #endif #ifdef __cplusplus extern "C" { #endif #ifdef USG extern void* memset(void*, int, int); extern void* memcpy(void*, const void*, int); /*inline void bzero(void* s, int l) { memset(s, 0, l); }*/ #else /*extern void bzero(void*, unsigned int);*/ #endif /*extern void bcopy(void*, void*, unsigned int);*/ extern void* sbrk(unsigned int); /* Put this in instead of commmented out stuff above. */ #define bcopy(s,d,n) memcpy((d),(s),(n)) #define bcmp(s1,s2,n) memcmp((s1),(s2),(n)) #define bzero(s,n) memset((s),0,(n)) #ifdef __GNUC__ extern volatile void abort(); #else extern void abort(); #endif #ifdef __cplusplus }; /* end of extern "C" */ #endif /* A good multiple to call sbrk with */ #define SBRK_UNIT 4096 /* how to die on detected error */ #ifdef __GNUC__ static volatile void malloc_user_error() #else static void malloc_user_error() #endif { fputs("malloc/free/realloc: clobbered space detected\n", stderr); abort(); } /* Basic overhead for each malloc'ed chunk */ struct malloc_chunk { unsigned int size; /* Size in bytes, including overhead. */ /* Or'ed with INUSE if in use. */ struct malloc_chunk* fd; /* double links -- used only if free. */ struct malloc_chunk* bk; }; typedef struct malloc_chunk* mchunkptr; struct malloc_bin { struct malloc_chunk hd; /* dummy list header */ unsigned int dirty; /* True if maybe consolidatable */ /* Wasting a word here makes */ /* sizeof(bin) a power of 2, */ /* which makes size2bin() faster */ }; typedef struct malloc_bin* mbinptr; /* sizes, alignments */ #define SIZE_SZ (sizeof(unsigned int)) #define MALLOC_MIN_OVERHEAD (SIZE_SZ + SIZE_SZ) #define MALLOC_ALIGN_MASK (MALLOC_MIN_OVERHEAD - 1) #define MINSIZE (sizeof(struct malloc_chunk) + SIZE_SZ) /* MUST == 16! */ /* pad request bytes into a usable size */ static inline unsigned int request2size(unsigned int request) { return (request == 0) ? MINSIZE : ((request + MALLOC_MIN_OVERHEAD + MALLOC_ALIGN_MASK) & ~(MALLOC_ALIGN_MASK)); } static inline int aligned_OK(void* m) { return ((unsigned int)(m) & (MALLOC_ALIGN_MASK)) == 0; } /* size field or'd with INUSE when in use */ #define INUSE 0x1 /* the bins, initialized to have null double linked lists */ #define MAXBIN 120 /* 1 more than needed for 32 bit addresses */ #define FIRSTBIN (&(av[0])) static struct malloc_bin av[MAXBIN] = { { { 0, &(av[0].hd), &(av[0].hd) }, 0 }, { { 0, &(av[1].hd), &(av[1].hd) }, 0 }, { { 0, &(av[2].hd), &(av[2].hd) }, 0 }, { { 0, &(av[3].hd), &(av[3].hd) }, 0 }, { { 0, &(av[4].hd), &(av[4].hd) }, 0 }, { { 0, &(av[5].hd), &(av[5].hd) }, 0 }, { { 0, &(av[6].hd), &(av[6].hd) }, 0 }, { { 0, &(av[7].hd), &(av[7].hd) }, 0 }, { { 0, &(av[8].hd), &(av[8].hd) }, 0 }, { { 0, &(av[9].hd), &(av[9].hd) }, 0 }, { { 0, &(av[10].hd), &(av[10].hd) }, 0 }, { { 0, &(av[11].hd), &(av[11].hd) }, 0 }, { { 0, &(av[12].hd), &(av[12].hd) }, 0 }, { { 0, &(av[13].hd), &(av[13].hd) }, 0 }, { { 0, &(av[14].hd), &(av[14].hd) }, 0 }, { { 0, &(av[15].hd), &(av[15].hd) }, 0 }, { { 0, &(av[16].hd), &(av[16].hd) }, 0 }, { { 0, &(av[17].hd), &(av[17].hd) }, 0 }, { { 0, &(av[18].hd), &(av[18].hd) }, 0 }, { { 0, &(av[19].hd), &(av[19].hd) }, 0 }, { { 0, &(av[20].hd), &(av[20].hd) }, 0 }, { { 0, &(av[21].hd), &(av[21].hd) }, 0 }, { { 0, &(av[22].hd), &(av[22].hd) }, 0 }, { { 0, &(av[23].hd), &(av[23].hd) }, 0 }, { { 0, &(av[24].hd), &(av[24].hd) }, 0 }, { { 0, &(av[25].hd), &(av[25].hd) }, 0 }, { { 0, &(av[26].hd), &(av[26].hd) }, 0 }, { { 0, &(av[27].hd), &(av[27].hd) }, 0 }, { { 0, &(av[28].hd), &(av[28].hd) }, 0 }, { { 0, &(av[29].hd), &(av[29].hd) }, 0 }, { { 0, &(av[30].hd), &(av[30].hd) }, 0 }, { { 0, &(av[31].hd), &(av[31].hd) }, 0 }, { { 0, &(av[32].hd), &(av[32].hd) }, 0 }, { { 0, &(av[33].hd), &(av[33].hd) }, 0 }, { { 0, &(av[34].hd), &(av[34].hd) }, 0 }, { { 0, &(av[35].hd), &(av[35].hd) }, 0 }, { { 0, &(av[36].hd), &(av[36].hd) }, 0 }, { { 0, &(av[37].hd), &(av[37].hd) }, 0 }, { { 0, &(av[38].hd), &(av[38].hd) }, 0 }, { { 0, &(av[39].hd), &(av[39].hd) }, 0 }, { { 0, &(av[40].hd), &(av[40].hd) }, 0 }, { { 0, &(av[41].hd), &(av[41].hd) }, 0 }, { { 0, &(av[42].hd), &(av[42].hd) }, 0 }, { { 0, &(av[43].hd), &(av[43].hd) }, 0 }, { { 0, &(av[44].hd), &(av[44].hd) }, 0 }, { { 0, &(av[45].hd), &(av[45].hd) }, 0 }, { { 0, &(av[46].hd), &(av[46].hd) }, 0 }, { { 0, &(av[47].hd), &(av[47].hd) }, 0 }, { { 0, &(av[48].hd), &(av[48].hd) }, 0 }, { { 0, &(av[49].hd), &(av[49].hd) }, 0 }, { { 0, &(av[50].hd), &(av[50].hd) }, 0 }, { { 0, &(av[51].hd), &(av[51].hd) }, 0 }, { { 0, &(av[52].hd), &(av[52].hd) }, 0 }, { { 0, &(av[53].hd), &(av[53].hd) }, 0 }, { { 0, &(av[54].hd), &(av[54].hd) }, 0 }, { { 0, &(av[55].hd), &(av[55].hd) }, 0 }, { { 0, &(av[56].hd), &(av[56].hd) }, 0 }, { { 0, &(av[57].hd), &(av[57].hd) }, 0 }, { { 0, &(av[58].hd), &(av[58].hd) }, 0 }, { { 0, &(av[59].hd), &(av[59].hd) }, 0 }, { { 0, &(av[60].hd), &(av[60].hd) }, 0 }, { { 0, &(av[61].hd), &(av[61].hd) }, 0 }, { { 0, &(av[62].hd), &(av[62].hd) }, 0 }, { { 0, &(av[63].hd), &(av[63].hd) }, 0 }, { { 0, &(av[64].hd), &(av[64].hd) }, 0 }, { { 0, &(av[65].hd), &(av[65].hd) }, 0 }, { { 0, &(av[66].hd), &(av[66].hd) }, 0 }, { { 0, &(av[67].hd), &(av[67].hd) }, 0 }, { { 0, &(av[68].hd), &(av[68].hd) }, 0 }, { { 0, &(av[69].hd), &(av[69].hd) }, 0 }, { { 0, &(av[70].hd), &(av[70].hd) }, 0 }, { { 0, &(av[71].hd), &(av[71].hd) }, 0 }, { { 0, &(av[72].hd), &(av[72].hd) }, 0 }, { { 0, &(av[73].hd), &(av[73].hd) }, 0 }, { { 0, &(av[74].hd), &(av[74].hd) }, 0 }, { { 0, &(av[75].hd), &(av[75].hd) }, 0 }, { { 0, &(av[76].hd), &(av[76].hd) }, 0 }, { { 0, &(av[77].hd), &(av[77].hd) }, 0 }, { { 0, &(av[78].hd), &(av[78].hd) }, 0 }, { { 0, &(av[79].hd), &(av[79].hd) }, 0 }, { { 0, &(av[80].hd), &(av[80].hd) }, 0 }, { { 0, &(av[81].hd), &(av[81].hd) }, 0 }, { { 0, &(av[82].hd), &(av[82].hd) }, 0 }, { { 0, &(av[83].hd), &(av[83].hd) }, 0 }, { { 0, &(av[84].hd), &(av[84].hd) }, 0 }, { { 0, &(av[85].hd), &(av[85].hd) }, 0 }, { { 0, &(av[86].hd), &(av[86].hd) }, 0 }, { { 0, &(av[87].hd), &(av[87].hd) }, 0 }, { { 0, &(av[88].hd), &(av[88].hd) }, 0 }, { { 0, &(av[89].hd), &(av[89].hd) }, 0 }, { { 0, &(av[90].hd), &(av[90].hd) }, 0 }, { { 0, &(av[91].hd), &(av[91].hd) }, 0 }, { { 0, &(av[92].hd), &(av[92].hd) }, 0 }, { { 0, &(av[93].hd), &(av[93].hd) }, 0 }, { { 0, &(av[94].hd), &(av[94].hd) }, 0 }, { { 0, &(av[95].hd), &(av[95].hd) }, 0 }, { { 0, &(av[96].hd), &(av[96].hd) }, 0 }, { { 0, &(av[97].hd), &(av[97].hd) }, 0 }, { { 0, &(av[98].hd), &(av[98].hd) }, 0 }, { { 0, &(av[99].hd), &(av[99].hd) }, 0 }, { { 0, &(av[100].hd), &(av[100].hd) }, 0 }, { { 0, &(av[101].hd), &(av[101].hd) }, 0 }, { { 0, &(av[102].hd), &(av[102].hd) }, 0 }, { { 0, &(av[103].hd), &(av[103].hd) }, 0 }, { { 0, &(av[104].hd), &(av[104].hd) }, 0 }, { { 0, &(av[105].hd), &(av[105].hd) }, 0 }, { { 0, &(av[106].hd), &(av[106].hd) }, 0 }, { { 0, &(av[107].hd), &(av[107].hd) }, 0 }, { { 0, &(av[108].hd), &(av[108].hd) }, 0 }, { { 0, &(av[109].hd), &(av[109].hd) }, 0 }, { { 0, &(av[110].hd), &(av[110].hd) }, 0 }, { { 0, &(av[111].hd), &(av[111].hd) }, 0 }, { { 0, &(av[112].hd), &(av[112].hd) }, 0 }, { { 0, &(av[113].hd), &(av[113].hd) }, 0 }, { { 0, &(av[114].hd), &(av[114].hd) }, 0 }, { { 0, &(av[115].hd), &(av[115].hd) }, 0 }, { { 0, &(av[116].hd), &(av[116].hd) }, 0 }, { { 0, &(av[117].hd), &(av[117].hd) }, 0 }, { { 0, &(av[118].hd), &(av[118].hd) }, 0 }, { { 0, &(av[119].hd), &(av[119].hd) }, 0 } }; /* indexing into bins */ static inline mbinptr size2bin(unsigned int sz) { mbinptr b = av; while (sz >= (MINSIZE * 2)) { b += 4; sz >>= 1; } /* find power of 2 */ b += (sz - MINSIZE) >> 2; /* find quadrant */ return b; } /* counts maintained if MALLOC_STATS defined */ #ifdef MALLOC_STATS static unsigned int sbrked_mem; static unsigned int requested_mem; static unsigned int malloced_mem; static unsigned int freed_mem; static unsigned int max_used_mem; static unsigned int n_sbrks; static unsigned int n_mallocs; static unsigned int n_frees; static unsigned int n_reallocs; static unsigned int n_reallocs_with_copy; static unsigned int n_avail; static unsigned int max_inuse; static unsigned int n_malloc_chunks; static unsigned int n_malloc_bins; static unsigned int n_split; static unsigned int n_consol; static void do_malloc_stats(const mchunkptr p) { ++n_mallocs; if ((n_mallocs-n_frees) > max_inuse) max_inuse = n_mallocs - n_frees; malloced_mem += (p->size & ~(INUSE)); if (malloced_mem - freed_mem > max_used_mem) max_used_mem = malloced_mem - freed_mem; } static void do_free_stats(const mchunkptr p) { ++n_frees; freed_mem += (p->size & ~(INUSE)); } #endif /* Utilities needed below for memalign */ /* This is redundant with libg++ support, but not if used stand-alone */ static unsigned int gcd(unsigned int a, unsigned int b) { unsigned int tmp; if (b > a) { tmp = a; a = b; b = tmp; } for(;;) { if (b == 0) return a; else if (b == 1) return b; else { tmp = b; b = a % b; a = tmp; } } } static inline unsigned int lcm(unsigned int x, unsigned int y) { return x / gcd(x, y) * y; } /* maintaining INUSE via size field */ #define inuse(p) ((p)->size & INUSE) #define set_inuse(p) ((p)->size |= INUSE) #define clear_inuse(b) ((p)->size &= ~INUSE) /* operations on malloc_chunk addresses */ /* return ptr to next physical malloc_chunk */ #define next_chunk(p) ((mchunkptr)((char*)(p) + (p)->size)) /* return ptr to previous physical malloc_chunk */ #define prev_chunk(p) ((mchunkptr)((char*)(p)-((((int*)(p))[-1]) & ~(INUSE)))) /* place size at front and back of chunk */ static inline void set_size(mchunkptr p, unsigned int sz) { p->size = *((int*)((char*)(p) + sz - SIZE_SZ)) = sz; } /* conversion from malloc headers to user pointers, and back */ static inline void* chunk2mem(mchunkptr p) { void *mem; set_inuse(p); mem = (void*)((char*)(p) + SIZE_SZ); return mem; } /* xxxx my own */ mchunkptr sanity_check(void* mem) { mchunkptr p = (mchunkptr)((char*)(mem) - SIZE_SZ); /* a quick sanity check */ unsigned int sz = p->size & ~(INUSE); if (p->size == sz || sz != *((int*)((char*)(p) + sz - SIZE_SZ))) malloc_user_error(); return p; } static inline mchunkptr mem2chunk(void* mem) { mchunkptr p = (mchunkptr)((char*)(mem) - SIZE_SZ); /* a quick sanity check */ unsigned int sz = p->size & ~(INUSE); if (p->size == sz || sz != *((int*)((char*)(p) + sz - SIZE_SZ))) malloc_user_error(); p->size = sz; /* clears INUSE */ return p; } /* maintaining bins & pointers */ /* maximum bin actually used */ static mbinptr malloc_maxbin = FIRSTBIN; /* operations on lists inside bins */ /* take a chunk off a list */ static inline void unlink(mchunkptr p) { mchunkptr b = p->bk; mchunkptr f = p->fd; f->bk = b; b->fd = f; UPDATE_STATS (--n_avail); } /* split a chunk and place on the back of a list */ static inline void split(mchunkptr p, unsigned int offset) { unsigned int room = p->size - offset; if (room >= MINSIZE) { mbinptr bn = size2bin(room); /* new bin */ mchunkptr h = &(bn->hd); /* its head */ mchunkptr b = h->bk; /* old back element */ mchunkptr t = (mchunkptr)((char*)(p) + offset); /* remaindered chunk */ /* set size */ t->size = *((int*)((char*)(t) + room - SIZE_SZ)) = room; /* link up */ t->bk = b; t->fd = h; h->bk = b->fd = t; /* adjust maxbin (h == b means was empty) */ if (h == b && bn > malloc_maxbin) malloc_maxbin = bn; /* adjust size of chunk to be returned */ p->size = *((int*)((char*)(p) + offset - SIZE_SZ)) = offset; UPDATE_STATS ((++n_split, ++n_avail)); } } /* place a consolidated chunk on the back of a list */ /* like above, except no split */ static inline void consollink(mchunkptr p) { mbinptr bn = size2bin(p->size); mchunkptr h = &(bn->hd); mchunkptr b = h->bk; p->bk = b; p->fd = h; h->bk = b->fd = p; if (h == b && bn > malloc_maxbin) malloc_maxbin = bn; UPDATE_STATS(++n_avail); } /* place a freed chunk on the front of a list */ static inline void frontlink(mchunkptr p) { mbinptr bn = size2bin(p->size); mchunkptr h = &(bn->hd); mchunkptr f = h->fd; p->bk = h; p->fd = f; f->bk = h->fd = p; if (h == f && bn > malloc_maxbin) malloc_maxbin = bn; bn->dirty = 1; UPDATE_STATS(++n_avail); } /* Dealing with sbrk */ /* To link consecutive sbrk regions when possible */ static int* last_sbrk_end; /* who to call when sbrk returns failure */ #ifndef NO_NEW_HANDLER typedef volatile void (*vfp)(); #ifdef __cplusplus extern "C" vfp __new_handler; #else extern vfp __new_handler; #endif #endif static mchunkptr malloc_from_sys(unsigned nb) { mchunkptr p; unsigned int sbrk_size; int* ip; /* Minimally, we need to pad with enough space */ /* to place dummy size/use fields to ends if needed */ sbrk_size = ((nb + SBRK_UNIT - 1 + SIZE_SZ + SIZE_SZ) / SBRK_UNIT) * SBRK_UNIT; ip = (int*)(sbrk(sbrk_size)); if ((char*)ip == (char*)(-1)) /* sbrk returns -1 on failure */ { #ifndef NO_NEW_HANDLER (*__new_handler) (); #endif return 0; } UPDATE_STATS ((++n_sbrks, sbrked_mem += sbrk_size)); if (last_sbrk_end != &ip[-1]) { /* It's either first time through or someone else called sbrk. */ /* Arrange end-markers at front & back */ /* Shouldn't be necessary, but better to be safe */ while (!aligned_OK(ip)) { ++ip; sbrk_size -= SIZE_SZ; } /* Mark the front as in use to prevent merging. */ /* Note we can get away with only 1 word, not MINSIZE overhead here */ *ip++ = SIZE_SZ | INUSE; p = (mchunkptr)ip; set_size(p,sbrk_size - (SIZE_SZ + SIZE_SZ)); } else { mchunkptr l; /* We can safely make the header start at end of prev sbrked chunk. */ /* We will still have space left at the end from a previous call */ /* to place the end marker, below */ p = (mchunkptr)(last_sbrk_end); set_size(p, sbrk_size); /* Even better, maybe we can merge with last fragment: */ l = prev_chunk(p); if (!inuse(l)) { unlink(l); set_size(l, p->size + l->size); p = l; } } /* mark the end of sbrked space as in use to prevent merging */ last_sbrk_end = (int*)((char*)p + p->size); *last_sbrk_end = SIZE_SZ | INUSE; UPDATE_STATS((++n_avail, ++n_malloc_chunks)); /* make it safe to unlink in malloc */ UPDATE_STATS(++n_avail); p->fd = p->bk = p; return p; } /* Consolidate dirty bins. */ /* Stop if found a chunk big enough to satisfy current malloc request */ /* (It requires much less bookkeeping to consolidate entire bins */ /* at once than to keep records of which chunks might be */ /* consolidatable. So long as the lists are short, which we */ /* try to ensure via small bin ranges, there is little wasted effort.) */ static mchunkptr malloc_find_space(unsigned int nb) { mbinptr b; /* first, re-adjust max used bin */ while (malloc_maxbin >= FIRSTBIN && malloc_maxbin->hd.bk == &(malloc_maxbin->hd)) { malloc_maxbin->dirty = 0; --malloc_maxbin; } for (b = malloc_maxbin; b >= FIRSTBIN; --b) { UPDATE_STATS(++n_malloc_bins); if (b->dirty) { mchunkptr h = &(b->hd); /* head of list */ mchunkptr p = h->fd; /* chunk traverser */ while (p != h) { mchunkptr nextp = p->fd; /* save, in case of relinks */ int consolidated = 0; /* only unlink/relink if consolidated */ mchunkptr t; UPDATE_STATS(++n_malloc_chunks); while (!inuse(t = prev_chunk(p))) /* consolidate backward */ { if (!consolidated) { consolidated = 1; unlink(p); } if (t == nextp) nextp = t->fd; unlink(t); set_size(t, t->size + p->size); p = t; UPDATE_STATS (++n_consol); } while (!inuse(t = next_chunk(p))) /* consolidate forward */ { if (!consolidated) { consolidated = 1; unlink(p); } if (t == nextp) nextp = t->fd; unlink(t); set_size(p, p->size + t->size); UPDATE_STATS (++n_consol); } if (consolidated) { if (p->size >= nb) { /* make it safe to unlink in malloc */ UPDATE_STATS(++n_avail); p->fd = p->bk = p; return p; } else consollink(p); } p = nextp; } b->dirty = 0; } } /* nothing available - sbrk some more */ return malloc_from_sys(nb); } /* Finally, the user-level functions */ void* malloc(unsigned int bytes) { unsigned int nb = request2size(bytes); /* padded request size */ mbinptr b = size2bin(nb); /* corresponding bin */ mchunkptr hd = &(b->hd); /* head of its list */ mchunkptr p = hd->fd; /* chunk traverser */ UPDATE_STATS((requested_mem+=bytes, ++n_malloc_bins)); /* Try a (near) exact match in own bin */ /* clean out unusable but consolidatable chunks in bin while traversing */ while (p != hd) { UPDATE_STATS(++n_malloc_chunks); if (p->size >= nb) goto found; else /* try to consolidate; same code as malloc_find_space */ { mchunkptr nextp = p->fd; /* save, in case of relinks */ int consolidated = 0; /* only unlink/relink if consolidated */ mchunkptr t; while (!inuse(t = prev_chunk(p))) /* consolidate backward */ { if (!consolidated) { consolidated = 1; unlink(p); } if (t == nextp) nextp = t->fd; unlink(t); set_size(t, t->size + p->size); p = t; UPDATE_STATS (++n_consol); } while (!inuse(t = next_chunk(p))) /* consolidate forward */ { if (!consolidated) { consolidated = 1; unlink(p); } if (t == nextp) nextp = t->fd; unlink(t); set_size(p, p->size + t->size); UPDATE_STATS (++n_consol); } if (consolidated) { if (p->size >= nb) { /* make it safe to unlink again below */ UPDATE_STATS(++n_avail); p->fd = p->bk = p; goto found; } else consollink(p); } p = nextp; } } b->dirty = 0; /* true if got here */ /* Scan bigger bins for a victim */ while (++b <= malloc_maxbin) { UPDATE_STATS(++n_malloc_bins); if ((p = b->hd.bk) != &(b->hd)) /* no need to check size */ goto found; } /* Consolidate or sbrk */ p = malloc_find_space(nb); if (p == 0) return 0; /* allocation failure */ found: /* Use what we found */ unlink(p); split(p, nb); UPDATE_STATS(do_malloc_stats(p)); return chunk2mem(p); } void free(void* mem) { if (mem != 0) { mchunkptr p = mem2chunk(mem); UPDATE_STATS(do_free_stats(p)); frontlink(p); } } void* calloc(unsigned int n, unsigned int elem_size) { unsigned int sz = n * elem_size; void* p = malloc(sz); bzero(p, sz); return p; }; /* This is here for compatibility with older systems */ void cfree(void *mem) { free(mem); } unsigned int malloc_usable_size(void* mem) { if (mem == 0) return 0; else { mchunkptr p = (mchunkptr)((char*)(mem) - SIZE_SZ); unsigned int sz = p->size & ~(INUSE); if (p->size == sz || sz != *((int*)((char*)(p) + sz - SIZE_SZ))) return 0; else return sz - MALLOC_MIN_OVERHEAD; } } void* realloc(void* mem, unsigned int bytes) { if (mem == 0) return malloc(bytes); else { unsigned int nb = request2size(bytes); mchunkptr p = mem2chunk(mem); unsigned int oldsize = p->size; int room; mchunkptr nxt; UPDATE_STATS((++n_reallocs, requested_mem += bytes-oldsize)); /* try to expand (even if already big enough), to clean up chunk */ while (!inuse(nxt = next_chunk(p))) { UPDATE_STATS ((malloced_mem += nxt->size, ++n_consol)); unlink(nxt); set_size(p, p->size + nxt->size); } room = p->size - nb; if (room >= 0) { split(p, nb); UPDATE_STATS(malloced_mem -= room); return chunk2mem(p); } else /* do the obvious */ { void* newmem; set_inuse(p); /* don't let malloc consolidate us yet! */ newmem = malloc(nb); bcopy(mem, newmem, oldsize - SIZE_SZ); free(mem); UPDATE_STATS(++n_reallocs_with_copy); return newmem; } } } /* return a pointer to space with at least the alignment requested */ void* memalign(unsigned int alignment, unsigned int bytes) { mchunkptr p; unsigned int nb = request2size(bytes); /* find an alignment that both we and the user can live with: */ /* least common multiple guarantees mutual happiness */ unsigned int align = lcm(alignment, MALLOC_MIN_OVERHEAD); unsigned int mask = align - 1; /* call malloc with worst case padding to hit alignment; */ /* we will give back extra */ unsigned int req = nb + align + MINSIZE; void* m = malloc(req); if (m == 0) return m; p = mem2chunk(m); /* keep statistics on track */ UPDATE_STATS(--n_mallocs); UPDATE_STATS(malloced_mem -= p->size); UPDATE_STATS(requested_mem -= req); UPDATE_STATS(requested_mem += bytes); if (((int)(m) & (mask)) != 0) /* misaligned */ { /* find an aligned spot inside chunk */ mchunkptr ap = (mchunkptr)(( ((int)(m) + mask) & -align) - SIZE_SZ); unsigned int gap = (unsigned int)(ap) - (unsigned int)(p); unsigned int room; /* we need to give back leading space in a chunk of at least MINSIZE */ if (gap < MINSIZE) { /* This works since align >= MINSIZE */ /* and we've malloc'd enough total room */ ap = (mchunkptr)( (int)(ap) + align ); gap += align; } if (gap + nb > p->size) /* can't happen unless chunk sizes corrupted */ malloc_user_error(); room = p->size - gap; /* give back leader */ set_size(p, gap); consollink(p); /* use the rest */ p = ap; set_size(p, room); } /* also give back spare room at the end */ split(p, nb); UPDATE_STATS(do_malloc_stats(p)); return chunk2mem(p); } #ifndef sun #include "getpagesize.h" #endif static unsigned int malloc_pagesize = 0; void* valloc(unsigned int bytes) { if (malloc_pagesize == 0) malloc_pagesize = getpagesize(); return memalign (malloc_pagesize, bytes); } void malloc_stats() { #ifndef MALLOC_STATS } #else int i; mchunkptr p; double nm = (double)(n_mallocs + n_reallocs); fprintf(stderr, "\nmalloc statistics\n\n"); if (n_mallocs != 0) fprintf(stderr, "requests = %10u total size = %10u\tave = %10u\n", n_mallocs, requested_mem, requested_mem/n_mallocs); if (n_mallocs != 0) fprintf(stderr, "mallocs = %10u total size = %10u\tave = %10u\n", n_mallocs, malloced_mem, malloced_mem/n_mallocs); if (n_frees != 0) fprintf(stderr, "frees = %10u total size = %10u\tave = %10u\n", n_frees, freed_mem, freed_mem/n_frees); if (n_mallocs-n_frees != 0) fprintf(stderr, "in use = %10u total size = %10u\tave = %10u\n", n_mallocs-n_frees, malloced_mem-freed_mem, (malloced_mem-freed_mem) / (n_mallocs-n_frees)); if (max_inuse != 0) fprintf(stderr, "max in use= %10u total size = %10u\tave = %10u\n", max_inuse, max_used_mem, max_used_mem / max_inuse); if (n_avail != 0) fprintf(stderr, "available = %10u total size = %10u\tave = %10u\n", n_avail, sbrked_mem - (malloced_mem-freed_mem), (sbrked_mem - (malloced_mem-freed_mem)) / n_avail); if (n_sbrks != 0) fprintf(stderr, "sbrks = %10u total size = %10u\tave = %10u\n\n", n_sbrks, sbrked_mem, sbrked_mem/ n_sbrks); if (n_reallocs != 0) fprintf(stderr, "reallocs = %10u with copy = %10u\n\n", n_reallocs, n_reallocs_with_copy); if (nm != 0) { fprintf(stderr, "chunks scanned per malloc = %6.3f\n", n_malloc_chunks / nm); fprintf(stderr, "bins scanned per malloc = %6.3f\n", n_malloc_bins / nm); fprintf(stderr, "splits per malloc = %6.3f\n", n_split / nm); fprintf(stderr, "consolidations per malloc = %6.3f\n", n_consol / nm); } fprintf(stderr, "\nfree chunks:\n"); for (i = 0; i < MAXBIN; ++i) { p = av[i].hd.fd; if (p != &(av[i].hd)) { unsigned int count = 1; unsigned int sz = p->size; for (p = p->fd; p != &(av[i].hd); p = p->fd) { if (p->size == sz) ++count; else { fprintf(stderr, "\tsize = %10u count = %5u\n", sz, count); count = 1; sz = p->size; } } fprintf(stderr, "\tsize = %10u count = %5u\n", sz, count); } } } #endif /* MALLOC_STATS */ #endif /* NO_LIBGXX_MALLOC */ lyskom-server-2.1.2/src/libraries/regex/test/getpagesize.h0000664000015100472110000000064005314452726017341 #ifdef BSD #ifndef BSD4_1 #define HAVE_GETPAGESIZE #endif #endif #ifndef HAVE_GETPAGESIZE #include #ifdef EXEC_PAGESIZE #define getpagesize() EXEC_PAGESIZE #else #ifdef NBPG #define getpagesize() NBPG * CLSIZE #ifndef CLSIZE #define CLSIZE 1 #endif /* no CLSIZE */ #else /* no NBPG */ #define getpagesize() NBPC #endif /* no NBPG */ #endif /* no EXEC_PAGESIZE */ #endif /* not HAVE_GETPAGESIZE */ lyskom-server-2.1.2/src/libraries/regex/test/iregex.c0000664000015100472110000000613405533104563016310 /* Main program for interactive testing. For maximum output, compile this and regex.c with -DDEBUG. */ #include #include #include "regex.h" /* Don't bother to guess about vs , etc. */ extern int strlen (); #define BYTEWIDTH 8 extern void printchar (); extern char upcase[]; static void scanstring (); static void print_regs (); int main (argc, argv) int argc; char **argv; { int i; struct re_pattern_buffer buf; char fastmap[(1 << BYTEWIDTH)]; /* Allow a command argument to specify the style of syntax. You can use the `syntax' program to decode integer syntax values. */ if (argc > 1) re_set_syntax (atoi (argv[1])); buf.allocated = 0; buf.buffer = NULL; buf.fastmap = fastmap; buf.translate = upcase; for (;;) { char pat[500], str[500]; struct re_registers regs; /* Some C compilers don't like `char pat[500] = ""'. */ pat[0] = 0; printf ("Pattern (%s) = ", pat); gets (pat); scanstring (pat); if (feof (stdin)) { putchar ('\n'); exit (0); } if (*pat) { re_compile_pattern (pat, strlen (pat), &buf); re_compile_fastmap (&buf); #ifdef DEBUG print_compiled_pattern (&buf); #endif } printf ("String = "); gets (str); /* Now read the string to match against */ scanstring (str); i = re_match (&buf, str, strlen (str), 0, ®s); printf ("Match value %d.\t", i); if (i >= 0) print_regs (regs); putchar ('\n'); i = re_search (&buf, str, strlen (str), 0, strlen (str), ®s); printf ("Search value %d.\t", i); if (i >= 0) print_regs (regs); putchar ('\n'); } /* We never get here, but what the heck. */ return 0; } void scanstring (s) char *s; { char *write = s; while (*s != '\0') { if (*s == '\\') { s++; switch (*s) { case '\0': break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': *write = *s++ - '0'; if ('0' <= *s && *s <= '9') { *write = (*write << 3) + (*s++ - '0'); if ('0' <= *s && *s <= '9') *write = (*write << 3) + (*s++ - '0'); } write++; break; case 'n': *write++ = '\n'; s++; break; case 't': *write++ = '\t'; s++; break; default: *write++ = *s++; break; } } else *write++ = *s++; } *write++ = '\0'; } /* Print REGS in human-readable form. */ void print_regs (regs) struct re_registers regs; { int i, end; printf ("Registers: "); if (regs.num_regs == 0 || regs.start[0] == -1) { printf ("(none)"); } else { /* Find the last register pair that matched. */ for (end = regs.num_regs - 1; end >= 0; end--) if (regs.start[end] != -1) break; printf ("[%d ", regs.start[0]); for (i = 1; i <= end; i++) printf ("(%d %d) ", regs.start[i], regs.end[i]); printf ("%d]", regs.end[0]); } } lyskom-server-2.1.2/src/libraries/regex/test/main.c0000664000015100472110000000146305314452720015747 /* Main routine for running various tests. Meant only to be linked with all the auxiliary test source files, with `test' undefined. */ #include "test.h" test_type t = all_test; /* Use this to run the tests we've thought of. */ int main () { switch (t) { case all_test: test_regress (); test_others (); test_posix_basic (); test_posix_extended (); test_posix_interface (); break; case other_test: test_others (); break; case posix_basic_test: test_posix_basic (); break; case posix_extended_test: test_posix_extended (); break; case posix_interface_test: test_posix_interface (); break; case regress_test: test_regress (); break; default: fprintf (stderr, "Unknown test %d.\n", t); } return 0; } lyskom-server-2.1.2/src/libraries/regex/test/malloc-test.c0000664000015100472110000000164105314452721017246 typedef struct { unsigned *bits; unsigned size; } bits_list_type; #define BYTEWIDTH 8 #define NULL 0 #define BITS_BLOCK_SIZE (sizeof (unsigned) * BYTEWIDTH) #define BITS_BLOCK(position) ((position) / BITS_BLOCK_SIZE) #define BITS_MASK(position) (1 << ((position) % BITS_BLOCK_SIZE)) static unsigned init_bits_list (bits_list_ptr) bits_list_type *bits_list_ptr; { bits_list_ptr->bits = NULL; bits_list_ptr->bits = (unsigned *) malloc (sizeof (unsigned)); if (bits_list_ptr->bits == NULL) return 0; bits_list_ptr->bits[0] = (unsigned)0; bits_list_ptr->size = BITS_BLOCK_SIZE; return 1; } main() { bits_list_type dummy; bits_list_type dummy_1; bits_list_type dummy_2; bits_list_type dummy_3; init_bits_list (&dummy); printf("init 1\n"); init_bits_list (&dummy_1); printf("init 2\n"); init_bits_list (&dummy_2); printf("init 3\n"); init_bits_list (&dummy_3); printf("init 4\n"); } lyskom-server-2.1.2/src/libraries/regex/test/other.c0000664000015100472110000004617105314452721016152 /* other.c: test (not exhaustively) non-POSIX regular expressions. */ #include "test.h" void test_others () { struct re_registers regs; printf ("\nStarting non-POSIX tests.\n"); t = other_test; test_should_match = true; /* The big question: does the group participate in the match, or match the empty string? */ re_set_syntax (RE_NO_BK_PARENS); test_match ("(a*)*ab", "ab"); TEST_REGISTERS ("(a*)*ab", "ab", 0, 2, 0, 0, -1, -1); test_match ("(a*)*", ""); TEST_REGISTERS ("(a*)*ab", "ab", 0, 0, 0, 0, -1, -1); /* This tests finding the highest and lowest active registers. */ test_match ("(a(b)c(d(e)f)g)h(i(j)k(l(m)n)o)\\1\\2\\3\\4\\5\\6\\7\\8", "abcdefghijklmnoabcdefgbdefeijklmnojlmnm"); /* Test that \< and \> match at the beginning and end of the string. */ test_match ("\\", "abc"); /* May as well test \` and \' while we're at it. */ test_match ("\\`abc\\'", "abc"); #if 0 /* Test backreferencing and the fastmap -- which doesn't work. */ test_fastmap ("(a)*\\1", "a", 0, 0); #endif /* But at least we shouldn't search improperly. */ test_search_return (-1, "(a)\\1", ""); re_set_syntax (RE_SYNTAX_EMACS); MATCH_SELF("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); MATCH_SELF ("a^"); MATCH_SELF ("a^b"); MATCH_SELF ("$a"); MATCH_SELF ("a$b"); re_set_syntax (RE_BACKSLASH_ESCAPE_IN_LISTS); test_match ("[\\^a]", "a"); test_match ("[\\^a]", "^"); /* These op characters should be ordinary if RE_CONTEXT_INVALID_OPS isn't set. */ re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_BRACES | RE_INTERVALS | RE_NO_BK_PARENS); MATCH_SELF ("*"); test_match ("a|*", "*"); test_match ("(*)", "*"); MATCH_SELF ("+"); test_match ("a|+", "+"); test_match ("(+)", "+"); MATCH_SELF ("?"); test_match ("a|?", "?"); test_match ("(?)", "?"); MATCH_SELF ("{1}"); test_match ("a|{1}", "a"); test_match ("a|{1}", "{1}"); test_match ("({1})", "{1}"); test_match ("\\{", "{"); re_set_syntax (RE_LIMITED_OPS); MATCH_SELF ("|"); MATCH_SELF ("a|"); MATCH_SELF ("a|"); MATCH_SELF ("a||"); MATCH_SELF ("a||"); MATCH_SELF ("(|)"); re_set_syntax (RE_SYNTAX_EMACS); TEST_SEARCH ("^a", "b\na", 0, 3); TEST_SEARCH ("b$", "b\na", 0, 3); #if 0 /* Newline is no longer special for anchors (16 Sep 92). --karl */ test_match_2 ("a\n^b", "a", "\nb"); test_match_2 ("a$\nb", "a\n", "b"); #endif /* Test grouping. */ re_set_syntax (RE_NO_BK_PARENS); test_match ("()", ""); test_fastmap ("()", "", 0, 0); TEST_REGISTERS ("()", "", 0, 0, 0, 0, -1, -1); test_match ("((((((((()))))))))", ""); test_fastmap ("((((((((()))))))))", "", 0, 0); test_match ("a()b", "ab"); TEST_REGISTERS ("a()b", "ab", 0, 2, 1, 1, -1, -1); test_match ("(((((((((())))))))))", ""); test_fastmap ("(((((((((())))))))))", "", 0, 0); test_match ("()*", ""); TEST_REGISTERS ("()*", "", 0, 0, 0, 0, -1, -1); /* empty string */ test_match ("(())*", ""); re_set_syntax (RE_CONTEXT_INDEP_OPS); test_match ("*", ""); re_set_syntax (RE_INTERVALS | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES); test_match ("{1}", ""); /* Should remain an interval. */ MATCH_SELF ("{1"); /* Not a valid interval. */ re_set_syntax (RE_NEWLINE_ALT); test_match ("a\nb", "a"); test_match ("a\nb", "b"); re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS); test_match ("^a", "a"); test_match ("(^a)", "a"); test_match ("(a|^b)", "b"); test_match ("a$", "a"); test_match ("(a$)", "a"); test_match ("a$|b", "a"); /* You should be able to have empty alternatives if RE_NO_EMPTY_ALTS isn't set. */ re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS); test_match ("|", ""); test_match ("^|a", ""); test_match ("^|a", "a"); test_match ("a|", ""); test_match ("a|", "a"); test_match ("a|$", ""); test_match ("a|$", "a"); test_match ("a||b", "a"); test_match ("a||b", ""); test_match ("a||b", "b"); test_match ("(|a)", ""); test_match ("(|a)", "a"); test_match ("(a|)", ""); test_match ("(a|)", "a"); TEST_SEARCH ("a|$", "xa", 0, 2); TEST_SEARCH ("a|$", "x", 0, 1); TEST_SEARCH ("$|b", "x", 0, 1); TEST_SEARCH ("$|b", "xb", 0, 2); TEST_SEARCH ("c(a|$)", "xca", 0, 3); TEST_SEARCH ("c(a|$)", "xc", 0, 2); TEST_SEARCH ("c($|b)", "xcb", 0, 3); TEST_SEARCH ("c($|b)", "xc", 0, 2); TEST_SEARCH ("c($|b$)", "xcb", 0, 3); TEST_SEARCH ("c($|b$)", "xc", 0, 2); TEST_SEARCH ("c(a$|$)", "xca", 0, 3); TEST_SEARCH ("c(a$|$)", "xc", 0, 2); TEST_SEARCH ("(a$|b$)|$", "x", 0, 1); TEST_SEARCH ("(a$|b$)|$", "xa", 0, 2); TEST_SEARCH ("(a$|b$)|$", "xb", 0, 2); TEST_SEARCH ("(a$|$)|c$", "x", 0, 1); TEST_SEARCH ("(a$|$)|c$", "xa", 0, 2); TEST_SEARCH ("(a$|$)|c$", "xc", 0, 2); TEST_SEARCH ("($|b$)|c$", "x", 0, 1); TEST_SEARCH ("($|b$)|c$", "xb", 0, 2); TEST_SEARCH ("($|b$)|c$", "xc", 0, 2); TEST_SEARCH ("c$|(a$|$)", "x", 0, 1); TEST_SEARCH ("c$|(a$|$)", "xa", 0, 2); TEST_SEARCH ("c$|(a$|$)", "xc", 0, 2); TEST_SEARCH ("c$|($|b$)", "x", 0, 1); TEST_SEARCH ("c$|($|b$)", "xb", 0, 2); TEST_SEARCH ("c$|($|b$)", "xc", 0, 2); TEST_SEARCH ("$|(a$|b$)", "x", 0, 1); TEST_SEARCH ("$|(a$|b$)", "xa", 0, 2); TEST_SEARCH ("$|(a$|b$)", "xb", 0, 2); TEST_SEARCH ("c(a$|b$)|$", "x", 0, 1); TEST_SEARCH ("c(a$|b$)|$", "xca", 0, 3); TEST_SEARCH ("c(a$|b$)|$", "xcb", 0, 3); TEST_SEARCH ("c(a$|$)|d$", "xc", 0, 2); TEST_SEARCH ("c(a$|$)|d$", "xca", 0, 3); TEST_SEARCH ("c(a$|$)|d$", "xd", 0, 2); TEST_SEARCH ("c($|b$)|d$", "xc", 0, 2); TEST_SEARCH ("c($|b$)|d$", "xcb", 0, 3); TEST_SEARCH ("c($|b$)|d$", "xd", 0, 2); TEST_SEARCH ("d(c$|e((a$|$)))", "xdc", 0, 3); TEST_SEARCH ("d(c$|e((a$|$)))", "xde", 0, 3); TEST_SEARCH ("d(c$|e((a$|$)))", "xdea", 0, 4); TEST_SEARCH ("d(c$|e(($|b$)))", "xdc", 0, 3); TEST_SEARCH ("d(c$|e(($|b$)))", "xde", 0, 3); TEST_SEARCH ("d(c$|e(($|b$)))", "xdeb", 0, 4); TEST_SEARCH ("d($|e((a$|b$)))", "xd", 0, 2); TEST_SEARCH ("d($|e((a$|b$)))", "xdea", 0, 4); TEST_SEARCH ("d($|e((a$|b$)))", "xdeb", 0, 4); TEST_SEARCH ("a(b$|c$)|$", "x", 0, 1); TEST_SEARCH ("a(b$|c$)|$", "xab", 0, 3); TEST_SEARCH ("a(b$|c$)|$", "xac", 0, 3); TEST_SEARCH ("a(b$|$)|d$", "xa", 0, 2); TEST_SEARCH ("a(b$|$)|d$", "xab", 0, 3); TEST_SEARCH ("a(b$|$)|d$", "xd", 0, 2); TEST_SEARCH ("a($|c$)|d$", "xa", 0, 2); TEST_SEARCH ("a($|c$)|d$", "xac", 0, 3); TEST_SEARCH ("a($|c$)|d$", "xd", 0, 2); TEST_SEARCH ("d$|a(b$|$)", "xd", 0, 2); TEST_SEARCH ("d$|a(b$|$)", "xa", 0, 2); TEST_SEARCH ("d$|a(b$|$)", "xab", 0, 3); TEST_SEARCH ("d$|a($|c$)", "xd", 0, 2); TEST_SEARCH ("d$|a($|c$)", "xa", 0, 2); TEST_SEARCH ("d$|a($|c$)", "xac", 0, 3); TEST_SEARCH ("$|a(b$|c$)", "x", 0, 1); TEST_SEARCH ("$|a(b$|c$)", "xab", 0, 3); TEST_SEARCH ("$|a(b$|c$)", "xac", 0, 3); TEST_SEARCH ("(a)(b$|c$)|d$", "xab", 0, 3); TEST_SEARCH ("(a)(b$|c$)|d$", "xac", 0, 3); TEST_SEARCH ("(a)(b$|c$)|d$", "xd", 0, 2); TEST_SEARCH ("(a)(b$|$)|d$", "xa", 0, 2); TEST_SEARCH ("(a)(b$|$)|d$", "xab", 0, 3); TEST_SEARCH ("(a)(b$|$)|d$", "xd", 0, 2); TEST_SEARCH ("(a)($|c$)|d$", "xa", 0, 2); TEST_SEARCH ("(a)($|c$)|d$", "xac", 0, 3); TEST_SEARCH ("(a)($|c$)|d$", "xd", 0, 2); TEST_SEARCH ("d$|(a)(b$|$)", "xd", 0, 2); TEST_SEARCH ("d$|(a)(b$|$)", "xa", 0, 2); TEST_SEARCH ("d$|(a)(b$|$)", "xab", 0, 3); TEST_SEARCH ("d$|(a)($|c$)", "xd", 0, 2); TEST_SEARCH ("d$|(a)($|c$)", "xa", 0, 2); TEST_SEARCH ("d$|(a)($|c$)", "xac", 0, 3); TEST_SEARCH ("$|(a)(b$|c$)", "x", 0, 1); TEST_SEARCH ("$|(a)(b$|c$)", "xab", 0, 3); TEST_SEARCH ("$|(a)(b$|c$)", "xac", 0, 3); TEST_SEARCH ("d$|(c$|(a$|$))", "x", 0, 1); TEST_SEARCH ("d$|(c$|(a$|$))", "xd", 0, 2); TEST_SEARCH ("d$|(c$|(a$|$))", "xc", 0, 2); TEST_SEARCH ("d$|(c$|(a$|$))", "xa", 0, 2); TEST_SEARCH ("d$|(c$|($|b$))", "x", 0, 1); TEST_SEARCH ("d$|(c$|($|b$))", "xd", 0, 2); TEST_SEARCH ("d$|(c$|($|b$))", "xc", 0, 2); TEST_SEARCH ("d$|(c$|($|b$))", "xb", 0, 2); TEST_SEARCH ("d$|($|(a$|b$))", "x", 0, 1); TEST_SEARCH ("d$|($|(a$|b$))", "xd", 0, 2); TEST_SEARCH ("d$|($|(a$|b$))", "xa", 0, 2); TEST_SEARCH ("d$|($|(a$|b$))", "xb", 0, 2); TEST_SEARCH ("$|(c$|(a$|b$))", "x", 0, 1); TEST_SEARCH ("$|(c$|(a$|b$))", "xc", 0, 2); TEST_SEARCH ("$|(c$|(a$|b$))", "xa", 0, 2); TEST_SEARCH ("$|(c$|(a$|b$))", "xb", 0, 2); TEST_SEARCH ("d$|c(a$|$)", "xd", 0, 2); TEST_SEARCH ("d$|c(a$|$)", "xc", 0, 2); TEST_SEARCH ("d$|c(a$|$)", "xca", 0, 3); TEST_SEARCH ("d$|c($|b$)", "xd", 0, 2); TEST_SEARCH ("d$|c($|b$)", "xc", 0, 2); TEST_SEARCH ("d$|c($|b$)", "xcb", 0, 3); TEST_SEARCH ("$|c(a$|b$)", "x", 0, 1); TEST_SEARCH ("$|c(a$|b$)", "xca", 0, 3); TEST_SEARCH ("$|c(a$|b$)", "xcb", 0, 3); TEST_SEARCH ("e(d$|c((a$|$)))", "xed", 0, 3); TEST_SEARCH ("e(d$|c((a$|$)))", "xec", 0, 3); TEST_SEARCH ("e(d$|c((a$|$)))", "xeca", 0, 3); TEST_SEARCH ("e(d$|c(($|b$)))", "xed", 0, 3); TEST_SEARCH ("e(d$|c(($|b$)))", "xec", 0, 3); TEST_SEARCH ("e(d$|c(($|b$)))", "xecb", 0, 4); TEST_SEARCH ("e($|c((a$|b$)))", "xe", 0, 2); TEST_SEARCH ("e($|c((a$|b$)))", "xeca", 0, 4); TEST_SEARCH ("e($|c((a$|b$)))", "xecb", 0, 4); TEST_SEARCH ("ed$|(c((a$|$)))", "xed", 0, 3); TEST_SEARCH ("ed$|(c((a$|$)))", "xc", 0, 2); TEST_SEARCH ("ed$|(c((a$|$)))", "xca", 0, 3); TEST_SEARCH ("ed$|(c(($|b$)))", "xed", 0, 3); TEST_SEARCH ("ed$|(c(($|b$)))", "xc", 0, 2); TEST_SEARCH ("ed$|(c(($|b$)))", "xcb", 0, 3); TEST_SEARCH ("$|(c((a$|b$)))", "x", 0, 1); TEST_SEARCH ("$|(c((a$|b$)))", "xca", 0, 3); TEST_SEARCH ("$|(c((a$|b$)))", "xcb", 0, 3); TEST_SEARCH ("d$|($|(a|b)$)", "x", 0, 1); TEST_SEARCH ("d$|($|(a|b)$)", "xa", 0, 2); TEST_SEARCH ("d$|($|(a|b)$)", "xb", 0, 2); TEST_SEARCH ("$|(c$|(a|b)$)", "x", 0, 1); TEST_SEARCH ("$|(c$|(a|b)$)", "xc", 0, 2); TEST_SEARCH ("$|(c$|(a|b)$)", "xa", 0, 2); TEST_SEARCH ("$|(c$|(a|b)$)", "xb", 0, 2); re_set_syntax (0); test_match ("[^\n]", "a"); test_match ("[^a]", "\n"); TEST_SEARCH ("^a", "b\na", 0, 3); TEST_SEARCH ("b$", "b\na", 0, 3); test_case_fold ("[!-`]", "A"); test_case_fold ("[!-`]", "a"); re_set_syntax (RE_CONTEXT_INDEP_OPS | RE_NO_BK_VBAR | RE_NO_BK_PARENS | RE_NO_BK_BRACES | RE_INTERVALS); valid_nonposix_pattern ("()^a"); valid_nonposix_pattern ("()\\1^a"); /* Per Cederqvist (cedar@lysator.liu.se) bug. */ re_set_syntax (RE_SYNTAX_EMACS); /* One `a' before the \n and 638 a's after it. */ test_search_return (0, "\\(.*\\)\n\\(\\(.\\|\n\\)*\\)$", "a\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); /* No a's before the \n and 639 a's after it. */ test_search_return (0, "\\(.*\\)\n\\(\\(.\\|\n\\)*\\)$", "\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); /* One `a' before the \n and 639 a's after it. */ test_search_return (0, "\\(.*\\)\n\\(\\(.\\|\n\\)*\\)$", "a\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); /* No a's before the \n and 640 a's after it. */ test_search_return (0, "\\(.*\\)\n\\(\\(.\\|\n\\)*\\)$", "\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS); TEST_SEARCH ("^(^a)", "ab", 0, 2); TEST_SEARCH ("(a$)$", "ba", 0, 2); test_match ("a|$b", "$b"); /* Mike's curiosity item. */ re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS); test_all_registers ("(foo|foobar)(foo|bar)*\\1(foo|bar)*", "foobarfoobar", "", 0, 12, 0, 3, 3, 6, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); /* Another one from Mike. */ test_match ("(foo|foobarfoo)(bar)*", "foobarfoo"); /* And another. */ test_match("(foo|foobar)(bar|barfoo)?\\1", "foobarfoobar"); re_set_syntax (RE_NO_BK_PARENS | RE_INTERVALS | RE_NO_BK_VBAR | RE_NO_BK_BRACES); /* xx get new ones from ext.*/ test_match ("((a{0,}{0,0}()\\3\\b\\B\\<\\>\\`\\')|b)*", "bb"); test_all_registers ("((a{0,}{0,0}()\\3\\b\\B\\<\\>\\`\\')|b)*", "", "bb", 0, 2, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); test_match ("((a+?*{0,}{0,0}()\\3\\b\\B\\<\\>\\`\\')|b)", "b"); test_all_registers ("((a+?*{0,}{0,0}()\\3\\b\\B\\<\\>\\`\\')|b)", "", "b", 0, 1, 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); /* Valid anchoring. */ /* See generic_test.c and extended_test.c for more search tests. xx Not sure all these tests are represented in the search tests. */ re_set_syntax (RE_NO_BK_PARENS | RE_NO_BK_VBAR); valid_nonposix_pattern ("(((((((((((((((((((((((((((((((((^a)))))))))))))))))))))))))))))))))"); valid_nonposix_pattern ("(((((((((((((((((((((((((((((((((a$)))))))))))))))))))))))))))))))))"); valid_nonposix_pattern ("\\b\\B\\<\\>\\`\\'^a"); valid_nonposix_pattern ("a$\\b\\B\\<\\>\\`\\'"); valid_nonposix_pattern ("(^a)"); valid_nonposix_pattern ("(a$)"); valid_nonposix_pattern ("(^a)b"); valid_nonposix_pattern ("b(a$)"); valid_nonposix_pattern ("(^a|^b)c"); valid_nonposix_pattern ("c(a$|b$)"); valid_nonposix_pattern ("(^a|^b)|^c"); valid_nonposix_pattern ("(a$|b$)|c$"); valid_nonposix_pattern ("^c|(^a|^b)"); valid_nonposix_pattern ("c$|(a$|b$)"); valid_nonposix_pattern ("(^a|^b)c|^d"); valid_nonposix_pattern ("c(a$|b$)|d$"); valid_nonposix_pattern ("(((^a|^b))c|^d)e"); valid_nonposix_pattern ("(c((a|b))|d)e$"); valid_nonposix_pattern ("^d(c|e((a|b)))"); valid_nonposix_pattern ("d(c$|e((a$|b$)))"); valid_nonposix_pattern ("(((^a|^b))c)|^de"); valid_nonposix_pattern ("(((a|b))c$)|de$"); valid_nonposix_pattern ("((a$)$)$"); valid_nonposix_pattern ("^(^(^a))"); valid_nonposix_pattern ("^de|^(c((a|b)))"); valid_nonposix_pattern ("^de|(^c((a|b)))"); valid_nonposix_pattern ("de$|(c((a|b)$))"); valid_nonposix_pattern ("de$|(c((a|b))$)"); valid_nonposix_pattern ("de$|(c((a|b)))$"); valid_nonposix_pattern ("^a(b|c)|^d"); valid_nonposix_pattern ("a(b$|c$)|d$"); valid_nonposix_pattern ("^d|^a(b|c)"); valid_nonposix_pattern ("d$|a(b$|c$)"); valid_nonposix_pattern ("^d|^(b|c)a"); valid_nonposix_pattern ("d$|(b|c)a$"); valid_nonposix_pattern ("^(a)(b|c)|^d"); valid_nonposix_pattern ("(a)(b|c)$|d$"); valid_nonposix_pattern ("(^a)(b|c)|^d"); valid_nonposix_pattern ("(a)(b$|c$)|d$"); valid_nonposix_pattern ("^d|^(b|c)(a)"); valid_nonposix_pattern ("d$|(b|c)(a)$"); valid_nonposix_pattern ("^d|(^b|^c)(a)"); valid_nonposix_pattern ("d$|(b|c)(a$)"); valid_nonposix_pattern ("^d|^(a)(b|c)"); valid_nonposix_pattern ("^d|(^a)(b|c)"); valid_nonposix_pattern ("d$|(a)(b$|c$)"); valid_nonposix_pattern ("((^a|^b)|^c)|^d"); valid_nonposix_pattern ("d$|(c$|(a$|b$))"); /* Tests shouldn't match. */ test_should_match = false; /* Test that RE_CONTEXT_INVALID_OPS has precedence over RE_CONTEXT_INDEP_OPS. */ re_set_syntax (RE_CONTEXT_INDEP_OPS | RE_CONTEXT_INVALID_OPS | RE_NO_BK_VBAR | RE_NO_BK_PARENS | RE_NO_BK_BRACES | RE_INTERVALS); INVALID_PATTERN ("*"); INVALID_PATTERN ("^*"); INVALID_PATTERN ("a|*"); INVALID_PATTERN ("(*)"); INVALID_PATTERN ("^+"); INVALID_PATTERN ("+"); INVALID_PATTERN ("a|+"); INVALID_PATTERN ("(+)"); INVALID_PATTERN ("^?"); INVALID_PATTERN ("?"); INVALID_PATTERN ("a|?"); INVALID_PATTERN ("(?)"); INVALID_PATTERN ("^{1}"); INVALID_PATTERN ("{1}"); INVALID_PATTERN ("a|{1}"); INVALID_PATTERN ("({1})"); #if 0 /* No longer have this syntax option -- POSIX says empty alternatives are undefined as of draft 11.2. */ /* You can't have empty alternatives if RE_NO_EMPTY_ALTS is set. */ re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS | RE_NO_EMPTY_ALTS); INVALID_PATTERN ("|"); INVALID_PATTERN ("^|a"); INVALID_PATTERN ("a|"); INVALID_PATTERN ("a||"); INVALID_PATTERN ("a||b"); INVALID_PATTERN ("(|a)"); INVALID_PATTERN ("(a|)"); INVALID_PATTERN ("(a|)"); /* Test above with `\(' and `\)'. */ re_set_syntax (RE_NO_BK_VBAR | RE_NO_EMPTY_ALTS); INVALID_PATTERN ("\\(|a\\)"); INVALID_PATTERN ("\\(a|\\)"); re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS | RE_NO_EMPTY_ALTS); INVALID_PATTERN ("(|)()$|d$"); #endif /* Test grouping. */ test_match ("()", "a"); /* Test backslashed intervals that are CONTEXTly invalid if have nothing on which to operate. */ re_set_syntax (RE_INTERVALS | RE_CONTEXT_INVALID_OPS); INVALID_PATTERN ("\\{1\\}"); re_set_syntax (0); test_match ("z-a", "a"); re_set_syntax (RE_BK_PLUS_QM); INVALID_PATTERN ("a*\\"); re_set_syntax (0); INVALID_PATTERN ("a*\\"); re_set_syntax (RE_BACKSLASH_ESCAPE_IN_LISTS); INVALID_PATTERN ("[\\"); #if 0 /* Empty groups are always ok now. (13 Sep 92) */ re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS | RE_NO_EMPTY_GROUPS); INVALID_PATTERN ("(|)()$|d$"); #endif printf ("\nFinished non-POSIX tests.\n"); } /* Local variables: make-backup-files: t version-control: t trim-versions-without-asking: nil End: */ lyskom-server-2.1.2/src/libraries/regex/test/printchar.c0000664000015100472110000000034505314452721017014 void printchar (c) char c; { if (c < 040 || c >= 0177) { putchar ('\\'); putchar (((c >> 6) & 3) + '0'); putchar (((c >> 3) & 7) + '0'); putchar ((c & 7) + '0'); } else putchar (c); } lyskom-server-2.1.2/src/libraries/regex/test/psx-basic.c0000664000015100472110000002154705314452722016723 /* psx-basic.c: Test POSIX basic regular expressions. */ #include "test.h" void test_posix_basic () { /* Intervals can only match up to RE_DUP_MAX occurences of anything. */ char dup_max_plus_one[6]; sprintf (dup_max_plus_one, "%d", RE_DUP_MAX + 1); printf ("\nStarting POSIX basic tests.\n"); t = posix_basic_test; re_set_syntax (RE_SYNTAX_POSIX_MINIMAL_BASIC); test_posix_generic (); printf ("\nContinuing POSIX basic tests.\n"); /* Grouping tests that are not the same. */ test_should_match = false; invalid_pattern (REG_EPAREN, PARENS_TO_OPS ("a)")); test_should_match = true; /* Special characters. */ MATCH_SELF ("*"); test_match ("\\(*\\)", "*"); test_match ("\\(^*\\)", "*"); test_match ("**", "***"); test_match ("***", "****"); MATCH_SELF ("{"); /* of extended... */ MATCH_SELF ("()"); /* also non-Posix. */ MATCH_SELF ("a+"); MATCH_SELF ("a?"); MATCH_SELF ("a|b"); MATCH_SELF ("a|"); /* No alternations, */ MATCH_SELF ("|a"); /* so OK if empty. */ MATCH_SELF ("a||"); test_match ("\\(|a\\)", "|a"); test_match ("\\(a|\\)", "a|"); test_match ("a\\+", "a+"); test_match ("a\\?", "a?"); test_match ("a\\|b", "a|b"); test_match ("^*", "*"); test_match ("^+", "+"); test_match ("^?", "?"); test_match ("^{", "{"); /* Valid subexpressions (empty) in basic only. */ test_match ("\\(\\)", ""); test_match ("a\\(\\)", "a"); test_match ("\\(\\)b", "b"); test_match ("a\\(\\)b", "ab"); TEST_REGISTERS ("a\\(\\)b", "ab", 0, 2, 1, 1, -1, -1); test_match ("\\(\\)*", ""); test_match ("\\(\\(\\)\\)*", ""); /* Valid back references. */ /* N.B.: back references to subexpressions that include a * are undefined in the spec. The tests are in here to see if we handle the situation consistently, but if it fails any of them, it doesn't matter. */ test_match ("\\(\\)\\1", ""); TEST_REGISTERS ("\\(\\)\\1", "", 0, 0, 0, 0, -1, -1); test_match ("\\(\\(\\)\\)\\(\\)\\2", ""); test_match ("\\(a\\)\\1", "aa"); TEST_REGISTERS ("\\(a\\)\\1", "aa", 0, 2, 0, 1, -1, -1); TEST_REGISTERS ("\\(a\\)\\1", "xaax", 1, 3, 1, 2, -1, -1); test_match ("\\(\\(a\\)\\)\\1", "aa"); test_match ("\\(a\\)\\(b\\)\\2\\1", "abba"); test_match ("\\(a\\)*\\1", "aa"); TEST_REGISTERS ("\\(a\\)*\\1", "aa", 0, 2, 0, 1, -1, -1); TEST_REGISTERS ("\\(a\\)*\\1", "xaax", 0, 0, -1, -1, -1, -1); test_match ("\\(\\(a\\)\\2b\\)*", "aab"); TEST_REGISTERS ("\\(\\(a\\)\\2b\\)*", "aab", 0, 3, 0, 3, 0, 1); TEST_REGISTERS ("\\(\\(a\\)\\2b\\)*", "xaabx", 0, 0, -1, -1, -1, -1); test_match ("\\(a*\\)*\\1", ""); test_match ("\\(a*\\)*\\1", "aa"); TEST_REGISTERS ("\\(a*\\)*\\1", "aa", 0, 2, 0, 1, -1, -1); TEST_REGISTERS ("\\(a*\\)*\\1", "xaax", 0, 0, 0, 0, -1, -1); test_match ("\\(a*\\)*\\1", ""); test_match ("\\(a*\\)*\\1", "aa"); test_match ("\\(\\(a*\\)*\\)*\\1", "aa"); test_match ("\\(ab*\\)*\\1", "abab"); TEST_REGISTERS ("\\(ab*\\)*\\1", "abab", 0, 4, 0, 2, -1, -1); TEST_REGISTERS ("\\(ab*\\)*\\1", "xababx", 0, 0, -1, -1, -1, -1); test_match ("\\(a*\\)ab\\1", "aaba"); TEST_REGISTERS ("\\(a*\\)ab\\1", "aaba", 0, 4, 0, 1, -1, -1); TEST_REGISTERS ("\\(a*\\)ab\\1", "xaabax", 1, 5, 1, 2, -1, -1); test_match ("\\(a*\\)*ab\\1", "aaba"); TEST_REGISTERS ("\\(a*\\)*ab\\1", "aaba", 0, 4, 0, 1, -1, -1); TEST_REGISTERS ("\\(a*\\)*ab\\1", "xaabax", 1, 5, 1, 2, -1, -1); test_match ("\\(\\(a*\\)b\\)*\\2", "abb"); TEST_REGISTERS ("\\(\\(a*\\)b\\)*\\2", "abb", 0, 3, 2, 3, 2, 2); TEST_REGISTERS ("\\(\\(a*\\)b\\)*\\2", "xabbx", 0, 0, -1, -1, -1, -1); /* Different from above. */ test_match ("\\(\\(a*\\)b*\\)*\\2", "aa"); TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "aa", 0, 2, 0, 1, 0, 1); TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "xaax", 0, 0, 0, 0, 0, 0); test_match ("\\(\\(a*\\)b*\\)*\\2", "aba"); TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "aba", 0, 3, 0, 2, 0, 1); TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "xabax", 0, 0, 0, 0, 0, 0); test_match ("\\(\\(a*\\)b\\)*\\2", "aababa"); TEST_REGISTERS ("\\(\\(a*\\)b\\)*\\2", "aababa", 0, 6, 3, 5, 3, 4); TEST_REGISTERS ("\\(\\(a*\\)b\\)*\\2", "xaababax", 0, 0, -1, -1, -1, -1); test_match ("\\(\\(a*\\)b*\\)*\\2", "aabaa"); TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "aabaa", 0, 5, 0, 3, 0, 2); TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "xaabaax", 0, 0, 0, 0, 0, 0); test_match ("\\(\\(a*\\)b*\\)*\\2", "aabbaa"); TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "aabbaa", 0, 6, 0, 4, 0, 2); TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "xaabbaax", 0, 0, 0, 0, 0, 0); test_match ("\\(\\(a*\\)b*\\)*\\2", "abaabaa"); TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "abaabaa", 0, 7, 2, 5, 2, 4); TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "xaababaax", 0, 0, 0, 0, 0, 0); test_match ("\\(\\(a*\\)b*\\)*a\\2", "aabaaa"); TEST_REGISTERS ("\\(\\(a*\\)b*a\\)*\\2", "aabaaa", 0, 6, 0, 3, 0, 2); TEST_REGISTERS ("\\(\\(a*\\)b*a\\)*\\2", "xaabaax", 0, 0, -1, -1, -1, -1); test_match ("\\(\\(a*\\)b*\\)*\\2a", "aabaaa"); TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2a", "aabaaa", 0, 6, 0, 3, 0, 2); TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2a", "xaabaaax", 1, 7, 1, 4, 1, 3); test_match ("\\(\\(a*\\)b\\)*\\2\\1", "abaabaaaab"); TEST_REGISTERS ("\\(\\(a*\\)b\\)*\\2\\1", "abaabaaaab", 0, 10, 2, 5, 2, 4); /* We are matching the empty string here. */ TEST_REGISTERS ("\\(\\(a*\\)b\\)*\\2\\1", "xabaabaaaabx", 0, 0, -1, -1, -1, -1); test_match ("\\(a*b\\)\\1", "abab"); test_match ("\\(a\\)\\1\\1", "aaa"); test_match ("\\(a\\(c\\)d\\)\\1\\2", "acdacdc"); test_match ("\\(a\\)\\1*", "aaa"); TEST_REGISTERS ("\\(a\\)\\1*", "aaa", 0, 3, 0, 1, -1, -1); TEST_REGISTERS ("\\(a\\)\\1*", "xaaax", 1, 4, 1, 2, -1, -1); test_match ("\\(a\\)\\{1,3\\}b\\1", "aba"); TEST_REGISTERS ("\\(a\\)\\{1,3\\}b\\1", "aba", 0, 3, 0, 1, -1, -1); TEST_REGISTERS ("\\(a\\)\\{1,3\\}b\\1", "xabax", 1, 4, 1, 2, -1, -1); test_match ("\\(\\(a\\)\\2\\)*", "aaaa"); /* rms? */ TEST_REGISTERS ("\\(\\(a*b\\)\\2\\)*", "bbabab", 0, 6, 2, 6, 2, 4); /* rms? */ test_match ("\\(\\(a\\)\\1\\)*", "a1a1"); test_match ("\\(\\(a\\)\\2\\)\\1", "aaaa"); test_match ("\\(\\(a*\\)\\2\\)\\1", "aaaa"); TEST_REGISTERS ("\\(\\(a*\\)\\2\\)\\1", "aaaa", 0, 4, 0, 2, 0, 1); TEST_REGISTERS ("\\(\\(a*\\)\\2\\)\\1", "xaaaax", 0, 0, 0, 0, 0, 0); test_match ("\\{1\\}", "{1}"); test_match ("^\\{1\\}", "{1}"); test_match ("\\(a\\)\\1\\{1,2\\}", "aaa"); TEST_REGISTERS ("\\(a\\)\\1\\{1,2\\}", "aaa", 0, 3, 0, 1, -1, -1); TEST_REGISTERS ("\\(a\\)\\1\\{1,2\\}", "xaaax", 1, 4, 1, 2, -1, -1); /* Per POSIX D11.1 p. 109, leftmost longest match. */ test_match (PARENS_TO_OPS ("(.*).*\\1"), "abcabc"); /* Per POSIX D11.1, p. 125, leftmost longest match. */ test_match (PARENS_TO_OPS ("(ac*)c*d[ac]*\\1"), "acdacaaa"); TEST_REGISTERS (PARENS_TO_OPS ("(ac*)c*d[ac]*\\1"), "acdacaaa", 0, 8, 0, 1, -1, -1); /* Anchors become ordinary, sometimes. */ MATCH_SELF ("a^"); MATCH_SELF ("$a"); MATCH_SELF ("$^"); test_fastmap ("$a^", "$", 0, 0); test_match ("$^*", "$^^"); test_match ("\\($^\\)", "$^"); test_match ("$*", "$$"); /* xx -- known bug, solution pending test_match ("^^$", "^"); */ test_match ("$\\{0,\\}", "$$"); TEST_SEARCH ("^$*", "$$", 0, 2); TEST_SEARCH ("^$\\{0,\\}", "$$", 0, 2); MATCH_SELF ("2^10"); MATCH_SELF ("$HOME"); MATCH_SELF ("$1.35"); /* Basic regular expressions, continued; these don't match their strings. */ test_should_match = false; invalid_pattern (REG_EESCAPE, "\\(a\\"); /* Invalid back references. */ test_match ("\\(a\\)\\1", "ab"); test_match ("\\(a\\)\\1\\1", "aab"); test_match ("\\(a\\)\\(b\\)\\2\\1", "abab"); test_match ("\\(a\\(c\\)d\\)\\1\\2", "acdc"); test_match ("\\(a*b\\)\\1", "abaab"); test_match ("\\(a\\)\\1*", "aaaaaaaaaab"); test_match ("\\(\\(a\\)\\1\\)*", "aaa"); invalid_pattern (REG_ESUBREG, "\\1"); invalid_pattern (REG_ESUBREG, "\\(a\\)\\2"); test_match ("\\(\\(a\\)\\2\\)*", "abaa"); test_match ("\\(\\(a\\)\\1\\)*", "a"); test_match ("\\(\\(a\\)\\2\\)\\1", "abaa"); test_match ("\\(\\(a*\\)\\2\\)\\1", "abaa"); /* Invalid intervals. */ invalid_pattern (REG_EBRACE, "a\\{"); invalid_pattern (REG_BADBR, "a\\{-1"); invalid_pattern (REG_BADBR, concat ("a\\{", (char *)dup_max_plus_one)); invalid_pattern (REG_BADBR, concat (concat ("a\\{", (char *)dup_max_plus_one), ",")); invalid_pattern (REG_BADBR, "a\\{1,0"); invalid_pattern (REG_EBRACE, "a\\{1"); invalid_pattern (REG_EBRACE, "a\\{0,"); invalid_pattern (REG_EBRACE, "a\\{0,1"); invalid_pattern (REG_EBRACE, "a\\{0,1}"); printf ("\nFinished POSIX basic tests.\n"); } /* Local variables: make-backup-files: t version-control: t trim-versions-without-asking: nil End: */ lyskom-server-2.1.2/src/libraries/regex/test/psx-extend.c0000664000015100472110000012215605314452722017127 /* psx-extend.c: Test POSIX extended regular expressions. */ #include "test.h" void test_posix_extended () { /* Intervals can only match up to RE_DUP_MAX occurences of anything. */ char dup_max_plus_one[6]; sprintf (dup_max_plus_one, "%d", RE_DUP_MAX + 1); printf ("\nStarting POSIX extended tests.\n"); t = posix_extended_test; re_set_syntax (RE_SYNTAX_POSIX_MINIMAL_EXTENDED); test_posix_generic (); printf ("\nContinuing POSIX extended tests.\n"); /* Grouping tests that differ from basic's. */ test_should_match = true; MATCH_SELF ("a)"); /* Valid use of special characters. */ test_match ("\\(a", "(a"); test_match ("a\\+", "a+"); test_match ("a\\?", "a?"); test_match ("\\{a", "{a"); test_match ("\\|a", "|a"); test_match ("a\\|b", "a|b"); test_match ("a\\|?", "a"); test_match ("a\\|?", "a|"); test_match ("a\\|*", "a"); test_match ("a\\|*", "a||"); test_match ("\\(*\\)", ")"); test_match ("\\(*\\)", "(()"); test_match ("a\\|+", "a|"); test_match ("a\\|+", "a||"); test_match ("\\(+\\)", "()"); test_match ("\\(+\\)", "(()"); test_match ("a\\||b", "a|"); test_match ("\\(?\\)", ")"); test_match ("\\(?\\)", "()"); test_match ("a+", "a"); test_match ("a+", "aa"); test_match ("a?", ""); test_match ("a?", "a"); /* Bracket expressions. */ test_match ("[(]", "("); test_match ("[+]", "+"); test_match ("[?]", "?"); test_match ("[{]", "{"); test_match ("[|]", "|"); /* Subexpressions. */ test_match ("(a+)*", ""); test_match ("(a+)*", "aa"); test_match ("(a?)*", ""); test_match ("(a?)*", "aa"); /* (No) back references. */ test_match ("(a)\\1", "a1"); /* Invalid as intervals, but are valid patterns. */ MATCH_SELF ("{"); test_match ("^{", "{"); test_match ("a|{", "{"); test_match ("({)", "{"); MATCH_SELF ("a{"); MATCH_SELF ("a{}"); MATCH_SELF ("a{-1"); MATCH_SELF ("a{-1}"); MATCH_SELF ("a{0"); MATCH_SELF ("a{0,"); MATCH_SELF (concat ("a{", dup_max_plus_one)); MATCH_SELF (concat (concat ("a{", dup_max_plus_one), ",")); MATCH_SELF ("a{1,0"); MATCH_SELF ("a{1,0}"); MATCH_SELF ("a{0,1"); test_match ("[a{0,1}]", "}"); test_match ("a{1,3}{-1}", "aaa{-1}"); test_match (concat ("a{1,3}{", dup_max_plus_one), concat ("aaa{", dup_max_plus_one)); test_match ("a{1,3}{2,1}", "aaa{2,1}"); test_match ("a{1,3}{1,2", "aaa{1,2"); /* Valid consecutive repetitions. */ test_match ("a*+", "a"); test_match ("a*?", "a"); test_match ("a++", "a"); test_match ("a+*", "a"); test_match ("a+?", "a"); test_match ("a??", "a"); test_match ("a?*", "a"); test_match ("a?+", "a"); test_match ("a{2}?", ""); test_match ("a{2}?", "aa"); test_match ("a{2}+", "aa"); test_match ("a{2}{2}", "aaaa"); test_match ("a{1}?*", ""); test_match ("a{1}?*", "aa"); test_match ("(a?){0,3}b", "aaab"); test_fastmap ("(a?){0,3}b", "ab", 0, 0); test_match ("(a+){0,3}b", "b"); test_fastmap ("(a+){0,3}b", "ab", 0, 0); test_match ("(a+){0,3}b", "ab"); test_fastmap ("(a+){0,3}b", "ab", 0, 0); test_match ("(a+){1,3}b", "aaab"); test_match ("(a?){1,3}b", "aaab"); test_match ("\\\\{1}", "\\"); /* Extended only. */ test_match ("(a?)?", "a"); test_match ("(a?b)?c", "abc"); test_match ("(a+)*b", "b"); /* Alternatives. */ test_match ("a|b", "a"); test_match ("a|b", "b"); test_fastmap ("a|b", "ab", 0, 0); TEST_SEARCH ("a|b", "cb", 0, 2); TEST_SEARCH ("a|b", "cb", 0, 2); test_match ("(a|b|c)", "a"); test_match ("(a|b|c)", "b"); test_match ("(a|b|c)", "c"); test_match ("(a|b|c)*", "abccba"); test_match ("(a(b*))|c", "a"); /* xx do registers. */ test_match ("(a(b*))|c", "ab"); test_match ("(a(b*))|c", "c"); test_fastmap ("(a+?*|b)", "ab", 0, 0); test_match ("(a+?*|b)", "b"); TEST_REGISTERS ("(a+?*|b)", "b", 0, 1, 0, 1, -1, -1); test_fastmap ("(a+?*|b)*", "ab", 0, 0); test_match ("(a+?*|b)*", "bb"); TEST_REGISTERS ("(a+?*|b)*", "bb", 0, 2, 1, 2, -1, -1); test_fastmap ("(a*|b)*", "ab", 0, 0); test_match ("(a*|b)*", "bb"); TEST_REGISTERS ("(a*|b)*", "bb", 0, 2, 1, 2, -1, -1); test_fastmap ("((a*)|b)*", "ab", 0, 0); test_match ("((a*)|b)*", "bb"); TEST_REGISTERS ("((a*)|b)*", "bb", 0, 2, 1, 2, 1, 1); test_fastmap ("(a{0,}|b)*", "ab", 0, 0); test_match ("(a{0,}|b)*", "bb"); TEST_REGISTERS ("(a{0,}|b)*", "bb", 0, 2, 1, 2, -1, -1); test_fastmap ("((a{0,})|b)*", "ab", 0, 0); test_match ("((a{0,})|b)*", "bb"); TEST_REGISTERS ("((a{0,})|b)*", "bb", 0, 2, 1, 2, 1, 1); /* With c's */ test_fastmap ("(a+?*|b)c", "abc", 0, 0); test_match ("(a+?*|b)c", "bc"); TEST_REGISTERS ("(a+?*|b)c", "bc", 0, 2, 0, 1, -1, -1); test_fastmap ("(a+?*|b)*c", "abc", 0, 0); test_match ("(a+?*|b)*c", "bbc"); TEST_REGISTERS ("(a+?*|b)*c", "bbc", 0, 3, 1, 2, -1, -1); test_fastmap ("(a*|b)*c", "abc", 0, 0); test_match ("(a*|b)*c", "bbc"); TEST_REGISTERS ("(a*|b)*c", "bbc", 0, 3, 1, 2, -1, -1); test_fastmap ("((a*)|b)*c", "abc", 0, 0); test_match ("((a*)|b)*c", "bbc"); TEST_REGISTERS ("((a*)|b)*c", "bbc", 0, 3, 1, 2, 1, 1); test_fastmap ("(a{0,}|b)*c", "abc", 0, 0); test_match ("(a{0,}|b)*c", "bbc"); TEST_REGISTERS ("(a{0,}|b)*c", "bbc", 0, 3, 1, 2, -1, -1); test_fastmap ("((a{0,})|b)*c", "abc", 0, 0); test_match ("((a{0,})|b)*c", "bbc"); TEST_REGISTERS ("((a{0,})|b)*c", "bbc", 0, 3, 1, 2, 1, 1); test_fastmap ("((a{0,}\\b\\<)|b)", "ab", 0, 0); test_match ("((a{0,}\\b\\<)|b)", "b"); TEST_REGISTERS ("((a{0,}\\b\\<)|b)", "b", 0, 1, 0, 1, 0, 0); test_fastmap ("((a{0,}\\b\\<)|b)*", "ab", 0, 0); test_match ("((a{0,}\\b\\<)|b)*", "b"); TEST_REGISTERS ("((a{0,}\\b\\<)|b)*", "b", 0, 1, 0, 1, 0, 0); test_fastmap ("((a+?*{0,1}\\b\\<)|b)", "ab", 0, 0); test_match ("((a+?*{0,1}\\b\\<)|b)", "b"); TEST_REGISTERS ("((a+?*{0,1}\\b\\<)|b)", "b", 0, 1, 0, 1, 0, 0); test_fastmap ("((a+?*{0,2}\\b\\<)|b)", "ab", 0, 0); test_match ("((a+?*{0,2}\\b\\<)|b)", "b"); TEST_REGISTERS ("((a+?*{0,2}\\b\\<)|b)", "b", 0, 1, 0, 1, 0, 0); test_fastmap ("((a+?*{0,4095}\\b\\<)|b)", "ab", 0, 0); test_match ("((a+?*{0,4095}\\b\\<)|b)", "b"); TEST_REGISTERS ("((a+?*{0,4095}\\b\\<)|b)", "b", 0, 1, 0, 1, 0, 0); test_fastmap ("((a+?*{0,5119}\\b\\<)|b)", "ab", 0, 0); test_match ("((a+?*{0,5119}\\b\\<)|b)", "b"); TEST_REGISTERS ("((a+?*{0,5119}\\b\\<)|b)", "b", 0, 1, 0, 1, 0, 0); test_fastmap ("((a+?*{0,6143}\\b\\<)|b)", "ab", 0, 0); test_match ("((a+?*{0,6143}\\b\\<)|b)", "b"); TEST_REGISTERS ("((a+?*{0,6143}\\b\\<)|b)", "b", 0, 1, 0, 1, 0, 0); test_fastmap ("((a+?*{0,8191}\\b\\<)|b)", "ab", 0, 0); test_match ("((a+?*{0,8191}\\b\\<)|b)", "b"); TEST_REGISTERS ("((a+?*{0,8191}\\b\\<)|b)", "b", 0, 1, 0, 1, 0, 0); test_fastmap ("((a+?*{0,16383}\\b\\<)|b)", "ab", 0, 0); test_match ("((a+?*{0,16383}\\b\\<)|b)", "b"); TEST_REGISTERS ("((a+?*{0,16383}\\b\\<)|b)", "b", 0, 1, 0, 1, 0, 0); test_fastmap ("((a+?*{0,}\\b\\<)|b)", "ab", 0, 0); test_match ("((a+?*{0,}\\b\\<)|b)", "b"); TEST_REGISTERS ("((a+?*{0,}\\b\\<)|b)", "b", 0, 1, 0, 1, 0, 0); test_fastmap ("((a+?*{0,}\\b\\<)|b)*", "ab", 0, 0); test_match ("((a+?*{0,}\\b\\<)|b)*", "b"); TEST_REGISTERS ("((a+?*{0,}\\b\\<)|b)*", "b", 0, 1, 0, 1, 0, 0); test_fastmap ("((a+?*{0,}\\b\\<)|b)*", "ab", 0, 0); test_match ("((a+?*{0,}\\b\\<)|b)*", "bb"); TEST_REGISTERS ("((a+?*{0,}\\b\\<)|b)*", "bb", 0, 2, 1, 2, 0, 0); /* `*' after group. */ test_match ("(a*|b*)*c", "c"); TEST_REGISTERS ("(a*|b*)*c", "c", 0, 1, 0, 0, -1, -1); test_match ("(a*|b*)*c", "ac"); TEST_REGISTERS ("(a*|b*)*c", "ac", 0, 2, 0, 1, -1, -1); test_match ("(a*|b*)*c", "aac"); TEST_REGISTERS ("(a*|b*)*c", "aac", 0, 3, 0, 2, -1, -1); test_match ("(a*|b*)*c", "bbc"); TEST_REGISTERS ("(a*|b*)*c", "bbc", 0, 3, 0, 2, -1, -1); test_match ("(a*|b*)*c", "abc"); TEST_REGISTERS ("(a*|b*)*c", "abc", 0, 3, 1, 2, -1, -1); /* No `*' after group. */ test_match ("(a*|b*)c", "c"); TEST_REGISTERS ("(a*|b*)c", "c", 0, 1, 0, 0, -1, -1); test_match ("(a*|b*)c", "ac"); TEST_REGISTERS ("(a*|b*)c", "ac", 0, 2, 0, 1, -1, -1); test_match ("(a*|b*)c", "bc"); TEST_REGISTERS ("(a*|b*)c", "bc", 0, 2, 0, 1, -1, -1); test_match ("(a*|b*)c", "aac"); TEST_REGISTERS ("(a*|b*)c", "aac", 0, 3, 0, 2, -1, -1); /* Same as above, but with no `*'s in alternatives. test_match ("(a|b)*c", "c"); /* `*' after group. */ TEST_REGISTERS ("(a|b)*c", "c", 0, 1, -1, -1, -1, -1); test_match ("(a|b)*c", "ac"); TEST_REGISTERS ("(a|b)*c", "ac", 0, 2, 0, 1, -1, -1); test_match ("(a|b)*c", "bc"); TEST_REGISTERS ("(a|b)*c", "bc", 0, 2, 0, 1, -1, -1); test_match ("(a|b)*c", "abc"); TEST_REGISTERS ("(a|b)*c", "abc", 0, 3, 1, 2, -1, -1); test_match ("(a*|b*)c", "bbc"); TEST_REGISTERS ("(a*|b*)c", "bbc", 0, 3, 0, 2, -1, -1); /* Complicated second alternative. */ test_match ("(a*|(b*)*)*c", "bc"); TEST_REGISTERS ("(a*|(b*)*)*c", "bc", 0, 2, 0, 1, 0, 1); test_match ("(a*|(b*|c*)*)*d", "bd"); TEST_REGISTERS ("(a*|(b*|c*)*)*d", "bd", 0, 2, 0, 1, 0, 1); test_match ("(a*|(b*|c*)*)*d", "bbd"); TEST_REGISTERS ("(a*|(b*|c*)*)*d", "bbd", 0, 3, 0, 2, 0, 2); test_match ("(a*|(b*|c*)*)*d", "cd"); TEST_REGISTERS ("(a*|(b*|c*)*)*d", "cd", 0, 2, 0, 1, 0, 1); test_match ("(a*|(b*|c*)*)*d", "ccd"); TEST_REGISTERS ("(a*|(b*|c*)*)*d", "ccd", 0, 3, 0, 2, 0, 2); test_match ("(a*|b*|c*)*d", "aad"); TEST_REGISTERS ("(a*|b*|c*)*d", "aad", 0, 3, 0, 2, 0, 2); test_match ("(a*|b*|c*)*d", "bbd"); TEST_REGISTERS ("(a*|b*|c*)*d", "bbd", 0, 3, 0, 2, 0, 2); test_match ("(a*|b*|c*)*d", "ccd"); TEST_REGISTERS ("(a*|b*|c*)*d", "ccd", 0, 3, 0, 2, 0, 2); /* Valid anchoring. */ valid_pattern ("a^"); valid_pattern ("a^b"); valid_pattern ("$a"); valid_pattern ("a$b"); valid_pattern ("foo^bar"); valid_pattern ("foo$bar"); valid_pattern ("(^)"); valid_pattern ("($)"); valid_pattern ("(^$)"); /* These are the same (but valid) as those (invalid) in other_test.c. */ valid_pattern ("(((((((((((((((((((((((((((((((((a^)))))))))))))))))))))))))))))))))"); valid_pattern ("((((((((((((((((((((((((((((((((($a)))))))))))))))))))))))))))))))))"); valid_pattern ("\\(^a\\)"); valid_pattern ("a\\|^b"); valid_pattern ("\\w^a"); valid_pattern ("\\W^a"); valid_pattern ("(a^)"); valid_pattern ("($a)"); valid_pattern ("a(^b)"); valid_pattern ("a$(b)"); valid_pattern ("(a)^b"); valid_pattern ("(a)$b"); valid_pattern ("(a)(^b)"); valid_pattern ("(a$)(b)"); valid_pattern ("(a|b)^c"); valid_pattern ("(a|b)$c"); valid_pattern ("(a$|b)c"); valid_pattern ("(a|b$)c"); valid_pattern ("a(b|^c)"); valid_pattern ("a(^b|c)"); valid_pattern ("a$(b|c)"); valid_pattern ("(a)(^b|c)"); valid_pattern ("(a)(b|^c)"); valid_pattern ("(b$|c)(a)"); valid_pattern ("(b|c$)(a)"); valid_pattern ("(a(^b|c))"); valid_pattern ("(a(b|^c))"); valid_pattern ("((b$|c)a)"); valid_pattern ("((b|c$)a)"); valid_pattern ("((^a|^b)^c)"); valid_pattern ("(c$(a$|b$))"); valid_pattern ("((^a|^b)^c)"); valid_pattern ("((a$|b$)c)"); valid_pattern ("(c$(a$|b$))"); valid_pattern ("((^a|^b)|^c)^d"); valid_pattern ("((a$|b$)|c$)d$"); valid_pattern ("d$(c$|(a$|b$))"); valid_pattern ("((^a|^b)|^c)(^d)"); valid_pattern ("((a$|b$)|c$)(d$)"); valid_pattern ("(d$)((a$|b$)|c$)"); valid_pattern ("((^a|^b)|^c)((^d))"); valid_pattern ("((a$|b$)|c$)((d$))"); valid_pattern ("((d$))((a$|b$)|c$)"); valid_pattern ("(((^a|^b))c|^d)^e"); valid_pattern ("(((a$|b$))c|d$)$e$"); valid_pattern ("e$(d$|c((a$|b$)))"); valid_pattern ("(^a)((^b))"); valid_pattern ("(a$)((b$))"); valid_pattern ("((^a))(^b)"); valid_pattern ("((a$))(b$)"); valid_pattern ("((^a))((^b))"); valid_pattern ("((a$))((b$))"); valid_pattern ("((^a)^b)"); valid_pattern ("((a$)b$)"); valid_pattern ("(b$(a$))"); valid_pattern ("(((^a)b)^c)"); valid_pattern ("(((a$)b)c$)"); valid_pattern ("(c$(b(a$)))"); valid_pattern ("(((^a)b)c)^d"); valid_pattern ("(((a$)b)c)d$"); valid_pattern ("d$(c(b(a$)))"); valid_pattern (".^a"); valid_pattern ("a$."); valid_pattern ("[a]^b"); valid_pattern ("b$[a]"); valid_pattern ("\\(a$\\)"); valid_pattern ("a$\\|b"); valid_pattern ("(^a|^b)^c"); valid_pattern ("c$(a$|b$)"); valid_pattern ("(^a|^b)^|^c"); valid_pattern ("(a$|b$)$|$c$"); valid_pattern ("(a$|$b$)$|c$"); valid_pattern ("($a$|b$)$|c$"); valid_pattern ("$(a$|b$)$|c$"); valid_pattern ("^c|d(^a|^b)"); valid_pattern ("(^a|^b)|d^c"); valid_pattern ("c$|(a$|b$)d"); valid_pattern ("c$d|(a$|b$)"); valid_pattern ("c(^a|^b)|^d"); valid_pattern ("(a$|b$)c|d$"); valid_pattern ("c(((^a|^b))|^d)e"); valid_pattern ("(c((^a|^b))|^d)e"); valid_pattern ("((c(^a|^b))|^d)e"); valid_pattern ("(((^a|^b))|c^d)e"); valid_pattern ("(((^a|^b))|^d)^e"); valid_pattern ("(c$((a|b))|d)e$"); valid_pattern ("(c((a$|b$))|d)e$"); valid_pattern ("(c((a|b)$)|d)e$"); valid_pattern ("(c((a|b))|d$)e$"); valid_pattern ("^d(^c|e((a|b)))"); valid_pattern ("^d(c|^e((a|b)))"); valid_pattern ("^d(c|e(^(a|b)))"); valid_pattern ("^d(c|e((^a|b)))"); valid_pattern ("^d(c|e((a|^b)))"); valid_pattern ("^d(c|e((a|b^)))"); valid_pattern ("^d(c|e((a|b)^))"); valid_pattern ("^d(c|e((a|b))^)"); valid_pattern ("^d(c|e((a|b)))^"); valid_pattern ("d$(c$|e((a$|b$)))"); valid_pattern ("d(c$|e$((a$|b$)))"); valid_pattern ("(((^a|^b))^c)|^de"); valid_pattern ("(((^a|^b))c)|^d^e"); valid_pattern ("(((a$|b))c$)|de$"); valid_pattern ("(((a|b$))c$)|de$"); valid_pattern ("(((a|b))c$)|d$e$"); valid_pattern ("^d^e|^(c((a|b)))"); valid_pattern ("^de|^(c^((a|b)))"); valid_pattern ("^de|^(c(^(a|b)))"); valid_pattern ("^de|^(c((^a|b)))"); valid_pattern ("^de|^(c((a|^b)))"); valid_pattern ("^de|(^c(^(a|b)))"); valid_pattern ("^de|(^c((^a|b)))"); valid_pattern ("^de|(^c((a|^b)))"); valid_pattern ("de$|(c($(a|b)$))"); valid_pattern ("de$|(c$((a|b)$))"); valid_pattern ("de$|($c((a|b)$))"); valid_pattern ("de$|$(c((a|b)$))"); valid_pattern ("de$|(c($(a|b))$)"); valid_pattern ("de$|(c$((a|b))$)"); valid_pattern ("de$|$(c((a|b))$)"); valid_pattern ("de$|(c($(a|b)))$"); valid_pattern ("de$|(c$((a|b)))$"); valid_pattern ("de$|($c((a|b)))$"); valid_pattern ("de$|$(c((a|b)))$"); valid_pattern ("^a(^b|c)|^d"); valid_pattern ("^a(b|^c)|^d"); valid_pattern ("^a(b|c^)|^d"); valid_pattern ("^a(b|c)^|^d"); valid_pattern ("a$(b$|c$)|d$"); valid_pattern ("^d|^a(^b|c)"); valid_pattern ("^d|^a(b|^c)"); valid_pattern ("d$|a$(b$|c$)"); valid_pattern ("^d|^(b|c)^a"); valid_pattern ("d$|(b|c$)a$"); valid_pattern ("d$|(b$|c)a$"); valid_pattern ("^(a)^(b|c)|^d"); valid_pattern ("^(a)(^b|c)|^d"); valid_pattern ("^(a)(b|^c)|^d"); valid_pattern ("(a)$(b|c)$|d$"); valid_pattern ("(a$)(b|c)$|d$"); valid_pattern ("(^a)(^b|c)|^d"); valid_pattern ("(^a)(b|^c)|^d"); valid_pattern ("(a)$(b$|c$)|d$"); valid_pattern ("(a$)(b$|c$)|d$"); valid_pattern ("^d|^(b|c)^(a)"); valid_pattern ("^d|^(b|c)(^a)"); valid_pattern ("d$|(b|c$)(a)$"); valid_pattern ("d$|(b$|c)(a)$"); valid_pattern ("^d|(^b|^c)^(a)"); valid_pattern ("^d|(^b|^c)(^a)"); valid_pattern ("d$|(b|c)$(a$)"); valid_pattern ("d$|(b|c$)(a$)"); valid_pattern ("d$|(b$|c)(a$)"); valid_pattern ("^d|^(a)^(b|c)"); valid_pattern ("^d|^(a)(^b|c)"); valid_pattern ("^d|^(a)(b|^c)"); valid_pattern ("^d|(^a)^(b|c)"); valid_pattern ("^d|(^a)(^b|c)"); valid_pattern ("^d|(^a)(b|^c)"); valid_pattern ("d$|(a)$(b$|c$)"); valid_pattern ("d$|(a$)(b$|c$)"); valid_pattern ("((e^a|^b)|^c)|^d"); valid_pattern ("((^a|e^b)|^c)|^d"); valid_pattern ("((^a|^b)|e^c)|^d"); valid_pattern ("((^a|^b)|^c)|e^d"); valid_pattern ("d$e|(c$|(a$|b$))"); valid_pattern ("d$|(c$e|(a$|b$))"); valid_pattern ("d$|(c$|(a$e|b$))"); valid_pattern ("d$|(c$|(a$|b$e))"); valid_pattern ("d$|(c$|(a$|b$)e)"); valid_pattern ("d$|(c$|(a$|b$))e"); valid_pattern ("(a|b)^|c"); valid_pattern ("(a|b)|c^"); valid_pattern ("$(a|b)|c"); valid_pattern ("(a|b)|$c"); valid_pattern ("(a^|^b)|^c"); valid_pattern ("(^a|b^)|^c"); valid_pattern ("(^a|^b)|c^"); valid_pattern ("($a|b$)|c$"); valid_pattern ("(a$|$b)|c$"); valid_pattern ("(a$|b$)|$c"); valid_pattern ("c^|(^a|^b)"); valid_pattern ("^c|(a^|^b)"); valid_pattern ("^c|(^a|b^)"); valid_pattern ("$c|(a$|b$)"); valid_pattern ("c$|($a|b$)"); valid_pattern ("c$|(a$|$b)"); valid_pattern ("c^|^(a|b)"); valid_pattern ("^c|(a|b)^"); valid_pattern ("$c|(a|b)$"); valid_pattern ("c$|$(a|b)"); valid_pattern ("(a^|^b)c|^d"); valid_pattern ("(^a|b^)c|^d"); valid_pattern ("(^a|^b)c|d^"); valid_pattern ("(^a|^b)^c|^d"); valid_pattern ("(a|b)c$|$d"); valid_pattern ("(a|b)$c$|d$"); valid_pattern ("(a|b)$c$|d$"); valid_pattern ("(a|b$)c$|d$"); valid_pattern ("(a$|b)c$|d$"); valid_pattern ("($a|b)c$|d$"); valid_pattern ("$(a|b)c$|d$"); valid_pattern ("^d|^c^(a|b)"); valid_pattern ("^d|^c(^a|b)"); valid_pattern ("^d|^c(a|^b)"); valid_pattern ("^d|^c(a|b^)"); valid_pattern ("^d|^c(a|b)^"); valid_pattern ("$d|c(a$|b$)"); valid_pattern ("d$|c($a$|b$)"); valid_pattern ("d$|c$(a$|b$)"); valid_pattern ("d$|$c(a$|b$)"); valid_pattern ("(((a^|^b))c|^d)e"); valid_pattern ("(((^a|b^))c|^d)e"); valid_pattern ("(((^a|^b))^c|^d)e"); valid_pattern ("((^(a|b))c|d^)e"); valid_pattern ("(^((a|b))c|^d)^e"); valid_pattern ("(^((a|b)^)c|^d)e"); valid_pattern ("(^((a^|b))c|^d)e"); valid_pattern ("(^((a|b^))c|^d)e"); valid_pattern ("(^((a|b)^)c|^d)e"); valid_pattern ("(^((a|b))^c|^d)e"); valid_pattern ("(^((a|b))c^|^d)e"); valid_pattern ("(^((a|b))c|^d^)e"); valid_pattern ("(^((a|b))c|^d)^e"); valid_pattern ("(((a|b))c|d)$e$"); valid_pattern ("(((a|b))c|d$)e$"); valid_pattern ("(((a|b))c|$d)e$"); valid_pattern ("(((a|b))c$|d)e$"); valid_pattern ("(((a|b))$c|d)e$"); valid_pattern ("(((a|b)$)c|d)e$"); valid_pattern ("(((a|b$))c|d)e$"); valid_pattern ("(((a$|b))c|d)e$"); valid_pattern ("((($a|b))c|d)e$"); valid_pattern ("(($(a|b))c|d)e$"); valid_pattern ("($((a|b))c|d)e$"); valid_pattern ("$(((a|b))c|d)e$"); valid_pattern ("(^((a|b)^)c|^d)e"); valid_pattern ("(^((a|b))^c|^d)e"); valid_pattern ("(^((a|b))c|^d^)e"); valid_pattern ("(^((a|b))c|^d)^e"); valid_pattern ("^e(^d|c((a|b)))"); valid_pattern ("^e(d|^c((a|b)))"); valid_pattern ("^e(d|c^((a|b)))"); valid_pattern ("^e(d|c(^(a|b)))"); valid_pattern ("^e(d|c((^a|b)))"); valid_pattern ("^e(d|c((a|^b)))"); valid_pattern ("^e(d|c((a|b^)))"); valid_pattern ("^e(d|c((a|b)^))"); valid_pattern ("^e(d|c((a|b))^)"); valid_pattern ("^e(d|c((a|b)))^"); valid_pattern ("e$(d$|c((a$|b$)))"); valid_pattern ("e(d$|c$((a$|b$)))"); valid_pattern ("e(d$|c($(a$|b$)))"); valid_pattern ("e(d$|c(($a$|b$)))"); valid_pattern ("e$(d$|c((a|b)$))"); valid_pattern ("e($d$|c((a|b)$))"); valid_pattern ("e(d$|$c((a|b)$))"); valid_pattern ("e(d$|c$((a|b)$))"); valid_pattern ("e(d$|c($(a|b)$))"); valid_pattern ("e(d$|c(($a|b)$))"); valid_pattern ("e(d$|c((a|$b)$))"); valid_pattern ("e(d$|c((a$|$b$)))"); valid_pattern ("e$(d$|c((a|b))$)"); valid_pattern ("e($d$|c((a|b))$)"); valid_pattern ("e(d$|$c((a|b))$)"); valid_pattern ("e(d$|c$((a|b))$)"); valid_pattern ("e(d$|c($(a|b))$)"); valid_pattern ("e(d$|c(($a|b))$)"); valid_pattern ("e(d$|c((a|$b))$)"); valid_pattern ("e$(d$|c((a|b)))$"); valid_pattern ("e($d$|c((a|b)))$"); valid_pattern ("e(d$|$c((a|b)))$"); valid_pattern ("e(d$|c$((a|b)))$"); valid_pattern ("e(d$|c($(a|b)))$"); valid_pattern ("e(d$|c(($a|b)))$"); valid_pattern ("e(d$|c((a|$b)))$"); valid_pattern ("(((^a|^b)^)c)|^de"); valid_pattern ("(((^a|^b))^c)|^de"); valid_pattern ("(((^a|^b))c)^|^de"); valid_pattern ("$(((a|b))c$)|de$"); valid_pattern ("($((a|b))c$)|de$"); valid_pattern ("(($(a|b))c$)|de$"); valid_pattern ("((($a|b))c$)|de$"); valid_pattern ("(((a|$b))c$)|de$"); valid_pattern ("(((a|b)$)c$)|de$"); valid_pattern ("(((a|b))$c$)|de$"); valid_pattern ("$(((a|b))c)$|de$"); valid_pattern ("($((a|b))c)$|de$"); valid_pattern ("(($(a|b))c)$|de$"); valid_pattern ("((($a|b))c)$|de$"); valid_pattern ("(((a|$b))c)$|de$"); valid_pattern ("(((a|b)$)c)$|de$"); valid_pattern ("(((a|b))$c)$|de$"); valid_pattern ("^ed|^(c((a|b)))^"); valid_pattern ("^ed|^(c((a|b))^)"); valid_pattern ("^ed|^(c((a|b)^))"); valid_pattern ("^ed|^(c((a|b^)))"); valid_pattern ("^ed|^(c((a^|b)))"); valid_pattern ("^ed|^(c((^a|b)))"); valid_pattern ("^ed|^(c(^(a|b)))"); valid_pattern ("^ed|^(c^((a|b)))"); valid_pattern ("^ed|(^c((a|b)))^"); valid_pattern ("^ed|(^c((a|b))^)"); valid_pattern ("^ed|(^c((a|b)^))"); valid_pattern ("^ed|(^c((a|b^)))"); valid_pattern ("^ed|(^c((a|^b)))"); valid_pattern ("^ed|(^c((a^|b)))"); valid_pattern ("^ed|(^c((^a|b)))"); valid_pattern ("^ed|(^c(^(a|b)))"); valid_pattern ("^ed|(^c(^(a|b)))"); valid_pattern ("^ed|(^c^((a|b)))"); valid_pattern ("ed$|$(c((a|b)))$"); valid_pattern ("ed$|($c((a|b)))$"); valid_pattern ("ed$|(c$((a|b)))$"); valid_pattern ("ed$|(c($(a|b)))$"); valid_pattern ("ed$|(c(($a|b)))$"); valid_pattern ("ed$|(c((a|$b)))$"); valid_pattern ("ed$|$(c((a|b))$)"); valid_pattern ("ed$|($c((a|b))$)"); valid_pattern ("ed$|(c$((a|b))$)"); valid_pattern ("ed$|(c($(a|b))$)"); valid_pattern ("ed$|(c(($a|b))$)"); valid_pattern ("ed$|(c((a|$b))$)"); valid_pattern ("ed$|$(c((a|b)$))"); valid_pattern ("ed$|($c((a|b)$))"); valid_pattern ("ed$|(c$((a|b)$))"); valid_pattern ("ed$|(c($(a|b)$))"); valid_pattern ("ed$|(c(($a|b)$))"); valid_pattern ("ed$|(c((a|$b)$))"); valid_pattern ("ed$|$(c((a|b)$))"); valid_pattern ("ed$|($c((a|b)$))"); valid_pattern ("ed$|(c$((a|b)$))"); valid_pattern ("ed$|(c($(a|b)$))"); valid_pattern ("ed$|(c(($a|b)$))"); valid_pattern ("ed$|(c((a|$b)$))"); valid_pattern ("ed$|$(c((a|b)$))"); valid_pattern ("ed$|($c((a|b)$))"); valid_pattern ("ed$|(c$((a|b)$))"); valid_pattern ("ed$|(c($(a|b)$))"); valid_pattern ("ed$|(c(($a|b)$))"); valid_pattern ("ed$|(c((a|$b)$))"); valid_pattern ("ed$|$(c((a|b)$))"); valid_pattern ("ed$|($c((a|b)$))"); valid_pattern ("ed$|(c$((a|b)$))"); valid_pattern ("ed$|(c($(a|b)$))"); valid_pattern ("ed$|(c(($a|b)$))"); valid_pattern ("ed$|(c((a|$b)$))"); valid_pattern ("ed$|$(c((a|b)$))"); valid_pattern ("ed$|($c((a|b)$))"); valid_pattern ("ed$|(c$((a|b)$))"); valid_pattern ("ed$|(c($(a|b)$))"); valid_pattern ("ed$|(c(($a|b)$))"); valid_pattern ("ed$|(c((a|$b)$))"); valid_pattern ("ed$|$(c((a$|b$)))"); valid_pattern ("ed$|($c((a$|b$)))"); valid_pattern ("ed$|(c$((a$|b$)))"); valid_pattern ("ed$|(c($(a$|b$)))"); valid_pattern ("ed$|(c(($a$|b$)))"); valid_pattern ("ed$|(c((a$|$b$)))"); valid_pattern ("^a(b|c)^|^d"); valid_pattern ("^a(b|c^)|^d"); valid_pattern ("^a(b|^c)|^d"); valid_pattern ("^a(b^|c)|^d"); valid_pattern ("^a(^b|c)|^d"); valid_pattern ("^a^(b|c)|^d"); valid_pattern ("$a(b$|c$)|d$"); valid_pattern ("a$(b$|c$)|d$"); valid_pattern ("a($b$|c$)|d$"); valid_pattern ("a(b$|$c$)|d$"); valid_pattern ("a(b$|c$)|$d$"); valid_pattern ("^(a^)(b|c)|^d"); valid_pattern ("^(a)^(b|c)|^d"); valid_pattern ("^(a)(^b|c)|^d"); valid_pattern ("^(a)(b^|c)|^d"); valid_pattern ("^(a)(b|^c)|^d"); valid_pattern ("^(a)(b|c^)|^d"); valid_pattern ("^(a)(b|c)^|^d"); valid_pattern ("(^a^)(b|c)|^d"); valid_pattern ("(^a)^(b|c)|^d"); valid_pattern ("(^a)(^b|c)|^d"); valid_pattern ("(^a)(b^|c)|^d"); valid_pattern ("(^a)(b|^c)|^d"); valid_pattern ("(^a)(b|c^)|^d"); valid_pattern ("(^a)(b|c)^|^d"); valid_pattern ("(a)(b$|c$)d$"); valid_pattern ("(a)(b|$c)$|d$"); valid_pattern ("(a)($b|c)$|d$"); valid_pattern ("(a)$(b|c)$|d$"); valid_pattern ("(a$)(b|c)$|d$"); valid_pattern ("($a)(b|c)$|d$"); valid_pattern ("$(a)(b|c)$|d$"); valid_pattern ("(b|c)($a)$|d$"); valid_pattern ("(b|c)$(a)$|d$"); valid_pattern ("(b|c$)(a)$|d$"); valid_pattern ("(b|$c)(a)$|d$"); valid_pattern ("(b$|c)(a)$|d$"); valid_pattern ("($b|c)(a)$|d$"); valid_pattern ("$(b|c)(a)$|d$"); valid_pattern ("(b|c)($a$)|d$"); valid_pattern ("(b|c)$(a$)|d$"); valid_pattern ("(b|c$)(a$)|d$"); valid_pattern ("(b|$c)(a$)|d$"); valid_pattern ("(b$|c)(a$)|d$"); valid_pattern ("($b|c)(a$)|d$"); valid_pattern ("$(b|c)(a$)|d$"); valid_pattern ("(a)$(b$|c$)|d$"); valid_pattern ("(a$)(b$|c$)|d$"); valid_pattern ("($a)(b$|c$)|d$"); valid_pattern ("$(a)(b$|c$)|d$"); valid_pattern ("^d|^(b^|c)(a)"); valid_pattern ("^d|^(b|c^)(a)"); valid_pattern ("^d|^(b|c)^(a)"); valid_pattern ("^d|^(b|c)(^a)"); valid_pattern ("^d|^(b|c)(a^)"); valid_pattern ("^d|^(b|c)(a)^"); valid_pattern ("^d|(^b|^c^)(a)"); valid_pattern ("^d|(^b|^c)^(a)"); valid_pattern ("^d|(^b|^c)(^a)"); valid_pattern ("^d|(^b|^c)(a^)"); valid_pattern ("^d|(^b|^c)(a)^"); valid_pattern ("d$|(b|c)($a$)"); valid_pattern ("d$|(b|c)$(a$)"); valid_pattern ("d$|(b|c$)(a$)"); valid_pattern ("d$|(b$|c)(a$)"); valid_pattern ("d$|($b|c)(a$)"); valid_pattern ("d$|$(b|c)(a$)"); valid_pattern ("d$|(b|c)($a)$"); valid_pattern ("d$|(b|c)$(a)$"); valid_pattern ("d$|(b|c$)(a)$"); valid_pattern ("d$|(b$|c)(a)$"); valid_pattern ("d$|($b|c)(a)$"); valid_pattern ("d$|$(b|c)(a)$"); valid_pattern ("^d|^(a^)(b|c)"); valid_pattern ("^d|^(a)^(b|c)"); valid_pattern ("^d|^(a)(^b|c)"); valid_pattern ("^d|^(a)(b^|c)"); valid_pattern ("^d|^(a)(b|^c)"); valid_pattern ("^d|^(a)(b|c^)"); valid_pattern ("^d|^(a)(b|c)^"); valid_pattern ("^d|(^a^)(b|c)"); valid_pattern ("^d|(^a)^(b|c)"); valid_pattern ("^d|(^a)(^b|c)"); valid_pattern ("^d|(^a)(b^|c)"); valid_pattern ("^d|(^a)(b|^c)"); valid_pattern ("^d|(^a)(b|c^)"); valid_pattern ("^d|(^a)(b|c)^"); valid_pattern ("d$|(a)$(b$|c$)"); valid_pattern ("d$|(a$)(b$|c$)"); valid_pattern ("d$|($a)(b$|c$)"); valid_pattern ("d$|$(a)(b$|c$)"); valid_pattern ("d$|(a)(b|$c)$"); valid_pattern ("d$|(a)($b|c)$"); valid_pattern ("d$|(a)$(b|c)$"); valid_pattern ("d$|(a$)(b|c)$"); valid_pattern ("d$|($a)(b|c)$"); valid_pattern ("d$|$(a)(b|c)$"); valid_pattern ("((^a|^b)|^c)|^d^"); valid_pattern ("((^a|^b)|^c)^|^d"); valid_pattern ("((^a|^b)|^c^)|^d"); valid_pattern ("((^a|^b)^|^c)|^d"); valid_pattern ("((^a|^b^)|^c)|^d"); valid_pattern ("((^a^|^b)|^c)|^d"); valid_pattern ("((a|b)|c)|$d$"); valid_pattern ("((a|b)|$c)|d$"); valid_pattern ("((a|$b)|c)|d$"); valid_pattern ("(($a|b)|c)|d$"); valid_pattern ("($(a|b)|c)|d$"); valid_pattern ("$((a|b)|c)|d$"); valid_pattern ("^d^|(c|(a|b))"); valid_pattern ("^d|(c^|(a|b))"); valid_pattern ("^d|(c|(a^|b))"); valid_pattern ("^d|(c|(a|b^))"); valid_pattern ("^d|(c|(a|b)^)"); valid_pattern ("^d|(c|(a|b))^"); valid_pattern ("d$|(c$|(a$|$b$))"); valid_pattern ("d$|(c$|($a$|b$))"); valid_pattern ("d$|($c$|(a$|b$))"); valid_pattern ("d$|$(c$|(a$|b$))"); valid_pattern ("$d$|(c$|(a$|b$))"); valid_pattern ("d$|(c$|(a|$b)$)"); valid_pattern ("d$|(c$|($a|b)$)"); valid_pattern ("d$|($c$|(a|b)$)"); valid_pattern ("d$|$(c$|(a|b)$)"); valid_pattern ("$d$|(c$|(a|b)$)"); valid_pattern ("d$|(c$|(a|$b))$"); valid_pattern ("d$|(c$|($a|b))$"); valid_pattern ("d$|($c$|(a|b))$"); valid_pattern ("d$|$(c$|(a|b))$"); valid_pattern ("$d$|(c$|(a|b))$"); valid_pattern ("^c^|(^a|^b)"); valid_pattern ("^c|(^a^|^b)"); valid_pattern ("^c|(^a|^b^)"); valid_pattern ("^c|(^a|^b)^"); valid_pattern ("c$|(a$|$b$)"); valid_pattern ("c$|($a$|b$)"); valid_pattern ("c$|$(a$|b$)"); valid_pattern ("$c$|(a$|b$)"); valid_pattern ("^d^(c|e((a|b)))"); valid_pattern ("^d(^c|e((a|b)))"); valid_pattern ("^d(c^|e((a|b)))"); valid_pattern ("^d(c|^e((a|b)))"); valid_pattern ("^d(c|e^((a|b)))"); valid_pattern ("^d(c|e(^(a|b)))"); valid_pattern ("^d(c|e((^a|b)))"); valid_pattern ("^d(c|e((a|^b)))"); valid_pattern ("^d(c|e((a|b^)))"); valid_pattern ("^d(c|e((a|b)^))"); valid_pattern ("^d(c|e((a|b))^)"); valid_pattern ("^d(c|e((a|b)))^"); valid_pattern ("d(c$|e($(a$|b$)))"); valid_pattern ("d(c$|e$((a$|b$)))"); valid_pattern ("d(c$|$e((a$|b$)))"); valid_pattern ("d($c$|e((a$|b$)))"); valid_pattern ("d$(c$|e((a$|b$)))"); valid_pattern ("$d(c$|e((a$|b$)))"); valid_pattern ("^d|^a^(b|c)"); valid_pattern ("^d|^a(^b|c)"); valid_pattern ("^d|^a(b^|c)"); valid_pattern ("^d|^a(b|^c)"); valid_pattern ("^d|^a(b|c^)"); valid_pattern ("^d|^a(b|c)^"); valid_pattern ("d$|a($b$|c$)"); valid_pattern ("d$|a$(b$|c$)"); valid_pattern ("d$|$a(b$|c$)"); valid_pattern ("$d$|a(b$|c$)"); valid_pattern ("^d|^(b^|c)a"); valid_pattern ("^d|^(b|c^)a"); valid_pattern ("^d|^(b|c)^a"); valid_pattern ("^d|^(b|c)a^"); valid_pattern ("d$|(b|c)$a$"); valid_pattern ("d$|(b|c$)a$"); valid_pattern ("d$|(b|$c)a$"); valid_pattern ("d$|(b$|c)a$"); valid_pattern ("d$|($b|c)a$"); valid_pattern ("d$|$(b|c)a$"); valid_pattern ("$d$|(b|c)a$"); /* xx Do these use all the valid_nonposix_pattern ones in other_test.c? */ TEST_SEARCH ("(^a|^b)c", "ac", 0, 2); TEST_SEARCH ("(^a|^b)c", "bc", 0, 2); TEST_SEARCH ("c(a$|b$)", "ca", 0, 2); TEST_SEARCH ("c(a$|b$)", "cb", 0, 2); TEST_SEARCH ("^(a|b)|^c", "ad", 0, 2); TEST_SEARCH ("^(a|b)|^c", "bd", 0, 2); TEST_SEARCH ("(a|b)$|c$", "da", 0, 2); TEST_SEARCH ("(a|b)$|c$", "db", 0, 2); TEST_SEARCH ("(a|b)$|c$", "dc", 0, 2); TEST_SEARCH ("(^a|^b)|^c", "ad", 0, 2); TEST_SEARCH ("(^a|^b)|^c", "bd", 0, 2); TEST_SEARCH ("(^a|^b)|^c", "cd", 0, 2); TEST_SEARCH ("(a$|b$)|c$", "da", 0, 2); TEST_SEARCH ("(a$|b$)|c$", "db", 0, 2); TEST_SEARCH ("(a$|b$)|c$", "dc", 0, 2); TEST_SEARCH ("^c|(^a|^b)", "ad", 0, 2); TEST_SEARCH ("^c|(^a|^b)", "bd", 0, 2); TEST_SEARCH ("^c|(^a|^b)", "cd", 0, 2); TEST_SEARCH ("c$|(a$|b$)", "da", 0, 2); TEST_SEARCH ("c$|(a$|b$)", "db", 0, 2); TEST_SEARCH ("c$|(a$|b$)", "dc", 0, 2); TEST_SEARCH ("^c|^(a|b)", "ad", 0, 2); TEST_SEARCH ("^c|^(a|b)", "bd", 0, 2); TEST_SEARCH ("^c|^(a|b)", "cd", 0, 2); TEST_SEARCH ("c$|(a|b)$", "da", 0, 2); TEST_SEARCH ("c$|(a|b)$", "db", 0, 2); TEST_SEARCH ("c$|(a|b)$", "dc", 0, 2); TEST_SEARCH ("(^a|^b)c|^d", "ace", 0, 3); TEST_SEARCH ("(^a|^b)c|^d", "bce", 0, 3); TEST_SEARCH ("(^a|^b)c|^d", "de", 0, 2); TEST_SEARCH ("(a|b)c$|d$", "eac", 0, 3); TEST_SEARCH ("(a|b)c$|d$", "ebc", 0, 3); TEST_SEARCH ("(a|b)c$|d$", "ed", 0, 3); TEST_SEARCH ("^d|^c(a|b)", "cae", 0, 3); TEST_SEARCH ("^d|^c(a|b)", "cbe", 0, 3); TEST_SEARCH ("^d|^c(a|b)", "de", 0, 3); TEST_SEARCH ("d$|c(a$|b$)", "eca", 0, 3); TEST_SEARCH ("d$|c(a$|b$)", "ecb", 0, 3); TEST_SEARCH ("d$|c(a$|b$)", "ed", 0, 3); TEST_SEARCH ("(((^a|^b))c|^d)e", "acef", 0, 4); TEST_SEARCH ("(((^a|^b))c|^d)e", "bcef", 0, 4); TEST_SEARCH ("(((^a|^b))c|^d)e", "def", 0, 3); TEST_SEARCH ("((^(a|b))c|^d)e", "acef", 0, 4); TEST_SEARCH ("((^(a|b))c|^d)e", "bcef", 0, 4); TEST_SEARCH ("((^(a|b))c|^d)e", "def", 0, 3); TEST_SEARCH ("(^((a|b))c|^d)e", "acef", 0, 4); TEST_SEARCH ("(^((a|b))c|^d)e", "bcef", 0, 4); TEST_SEARCH ("(^((a|b))c|^d)e", "def", 0, 3); TEST_SEARCH ("(((a|b))c|d)e$", "face", 0, 4); TEST_SEARCH ("(((a|b))c|d)e$", "fbce", 0, 4); TEST_SEARCH ("(((a|b))c|d)e$", "fde", 0, 3); TEST_SEARCH ("^e(d|c((a|b)))", "edf", 0, 3); TEST_SEARCH ("^e(d|c((a|b)))", "ecaf", 0, 4); TEST_SEARCH ("^e(d|c((a|b)))", "ecbf", 0, 4); TEST_SEARCH ("e(d$|c((a$|b$)))", "fed", 0, 3); TEST_SEARCH ("e(d$|c((a$|b$)))", "feca", 0, 4); TEST_SEARCH ("e(d$|c((a$|b$)))", "fecb", 0, 4); TEST_SEARCH ("e(d$|c((a|b)$))", "fed", 0, 3); TEST_SEARCH ("e(d$|c((a|b)$))", "feca", 0, 4); TEST_SEARCH ("e(d$|c((a|b)$))", "fecb", 0, 4); TEST_SEARCH ("e(d$|c((a|b))$)", "fed", 0, 3); TEST_SEARCH ("e(d$|c((a|b))$)", "feca", 0, 3); TEST_SEARCH ("e(d$|c((a|b))$)", "fecb", 0, 3); TEST_SEARCH ("e(d$|c((a|b)))$", "fed", 0, 3); TEST_SEARCH ("e(d$|c((a|b)))$", "feca", 0, 3); TEST_SEARCH ("e(d$|c((a|b)))$", "fecb", 0, 3); TEST_SEARCH ("(((^a|^b))c)|^de", "acf", 0, 3); TEST_SEARCH ("(((^a|^b))c)|^de", "bcf", 0, 3); TEST_SEARCH ("(((^a|^b))c)|^de", "def", 0, 3); TEST_SEARCH ("(((a|b))c$)|de$", "fac", 0, 3); TEST_SEARCH ("(((a|b))c$)|de$", "fbc", 0, 3); TEST_SEARCH ("(((a|b))c$)|de$", "fde", 0, 3); TEST_SEARCH ("(((a|b))c)$|de$", "fac", 0, 3); TEST_SEARCH ("(((a|b))c)$|de$", "fbc", 0, 3); TEST_SEARCH ("(((a|b))c)$|de$", "fde", 0, 3); TEST_SEARCH ("^ed|^(c((a|b)))", "edf", 0, 3); TEST_SEARCH ("^ed|^(c((a|b)))", "caf", 0, 3); TEST_SEARCH ("^ed|^(c((a|b)))", "cbf", 0, 3); TEST_SEARCH ("^ed|(^c((a|b)))", "edf", 0, 3); TEST_SEARCH ("^ed|(^c((a|b)))", "caf", 0, 3); TEST_SEARCH ("^ed|(^c((a|b)))", "cbf", 0, 3); TEST_SEARCH ("ed$|(c((a|b)))$", "fed", 0, 3); TEST_SEARCH ("ed$|(c((a|b)))$", "fca", 0, 3); TEST_SEARCH ("ed$|(c((a|b)))$", "fcb", 0, 3); TEST_SEARCH ("ed$|(c((a|b))$)", "fed", 0, 3); TEST_SEARCH ("ed$|(c((a|b))$)", "fca", 0, 3); TEST_SEARCH ("ed$|(c((a|b))$)", "fcb", 0, 3); TEST_SEARCH ("ed$|(c((a|b)$))", "fed", 0, 3); TEST_SEARCH ("ed$|(c((a|b)$))", "fca", 0, 3); TEST_SEARCH ("ed$|(c((a|b)$))", "fcb", 0, 3); TEST_SEARCH ("ed$|(c((a$|b$)))", "fed", 0, 3); TEST_SEARCH ("ed$|(c((a$|b$)))", "fca", 0, 3); TEST_SEARCH ("ed$|(c((a$|b$)))", "fcb", 0, 3); TEST_SEARCH ("^a(b|c)|^d", "abe", 0, 3); TEST_SEARCH ("^a(b|c)|^d", "ace", 0, 3); TEST_SEARCH ("^a(b|c)|^d", "df", 0, 2); TEST_SEARCH ("a(b$|c$)|d$", "fab", 0, 3); TEST_SEARCH ("a(b$|c$)|d$", "fac", 0, 3); TEST_SEARCH ("a(b$|c$)|d$", "fd", 0, 2); TEST_SEARCH ("^(a)(b|c)|^d", "abe", 0, 3); TEST_SEARCH ("^(a)(b|c)|^d", "ace", 0, 3); TEST_SEARCH ("^(a)(b|c)|^d", "df", 0, 2); TEST_SEARCH ("(^a)(b|c)|^d", "abe", 0, 3); TEST_SEARCH ("(^a)(b|c)|^d", "ace", 0, 3); TEST_SEARCH ("(^a)(b|c)|^d", "df", 0, 2); TEST_SEARCH ("(a)(b|c)$|d$", "fab", 0, 3); TEST_SEARCH ("(a)(b|c)$|d$", "fac", 0, 3); TEST_SEARCH ("(a)(b|c)$|d$", "fd", 0, 2); TEST_SEARCH ("(b|c)(a)$|d$", "fba", 0, 3); TEST_SEARCH ("(b|c)(a)$|d$", "fca", 0, 3); TEST_SEARCH ("(b|c)(a)$|d$", "fd", 0, 2); TEST_SEARCH ("(b|c)(a$)|d$", "fba", 0, 3); TEST_SEARCH ("(b|c)(a$)|d$", "fca", 0, 3); TEST_SEARCH ("(b|c)(a$)|d$", "fd", 0, 2); TEST_SEARCH ("(a)(b$|c$)|d$", "fab", 0, 3); TEST_SEARCH ("(a)(b$|c$)|d$", "fac", 0, 3); TEST_SEARCH ("(a)(b$|c$)|d$", "fd", 0, 2); TEST_SEARCH ("^d|^(b|c)(a)", "df", 0, 2); TEST_SEARCH ("^d|^(b|c)(a)", "baf", 0, 3); TEST_SEARCH ("^d|^(b|c)(a)", "caf", 0, 3); TEST_SEARCH ("^d|(^b|^c)(a)", "df", 0, 2); TEST_SEARCH ("^d|(^b|^c)(a)", "baf", 0, 3); TEST_SEARCH ("^d|(^b|^c)(a)", "caf", 0, 3); TEST_SEARCH ("d$|(b|c)(a$)", "fd", 0, 2); TEST_SEARCH ("d$|(b|c)(a$)", "fba", 0, 3); TEST_SEARCH ("d$|(b|c)(a$)", "fca", 0, 3); TEST_SEARCH ("d$|(b|c)(a)$", "fd", 0, 2); TEST_SEARCH ("d$|(b|c)(a)$", "fba", 0, 3); TEST_SEARCH ("d$|(b|c)(a)$", "fca", 0, 3); TEST_SEARCH ("d$|(b|c)(a$)", "fd", 0, 2); TEST_SEARCH ("d$|(b|c)(a$)", "fba", 0, 3); TEST_SEARCH ("d$|(b|c)(a$)", "fca", 0, 3); TEST_SEARCH ("^d|^(a)(b|c)", "df", 0, 2); TEST_SEARCH ("^d|^(a)(b|c)", "abf", 0, 3); TEST_SEARCH ("^d|^(a)(b|c)", "acf", 0, 3); TEST_SEARCH ("^d|(^a)(b|c)", "df", 0, 2); TEST_SEARCH ("^d|(^a)(b|c)", "abf", 0, 3); TEST_SEARCH ("^d|(^a)(b|c)", "acf", 0, 3); TEST_SEARCH ("d$|(a)(b$|c$)", "fd", 0, 2); TEST_SEARCH ("d$|(a)(b$|c$)", "fab", 0, 3); TEST_SEARCH ("d$|(a)(b$|c$)", "fac", 0, 3); TEST_SEARCH ("d$|(a)(b|c)$", "fd", 0, 2); TEST_SEARCH ("d$|(a)(b|c)$", "fab", 0, 3); TEST_SEARCH ("d$|(a)(b|c)$", "fac", 0, 3); TEST_SEARCH ("((^a|^b)|^c)|^d", "ae", 0, 2); TEST_SEARCH ("((^a|^b)|^c)|^d", "be", 0, 2); TEST_SEARCH ("((^a|^b)|^c)|^d", "ce", 0, 2); TEST_SEARCH ("((^a|^b)|^c)|^d", "de", 0, 2); TEST_SEARCH ("((a|b)|c)|d$", "ed", 0, 2); TEST_SEARCH ("((a|b)|c)|d$", "ea", 0, 2); TEST_SEARCH ("((a|b)|c)|d$", "eb", 0, 2); TEST_SEARCH ("((a|b)|c)|d$", "ec", 0, 2); TEST_SEARCH ("^d|(c|(a|b))", "de", 0, 2); TEST_SEARCH ("d$|(c$|(a$|b$))", "ed", 0, 2); TEST_SEARCH ("d$|(c$|(a$|b$))", "ec", 0, 2); TEST_SEARCH ("d$|(c$|(a$|b$))", "ea", 0, 2); TEST_SEARCH ("d$|(c$|(a$|b$))", "eb", 0, 2); TEST_SEARCH ("d$|(c$|(a|b)$)", "ed", 0, 2); TEST_SEARCH ("d$|(c$|(a|b)$)", "ec", 0, 2); TEST_SEARCH ("d$|(c$|(a|b)$)", "ea", 0, 2); TEST_SEARCH ("d$|(c$|(a|b)$)", "eb", 0, 2); TEST_SEARCH ("d$|(c$|(a|b))$", "ed", 0, 2); TEST_SEARCH ("d$|(c$|(a|b))$", "ec", 0, 2); TEST_SEARCH ("d$|(c$|(a|b))$", "ea", 0, 2); TEST_SEARCH ("d$|(c$|(a|b))$", "eb", 0, 2); test_match ("a|^b", "b"); test_match ("a|b$", "b"); test_match ("^b|a", "b"); test_match ("b$|a", "b"); test_match ("(^a)", "a"); test_match ("(a$)", "a"); TEST_SEARCH ("c|^ab", "aba", 0, 3); TEST_SEARCH ("c|ba$", "aba", 0, 3); TEST_SEARCH ("^ab|c", "aba", 0, 3); TEST_SEARCH ("ba$|c", "aba", 0, 3); TEST_SEARCH ("(^a)", "ab", 0, 2); TEST_SEARCH ("(a$)", "ba", 0, 2); TEST_SEARCH ("(^a$)", "a", 0, 1); TEST_SEARCH ("(^a)", "ab", 0, 2); TEST_SEARCH ("(b$)", "ab", 0, 2); /* Backtracking. */ /* Per POSIX D11.1 p. 108, leftmost longest match. */ test_match ("(wee|week)(knights|night)", "weeknights"); test_match ("(fooq|foo)qbar", "fooqbar"); test_match ("(fooq|foo)(qbarx|bar)", "fooqbarx"); /* Take first alternative that does the longest match. */ test_all_registers ("(fooq|(foo)|(fo))((qbarx)|(oqbarx)|bar)", "fooqbarx", "", 0, 8, 0, 3, 0, 3, -1, -1, 3, 8, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1); test_match ("(fooq|foo)*qbar", "fooqbar"); test_match ("(fooq|foo)*(qbar)", "fooqbar"); test_match ("(fooq|foo)*(qbar)*", "fooqbar"); test_match ("(fooq|fo|o)*qbar", "fooqbar"); test_match ("(fooq|fo|o)*(qbar)", "fooqbar"); test_match ("(fooq|fo|o)*(qbar)*", "fooqbar"); test_match ("(fooq|fo|o)*(qbar|q)*", "fooqbar"); test_match ("(fooq|foo)*(qbarx|bar)", "fooqbarx"); test_match ("(fooq|foo)*(qbarx|bar)*", "fooqbarx"); test_match ("(fooq|fo|o)+(qbar|q)+", "fooqbar"); test_match ("(fooq|foo)+(qbarx|bar)", "fooqbarx"); test_match ("(fooq|foo)+(qbarx|bar)+", "fooqbarx"); /* Per Mike Haertel. */ test_match ("(foo|foobarfoo)(bar)*", "foobarfoo"); /* Combination. */ test_match ("[ab]?c", "ac"); test_match ("[ab]*c", "ac"); test_match ("[ab]+c", "ac"); test_match ("(a|b)?c", "ac"); test_match ("(a|b)*c", "ac"); test_match ("(a|b)+c", "ac"); test_match ("(a*c)?b", "b"); test_match ("(a*c)+b", "aacb"); /* Registers. */ /* Per David A. Willcox. */ test_match ("a((b)|(c))d", "acd"); test_all_registers ("a((b)|(c))d", "acd", "", 0, 3, 1, 2, -1, -1, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); /* Extended regular expressions, continued; these don't match their strings. */ test_should_match = false; #if 0 /* Invalid use of special characters. */ /* These are not invalid anymore, since POSIX says the behavior is undefined, and we prefer context-independent to context-invalid. */ invalid_pattern (REG_BADRPT, "*"); invalid_pattern (REG_BADRPT, "a|*"); invalid_pattern (REG_BADRPT, "(*)"); invalid_pattern (REG_BADRPT, "^*"); invalid_pattern (REG_BADRPT, "+"); invalid_pattern (REG_BADRPT, "a|+"); invalid_pattern (REG_BADRPT, "(+)"); invalid_pattern (REG_BADRPT, "^+"); invalid_pattern (REG_BADRPT, "?"); invalid_pattern (REG_BADRPT, "a|?"); invalid_pattern (REG_BADRPT, "(?)"); invalid_pattern (REG_BADRPT, "^?"); invalid_pattern (REG_BADPAT, "|"); invalid_pattern (REG_BADPAT, "a|"); invalid_pattern (REG_BADPAT, "a||"); invalid_pattern (REG_BADPAT, "(|a)"); invalid_pattern (REG_BADPAT, "(a|)"); invalid_pattern (REG_BADPAT, PARENS_TO_OPS ("(|)")); invalid_pattern (REG_BADRPT, "{1}"); invalid_pattern (REG_BADRPT, "a|{1}"); invalid_pattern (REG_BADRPT, "^{1}"); invalid_pattern (REG_BADRPT, "({1})"); invalid_pattern (REG_BADPAT, "|b"); invalid_pattern (REG_BADRPT, "^{0,}*"); invalid_pattern (REG_BADRPT, "$*"); invalid_pattern (REG_BADRPT, "${0,}*"); #endif /* 0 */ invalid_pattern (REG_EESCAPE, "\\"); test_match ("a?b", "a"); test_match ("a+", ""); test_match ("a+b", "a"); test_match ("a?", "b"); #if 0 /* We make empty groups valid now, since they are undefined in POSIX. (13 Sep 92) */ /* Subexpressions. */ invalid_pattern (REG_BADPAT, "()"); invalid_pattern (REG_BADPAT, "a()"); invalid_pattern (REG_BADPAT, "()b"); invalid_pattern (REG_BADPAT, "a()b"); invalid_pattern (REG_BADPAT, "()*"); invalid_pattern (REG_BADPAT, "(()*"); #endif /* Invalid intervals. */ test_match ("a{2}*", "aaa"); test_match ("a{2}?", "aaa"); test_match ("a{2}+", "aaa"); test_match ("a{2}{2}", "aaa"); test_match ("a{1}{1}{2}", "aaa"); test_match ("a{1}{1}{2}", "a"); /* Invalid alternation. */ test_match ("a|b", "c"); TEST_SEARCH ("c|^ba", "aba", 0, 3); TEST_SEARCH ("c|ab$", "aba", 0, 3); TEST_SEARCH ("^ba|c", "aba", 0, 3); TEST_SEARCH ("ab$|c", "aba", 0, 3); /* Invalid anchoring. */ TEST_SEARCH ("(^a)", "ba", 0, 2); TEST_SEARCH ("(b$)", "ba", 0, 2); printf ("\nFinished POSIX extended tests.\n"); } /* Local variables: make-backup-files: t version-control: t trim-versions-without-asking: nil End: */ lyskom-server-2.1.2/src/libraries/regex/test/psx-generic.c0000664000015100472110000002604505314452723017255 /* psx-generic.c: test POSIX re's independent of us using basic or extended syntax. */ #include "test.h" void test_posix_generic () { int omit_generic_tests = 0; /* reset in debugger to skip */ if (omit_generic_tests) return; /* Tests somewhat in the order of P1003.2. */ /* Both posix basic and extended; should match. */ printf ("\nStarting generic POSIX tests.\n"); test_grouping (); test_intervals (); test_should_match = true; /* Ordinary characters. */ printf ("\nContinuing generic POSIX tests.\n"); MATCH_SELF (""); test_fastmap ("", "", 0, 0); test_fastmap_search ("", "", "", 0, 0, 2, 0, 0); TEST_REGISTERS ("", "", 0, 0, -1, -1, -1, -1); TEST_SEARCH ("", "", 0, 0); TEST_SEARCH_2 ("", "", "", 0, 1, 0); MATCH_SELF ("abc"); test_fastmap ("abc", "a", 0, 0); TEST_REGISTERS ("abc", "abc", 0, 3, -1, -1, -1, -1); TEST_REGISTERS ("abc", "xabcx", 1, 4, -1, -1, -1, -1); test_match ("\\a","a"); test_match ("\\0", "0"); TEST_SEARCH ("a", "ab", 0, 2); TEST_SEARCH ("b", "ab", 0, 2); TEST_SEARCH ("a", "ab", 1, -2); TEST_SEARCH_2 ("a", "a", "b", 0, 2, 2); TEST_SEARCH_2 ("b", "a", "b", 0, 2, 2); TEST_SEARCH_2 ("a", "a", "b", 1, -2, 2); test_match ("\n", "\n"); test_match ("a\n", "a\n"); test_match ("\nb", "\nb"); test_match ("a\nb", "a\nb"); TEST_SEARCH ("b", "baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 236, -237); /* Valid use of special characters. */ test_match ("a*", "aa"); test_fastmap ("a*", "a", 0, 0); TEST_REGISTERS ("a*", "aa", 0, 2, -1, -1, -1, -1); test_match ("a*b", "aab"); test_fastmap ("a*b", "ab", 0, 0); test_match ("a*ab", "aab"); TEST_REGISTERS ("a*a", "aa", 0, 2, -1, -1, -1, -1); TEST_REGISTERS ("a*a", "xaax", 1, 3, -1, -1, -1, -1); test_match ("\\{", "{"); test_match ("\\^", "^"); test_match ("\\.", "."); test_match ("\\*", "*"); test_match ("\\[", "["); test_match ("\\$", "$"); test_match ("\\\\", "\\"); test_match ("ab*", "a"); test_match ("ab*", "abb"); /* Valid consecutive repetitions. */ test_match ("a**", "a"); /* Valid period. */ test_match (".", "a"); TEST_REGISTERS (".", "a", 0, 1, -1, -1, -1, -1); test_match (".", "\004"); test_match (".", "\n"); /* Valid bracket expressions. */ test_match ("[ab]", "a"); test_match ("[ab]", "b"); test_fastmap ("[ab]", "ab", 0, 0); TEST_REGISTERS ("[ab]", "a", 0, 1, -1, -1, -1, -1); TEST_REGISTERS ("[ab]", "xax", 1, 2, -1, -1, -1, -1); test_fastmap ("[^ab]", "ab", 1, 1); test_match ("[^ab]", "c"); test_match ("[^a]", "\n"); test_match ("[a]*a", "aa"); test_match ("[[]", "["); test_match ("[]]", "]"); test_match ("[.]", "."); test_match ("[*]", "*"); test_match ("[\\]", "\\"); test_match ("[\\(]", "("); test_match ("[\\)]", ")"); test_match ("[^]]", "a"); test_match ("[a^]", "^"); test_match ("[a$]", "$"); test_match ("[]a]", "]"); test_match ("[a][]]", "a]"); test_match ("[\n]", "\n"); test_match ("[^a]", "\n"); test_match ("[a-]", "a"); TEST_REGISTERS ("\\`[ \t\n]*", " karl (Karl Berry)", 0, 1, -1, -1, -1, -1); TEST_REGISTERS ("[ \t\n]*\\'", " karl (Karl Berry)", 18, 18, -1, -1, -1, -1); /* Collating, noncollating, equivalence classes aren't implemented yet. */ /* Character classes. */ test_match ("[:alpha:]", "p"); test_match ("[[:alpha:]]", "a"); test_match ("[[:alpha:]]", "z"); test_match ("[[:alpha:]]", "A"); test_match ("[[:alpha:]]", "Z"); test_match ("[[:upper:]]", "A"); test_match ("[[:upper:]]", "Z"); test_match ("[[:lower:]]", "a"); test_match ("[[:lower:]]", "z"); test_match ("[[:digit:]]", "0"); test_match ("[[:digit:]]", "9"); test_fastmap ("[[:digit:]]", "0123456789", 0, 0); test_match ("[[:alnum:]]", "0"); test_match ("[[:alnum:]]", "9"); test_match ("[[:alnum:]]", "a"); test_match ("[[:alnum:]]", "z"); test_match ("[[:alnum:]]", "A"); test_match ("[[:alnum:]]", "Z"); test_match ("[[:xdigit:]]", "0"); test_match ("[[:xdigit:]]", "9"); test_match ("[[:xdigit:]]", "A"); test_match ("[[:xdigit:]]", "F"); test_match ("[[:xdigit:]]", "a"); test_match ("[[:xdigit:]]", "f"); test_match ("[[:space:]]", " "); test_match ("[[:print:]]", " "); test_match ("[[:print:]]", "~"); test_match ("[[:punct:]]", ","); test_match ("[[:graph:]]", "!"); test_match ("[[:graph:]]", "~"); test_match ("[[:cntrl:]]", "\177"); test_match ("[[:digit:]a]", "a"); test_match ("[[:digit:]a]", "2"); test_match ("[a[:digit:]]", "a"); test_match ("[a[:digit:]]", "2"); test_match ("[[:]", "["); test_match ("[:]", ":"); test_match ("[[:a]", "["); test_match ("[[:alpha:a]", "["); /* Valid ranges. */ test_match ("[a-a]", "a"); test_fastmap ("[a-a]", "a", 0, 0); TEST_REGISTERS ("[a-a]", "xax", 1, 2, -1, -1, -1, -1); test_match ("[a-z]", "z"); test_fastmap ("[a-z]", "abcdefghijklmnopqrstuvwxyz", 0, 0); test_match ("[-a]", "-"); /* First */ test_match ("[-a]", "a"); test_match ("[a-]", "-"); /* Last */ test_match ("[a-]", "a"); test_match ("[--@]", "@"); /* First and starting point. */ test_match ("[%--a]", "%"); /* Ending point. */ test_match ("[%--a]", "-"); /* Ditto. */ test_match ("[a%--]", "%"); /* Both ending point and last. */ test_match ("[a%--]", "-"); test_match ("[%--a]", "a"); /* Ending point only. */ test_match ("[a-c-f]", "e"); /* Piggyback. */ test_match ("[)-+--/]", "*"); test_match ("[)-+--/]", ","); test_match ("[)-+--/]", "/"); test_match ("[[:digit:]-]", "-"); /* Concatenation ????*/ test_match ("[ab][cd]", "ac"); test_fastmap ("[ab][cd]", "ab", 0, 0); TEST_REGISTERS ("[ab][cd]", "ad", 0, 2, -1, -1, -1, -1); TEST_REGISTERS ("[ab][cd]", "xadx", 1, 3, -1, -1, -1, -1); /* Valid expression anchoring. */ test_match ("^a", "a"); test_fastmap ("^a", "a", 0, 0); TEST_REGISTERS ("^a", "ax", 0, 1, -1, -1, -1, -1); test_match ("^", ""); TEST_REGISTERS ("^", "", 0, 0, -1, -1, -1, -1); test_match ("$", ""); TEST_REGISTERS ("$", "", 0, 0, -1, -1, -1, -1); test_match ("a$", "a"); test_fastmap ("a$", "a", 0, 0); TEST_REGISTERS ("a$", "xa", 1, 2, -1, -1, -1, -1); test_match ("^ab$", "ab"); test_fastmap ("^ab$", "a", 0, 0); TEST_REGISTERS ("^a$", "a", 0, 1, -1, -1, -1, -1); test_fastmap ("^$", "", 0, 0); test_match ("^$", ""); TEST_REGISTERS ("^$", "", 0, 0, -1, -1, -1, -1); TEST_SEARCH (PARENS_TO_OPS ("(^a)"), "ab", 0, 2); TEST_SEARCH (PARENS_TO_OPS ("(a$)"), "ba", 0, 2); TEST_SEARCH (PARENS_TO_OPS ("^(^a)"), "ab", 0, 2); TEST_SEARCH (PARENS_TO_OPS ("(a$)$"), "ba", 0, 2); /* Two strings. */ test_match_2 ("ab", "a", "b"); TEST_REGISTERS_2 ("ab", "a", "b", 0, 2, -1, -1, -1, -1); test_match_2 ("a", "", "a"); test_match_2 ("a", "a", ""); test_match_2 ("ab", "a", "b"); /* (start)pos. */ TEST_POSITIONED_MATCH ("b", "ab", 1); /* mstop. */ TEST_TRUNCATED_MATCH ("a", "ab", 1); /* Both basic and extended, continued; should not match. */ test_should_match = false; /* Ordinary characters. */ test_match ("abc", "ab"); TEST_SEARCH ("c", "ab", 0, 2); TEST_SEARCH ("c", "ab", 0, 2); TEST_SEARCH ("c", "ab", 1, -2); TEST_SEARCH ("c", "ab", 0, 10); TEST_SEARCH ("c", "ab", 1, -10); TEST_SEARCH_2 ("c", "a", "b", 0, 2, 2); TEST_SEARCH_2 ("c", "a", "b", 0, 2, 2); TEST_SEARCH_2 ("c", "a", "b", 0, 2, 2); TEST_SEARCH_2 ("c", "a", "b", 1, -2, 2); TEST_SEARCH_2 ("c", "a", "b", 1, -2, 2); TEST_SEARCH ("c", "baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 236, -237); /* Invalid use of special characters. */ invalid_pattern (REG_EESCAPE, "\\"); invalid_pattern (REG_EESCAPE, "a\\"); invalid_pattern (REG_EESCAPE, "a*\\"); /* Invalid period. */ test_match (".", ""); /* Invalid bracket expressions. */ test_match ("[ab]", "c"); test_match ("[^b]", "b"); test_match ("[^]]", "]"); invalid_pattern (REG_EBRACK, "["); invalid_pattern (REG_EBRACK, "[^"); invalid_pattern (REG_EBRACK, "[a"); invalid_pattern (REG_EBRACK, "[]"); invalid_pattern (REG_EBRACK, "[]a"); invalid_pattern (REG_EBRACK, "a[]a"); test_match ("[:alpha:]", "q"); /* Character classes. */ test_match ("[[:alpha:]]", "2"); test_match ("[[:upper:]]", "a"); test_match ("[[:lower:]]", "A"); test_match ("[[:digit:]]", "a"); test_match ("[[:alnum:]]", ":"); test_match ("[[:xdigit:]]", "g"); test_match ("[[:space:]]", "a"); test_match ("[[:print:]]", "\177"); test_match ("[[:punct:]]", "a"); test_match ("[[:graph:]]", " "); test_match ("[[:cntrl:]]", "a"); invalid_pattern (REG_EBRACK, "[[:"); invalid_pattern (REG_EBRACK, "[[:alpha:"); invalid_pattern (REG_EBRACK, "[[:alpha:]"); invalid_pattern (REG_ECTYPE, "[[::]]"); invalid_pattern (REG_ECTYPE, "[[:a:]]"); invalid_pattern (REG_ECTYPE, "[[:alpo:]]"); invalid_pattern (REG_ECTYPE, "[[:a:]"); test_match ("[a-z]", "2"); /* Invalid ranges. */ test_match ("[^-a]", "-"); test_match ("[^a-]", "-"); test_match ("[)-+--/]", "."); invalid_pattern (REG_ERANGE, "[z-a]"); /* Empty */ invalid_pattern (REG_ERANGE, "[a--]"); /* Empty */ invalid_pattern (REG_ERANGE, "[[:digit:]-9]"); invalid_pattern (REG_ERANGE, "[a-[:alpha:]]"); invalid_pattern (REG_ERANGE, "[a-"); invalid_pattern (REG_EBRACK, "[a-z"); test_match ("[ab][cd]", "ae"); /* Concatenation. */ test_match ("b*c", "b"); /* Star. */ /* Invalid anchoring. */ test_match ("^", "a"); test_match ("^a", "ba"); test_match ("$", "b"); test_match ("a$", "ab"); test_match ("^$", "a"); test_match ("^ab$", "a"); TEST_SEARCH ("^a", "b\na", 0, 3); TEST_SEARCH ("b$", "b\na", 0, 3); test_match_2 ("^a", "\n", "a"); test_match_2 ("a$", "a", "\n"); TEST_SEARCH (PARENS_TO_OPS ("(^a)"), "ba", 0, 2); TEST_SEARCH (PARENS_TO_OPS ("(a$)"), "ab", 0, 2); TEST_SEARCH (PARENS_TO_OPS ("^(^a)"), "ba", 0, 2); TEST_SEARCH (PARENS_TO_OPS ("(a$)$"), "ab", 0, 2); printf ("\nFinished generic POSIX tests.\n"); } /* Local variables: make-backup-files: t version-control: t trim-versions-without-asking: nil End: */ lyskom-server-2.1.2/src/libraries/regex/test/psx-group.c0000664000015100472110000004525005314452723016774 /* psx-group.c: test POSIX grouping, both basic and extended. */ #include "test.h" void test_grouping () { printf ("\nStarting POSIX grouping tests.\n"); test_should_match = true; test_fastmap (PARENS_TO_OPS ("(a)"), "a", 0, 0); test_match (PARENS_TO_OPS ("(a)"), "a"); TEST_REGISTERS (PARENS_TO_OPS ("(a)"), "a", 0, 1, 0, 1, -1, -1); TEST_REGISTERS (PARENS_TO_OPS ("(a)"), "xax", 1, 2, 1, 2, -1, -1); test_match (PARENS_TO_OPS ("((a))"), "a"); test_fastmap (PARENS_TO_OPS ("((a))"), "a", 0, 0); TEST_REGISTERS (PARENS_TO_OPS ("((a))"), "a", 0, 1, 0, 1, 0, 1); TEST_REGISTERS (PARENS_TO_OPS ("((a))"), "xax", 1, 2, 1, 2, 1, 2); test_fastmap (PARENS_TO_OPS ("(a)(b)"), "a", 0, 0); test_match (PARENS_TO_OPS ("(a)(b)"), "ab"); TEST_REGISTERS (PARENS_TO_OPS ("(a)(b)"), "ab", 0, 2, 0, 1, 1, 2); TEST_REGISTERS (PARENS_TO_OPS ("(a)(b)"), "xabx", 1, 3, 1, 2, 2, 3); test_all_registers (PARENS_TO_OPS ("((a)(b))"), "ab", "", 0, 2, 0, 2, 0, 1, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); /* Test that we simply ignore groups past the 255th. */ test_match (PARENS_TO_OPS ("((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((a))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))"), "a"); /* Per POSIX D11.1, p. 125. */ test_fastmap (PARENS_TO_OPS ("(a)*"), "a", 0, 0); test_match (PARENS_TO_OPS ("(a)*"), ""); TEST_REGISTERS (PARENS_TO_OPS ("(a)*"), "", 0, 0, -1, -1, -1, -1); TEST_REGISTERS (PARENS_TO_OPS ("(a)*"), "aa", 0, 2, 1, 2, -1, -1); test_fastmap (PARENS_TO_OPS ("(a*)"), "a", 0, 0); test_match (PARENS_TO_OPS ("(a*)"), ""); TEST_REGISTERS (PARENS_TO_OPS ("(a*)"), "", 0, 0, 0, 0, -1, -1); test_fastmap (PARENS_TO_OPS ("(a*)"), "a", 0, 0); test_match (PARENS_TO_OPS ("(a*)"), "a"); TEST_REGISTERS (PARENS_TO_OPS ("(a*)"), "a", 0, 1, 0, 1, -1, -1); test_fastmap (PARENS_TO_OPS ("(a*)b"), "ab", 0, 0); test_match (PARENS_TO_OPS ("(a*)b"), "b"); TEST_REGISTERS (PARENS_TO_OPS ("(a*)b"), "b", 0, 1, 0, 0, -1, -1); test_match (PARENS_TO_OPS ("(a*)b"), "ab"); TEST_REGISTERS (PARENS_TO_OPS ("(a*)b"), "ab", 0, 2, 0, 1, -1, -1); test_fastmap (PARENS_TO_OPS ("((a*)b)*"), "ab", 0, 0); test_match (PARENS_TO_OPS ("((a*)b)*"), ""); TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "", 0, 0, -1, -1, -1, -1); test_match (PARENS_TO_OPS ("((a*)b)*"), "ab"); TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "ab", 0, 2, 0, 2, 0, 1); test_match (PARENS_TO_OPS ("((a*)b)*"), "abb"); TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "abb", 0, 3, 2, 3, 2, 2); test_match (PARENS_TO_OPS ("((a*)b)*"), "aabab"); TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "aabab", 0, 5, 3, 5, 3, 4); test_match (PARENS_TO_OPS ("((a*)b)*"), "abbab"); TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "abbab", 0, 5, 3, 5, 3, 4); TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "xabbabx", 0, 0, -1, -1, -1, -1); test_match (PARENS_TO_OPS ("((a*)b)*"), "abaabaaaab"); TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "abaabaaab", 0, 9, 5, 9, 5, 8); test_fastmap (PARENS_TO_OPS ("(ab)*"), "a", 0, 0); test_match (PARENS_TO_OPS ("(ab)*"), ""); TEST_REGISTERS (PARENS_TO_OPS ("(ab)*"), "", 0, 0, -1, -1, -1, -1); test_match (PARENS_TO_OPS ("(ab)*"), "abab"); TEST_REGISTERS (PARENS_TO_OPS ("(ab)*"), "abab", 0, 4, 2, 4, -1, -1); /* We match the empty string here. */ TEST_REGISTERS (PARENS_TO_OPS ("(ab)*"), "xababx", 0, 0, -1, -1, -1, -1); /* Per David A. Willcox. */ TEST_REGISTERS (PARENS_TO_OPS ("a(b*)c"), "ac", 0, 2, 1, 1, -1, -1); test_fastmap (PARENS_TO_OPS ("(a)*b"), "ab", 0, 0); test_match (PARENS_TO_OPS ("(a)*b"), "b"); TEST_REGISTERS (PARENS_TO_OPS ("(a)*b"), "b", 0, 1, -1, -1, -1, -1); test_match (PARENS_TO_OPS ("(a)*b"), "ab"); TEST_REGISTERS (PARENS_TO_OPS ("(a)*b"), "ab", 0, 2, 0, 1, -1, -1); test_match_2 (PARENS_TO_OPS ("(a)*b"), "a", "ab"); TEST_REGISTERS_2 (PARENS_TO_OPS ("(a)*b"), "a", "ab", 0, 3, 1, 2, -1, -1); test_match (PARENS_TO_OPS ("(a)*b"), "aab"); TEST_REGISTERS (PARENS_TO_OPS ("(a)*b"), "aab", 0, 3, 1, 2, -1, -1); test_fastmap (PARENS_TO_OPS ("(a)*a"), "a", 0, 0); test_match (PARENS_TO_OPS ("(a)*a"), "a"); TEST_REGISTERS (PARENS_TO_OPS ("(a)*a"), "a", 0, 1, -1, -1, -1, -1); TEST_REGISTERS (PARENS_TO_OPS ("(a*)*"), "", 0, 0, 0, 0, 0, 0); test_match (PARENS_TO_OPS ("((a*))*"), ""); TEST_REGISTERS (PARENS_TO_OPS ("((a*))*"), "", 0, 0, 0, 0, 0, 0); test_match (PARENS_TO_OPS ("((a*))*"), "aa"); test_fastmap (PARENS_TO_OPS ("(a*)*b"), "ab", 0, 0); test_match (PARENS_TO_OPS ("(a*)*b"), "b"); TEST_REGISTERS (PARENS_TO_OPS ("(a*)*b"), "b", 0, 1, 0, 0, -1, -1); TEST_REGISTERS (PARENS_TO_OPS ("(a*)*b"), "xbx", 1, 2, 1, 1, -1, -1); test_match (PARENS_TO_OPS ("(a*)*b"), "ab"); /* Per rms. */ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*b"), "ab", 0, 2, 0, 1, -1, -1); TEST_REGISTERS (PARENS_TO_OPS ("(a*)*b"), "xabx", 1, 3, 1, 2, -1, -1); /* Test register restores. */ test_match (PARENS_TO_OPS ("(a*)*b"), "aab"); TEST_REGISTERS (PARENS_TO_OPS ("(a*)*b"), "aab", 0, 3, 0, 2, -1, -1); TEST_REGISTERS_2 (PARENS_TO_OPS ("(a*)*b"), "a", "ab", 0, 3, 0, 2, -1, -1); /* We are matching the empty string, with backtracking. */ test_fastmap (PARENS_TO_OPS ("(a*)a"), "a", 0, 0); test_match (PARENS_TO_OPS ("(a*)a"), "a"); TEST_REGISTERS (PARENS_TO_OPS ("(a*)a"), "a", 0, 1, 0, 0, -1, -1); test_match (PARENS_TO_OPS ("(a*)a"), "aa"); TEST_REGISTERS (PARENS_TO_OPS ("(a*)a"), "aa", 0, 2, 0, 1, -1, -1); /* We are matching the empty string, with backtracking. */ /*fails test_match (PARENS_TO_OPS ("(a*)*a"), "a"); */ test_match (PARENS_TO_OPS ("(a*)*a"), "aa"); /* Match the empty string. */ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*a"), "a", 0, 1, 0, 0, -1, -1); TEST_REGISTERS (PARENS_TO_OPS ("(a*)*a"), "xax", 1, 2, 1, 1, -1, -1); TEST_REGISTERS (PARENS_TO_OPS ("(a*)*a"), "aa", 0, 2, 0, 1, -1, -1); TEST_REGISTERS (PARENS_TO_OPS ("(a*)*a"), "xaax", 1, 3, 1, 2, -1, -1); test_fastmap (PARENS_TO_OPS ("(a)*ab"), "a", 0 , 0); test_match (PARENS_TO_OPS ("(a)*ab"), "ab"); TEST_REGISTERS (PARENS_TO_OPS ("(a)*ab"), "ab", 0, 2, -1, -1, -1, -1); test_match (PARENS_TO_OPS ("(a)*ab"), "aab"); TEST_REGISTERS (PARENS_TO_OPS ("(a)*ab"), "aab", 0, 3, 0, 1, -1, -1); TEST_REGISTERS (PARENS_TO_OPS("(a)*ab"), "xaabx", 1, 4, 1, 2, -1, -1); test_fastmap (PARENS_TO_OPS ("(a*)ab"), "a", 0 , 0); test_match (PARENS_TO_OPS ("(a*)ab"), "ab"); TEST_REGISTERS (PARENS_TO_OPS ("(a*)ab"), "ab", 0, 2, 0, 0, -1, -1); test_match (PARENS_TO_OPS ("(a*)ab"), "aab"); TEST_REGISTERS (PARENS_TO_OPS ("(a*)ab"), "aab", 0, 3, 0, 1, -1, -1); TEST_REGISTERS (PARENS_TO_OPS ("(a*)ab"), "xaabx", 1, 4, 1, 2, -1, -1); test_fastmap (PARENS_TO_OPS ("(a*)*ab"), "a", 0 , 0); test_match (PARENS_TO_OPS ("(a*)*ab"), "ab"); TEST_REGISTERS (PARENS_TO_OPS ("(a*)*ab"), "ab", 0, 2, 0, 0, -1, -1); test_match (PARENS_TO_OPS ("(a*)*ab"), "aab"); TEST_REGISTERS (PARENS_TO_OPS ("(a*)*ab"), "aab", 0, 3, 0, 1, -1, -1); TEST_REGISTERS (PARENS_TO_OPS("(a*)*ab"), "xaabx", 1, 4, 1, 2, -1, -1); test_fastmap (PARENS_TO_OPS ("(a*)*b*c"), "abc", 0, 0); test_match (PARENS_TO_OPS ("(a*)*b*c"), "c"); TEST_REGISTERS (PARENS_TO_OPS ("(a*)*b*c"), "c", 0, 1, 0, 0, -1, -1); test_fastmap (PARENS_TO_OPS ("(a)*(ab)*"), "a", 0, 0); test_match (PARENS_TO_OPS ("(a)*(ab)*"), "ab"); /* Register 1 doesn't match at all (vs. matching the empty string) because of backtracking, hence -1's. */ TEST_REGISTERS (PARENS_TO_OPS ("(a)*(ab)*"), "ab", 0, 2, -1, -1, 0, 2); test_match (PARENS_TO_OPS ("(a*)*(ab)*"), "ab"); TEST_REGISTERS (PARENS_TO_OPS ("(a*)*(ab)*"), "ab", 0, 2, 0, 0, 0, 2); test_fastmap (PARENS_TO_OPS ("(a*b)*"), "ab", 0, 0); test_match (PARENS_TO_OPS ("(a*b)*"), ""); TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*"), "", 0, 0, -1, -1, -1, -1); test_match (PARENS_TO_OPS ("(a*b)*"), "b"); TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*"), "b", 0, 1, 0, 1, -1, -1); test_match (PARENS_TO_OPS ("(a*b)*"), "baab"); TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*"), "baab", 0, 4, 1, 4, -1, -1); test_fastmap (PARENS_TO_OPS ("(a*b*)*"), "ab", 0, 0); test_match (PARENS_TO_OPS ("(a*b*)*"), ""); TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "", 0, 0, 0, 0, -1, -1); test_match (PARENS_TO_OPS ("(a*b*)*"), "a"); TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "a", 0, 1, 0, 1, -1, -1); test_match (PARENS_TO_OPS ("(a*b*)*"), "ba"); TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "ba", 0, 2, 1, 2, -1, -1); test_match (PARENS_TO_OPS ("(a*b*)*"), "ab"); TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "ab", 0, 2, 0, 2, -1, -1); test_match (PARENS_TO_OPS ("(a*b*)*"), "aa"); TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "aa", 0, 2, 0, 2, -1, -1); test_match (PARENS_TO_OPS ("(a*b*)*"), "bb"); TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "bb", 0, 2, 0, 2, -1, -1); test_match (PARENS_TO_OPS ("(a*b*)*"), "aba"); TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "aba", 0, 3, 2, 3, -1, -1); test_match (PARENS_TO_OPS ("(a*b*)b"), "b"); TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)b"), "b", 0, 1, 0, 0, -1, -1); test_fastmap (PARENS_TO_OPS ("((a*)*(b*)*)*"), "ab", 0, 0); test_match (PARENS_TO_OPS ("((a*)*(b*)*)*"), ""); test_all_registers (PARENS_TO_OPS ("((a*)*(b*)*)*"), "", "", 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); test_match (PARENS_TO_OPS ("((a*)*(b*)*)*"), "aba"); /* Perhaps register 3 should be 3/3 here? Not sure if standard specifies this. xx*/ test_all_registers (PARENS_TO_OPS ("((a*)*(b*)*)*"), "aba", "", 0, 3, 2, 3, 2, 3, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); test_fastmap (PARENS_TO_OPS ("((a*)(b*))*"), "ab", 0, 0); test_match (PARENS_TO_OPS ("((a*)(b*))*"), ""); test_all_registers (PARENS_TO_OPS ("((a*)(b*))*"), "", "", 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); test_match (PARENS_TO_OPS ("(c(c(a)*(b)*)*)*"), ""); test_match (PARENS_TO_OPS ("((a*)(b*))*"), "aba"); test_all_registers (PARENS_TO_OPS ("((a*)(b*))*"), "aba", "", 0, 3, 2, 3, 2, 3, 3, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); test_fastmap (PARENS_TO_OPS ("((a)*(b)*)*"), "ab", 0, 0); test_match (PARENS_TO_OPS ("((a)*(b)*)*"), ""); test_all_registers (PARENS_TO_OPS ("((a)*(b)*)*"), "", "", 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); test_match (PARENS_TO_OPS ("((a)*(b)*)*"), "aba"); test_all_registers (PARENS_TO_OPS ("((a)*(b)*)*"), "aba", "", 0, 3, 2, 3, 2, 3, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); test_fastmap (PARENS_TO_OPS ("(c(a)*(b)*)*"), "c", 0, 0); test_match (PARENS_TO_OPS ("(c(a)*(b)*)*"), ""); test_all_registers (PARENS_TO_OPS ("(c(a)*(b)*)*"), "", "", 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); test_match (PARENS_TO_OPS ("(c(a)*(b)*)*"), "c"); test_all_registers (PARENS_TO_OPS ("(c(a)*(b)*)*"), "c", "", 0, 1, 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); test_fastmap (PARENS_TO_OPS ("c((a)*(b)*)*"), "c", 0, 0); test_match (PARENS_TO_OPS ("c((a)*(b)*)*"), "c"); test_all_registers (PARENS_TO_OPS ("c((a)*(b)*)*"), "c", "", 0, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); test_fastmap (PARENS_TO_OPS ("(((a)*(b)*)*)*"), "ab", 0, 0); test_match (PARENS_TO_OPS ("(((a)*(b)*)*)*"), ""); test_all_registers (PARENS_TO_OPS ("(((a)*(b)*)*)*"), "", "", 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); test_match (PARENS_TO_OPS ("(c(c(a)*(b)*)*)*"), ""); test_fastmap (PARENS_TO_OPS ("(c(c(a)*(b)*)*)*"), "c", 0, 0); test_all_registers (PARENS_TO_OPS ("(c(c(a)*(b)*)*)*"), "", "", 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); test_fastmap (PARENS_TO_OPS ("((a)*b)*"), "ab", 0, 0); test_match (PARENS_TO_OPS ("((a)*b)*"), ""); test_match (PARENS_TO_OPS ("((a)*b)*"), ""); TEST_REGISTERS (PARENS_TO_OPS ("((a)*b)*"), "", 0, 0, -1, -1, -1, -1); test_match (PARENS_TO_OPS ("((a)*b)*"), "abb"); TEST_REGISTERS (PARENS_TO_OPS ("((a)*b)*"), "abb", 0, 3, 2, 3, 0, 1); /*zz*/ test_match (PARENS_TO_OPS ("((a)*b)*"), "abbab"); TEST_REGISTERS (PARENS_TO_OPS ("((a)*b)*"), "abbab", 0, 5, 3, 5, 3, 4); /* We match the empty string here. */ TEST_REGISTERS (PARENS_TO_OPS ("((a)*b)*"), "xabbabx", 0, 0, -1, -1, -1, -1); test_fastmap (PARENS_TO_OPS ("(a*)*"), "a", 0, 0); test_match (PARENS_TO_OPS ("(a*)*"), ""); TEST_REGISTERS (PARENS_TO_OPS ("(a*)*"), "", 0, 0, 0, 0, -1, -1); test_match (PARENS_TO_OPS ("(a*)*"), "aa"); TEST_REGISTERS (PARENS_TO_OPS ("(a*)*"), "aa", 0, 2, 0, 2, -1, -1); test_fastmap (PARENS_TO_OPS ("((a*)*)*"), "a", 0, 0); test_match (PARENS_TO_OPS ("((a*)*)*"), ""); TEST_REGISTERS (PARENS_TO_OPS ("((a*)*)*"), "", 0, 0, 0, 0, 0, 0); test_match (PARENS_TO_OPS ("((a*)*)*"), "a"); TEST_REGISTERS (PARENS_TO_OPS ("((a*)*)*"), "a", 0, 1, 0, 1, 0, 1); test_fastmap (PARENS_TO_OPS ("(ab*)*"), "a", 0, 0); test_match (PARENS_TO_OPS ("(ab*)*"), ""); TEST_REGISTERS (PARENS_TO_OPS ("(ab*)*"), "", 0, 0, -1, -1, -1, -1); test_match (PARENS_TO_OPS ("(ab*)*"), "aa"); TEST_REGISTERS (PARENS_TO_OPS ("(ab*)*"), "aa", 0, 2, 1, 2, -1, -1); test_fastmap (PARENS_TO_OPS ("(ab*)*c"), "ac", 0, 0); test_match (PARENS_TO_OPS ("(ab*)*c"), "c"); TEST_REGISTERS (PARENS_TO_OPS ("(ab*)*c"), "c", 0, 1, -1, -1, -1, -1); test_match (PARENS_TO_OPS ("(ab*)*c"), "abbac"); TEST_REGISTERS (PARENS_TO_OPS ("(ab*)*c"), "abbac", 0, 5, 3, 4, -1, -1); test_match (PARENS_TO_OPS ("(ab*)*c"), "abac"); TEST_REGISTERS (PARENS_TO_OPS ("(ab*)*c"), "abac", 0, 4, 2, 3, -1, -1); test_fastmap (PARENS_TO_OPS ("(a*b)*c"), "abc", 0, 0); test_match (PARENS_TO_OPS ("(a*b)*c"), "c"); TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*c"), "c", 0, 1, -1, -1, -1, -1); test_match (PARENS_TO_OPS ("(a*b)*c"), "bbc"); TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*c"), "bbc", 0, 3, 1, 2, -1, -1); test_match (PARENS_TO_OPS ("(a*b)*c"), "aababc"); TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*c"), "aababc", 0, 6, 3, 5, -1, -1); test_match (PARENS_TO_OPS ("(a*b)*c"), "aabaabc"); TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*c"), "aabaabc", 0, 7, 3, 6, -1, -1); test_fastmap (PARENS_TO_OPS ("((a*)b*)"), "ab", 0, 0); test_match (PARENS_TO_OPS ("((a*)b*)"), ""); TEST_REGISTERS (PARENS_TO_OPS ("((a*)b*)"), "", 0, 0, 0, 0, 0, 0); test_match (PARENS_TO_OPS ("((a*)b*)"), "a"); TEST_REGISTERS (PARENS_TO_OPS ("((a*)b*)"), "a", 0, 1, 0, 1, 0, 1); test_match (PARENS_TO_OPS ("((a*)b*)"), "b"); TEST_REGISTERS (PARENS_TO_OPS ("((a*)b*)"), "b", 0, 1, 0, 1, 0, 0); test_fastmap (PARENS_TO_OPS ("((a)*b*)"), "ab", 0, 0); test_match (PARENS_TO_OPS ("((a)*b*)"), ""); TEST_REGISTERS (PARENS_TO_OPS ("((a)*b*)"), "", 0, 0, 0, 0, -1, -1); test_match (PARENS_TO_OPS ("((a)*b*)"), "a"); TEST_REGISTERS (PARENS_TO_OPS ("((a)*b*)"), "a", 0, 1, 0, 1, 0, 1); test_match (PARENS_TO_OPS ("((a)*b*)"), "b"); TEST_REGISTERS (PARENS_TO_OPS ("((a)*b*)"), "b", 0, 1, 0, 1, -1, -1); test_match (PARENS_TO_OPS ("((a)*b*)"), "ab"); TEST_REGISTERS (PARENS_TO_OPS ("((a)*b*)"), "ab", 0, 2, 0, 2, 0, 1); test_fastmap (PARENS_TO_OPS ("((a*)b*)c"), "abc", 0, 0); test_match (PARENS_TO_OPS ("((a*)b*)c"), "c"); TEST_REGISTERS (PARENS_TO_OPS ("((a*)b*)c"), "c", 0, 1, 0, 0, 0, 0); test_fastmap (PARENS_TO_OPS ("((a)*b*)c"), "abc", 0, 0); test_match (PARENS_TO_OPS ("((a)*b*)c"), "c"); TEST_REGISTERS (PARENS_TO_OPS ("((a)*b*)c"), "c", 0, 1, 0, 0, -1, -1); test_fastmap (PARENS_TO_OPS ("(a*b*)*"), "ab", 0, 0); test_match (PARENS_TO_OPS ("(a*b*)*"), ""); TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "", 0, 0, 0, 0, -1, -1); test_fastmap (PARENS_TO_OPS ("(((a*))((b*)))*"), "ab", 0, 0); test_match (PARENS_TO_OPS ("(((a*))((b*)))*"), ""); test_all_registers (PARENS_TO_OPS ("(((a*))((b*)))*"), "", "", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1); test_fastmap (PARENS_TO_OPS ("(c*((a*))d*((b*))e*)*"), "abcde", 0, 0); test_match (PARENS_TO_OPS ("(c*((a*))d*((b*))e*)*"), ""); test_all_registers (PARENS_TO_OPS ("(c*((a*))d*((b*))e*)*"), "", "", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1); test_fastmap (PARENS_TO_OPS ("((a)*b)*c"), "abc", 0, 0); test_match (PARENS_TO_OPS ("((a)*b)*c"), "c"); TEST_REGISTERS (PARENS_TO_OPS ("((a)*b)*c"), "c", 0, 1, -1, -1, -1, -1); test_match (PARENS_TO_OPS ("(ab)*"), ""); test_match (PARENS_TO_OPS ("((ab)*)"), ""); test_match (PARENS_TO_OPS ("(((ab)*))"), ""); test_match (PARENS_TO_OPS ("((((ab)*)))"), ""); test_match (PARENS_TO_OPS ("(((((ab)*))))"), ""); test_match (PARENS_TO_OPS ("((((((ab)*)))))"), ""); test_match (PARENS_TO_OPS ("(((((((ab)*))))))"), ""); test_match (PARENS_TO_OPS ("((((((((ab)*)))))))"), ""); test_match (PARENS_TO_OPS ("(((((((((ab)*))))))))"), ""); test_fastmap (PARENS_TO_OPS ("(((((((((ab)*))))))))"), "a", 0, 0); test_match (PARENS_TO_OPS ("((((((((((ab)*)))))))))"), ""); test_match (PARENS_TO_OPS ("(((((((((ab)*))))))))"), ""); test_all_registers (PARENS_TO_OPS ("(((((((((ab)*))))))))"), "", NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1); test_match (PARENS_TO_OPS ("(((((((((ab)*))))))))"), "abab"); test_all_registers (PARENS_TO_OPS ("(((((((((ab)*))))))))"), "abab", NULL, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 2, 4); test_should_match = false; invalid_pattern (REG_EPAREN, PARENS_TO_OPS ("(a")); test_match (PARENS_TO_OPS ("(a)"), ""); test_match (PARENS_TO_OPS ("((a))"), "b"); test_match (PARENS_TO_OPS ("(a)(b)"), "ac"); test_match (PARENS_TO_OPS ("(ab)*"), "acab"); test_match (PARENS_TO_OPS ("(a*)*b"), "c"); test_match (PARENS_TO_OPS ("(a*b)*"), "baa"); test_match (PARENS_TO_OPS ("(a*b)*"), "baabc"); test_match (PARENS_TO_OPS ("(a*b*)*"), "c"); test_match (PARENS_TO_OPS ("((a*)*(b*)*)*"), "c"); test_match (PARENS_TO_OPS ("(a*)*"), "ab"); test_match (PARENS_TO_OPS ("((a*)*)*"), "ab"); test_match (PARENS_TO_OPS ("((a*)*)*"), "b"); test_match (PARENS_TO_OPS ("(ab*)*"), "abc"); test_match (PARENS_TO_OPS ("(ab*)*c"), "abbad"); test_match (PARENS_TO_OPS ("(a*c)*b"), "aacaacd"); test_match (PARENS_TO_OPS ("(a*)"), "b"); test_match (PARENS_TO_OPS ("((a*)b*)"), "c"); /* Expression anchoring. */ TEST_SEARCH (PARENS_TO_OPS ("(^b)"), "ab", 0, 2); TEST_SEARCH (PARENS_TO_OPS ("(a$)"), "ab", 0, 2); printf ("\nFinished POSIX grouping tests.\n"); } lyskom-server-2.1.2/src/libraries/regex/test/psx-interf.c0000664000015100472110000004477305533104657017143 /* psx-interf.c: test POSIX interface. */ #include #include #include "test.h" #define ERROR_CODE_LENGTH 20 #define TEST_ERRBUF_SIZE 15 void test_compile (); /* ANSWER should be at least ERROR_CODE_LENGTH long. */ static char * get_error_string (error_code, answer) int error_code; char answer[]; { switch (error_code) { case 0: strcpy (answer, "No error"); break; case REG_NOMATCH: strcpy (answer, "REG_NOMATCH"); break; case REG_BADPAT: strcpy (answer, "REG_BADPAT"); break; case REG_EPAREN: strcpy (answer, "REG_EPAREN"); break; case REG_ESPACE: strcpy (answer, "REG_ESPACE"); break; case REG_ECOLLATE: strcpy (answer, "REG_ECOLLATE"); break; case REG_ECTYPE: strcpy (answer, "REG_ECTYPE"); break; case REG_EESCAPE: strcpy (answer, "REG_EESCAPE"); break; case REG_ESUBREG: strcpy (answer, "REG_ESUBREG"); break; case REG_EBRACK: strcpy (answer, "REG_EBRACK"); break; case REG_EBRACE: strcpy (answer, "REG_EBRACE"); break; case REG_BADBR: strcpy (answer, "REG_BADBR"); break; case REG_ERANGE: strcpy (answer, "REG_ERANGE"); break; case REG_BADRPT: strcpy (answer, "REG_BADRPT"); break; case REG_EEND: strcpy (answer, "REG_EEND"); break; default: strcpy (answer, "Bad error code"); } return answer; } /* I don't think we actually need to initialize all these things. --karl */ void init_pattern_buffer (pattern_buffer_ptr) regex_t *pattern_buffer_ptr; { pattern_buffer_ptr->buffer = NULL; pattern_buffer_ptr->allocated = 0; pattern_buffer_ptr->used = 0; pattern_buffer_ptr->fastmap = NULL; pattern_buffer_ptr->fastmap_accurate = 0; pattern_buffer_ptr->translate = NULL; pattern_buffer_ptr->can_be_null = 0; pattern_buffer_ptr->re_nsub = 0; pattern_buffer_ptr->no_sub = 0; pattern_buffer_ptr->not_bol = 0; pattern_buffer_ptr->not_eol = 0; } void test_compile (valid_pattern, error_code_expected, pattern, pattern_buffer_ptr, cflags) unsigned valid_pattern; int error_code_expected; const char *pattern; regex_t *pattern_buffer_ptr; int cflags; { int error_code_returned; boolean error = false; char errbuf[TEST_ERRBUF_SIZE]; init_pattern_buffer (pattern_buffer_ptr); error_code_returned = regcomp (pattern_buffer_ptr, pattern, cflags); if (valid_pattern && error_code_returned) { printf ("\nShould have been a valid pattern but wasn't.\n"); regerror (error_code_returned, pattern_buffer_ptr, errbuf, TEST_ERRBUF_SIZE); printf ("%s", errbuf); error = true; } if (!valid_pattern && !error_code_returned) { printf ("\n\nInvalid pattern compiled as valid:\n"); error = true; } if (error_code_returned != error_code_expected) { char expected_error_string[ERROR_CODE_LENGTH]; char returned_error_string[ERROR_CODE_LENGTH]; get_error_string (error_code_expected, expected_error_string), get_error_string (error_code_returned, returned_error_string); printf (" Expected error code %s but got `%s'.\n", expected_error_string, returned_error_string); error = true; } if (error) print_pattern_info (pattern, pattern_buffer_ptr); } static void test_nsub (sub_count, pattern, cflags) unsigned sub_count; char *pattern; int cflags; { regex_t pattern_buffer; test_compile (1, 0, pattern, &pattern_buffer, cflags); if (pattern_buffer.re_nsub != sub_count) { printf ("\nShould have counted %d subexpressions but counted %d \ instead.\n", sub_count, pattern_buffer.re_nsub); } regfree (&pattern_buffer); } static void test_regcomp () { regex_t pattern_buffer; int cflags = 0; printf ("\nStarting regcomp tests.\n"); cflags = 0; test_compile (0, REG_ESUBREG, "\\(a\\)\\2", &pattern_buffer, cflags); test_compile (0, REG_EBRACE, "a\\{", &pattern_buffer, cflags); test_compile (0, REG_BADBR, "a\\{-1\\}", &pattern_buffer, cflags); test_compile (0, REG_EBRACE, "a\\{", &pattern_buffer, cflags); test_compile (0, REG_EBRACE, "a\\{1", &pattern_buffer, cflags); cflags = REG_EXTENDED; test_compile (0, REG_ECTYPE, "[[:alpo:]]", &pattern_buffer, cflags); test_compile (0, REG_EESCAPE, "\\", &pattern_buffer, cflags); test_compile (0, REG_EBRACK, "[a", &pattern_buffer, cflags); test_compile (0, REG_EPAREN, "(", &pattern_buffer, cflags); test_compile (0, REG_ERANGE, "[z-a]", &pattern_buffer, cflags); test_nsub (1, "(a)", cflags); test_nsub (2, "((a))", cflags); test_nsub (2, "(a)(b)", cflags); cflags = REG_EXTENDED | REG_NOSUB; test_nsub (1, "(a)", cflags); regfree (&pattern_buffer); printf ("\nFinished regcomp tests.\n"); } static void fill_pmatch (pmatch, start0, end0, start1, end1, start2, end2) regmatch_t pmatch[]; regoff_t start0, end0, start1, end1, start2, end2; { pmatch[0].rm_so = start0; pmatch[0].rm_eo = end0; pmatch[1].rm_so = start1; pmatch[1].rm_eo = end1; pmatch[2].rm_so = start2; pmatch[2].rm_eo = end2; } static void test_pmatch (pattern, string, nmatch, pmatch, correct_pmatch, cflags) char *pattern; char *string; unsigned nmatch; regmatch_t pmatch[]; regmatch_t correct_pmatch[]; int cflags; { regex_t pattern_buffer; unsigned this_match; int error_code_returned; boolean found_nonmatch = false; test_compile (1, 0, pattern, &pattern_buffer, cflags); error_code_returned = regexec (&pattern_buffer, string, nmatch, pmatch, 0); if (error_code_returned == REG_NOMATCH) printf ("Matching failed in test_pmatch.\n"); else { for (this_match = 0; this_match < nmatch; this_match++) { if (pmatch[this_match].rm_so != correct_pmatch[this_match].rm_so) { if (found_nonmatch == false) printf ("\n"); printf ("Pmatch start %d wrong: was %d when should have \ been %d.\n", this_match, pmatch[this_match].rm_so, correct_pmatch[this_match].rm_so); found_nonmatch = true; } if (pmatch[this_match].rm_eo != correct_pmatch[this_match].rm_eo) { if (found_nonmatch == false) printf ("\n"); printf ("Pmatch end %d wrong: was %d when should have been \ %d.\n", this_match, pmatch[this_match].rm_eo, correct_pmatch[this_match].rm_eo); found_nonmatch = true; } } if (found_nonmatch) { printf (" The number of pmatches requested was: %d.\n", nmatch); printf (" The string to match was: `%s'.\n", string); print_pattern_info (pattern, &pattern_buffer); } } /* error_code_returned == REG_NOMATCH */ regfree (&pattern_buffer); } static void test_eflags (must_match_bol, must_match_eol, pattern, string, cflags, eflags) boolean must_match_bol; boolean must_match_eol; char *pattern; char *string; int cflags; int eflags; { regex_t pattern_buffer; int error_code_returned; boolean was_error = false; test_compile (1, 0, pattern, &pattern_buffer, cflags); error_code_returned = regexec (&pattern_buffer, string, 0, 0, eflags); if (error_code_returned == REG_NOMATCH) { /* If wasn't true that both 1) the anchored part of the pattern had to match this string and 2) this string was a proper substring... */ if (!( (must_match_bol && (eflags & REG_NOTBOL)) || (must_match_eol && (eflags & REG_NOTEOL)) )) { printf ("\nEflags test failed: didn't match when should have.\n"); was_error = true; } } else /* We got a match. */ { /* If wasn't true that either 1) the anchored part of the pattern didn't have to match this string or 2) this string wasn't a proper substring... */ if ((must_match_bol == (eflags & REG_NOTBOL)) || (must_match_eol == (eflags & REG_NOTEOL))) { printf ("\nEflags test failed: matched when shouldn't have.\n"); was_error = true; } } if (was_error) { printf (" The string to match was: `%s'.\n", string); print_pattern_info (pattern, &pattern_buffer); if (eflags & REG_NOTBOL) printf (" The eflag REG_BOL was set.\n"); if (eflags & REG_NOTEOL) printf (" The eflag REG_EOL was set.\n"); } regfree (&pattern_buffer); } static void test_ignore_case (should_match, pattern, string, cflags) boolean should_match; char *pattern; char *string; int cflags; { regex_t pattern_buffer; int error_code_returned; test_compile (1, 0, pattern, &pattern_buffer, cflags); error_code_returned = regexec (&pattern_buffer, string, 0, 0, 0); if (should_match && error_code_returned == REG_NOMATCH) { printf ("\nIgnore-case test failed:\n"); printf (" The string to match was: `%s'.\n", string); print_pattern_info (pattern, &pattern_buffer); if (cflags & REG_ICASE) printf (" The cflag REG_ICASE was set.\n"); } regfree (&pattern_buffer); } static void test_newline (should_match, pattern, string, cflags) boolean should_match; char *pattern; char *string; int cflags; { regex_t pattern_buffer; int error_code_returned; test_compile (1, 0, pattern, &pattern_buffer, cflags); error_code_returned = regexec (&pattern_buffer, string, 0, 0, 0); if (should_match && error_code_returned == REG_NOMATCH) { printf ("\nNewline test failed:\n"); printf (" The string to match was: `%s'.\n", string); print_pattern_info (pattern, &pattern_buffer); if (cflags & REG_NEWLINE) printf (" The cflag REG_NEWLINE was set.\n"); else printf (" The cflag REG_NEWLINE wasn't set.\n"); } regfree (&pattern_buffer); } static void test_posix_match (should_match, pattern, string, cflags) boolean should_match; char *pattern; char *string; int cflags; { regex_t pattern_buffer; int error_code_returned; boolean was_error = false; test_compile (1, 0, pattern, &pattern_buffer, cflags); error_code_returned = regexec (&pattern_buffer, string, 0, 0, 0); if (should_match && error_code_returned == REG_NOMATCH) { printf ("\nShould have matched but didn't:\n"); was_error = true; } else if (!should_match && error_code_returned != REG_NOMATCH) { printf ("\nShould not have matched but did:\n"); was_error = true; } if (was_error) { printf (" The string to match was: `%s'.\n", string); print_pattern_info (pattern, &pattern_buffer); } regfree (&pattern_buffer); } static void test_regexec () { regmatch_t pmatch[3]; regmatch_t correct_pmatch[3]; int cflags = 0; int eflags = 0; printf ("\nStarting regexec tests.\n"); cflags = REG_NOSUB; /* shouldn't look at any of pmatch. */ test_pmatch ("a", "a", 0, pmatch, correct_pmatch, cflags); /* Ask for less `pmatch'es than there are pattern subexpressions. (Shouldn't look at pmatch[2]. */ cflags = REG_EXTENDED; fill_pmatch (correct_pmatch, 0, 1, 0, 1, 100, 101); test_pmatch ("((a))", "a", 2, pmatch, correct_pmatch, cflags); /* Ask for same number of `pmatch'es as there are pattern subexpressions. */ cflags = REG_EXTENDED; fill_pmatch(correct_pmatch, 0, 1, 0, 1, -1, -1); test_pmatch ("(a)", "a", 2, pmatch, correct_pmatch, cflags); /* Ask for more `pmatch'es than there are pattern subexpressions. */ cflags = REG_EXTENDED; fill_pmatch (correct_pmatch, 0, 1, -1, -1, -1, -1); test_pmatch ("a", "a", 2, pmatch, correct_pmatch, cflags); eflags = REG_NOTBOL; test_eflags (true, false, "^a", "a", cflags, eflags); test_eflags (true, false, "(^a)", "a", cflags, eflags); test_eflags (true, false, "a|^b", "b", cflags, eflags); test_eflags (true, false, "^b|a", "b", cflags, eflags); eflags = REG_NOTEOL; test_eflags (false, true, "a$", "a", cflags, eflags); test_eflags (false, true, "(a$)", "a", cflags, eflags); test_eflags (false, true, "a|b$", "b", cflags, eflags); test_eflags (false, true, "b$|a", "b", cflags, eflags); eflags = REG_NOTBOL | REG_NOTEOL; test_eflags (true, true, "^a$", "a", cflags, eflags); test_eflags (true, true, "(^a$)", "a", cflags, eflags); test_eflags (true, true, "a|(^b$)", "b", cflags, eflags); test_eflags (true, true, "(^b$)|a", "b", cflags, eflags); cflags = REG_ICASE; test_ignore_case (true, "a", "a", cflags); test_ignore_case (true, "A", "A", cflags); test_ignore_case (true, "A", "a", cflags); test_ignore_case (true, "a", "A", cflags); test_ignore_case (true, "@", "@", cflags); test_ignore_case (true, "\\[", "[", cflags); test_ignore_case (true, "`", "`", cflags); test_ignore_case (true, "{", "{", cflags); test_ignore_case (true, "[!-`]", "A", cflags); test_ignore_case (true, "[!-`]", "a", cflags); cflags = 0; test_ignore_case (false, "a", "a", cflags); test_ignore_case (false, "A", "A", cflags); test_ignore_case (false, "A", "a", cflags); test_ignore_case (false, "a", "A", cflags); test_ignore_case (true, "@", "@", cflags); test_ignore_case (true, "\\[", "[", cflags); test_ignore_case (true, "`", "`", cflags); test_ignore_case (true, "{", "{", cflags); test_ignore_case (true, "[!-`]", "A", cflags); test_ignore_case (false, "[!-`]", "a", cflags); /* Test newline stuff. */ cflags = REG_EXTENDED | REG_NEWLINE; test_newline (true, "\n", "\n", cflags); test_newline (true, "a\n", "a\n", cflags); test_newline (true, "\nb", "\nb", cflags); test_newline (true, "a\nb", "a\nb", cflags); test_newline (false, ".", "\n", cflags); test_newline (false, "[^a]", "\n", cflags); test_newline (true, "\n^a", "\na", cflags); test_newline (true, "\n(^a|b)", "\na", cflags); test_newline (true, "a$\n", "a\n", cflags); test_newline (true, "(a$|b)\n", "a\n", cflags); test_newline (true, "(a$|b|c)\n", "a\n", cflags); test_newline (true, "((a$|b|c)$)\n", "a\n", cflags); test_newline (true, "((a$|b|c)$)\n", "b\n", cflags); test_newline (true, "(a$|b)\n|a\n", "a\n", cflags); test_newline (true, "^a", "\na", cflags); test_newline (true, "a$", "a\n", cflags); /* Now test normal behavior. */ cflags = REG_EXTENDED; test_newline (true, "\n", "\n", cflags); test_newline (true, "a\n", "a\n", cflags); test_newline (true, "\nb", "\nb", cflags); test_newline (true, "a\nb", "a\nb", cflags); test_newline (true, ".", "\n", cflags); test_newline (true, "[^a]", "\n", cflags); test_newline (false, "\n^a", "\na", cflags); test_newline (false, "a$\n", "a\n", cflags); test_newline (false, "^a", "\na", cflags); test_newline (false, "a$", "a\n", cflags); /* Test that matches whole string only. */ cflags = 0; test_posix_match (true, "a", "a", cflags); /* Tests that match substrings. */ test_posix_match (true, "a", "ab", cflags); test_posix_match (true, "b", "ab", cflags); /* Test that doesn't match. */ test_posix_match (false, "a", "b", cflags); printf ("\nFinished regexec tests.\n"); } static void test_error_code_message (error_code, expected_error_message) int error_code; char *expected_error_message; { char returned_error_message[TEST_ERRBUF_SIZE]; char error_code_string[ERROR_CODE_LENGTH]; size_t expected_error_message_length = strlen (expected_error_message) + 1; size_t returned_error_message_length = regerror (error_code, 0, returned_error_message, TEST_ERRBUF_SIZE); if (returned_error_message_length != expected_error_message_length) { printf ("\n\n Testing returned error codes, with expected error \ message `%s':\n", expected_error_message); printf ("\n\n and returned error message `%s':\n", returned_error_message); printf (" should have returned a length of %d but returned %d.\n", expected_error_message_length, returned_error_message_length); } if (strncmp (expected_error_message, returned_error_message, TEST_ERRBUF_SIZE - 1) != 0) { get_error_string (error_code, error_code_string), printf ("\n\n With error code %s (%d), expected error message:\n", error_code_string, error_code); printf (" `%s'\n", expected_error_message); printf (" but got:\n"); printf (" `%s'\n", returned_error_message); } } static void test_error_code_allocation (error_code, expected_error_message) int error_code; char *expected_error_message; { char *returned_error_message = NULL; char error_code_string[ERROR_CODE_LENGTH]; size_t returned_error_message_length = regerror (error_code, 0, returned_error_message, (size_t)0); returned_error_message = xmalloc (returned_error_message_length + 1); regerror (error_code, 0, returned_error_message, returned_error_message_length); if (strcmp (expected_error_message, returned_error_message) != 0) { get_error_string (error_code, error_code_string), printf ("\n\n Testing error code allocation,\n"); printf ("with error code %s (%d), expected error message:\n", error_code_string, error_code); printf (" `%s'\n", expected_error_message); printf (" but got:\n"); printf (" `%s'\n", returned_error_message); } } static void test_regerror () { test_error_code_message (REG_NOMATCH, "No match"); test_error_code_message (REG_BADPAT, "Invalid regular expression"); test_error_code_message (REG_ECOLLATE, "Invalid collation character"); test_error_code_message (REG_ECTYPE, "Invalid character class name"); test_error_code_message (REG_EESCAPE, "Trailing backslash"); test_error_code_message (REG_ESUBREG, "Invalid back reference"); test_error_code_message (REG_EBRACK, "Unmatched [ or [^"); test_error_code_message (REG_EPAREN, "Unmatched ( or \\("); test_error_code_message (REG_EBRACE, "Unmatched \\{"); test_error_code_message (REG_BADBR, "Invalid content of \\{\\}"); test_error_code_message (REG_ERANGE, "Invalid range end"); test_error_code_message (REG_ESPACE, "Memory exhausted"); test_error_code_message (REG_BADRPT, "Invalid preceding regular expression"); test_error_code_message (REG_EEND, "Premature end of regular expression"); test_error_code_message (REG_ESIZE, "Regular expression too big"); test_error_code_allocation (REG_ERPAREN, "Unmatched ) or \\)"); } void test_posix_interface () { printf ("\nStarting POSIX interface tests.\n"); t = posix_interface_test; test_regcomp (); test_regexec (); test_regerror (); printf ("\nFinished POSIX interface tests.\n"); } lyskom-server-2.1.2/src/libraries/regex/test/psx-interv.c0000664000015100472110000001424605314452724017151 /* psx-interv.c: test POSIX intervals, both basic and extended. */ #include "test.h" void test_intervals () { printf ("\nStarting POSIX interval tests.\n"); test_should_match = true; /* Valid intervals. */ test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a{1,2}b)*")), "abaab"); test_fastmap (BRACES_TO_OPS (PARENS_TO_OPS ("(a{1,2}b)*")), "a", 0, 0); TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a{1,2}b)*")), "abaab", 0, 5, 2, 5, -1, -1); test_match (BRACES_TO_OPS ("a{0}"), ""); test_fastmap (BRACES_TO_OPS ("a{0}"), "", 0, 0); TEST_REGISTERS (BRACES_TO_OPS ("a{0}"), "", 0, 0, -1, -1, -1, -1); TEST_REGISTERS (BRACES_TO_OPS ("a{0}"), "x", 0, 0, -1, -1, -1, -1); test_match (BRACES_TO_OPS ("a{0,}"), ""); test_match (BRACES_TO_OPS ("a{0,}"), "a"); test_fastmap (BRACES_TO_OPS ("a{0,}"), "a", 0, 0); TEST_REGISTERS (BRACES_TO_OPS ("a{0,}"), "a", 0, 1, -1, -1, -1, -1); TEST_REGISTERS (BRACES_TO_OPS ("a{0,}"), "xax", 0, 0, -1, -1, -1, -1); test_match (BRACES_TO_OPS ("a{1}"), "a"); test_match (BRACES_TO_OPS ("a{1,}"), "a"); test_match (BRACES_TO_OPS ("a{1,}"), "aa"); test_match (BRACES_TO_OPS ("a{0,0}"), ""); test_match (BRACES_TO_OPS ("a{0,1}"), ""); test_match (BRACES_TO_OPS ("a{0,1}"), "a"); test_match (BRACES_TO_OPS ("a{1,3}"), "a"); test_match (BRACES_TO_OPS ("a{1,3}"), "aa"); test_match (BRACES_TO_OPS ("a{1,3}"), "aaa"); TEST_REGISTERS (BRACES_TO_OPS ("a{1,3}"), "aaa", 0, 3, -1, -1, -1, -1); TEST_REGISTERS (BRACES_TO_OPS ("a{1,3}"), "xaaax", 1, 4, -1, -1, -1, -1); test_match (BRACES_TO_OPS ("a{0,3}b"), "b"); test_match (BRACES_TO_OPS ("a{0,3}b"), "aaab"); test_fastmap (BRACES_TO_OPS ("a{0,3}b"), "ab", 0, 0); TEST_REGISTERS (BRACES_TO_OPS ("a{0,3}b"), "b", 0, 1, -1, -1, -1, -1); TEST_REGISTERS (BRACES_TO_OPS ("a{0,3}b"), "xbx", 1, 2, -1, -1, -1, -1); test_match (BRACES_TO_OPS ("a{1,3}b"), "ab"); test_match (BRACES_TO_OPS ("a{1,3}b"), "aaab"); test_match (BRACES_TO_OPS ("ab{1,3}c"), "abbbc"); test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a){0,3}b")), "b"); test_fastmap (BRACES_TO_OPS (PARENS_TO_OPS ("(a){0,3}b")), "ab", 0, 0); TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a){0,3}b")), "b", 0, 1, -1, -1, -1, -1); TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a){0,3}b")), "ab", 0, 2, 0, 1, -1, -1); TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a){0,3}b")), "xabx", 1, 3, 1, 2, -1, -1); test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a){1,3}b")), "ab"); test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a){1,3}b")), "aaab"); TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a){1,3}b")), "aaab", 0, 4, 2, 3, -1, -1); TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a){1,3}b")), "xaaabx", 1, 5, 3, 4, -1, -1); test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){0,3}b")), "aaaab"); test_fastmap (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){0,3}b")), "ab", 0, 0); TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){0,3}b")), "aaaab", 0, 5, 4, 4, -1, -1); test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){1,3}b")), "b"); test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){1,3}b")), "aaab"); test_fastmap (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){1,3}b")), "ab", 0, 0); test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){1,1}ab")), "aaaab"); TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){1,1}ab")), "aaaab", 0, 5, 0, 3, -1, -1); test_match (BRACES_TO_OPS (".{0,3}b"), "b"); test_match (BRACES_TO_OPS (".{0,3}b"), "ab"); test_match (BRACES_TO_OPS ("[a]{0,3}b"), "b"); test_match (BRACES_TO_OPS ("[a]{0,3}b"), "aaab"); test_fastmap (BRACES_TO_OPS ("[a]{0,3}b"), "ab", 0, 0); test_match (BRACES_TO_OPS ("[^a]{0,3}b"), "bcdb"); test_match (BRACES_TO_OPS ("ab{0,3}c"), "abbbc"); test_match (BRACES_TO_OPS ("[[:digit:]]{0,3}d"), "123d"); test_fastmap (BRACES_TO_OPS ("[[:digit:]]{0,3}d"), "0123456789d", 0, 0); test_match (BRACES_TO_OPS ("\\*{0,3}a"), "***a"); test_match (BRACES_TO_OPS (".{0,3}b"), "aaab"); test_match (BRACES_TO_OPS ("a{0,3}a"), "aaa"); /* Backtracking. */ test_fastmap (BRACES_TO_OPS (PARENS_TO_OPS ("(a{1,})*a")), "a", 0, 0); test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a{1,})*a")), "a"); TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a{1,})*a")), "a", 0, 1, -1, -1, -1, -1); test_fastmap (BRACES_TO_OPS (PARENS_TO_OPS ("(a{2,})*aa")), "aa", 0, 0); test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a{2,})*aa")), "aa"); TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a{2,})*aa")), "aa", 0, 2, -1, -1, -1, -1); test_match (BRACES_TO_OPS ("a{2}*"), ""); test_match (BRACES_TO_OPS ("a{2}*"), "aa"); test_match (BRACES_TO_OPS ("a{1}*"), ""); test_match (BRACES_TO_OPS ("a{1}*"), "a"); test_match (BRACES_TO_OPS ("a{1}*"), "aa"); test_match (BRACES_TO_OPS ("a{1}{1}"), "a"); test_match (BRACES_TO_OPS ("a{1}{1}{1}"), "a"); test_match (BRACES_TO_OPS ("a{1}{1}{2}"), "aa"); test_match (BRACES_TO_OPS ("a{1}{1}*"), ""); test_match (BRACES_TO_OPS ("a{1}{1}*"), "a"); test_match (BRACES_TO_OPS ("a{1}{1}*"), "aa"); test_match (BRACES_TO_OPS ("a{1}{1}*"), "aaa"); test_match (BRACES_TO_OPS ("a{1}{2}"), "aa"); test_match (BRACES_TO_OPS ("a{2}{1}"), "aa"); test_should_match = false; test_match (BRACES_TO_OPS ("a{0}"), "a"); test_match (BRACES_TO_OPS ("a{0,}"), "b"); test_match (BRACES_TO_OPS ("a{1}"), ""); test_match (BRACES_TO_OPS ("a{1}"), "aa"); test_match (BRACES_TO_OPS ("a{1,}"), ""); test_match (BRACES_TO_OPS ("a{1,}"), "b"); test_match (BRACES_TO_OPS ("a{0,0}"), "a"); test_match (BRACES_TO_OPS ("a{0,1}"), "aa"); test_match (BRACES_TO_OPS ("a{0,1}"), "b"); test_match (BRACES_TO_OPS ("a{1,3}"), ""); test_match (BRACES_TO_OPS ("a{1,3}"), "aaaa"); test_match (BRACES_TO_OPS ("a{1,3}"), "b"); test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a){1,3}b")), "aaaab"); test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){1,3}b")), "bb"); test_match (BRACES_TO_OPS ("[a]{0,3}"), "aaaa"); test_match (BRACES_TO_OPS ("[^a]{0,3}b"), "ab"); test_match (BRACES_TO_OPS ("ab{0,3}c"), "abababc"); test_match (BRACES_TO_OPS ("[:alpha:]{0,3}d"), "123d"); test_match (BRACES_TO_OPS ("\\^{1,3}a"), "a"); test_match (BRACES_TO_OPS (".{0,3}b"), "aaaab"); printf ("\nFinished POSIX interval tests.\n"); } lyskom-server-2.1.2/src/libraries/regex/test/syntax.skel0000664000015100472110000000306105314452727017070 /* Print which syntax bits are set. */ #include #include #include "regex.h" /* It's coincidental that these two are currently the same. */ #define LONGEST_BIT_NAME "RE_UNMATCHED_RIGHT_PAREN_ORD" #define LAST_BIT RE_UNMATCHED_RIGHT_PAREN_ORD /* Sum of above, when printed. Assigned in main. */ static unsigned longest; static void test_bit (syntax, bit, name) reg_syntax_t syntax; unsigned bit; char *name; { char padding[100], test_str[100]; int padding_count; sprintf (test_str, "%s (%d=0x%x)", name, bit, bit); padding_count = longest - strlen (test_str); padding[padding_count] = 0; while (padding_count--) { padding[padding_count] = ' '; } printf ("%s%s (%d=0x%x): %c\n", name, padding, bit, bit, syntax & bit ? 'y' : 'n'); } /* Macro to abbreviate the constant arguments. */ #define TEST_BIT(bit) test_bit (syntax, bit, #bit) int main (argc, argv) int argc; char *argv[]; { reg_syntax_t syntax; char syntax_str[1000], test_str[100]; switch (argc) { case 1: printf ("Syntax? "); scanf ("%s", syntax_str); break; case 2: strcpy (syntax_str, argv[1]); break; default: fprintf (stderr, "Usage: syntax [syntax].\n"); exit (1); } sscanf (syntax_str, "%i", &syntax); /* Figure out the longest name, so we can align the output nicely. */ sprintf (test_str, "%s (%d=0x%x)", LONGEST_BIT_NAME, LAST_BIT, LAST_BIT); longest = strlen (test_str); /* [[[replace with bit tests]]] */ return 0; } lyskom-server-2.1.2/src/libraries/regex/test/regexcpp.sed0000664000015100472110000000010505314452727017170 /;..*$/s/;/;\ /g /{ .*$/s/{/{\ /g / \?[^'] /s/?/?\ /g / : /s/:/:\ /g lyskom-server-2.1.2/src/libraries/regex/test/test.c0000664000015100472110000005352705314452725016017 /* test.c: testing routines for regex.c. */ #include #ifdef STDC_HEADERS #include #else char *malloc (); char *realloc (); #endif /* Just to be complete, we make both the system V/ANSI and the BSD versions of the string functions available. */ #if USG || STDC_HEADERS #include #define index strchr #define rindex strrchr #define bcmp(s1, s2, len) memcmp ((s1), (s2), (len)) #define bcopy(from, to, len) memcpy ((to), (from), (len)) #define bzero(s, len) memset ((s), 0, (len)) #else #include #define strchr index #define strrchr rindex #ifndef NEED_MEMORY_H #define memcmp(s1, s2, n) bcmp ((s1), (s2), (n)) #define memcpy(to, from, len) bcopy ((from), (to), (len)) #endif extern char *strtok (); extern char *strstr (); #endif /* not USG or STDC_HEADERS */ /* SunOS 4.1 declares memchr in , not . I don't understand why. */ #if NEED_MEMORY_H #include #endif #include "test.h" #define BYTEWIDTH 8 extern void print_partial_compiled_pattern (); extern void print_compiled_pattern (); extern void print_double_string (); /* If nonzero, the results of every test are displayed. */ boolean verbose = false; /* If nonzero, don't do register testing. */ boolean omit_register_tests = true; /* Says whether the current test should match or fail to match. */ boolean test_should_match; static void set_all_registers (start0, end0, start1, end1, start2, end2, start3, end3, start4, end4, start5, end5, start6, end6, start7, end7, start8, end8, start9, end9, regs) int start0; int end0; int start1; int end1; int start2; int end2; int start3; int end3; int start4; int end4; int start5; int end5; int start6; int end6; int start7; int end7; int start8; int end8; int start9; int end9; struct re_registers *regs; { unsigned r; regs->start[0] = start0; regs->end[0] = end0; regs->start[1] = start1; regs->end[1] = end1; regs->start[2] = start2; regs->end[2] = end2; regs->start[3] = start3; regs->end[3] = end3; regs->start[4] = start4; regs->end[4] = end4; regs->start[5] = start5; regs->end[5] = end5; regs->start[6] = start6; regs->end[6] = end6; regs->start[7] = start7; regs->end[7] = end7; regs->start[8] = start8; regs->end[8] = end8; regs->start[9] = start9; regs->end[9] = end9; for (r = 10; r < regs->num_regs; r++) { regs->start[r] = -1; regs->end[r] = -1; } } /* Return the concatenation of S1 and S2. This would be a prime place to use varargs. */ char * concat (s1, s2) char *s1; char *s2; { char *answer = xmalloc (strlen (s1) + strlen (s2) + 1); strcpy (answer, s1); strcat (answer, s2); return answer; } #define OK_TO_SEARCH (nonconst_buf.fastmap_accurate && (str1 || str2)) /* We ignore the `can_be_null' argument. Should just be removed. */ void general_test (pattern_should_be_valid, match_whole_string, pat, str1, str2, start, range, end, correct_fastmap, correct_regs, can_be_null) unsigned pattern_should_be_valid; unsigned match_whole_string; const char *pat; char *str1, *str2; int start, range, end; char *correct_fastmap; struct re_registers *correct_regs; int can_be_null; { struct re_pattern_buffer nonconst_buf; struct re_pattern_buffer old_buf; struct re_registers regs; const char *r; char fastmap[1 << BYTEWIDTH]; unsigned *regs_correct = NULL; unsigned all_regs_correct = 1; boolean fastmap_internal_error = false; unsigned match = 0; unsigned match_1 = 0; unsigned match_2 = 0; unsigned invalid_pattern = 0; boolean internal_error_1 = false; boolean internal_error_2 = false; nonconst_buf.allocated = 8; nonconst_buf.buffer = xmalloc (nonconst_buf.allocated); nonconst_buf.fastmap = fastmap; nonconst_buf.translate = 0; assert (pat != NULL); r = re_compile_pattern (pat, strlen (pat), &nonconst_buf); /* Kludge: if we are doing POSIX testing, we really should have called regcomp, not re_compile_pattern. As it happens, the only way in which it matters is that re_compile_pattern sets the newline/anchor field for matching (part of what happens when REG_NEWLINE is given to regcomp). We have to undo that for POSIX matching. */ if (t == posix_basic_test || t == posix_extended_test) nonconst_buf.newline_anchor = 0; invalid_pattern = r != NULL; if (!r) { int r; if (!pattern_should_be_valid) printf ("\nShould have been an invalid pattern but wasn't:\n"); else { fastmap_internal_error = (re_compile_fastmap (&nonconst_buf) == -2); if (correct_fastmap) nonconst_buf.fastmap_accurate = memcmp (nonconst_buf.fastmap, correct_fastmap, 1 << BYTEWIDTH) == 0; if (OK_TO_SEARCH) { old_buf = nonconst_buf; old_buf.buffer = (unsigned char *) xmalloc (nonconst_buf.used); memcpy (old_buf.buffer, nonconst_buf.buffer, nonconst_buf.used); /* If only one string is null, call re_match or re_search, which is what the user would probably do. */ if (str1 == NULL && str2 != NULL || str2 == NULL && str1 != NULL) { char *the_str = str1 == NULL ? str2 : str1; match_1 = match_whole_string ? (r = re_match (&nonconst_buf, the_str, strlen (the_str), start, ®s)) == strlen (the_str) : (r = re_search (&nonconst_buf, the_str, strlen (the_str), start, range, ®s)) >= 0; if (r == -2) internal_error_1 = true; } else match_1 = 1; /* Also call with re_match_2 or re_search_2, as they might do this. (Also can check calling with either string1 or string2 or both null.) */ if (match_whole_string) { r = re_match_2 (&nonconst_buf, str1, SAFE_STRLEN (str1), str2, SAFE_STRLEN (str2), start, ®s, end); match_2 = r == SAFE_STRLEN (str1) + SAFE_STRLEN (str2); } else { r = re_search_2 (&nonconst_buf, str1, SAFE_STRLEN (str1), str2, SAFE_STRLEN (str2), start, range, ®s, end); match_2 = r >= 0; } if (r == -2) internal_error_2 = true; match = match_1 & match_2; if (correct_regs) { unsigned reg; if (regs_correct != NULL) free (regs_correct); regs_correct = (unsigned *) xmalloc (regs.num_regs * sizeof (unsigned)); for (reg = 0; reg < regs.num_regs && reg < correct_regs->num_regs; reg++) { regs_correct[reg] = (regs.start[reg] == correct_regs->start[reg] && regs.end[reg] == correct_regs->end[reg]) #ifdef EMPTY_REGS_CONFUSED /* There is confusion in the standard about the registers in some patterns which can match either the empty string or not match. For example, in `((a*))*' against the empty string, the two registers can either match the empty string (be 0/0), or not match (because of the outer *) (be -1/-1). (Or one can do one and one can do the other.) */ || (regs.start[reg] == -1 && regs.end[reg] == -1 && correct_regs->start[reg] == correct_regs->end[reg]) #endif ; all_regs_correct &= regs_correct[reg]; } } } /* OK_TO_SEARCH */ } } if (fastmap_internal_error) printf ("\n\nInternal error in re_compile_fastmap:"); if (internal_error_1) { if (!fastmap_internal_error) printf ("\n"); printf ("\nInternal error in re_match or re_search:"); } if (internal_error_2) { if (!internal_error_1) printf ("\n"); printf ("\nInternal error in re_match_2 or re_search_2:"); } if ((OK_TO_SEARCH && ((match && !test_should_match) || (!match && test_should_match)) || (correct_regs && !all_regs_correct)) || !nonconst_buf.fastmap_accurate || invalid_pattern || !pattern_should_be_valid || internal_error_1 || internal_error_2 || verbose) { if (OK_TO_SEARCH && match && !test_should_match) { printf ("\n\nMatched but shouldn't have:\n"); if (match_1) printf ("The single match/search succeeded.\n"); if (match_2) printf ("The double match/search succeeded.\n"); } else if (OK_TO_SEARCH && !match && test_should_match) { printf ("\n\nDidn't match but should have:\n"); if (!match_1) printf ("The single match/search failed.\n"); if (!match_2) printf ("The double match/search failed.\n"); } else if (invalid_pattern && pattern_should_be_valid) printf ("\n\nInvalid pattern (%s):\n", r); else if (!nonconst_buf.fastmap_accurate && pattern_should_be_valid) printf ("\n\nIncorrect fastmap:\n"); else if (OK_TO_SEARCH && correct_regs && !all_regs_correct) printf ("\n\nNot all registers were correct:\n"); else if (verbose) printf ("\n\nTest was OK:\n"); if ((!(invalid_pattern && !pattern_should_be_valid)) || verbose) printf (" Pattern: `%s'.\n", pat); if (pattern_should_be_valid || verbose || internal_error_1 || internal_error_2) { printf(" Strings: "); printf ("`%s' and ", str1 == NULL ? "NULL" : str1); printf ("`%s'.\n", str2 == NULL ? "NULL" : str2); if ((OK_TO_SEARCH || verbose || internal_error_1 || internal_error_2) && !invalid_pattern) { if (memcmp (old_buf.buffer, nonconst_buf.buffer, nonconst_buf.used) != 0 && !invalid_pattern) { printf(" (%s)\n", r ? r : "Valid regular expression"); printf ("\n Compiled pattern before matching: "); print_compiled_pattern (&old_buf); printf ("\n Compiled pattern after matching: "); } else printf ("\n Compiled pattern: "); print_compiled_pattern (&nonconst_buf); } if (correct_fastmap && (!nonconst_buf.fastmap_accurate || verbose)) { printf ("\n The fastmap should have been: "); print_fastmap (correct_fastmap); printf ("\n Fastmap: "); print_fastmap (fastmap); printf ("\n Compiled pattern before matching: "); print_compiled_pattern (&nonconst_buf); } if ((!all_regs_correct || verbose) && correct_regs) { unsigned this_reg; printf ("\n Incorrect registers:"); for (this_reg = 0; this_reg < regs.num_regs; this_reg++) { if (!regs_correct[this_reg]) { printf ("\n Register %d's start was %2d. ", this_reg, regs.start[this_reg]); printf ("\tIt should have been %d.\n", correct_regs->start[this_reg]); printf (" Register %d's end was %2d. ", this_reg, regs.end[this_reg]); printf ("\tIt should have been %d.\n", correct_regs->end[this_reg]); } } } } } if (nonconst_buf.buffer != NULL) free (nonconst_buf.buffer); if (OK_TO_SEARCH) { free (old_buf.buffer); if (correct_regs) free (regs_correct); } nonconst_buf.buffer = old_buf.buffer = NULL; regs_correct = NULL; regs.start = regs.end = NULL; } /* general_test */ void test_search_return (match_start_wanted, pattern, string) int match_start_wanted; const char *pattern; char *string; { struct re_pattern_buffer buf; char fastmap[1 << BYTEWIDTH]; const char *compile_return; int match_start; static num_times_called = 0; num_times_called++; buf.allocated = 1; buf.buffer = xmalloc (buf.allocated); assert (pattern != NULL); buf.translate = 0; compile_return = re_compile_pattern (pattern, strlen (pattern), &buf); if (compile_return) { printf ("\n\nInvalid pattern in test_match_start:\n"); printf ("%s\n", compile_return); } else { buf.fastmap = fastmap; match_start = re_search (&buf, string, strlen (string), 0, strlen (string), 0); if (match_start != match_start_wanted) printf ("\nWanted search to start at %d but started at %d.\n", match_start, match_start_wanted); } free (buf.buffer); buf.buffer = NULL; } #define SET_FASTMAP() \ { \ unsigned this_char; \ \ memset (correct_fastmap, invert, (1 << BYTEWIDTH)); \ \ for (this_char = 0; this_char < strlen (fastmap_string); this_char++)\ correct_fastmap[fastmap_string[this_char]] = !invert; \ correct_fastmap['\n'] = match_newline; \ } void test_fastmap (pat, fastmap_string, invert, match_newline) const char *pat; char *fastmap_string; unsigned invert; unsigned match_newline; { char correct_fastmap[(1 << BYTEWIDTH)]; SET_FASTMAP (); general_test (1, 0, pat, NULL, NULL, -1, 0, -1, correct_fastmap, 0, -1); } void test_fastmap_search (pat, str, fastmap_string, invert, match_newline, can_be_null, start0, end0) const char *pat; char *str; char *fastmap_string; unsigned invert; unsigned match_newline; int can_be_null; int start0; int end0; { char correct_fastmap[(1 << BYTEWIDTH)]; struct re_registers correct_regs; correct_regs.num_regs = RE_NREGS; correct_regs.start = (int *) xmalloc (RE_NREGS * sizeof (int)); correct_regs.end = (int *) xmalloc (RE_NREGS * sizeof (int)); set_all_registers (start0, end0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, &correct_regs); SET_FASTMAP (); general_test (1, 0, pat, str, NULL, 0, SAFE_STRLEN (str), SAFE_STRLEN (str), correct_fastmap, &correct_regs, can_be_null); free (correct_regs.start); free (correct_regs.end); } void test_all_registers (pat, str1, str2, start0, end0, start1, end1, start2, end2, start3, end3, start4, end4, start5, end5, start6, end6, start7, end7, start8, end8, start9, end9) char *pat; char *str1; char *str2; int start0; int end0; int start1; int end1; int start2; int end2; int start3; int end3; int start4; int end4; int start5; int end5; int start6; int end6; int start7; int end7; int start8; int end8; int start9; int end9; { struct re_registers correct_regs; if (omit_register_tests) return; correct_regs.num_regs = RE_NREGS; correct_regs.start = (int *) xmalloc (RE_NREGS * sizeof (int)); correct_regs.end = (int *) xmalloc (RE_NREGS * sizeof (int)); set_all_registers (start0, end0, start1, end1, start2, end2, start3, end3, start4, end4, start5, end5, start6, end6, start7, end7, start8, end8, start9, end9, &correct_regs); general_test (1, 0, pat, str1, str2, 0, SAFE_STRLEN (str1) + SAFE_STRLEN (str2), SAFE_STRLEN (str1) + SAFE_STRLEN (str2), NULL, &correct_regs, -1); free (correct_regs.start); free (correct_regs.end); } void invalid_pattern (error_code_expected, pattern) int error_code_expected; char *pattern; { regex_t pattern_buffer; int cflags = re_syntax_options == RE_SYNTAX_POSIX_EXTENDED || re_syntax_options == RE_SYNTAX_POSIX_MINIMAL_EXTENDED ? REG_EXTENDED : 0; test_compile (0, error_code_expected, pattern, &pattern_buffer, cflags); } void valid_pattern (pattern) char *pattern; { regex_t pattern_buffer; int cflags = re_syntax_options == RE_SYNTAX_POSIX_EXTENDED || re_syntax_options == RE_SYNTAX_POSIX_MINIMAL_EXTENDED ? REG_EXTENDED : 0; test_compile (1, 0, pattern, &pattern_buffer, cflags); } char * delimiters_to_ops (source, left_delimiter, right_delimiter) char *source; char left_delimiter; char right_delimiter; { static char *answer = NULL; char *tmp = NULL; boolean double_size = false; unsigned source_char; unsigned answer_char = 0; assert (source != NULL); switch (left_delimiter) { case '(': if (!(re_syntax_options & RE_NO_BK_PARENS)) double_size = true; break; case '{': if (!(re_syntax_options & RE_NO_BK_BRACES)) double_size = true; break; default: printf ("Found strange delimiter %c in delimiter_to_ops.\n", left_delimiter); printf ("The source was `%s'\n", source); exit (0); } if (answer == source) { tmp = (char *) xmalloc (strlen (source) + 1); strcpy (tmp, source); source = tmp; } if (answer) { free (answer); answer = NULL; } answer = (char *) xmalloc ((double_size ? strlen (source) << 1 : strlen (source)) + 1); if (!double_size) strcpy (answer, source); else { for (source_char = 0; source_char < strlen (source); source_char++) { if (source[source_char] == left_delimiter || source[source_char] == right_delimiter) answer[answer_char++] = '\\'; answer[answer_char++] = source[source_char]; } answer[answer_char] = 0; } return answer; } void print_pattern_info (pattern, pattern_buffer_ptr) const char *pattern; regex_t *pattern_buffer_ptr; { printf (" Pattern: `%s'.\n", pattern); printf (" Compiled pattern: "); print_compiled_pattern (pattern_buffer_ptr); } void valid_nonposix_pattern (pattern) char *pattern; { struct re_pattern_buffer nonconst_buf; nonconst_buf.allocated = 0; nonconst_buf.buffer = NULL; nonconst_buf.translate = NULL; assert (pattern != NULL); if (re_compile_pattern (pattern, strlen (pattern), &nonconst_buf)) { printf ("Couldn't compile the pattern.\n"); print_pattern_info (pattern, &nonconst_buf); } } void compile_and_print_pattern (pattern) char *pattern; { struct re_pattern_buffer nonconst_buf; nonconst_buf.allocated = 0; nonconst_buf.buffer = NULL; if (re_compile_pattern (pattern, strlen (pattern), &nonconst_buf)) printf ("Couldn't compile the pattern.\n"); print_pattern_info (pattern, &nonconst_buf); } void test_case_fold (pattern, string) const char *pattern; char* string; { struct re_pattern_buffer nonconst_buf; const char *ret; init_pattern_buffer (&nonconst_buf); nonconst_buf.translate = upcase; assert (pattern != NULL); ret = re_compile_pattern (pattern, strlen (pattern), &nonconst_buf); if (ret) { printf ("\nShould have been a valid pattern but wasn't.\n"); print_pattern_info (pattern, &nonconst_buf); } else { if (test_should_match && re_match (&nonconst_buf, string, strlen (string), 0, 0) != strlen (string)) { printf ("Match failed for case fold.\n"); printf (" Pattern: `%s'.\n", pattern); printf (" String: `%s'.\n", string == NULL ? "NULL" : string); } } } void test_match_n_times (n, pattern, string) unsigned n; char* pattern; char* string; { struct re_pattern_buffer buf; const char *r; unsigned match = 0; unsigned this_match; buf.allocated = 0; buf.buffer = NULL; buf.translate = 0; assert (pattern != NULL); r = re_compile_pattern (pattern, strlen (pattern), &buf); if (r) { printf ("Didn't compile.\n"); printf (" Pattern: %s.\n", pattern); } else { for (this_match = 1; this_match <= n; this_match++) match = (re_match (&buf, string, strlen (string), 0, 0) == strlen (string)); if (match && !test_should_match) printf ("\n\nMatched but shouldn't have:\n"); else if (!match && test_should_match) printf ("\n\nDidn't match but should have:\n"); if ((match && !test_should_match) || (!match && test_should_match)) { printf(" The string to match was: "); if (string) printf ("`%s' and ", string); else printf ("`'"); printf (" Pattern: %s.\n", pattern); printf (" Compiled pattern: %s.\n", pattern); print_compiled_pattern (&buf); } } } void test_match_2 (pat, str1, str2) const char *pat; char *str1; char *str2; { general_test (1, 1, pat, str1, str2, 0, 1, SAFE_STRLEN (str1) + SAFE_STRLEN (str2), NULL, 0, -1); } void test_match (pat, str) const char *pat; char *str; { test_match_2 (pat, str, NULL); test_match_2 (pat, NULL, str); } lyskom-server-2.1.2/src/libraries/regex/test/test.h0000664000015100472110000001016205314452726016011 /* test.h: for Regex testing. */ #ifndef TEST_H #define TEST_H #include #include #include #include "regex.h" /* A strlen that works even on a null pointer. */ #define SAFE_STRLEN(s) (s == NULL ? 0 : strlen (s)) typedef enum { false = 0, true = 1 } boolean; extern boolean test_should_match; extern boolean omit_register_tests; extern void *xmalloc (); /* Defined in upcase.c. */ extern char upcase[]; typedef enum { all_test, other_test, posix_basic_test, posix_extended_test, posix_interface_test, regress_test } test_type; extern test_type t; #if __STDC__ extern char *concat (char *, char *); extern void general_test (unsigned pattern_should_be_valid, unsigned match_whole_string, const char *pat, char *str1, char *str2, int start, int range, int end, char *correct_fastmap, struct re_registers *correct_regs, int can_be_null); extern void init_pattern_buffer (regex_t *pattern_buffer_ptr); extern void test_compile (unsigned valid_pattern, int error_code_expected, const char *pattern, regex_t *pattern_buffer_ptr, int cflags); extern char *delimiter_to_ops (char *source, char left_delimiter, char right_delimiter); extern void test_search_return (int, const char *, char *); extern void test_berk_search (const char *pattern, char *string); extern void test_fastmap (const char *pat, char *fastmap_string, unsigned invert, unsigned match_newline); extern void test_fastmap_search (const char *pat, char *str, char *fastmap_string, unsigned invert, unsigned match_newline, int can_be_null, int start0, int end0); extern void test_all_registers (char *pat, char *str1, char *str2, int start0, int end0, int start1, int end1, int start2, int end2, int start3, int end3, int start4, int end4, int start5, int end5, int start6, int end6, int start7, int end7, int start8, int end8, int start9, int end9); extern void print_pattern_info (const char *pattern, regex_t *pattern_buffer_ptr); extern void compile_and_print_pattern (char *pattern); extern void test_case_fold (const char *pattern, char* string); extern void test_posix_generic (); extern void test_grouping (); extern void invalid_pattern (int error_code_expected, char *pattern); extern void valid_nonposix_pattern (char *pattern); extern void valid_pattern (char *pattern); extern void test_match_2 (const char *pat, char *str1, char *str2); extern void test_match (const char *pat, char *str); #endif /* __STDC__ */ #define TEST_REGISTERS_2(pat, str1, str2, start0, end0, start1, end1, start2, end2)\ if (!omit_register_tests) \ test_all_registers (pat, str1, str2, start0, end0, start1, end1, \ start2, end2, -1, -1, -1, -1, -1, -1, -1, -1,\ -1, -1, -1, -1, -1, -1) \ #define TEST_REGISTERS(pat, str, start0, end0, start1, end1, start2, end2) \ TEST_REGISTERS_2 (pat, str, NULL, start0, end0, start1, end1, start2, end2)\ #define BRACES_TO_OPS(string) ((char *) delimiters_to_ops (string, '{', '}')) #define PARENS_TO_OPS(string) ((char *) delimiters_to_ops (string, '(', ')')) #define INVALID_PATTERN(pat) \ general_test (0, 0, pat, NULL, NULL, -1, 0, -1, NULL, 0, -1) #define MATCH_SELF(p) test_match (p, p) #define TEST_POSITIONED_MATCH(pat, str, start) \ general_test (1, 0, pat, str, NULL, start, 1, SAFE_STRLEN (str), \ NULL, 0, -1) #define TEST_TRUNCATED_MATCH(pat, str, end) \ general_test (1, 0, pat, str, NULL, 0, 1, end, NULL, 0, -1) #define TEST_SEARCH_2(pat, str1, str2, start, range, one_past_end) \ general_test (1, 0, pat, str1, str2, start, range, one_past_end, \ NULL, 0, -1) #define TEST_SEARCH(pat, str, start, range) \ { \ TEST_SEARCH_2 (pat, str, NULL, start, range, SAFE_STRLEN (str)); \ TEST_SEARCH_2 (pat, NULL, str, start, range, SAFE_STRLEN (str)); \ } #endif /* TEST_H */ /* Local variables: make-backup-files: t version-control: t trim-versions-without-asking: nil End: */ lyskom-server-2.1.2/src/libraries/regex/test/tregress.c0000664000015100472110000004350705533104674016673 /* tregress.c: reported bugs. The `t' just makes the filename not have a common prefix with `regex.c', so completion works better. */ #include "test.h" boolean pause_at_error = true; char * itoa (i) int i; { char *a = xmalloc (21); /* sign + 19 digits (enough for 64 bits) + null */ sprintf (a, "%d", i); return a; } static void simple_fail (routine, pat, buf, str, ret) const char *routine; const char *pat; struct re_pattern_buffer *buf; const char *str; char *ret; { fprintf (stderr, "Failed %s (return = %s).\n", routine, ret); if (str && *str) fprintf (stderr, " String = %s\n", str); fprintf (stderr, " Pattern = %s\n", pat); print_compiled_pattern (buf); if (pause_at_error) { fprintf (stderr, "RET to continue: "); (void) getchar (); } } /* Abbreviate the most common calls. */ static void simple_compile (pat, buf) const char *pat; struct re_pattern_buffer *buf; { const char *ret = re_compile_pattern (pat, strlen (pat), buf); if (ret != NULL) simple_fail ("compile", pat, buf, NULL, ret); } static void simple_fastmap (pat) const char *pat; { struct re_pattern_buffer buf; char fastmap[256]; int ret; buf.allocated = 0; buf.buffer = buf.translate = NULL; buf.fastmap = fastmap; simple_compile (pat, &buf); ret = re_compile_fastmap (&buf); if (ret != 0) simple_fail ("fastmap compile", pat, &buf, NULL, itoa (ret)); } #define SIMPLE_MATCH(pat, str) do_match (pat, str, strlen (str)) #define SIMPLE_NONMATCH(pat, str) do_match (pat, str, -1) static void do_match (pat, str, expected) const char *pat, *str; int expected; { int ret; unsigned len; struct re_pattern_buffer buf; buf.allocated = 0; buf.buffer = buf.translate = buf.fastmap = NULL; simple_compile (pat, &buf); len = strlen (str); ret = re_match_2 (&buf, NULL, 0, str, len, 0, NULL, len); if (ret != expected) simple_fail ("match", pat, &buf, str, itoa (ret)); } static void simple_search (pat, str, correct_startpos) const char *pat, *str; int correct_startpos; { int ret; unsigned len; struct re_pattern_buffer buf; buf.allocated = 0; buf.buffer = buf.translate = buf.fastmap = NULL; simple_compile (pat, &buf); len = strlen (str); ret = re_search_2 (&buf, NULL, 0, str, len, 0, len, NULL, len); if (ret != correct_startpos) simple_fail ("match", pat, &buf, str, itoa (ret)); } /* Past bugs people have reported. */ void test_regress () { extern char upcase[]; struct re_pattern_buffer buf; unsigned len; struct re_registers regs; int ret; char *fastmap = xmalloc (256); buf.translate = NULL; buf.fastmap = NULL; buf.allocated = 0; buf.buffer = NULL; printf ("\nStarting regression tests.\n"); t = regress_test; test_should_match = true; re_set_syntax (RE_SYNTAX_EMACS); /* enami@sys.ptg.sony.co.jp 10 Nov 92 15:19:02 JST */ buf.translate = upcase; SIMPLE_MATCH ("[A-[]", "A"); buf.translate = NULL; /* meyering@cs.utexas.edu Nov 6 22:34:41 1992 */ simple_search ("\\w+", "a", 0); /* jimb@occs.cs.oberlin.edu 10 Sep 92 00:42:33 */ buf.translate = upcase; SIMPLE_MATCH ("[\001-\377]", "\001"); SIMPLE_MATCH ("[\001-\377]", "a"); SIMPLE_MATCH ("[\001-\377]", "\377"); buf.translate = NULL; /* mike@skinner.cs.uoregon.edu 1 Sep 92 01:45:22 */ SIMPLE_MATCH ("^^$", "^"); /* pclink@qld.tne.oz.au Sep 7 22:42:36 1992 */ re_set_syntax (RE_INTERVALS); SIMPLE_MATCH ("^a\\{3\\}$", "aaa"); SIMPLE_NONMATCH ("^a\\{3\\}$", "aa"); re_set_syntax (RE_SYNTAX_EMACS); /* pclink@qld.tne.oz.au, 31 Aug 92. (conjecture) */ re_set_syntax (RE_INTERVALS); simple_search ("a\\{1,3\\}b", "aaab", 0); simple_search ("a\\{1,3\\}b", "aaaab", 1); re_set_syntax (RE_SYNTAX_EMACS); /* trq@dionysos.thphys.ox.ac.uk, 31 Aug 92. (simplified) */ simple_fastmap ("^.*\n[ ]*"); /* wind!greg@plains.NoDak.edu, 25 Aug 92. (simplified) */ re_set_syntax (RE_INTERVALS); SIMPLE_MATCH ("[a-zA-Z]*.\\{5\\}", "xN0000"); SIMPLE_MATCH ("[a-zA-Z]*.\\{5\\}$", "systemxN0000"); SIMPLE_MATCH ("\\([a-zA-Z]*\\).\\{5\\}$", "systemxN0000"); re_set_syntax (RE_SYNTAX_EMACS); /* jimb, 18 Aug 92. Don't use \000, so `strlen' (in our testing routines) will work. (This still tickles the bug jimb reported.) */ SIMPLE_MATCH ("[\001-\377]", "\001"); SIMPLE_MATCH ("[\001-\377]", "a"); SIMPLE_MATCH ("[\001-\377]", "\377"); /* jimb, 13 Aug 92. */ SIMPLE_MATCH ("[\001-\177]", "\177"); /* Tests based on bwoelfel's below. */ SIMPLE_MATCH ("\\(a\\|ab\\)*", "aab"); SIMPLE_MATCH ("\\(a\\|ab\\)+", "aab"); SIMPLE_MATCH ("\\(a*\\|ab\\)+", "aab"); SIMPLE_MATCH ("\\(a+\\|ab\\)+", "aab"); SIMPLE_MATCH ("\\(a?\\|ab\\)+", "aab"); /* bwoelfel@widget.seas.upenn.edu, 25 Jul 92. */ SIMPLE_MATCH ("^\\([ab]+\\|bc\\)+", "abc"); /* jla, 3 Jul 92. Core dump in re_search_2. */ buf.fastmap = fastmap; buf.translate = upcase; #define DATEDUMP_PATTERN " *[0-9]*:" if (re_compile_pattern (DATEDUMP_PATTERN, strlen (DATEDUMP_PATTERN), &buf) != NULL) printf ("date dump compile failed.\n"); regs.num_regs = 0; regs.start = regs.end = NULL; if (re_search_2 (&buf, NULL, 0, "Thu Jul 2 18:34:18 1992", 24, 3, 21, ®s, 24) != 10) printf ("date dump search failed.\n"); buf.fastmap = 0; buf.translate = 0; /* rms, 4 Jul 1992. Pattern is much slower in Emacs 19. Fastmap should be only a backslash. */ #define BEGINEND_PATTERN "\\(\\\\begin\\s *{\\)\\|\\(\\\\end\\s *{\\)" test_fastmap (BEGINEND_PATTERN, "\\", false, 0); /* kaoru@is.s.u-tokyo.ac.jp, 27 Jun 1992. Code for [a-z] (in regex.c) should translate the whole set. */ buf.translate = upcase; #define CASE_SET_PATTERN "[ -`]" if (re_compile_pattern (CASE_SET_PATTERN, strlen (CASE_SET_PATTERN), &buf) != NULL) printf ("case set compile failed.\n"); if (re_match_2 (&buf, "K", 1, "", 0, 0, NULL, 1) != 1) printf ("case set match failed.\n"); #define CASE_SET_PATTERN2 "[`-|]" if (re_compile_pattern (CASE_SET_PATTERN2, strlen (CASE_SET_PATTERN2), &buf) != NULL) printf ("case set2 compile failed.\n"); if (re_match_2 (&buf, "K", 1, "", 0, 0, NULL, 1) != 1) printf ("case set2 match failed.\n"); buf.translate = NULL; /* jimb, 27 Jun 92. Problems with gaps in the string. */ #define GAP_PATTERN "x.*y.*z" if (re_compile_pattern (GAP_PATTERN, strlen (GAP_PATTERN), &buf) != NULL) printf ("gap didn't compile.\n"); if (re_match_2 (&buf, "x-", 2, "y-z-", 4, 0, NULL, 6) != 5) printf ("gap match failed.\n"); /* jimb, 19 Jun 92. Since `beginning of word' matches at the beginning of the string, then searching ought to find it there. If `re_compile_fastmap' is not called, then it works ok. */ buf.fastmap = fastmap; #define BOW_BEG_PATTERN "\\<" if (re_compile_pattern (BOW_BEG_PATTERN, strlen (BOW_BEG_PATTERN), &buf) != NULL) printf ("begword-begstring didn't compile.\n"); if (re_search (&buf, "foo", 3, 0, 3, NULL) != 0) printf ("begword-begstring search failed.\n"); /* Same bug report, different null-matching pattern. */ #define EMPTY_ANCHOR_PATTERN "^$" if (re_compile_pattern (EMPTY_ANCHOR_PATTERN, strlen (EMPTY_ANCHOR_PATTERN), &buf) != NULL) printf ("empty anchor didn't compile.\n"); if (re_search (&buf, "foo\n\nbar", 8, 0, 8, NULL) != 4) printf ("empty anchor search failed.\n"); /* jimb@occs.cs.oberlin.edu, 21 Apr 92. After we first allocate registers for a particular re_pattern_buffer, we might have to reallocate more registers on subsequent calls -- and we should be reusing the same memory. */ #define ALLOC_REG_PATTERN "\\(abc\\)" free (buf.fastmap); buf.fastmap = 0; if (re_compile_pattern (ALLOC_REG_PATTERN, strlen (ALLOC_REG_PATTERN), &buf) != NULL) printf ("register allocation didn't compile.\n"); if (re_match (&buf, "abc", 3, 0, ®s) != 3) printf ("register allocation didn't match.\n"); if (regs.start[1] != 0 || regs.end[1] != 3) printf ("register allocation reg #1 wrong.\n"); { int *old_regstart = regs.start; int *old_regend = regs.end; if (re_match (&buf, "abc", 3, 0, ®s) != 3) printf ("register reallocation didn't match.\n"); if (regs.start[1] != 0 || regs.end[1] != 3 || old_regstart[1] != 0 || old_regend[1] != 3 || regs.start != old_regstart || regs.end != old_regend) printf ("register reallocation registers wrong.\n"); } /* jskudlarek@std.MENTORG.COM, 21 Apr 92 (string-match). */ #define JSKUD_PATTERN "[^/]+\\(/[^/.]+\\)?/[0-9]+$" if (re_compile_pattern (JSKUD_PATTERN, strlen (JSKUD_PATTERN), &buf) != NULL) printf ("jskud test didn't compile.\n"); if (re_search (&buf, "a/1", 3, 0, 3, ®s) != 0) printf ("jskud test didn't match.\n"); if (regs.start[1] != -1 || regs.end[1] != -1) printf ("jskud test, reg #1 wrong.\n"); /* jla's bug (with string-match), 5 Feb 92. */ TEST_SEARCH ("\\`[ \t\n]*", "jla@challenger (Joseph Arceneaux)", 0, 100); /* jwz@lucid.com, 8 March 1992 (re-search-forward). (His is the second.) These are not supposed to match. */ #if 0 /* This one fails quickly, because we can change the maybe_pop_jump from the + to a pop_failure_pop, because of the c's. */ TEST_SEARCH ("^\\(To\\|CC\\):\\([^c]*\\)+co", "To: hbs%titanic@lucid.com (Harlan Sexton)\n\ Cc: eb@thalidomide, jlm@thalidomide\n\ Subject: Re: so is this really as horrible an idea as it seems to me?\n\ In-Reply-To: Harlan Sexton's message of Sun 8-Mar-92 11:00:06 PST <9203081900.AA24794@titanic.lucid>\n\ References: <9203080736.AA05869@thalidomide.lucid>\n\ <9203081900.AA24794@titanic.lucid>", 0, 5000); /* This one takes a long, long time to complete, because we have to keep the failure points around because we might backtrack. */ TEST_SEARCH ("^\\(To\\|CC\\):\\(.*\n.*\\)+co", /* "X-Windows: The joke that kills.\n\ FCC: /u/jwz/VM/inbox\n\ From: Jamie Zawinski \n\ */ "To: hbs%titanic@lucid.com (Harlan Sexton)\n\ Cc: eb@thalidomide, jlm@thalidomide\n\ Subject: Re: so is this really as horrible an idea as it seems to me?\n\ In-Reply-To: Harlan Sexton's message of Sun 8-Mar-92 11:00:06 PST <9203081900.AA24794@titanic.lucid>\n\ References: <9203080736.AA05869@thalidomide.lucid>\n\ <9203081900.AA24794@titanic.lucid>", 0, 5000); #endif /* 0 [failed searches] */ /* macrakis' bugs. */ buf.translate = upcase; /* message of 24 Jan 91 */ if (re_compile_pattern ("[!-`]", 5, &buf) != NULL) printf ("Range test didn't compile.\n"); if (re_match (&buf, "A", 1, 0, NULL) != 1) printf ("Range test #1 didn't match.\n"); if (re_match (&buf, "a", 1, 0, NULL) != 1) printf ("Range test #2 didn't match.\n"); buf.translate = 0; #define FAO_PATTERN "\\(f\\(.\\)o\\)+" if (re_compile_pattern (FAO_PATTERN, strlen (FAO_PATTERN), &buf) != NULL) printf ("faofdx test didn't compile.\n"); if (re_search (&buf, "faofdx", 6, 0, 6, ®s) != 0) printf ("faofdx test didn't match.\n"); if (regs.start[1] != 0 || regs.end[1] != 3) printf ("faofdx test, reg #1 wrong.\n"); if (regs.start[2] != 1 || regs.end[2] != 2) printf ("faofdx test, reg #2 wrong.\n"); TEST_REGISTERS ("\\(a\\)*a", "aaa", 0, 3, 1, 2, -1, -1); test_fastmap ("^\\([^ \n]+:\n\\)+\\([^ \n]+:\\)", " \n", 1, 0); /* 40 lines, 48 a's in each line. */ test_match ("^\\([^ \n]+:\n\\)+\\([^ \n]+:\\)", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:"); /* 640 a's followed by one b, twice. */ test_match ("\\(.*\\)\\1", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab"); /* 640 a's followed by two b's, twice. */ test_match ("\\(.*\\)\\1", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabb"); /* Dave G. bug: Reference to a subexpression which didn't match. Should fail. */ re_set_syntax (RE_NO_BK_PARENS | RE_NO_BK_VBAR); test_match ("(ooooooooooone())-annnnnnnnnnnd-(twooooooooooo\\2)", "ooooooooooone-annnnnnnnnnnd-twooooooooooo"); test_match ("(o|t)", "o"); test_match ("(o()|t)", "o"); test_match ("(o|t)", "o"); test_match ("(ooooooooooooooo|tttttttttttttttt())", "ooooooooooooooo"); test_match ("(o|t())", "o"); test_match ("(o()|t())", "o"); test_match ("(ooooooooooooooooooooooooone()|twooooooooooooooooooooooooo())", "ooooooooooooooooooooooooone"); test_match ("(o()|t())-a-(t\\2|f\\3)", "o-a-t"); test_match ("(o()|t())-a-(t\\2|f\\3)", "t-a-f"); test_should_match = 0; test_match ("(foo(bar)|second)\\2", "second"); test_match ("(o()|t())-a-(t\\2|f\\3)", "t-a-t"); test_match ("(o()|t())-a-(t\\2|f\\3)", "o-a-f"); re_set_syntax (RE_SYNTAX_EMACS); test_match ("\\(foo\\(bar\\)\\|second\\)\\2", "secondbar"); test_match ("\\(one\\(\\)\\|two\\(\\)\\)-and-\\(three\\2\\|four\\3\\)", "one-and-four"); test_match ("\\(one\\(\\)\\|two\\(\\)\\)-and-\\(three\\2\\|four\\3\\)", "two-and-three"); test_should_match = 1; re_set_syntax (RE_SYNTAX_EMACS); test_match ("\\(one\\(\\)\\|two\\(\\)\\)-and-\\(three\\2\\|four\\3\\)", "one-and-three"); test_match ("\\(one\\(\\)\\|two\\(\\)\\)-and-\\(three\\2\\|four\\3\\)", "two-and-four"); TEST_REGISTERS (":\\(.*\\)", ":/", 0, 2, 1, 2, -1, -1); /* Bug with `upcase' translation table, from Nico Josuttis */ test_should_match = 1; test_case_fold ("[a-a]", "a"); printf ("\nFinished regression tests.\n"); } /* Local variables: make-backup-files: t version-control: t trim-versions-without-asking: nil End: */ lyskom-server-2.1.2/src/libraries/regex/test/upcase.c0000664000015100472110000000326005314452726016306 /* Indexed by a character, gives the upper case equivalent of the character. */ char upcase[0400] = { 000, 001, 002, 003, 004, 005, 006, 007, 010, 011, 012, 013, 014, 015, 016, 017, 020, 021, 022, 023, 024, 025, 026, 027, 030, 031, 032, 033, 034, 035, 036, 037, 040, 041, 042, 043, 044, 045, 046, 047, 050, 051, 052, 053, 054, 055, 056, 057, 060, 061, 062, 063, 064, 065, 066, 067, 070, 071, 072, 073, 074, 075, 076, 077, 0100, 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117, 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127, 0130, 0131, 0132, 0133, 0134, 0135, 0136, 0137, 0140, 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117, 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127, 0130, 0131, 0132, 0173, 0174, 0175, 0176, 0177, 0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207, 0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217, 0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227, 0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237, 0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247, 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257, 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267, 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307, 0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317, 0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327, 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337, 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347, 0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357, 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367, 0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377 }; lyskom-server-2.1.2/src/libraries/regex/test/xmalloc.c0000664000015100472110000000045705314452726016472 #include extern char *malloc (); #ifndef NULL #define NULL 0 #endif void * xmalloc (size) unsigned size; { char *new_mem = malloc (size); if (new_mem == NULL) { fprintf (stderr, "xmalloc: request for %u bytes failed.\n", size); abort (); } return new_mem; } lyskom-server-2.1.2/src/libraries/libcommon/0000777000015100472110000000000007723710337014632 5lyskom-server-2.1.2/src/libraries/libcommon/README0000664000015100472110000000031205064201276015415 Functions for both the server and the clients to use. kom-errno.c - contains the kom_perror function parser.c - routines for parsing the lyskom protocol misc-parser.c - routines for parsing misc-info lyskom-server-2.1.2/src/libraries/libcommon/Makefile.am0000664000015100472110000000244307721716123016604 # $Id: Makefile.am,v 1.11 2003/08/23 16:38:20 ceder Exp $ # Copyright (C) 1998-1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # include $(top_srcdir)/scripts/common.make noinst_LIBRARIES = liblyskom-server.a liblyskom_server_a_SOURCES = kom-errno.c misc-parser.c parser.c \ misc-parser.h parser.h EXTRA_DIST = .cvsignore ChangeLog.1 AM_CPPFLAGS = -I$(srcdir)/../../include -I$(srcdir)/../libmisc MOSTLYCLEANFILES = *.da *.bb *.gcov *.bbg lyskom-server-2.1.2/src/libraries/libcommon/Makefile.in0000664000015100472110000003377507723707424016637 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # $Id: Makefile.am,v 1.11 2003/08/23 16:38:20 ceder Exp $ # Copyright (C) 1998-1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEBUG_CALLS = @DEBUG_CALLS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EFENCE = @EFENCE@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FLEX = @FLEX@ HAVE_PYTHON_FALSE = @HAVE_PYTHON_FALSE@ HAVE_PYTHON_TRUE = @HAVE_PYTHON_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSURE = @INSURE@ LANGUAGE_SUFFIX = @LANGUAGE_SUFFIX@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ SED = @SED@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRACED_ALLOCATIONS = @TRACED_ALLOCATIONS@ U = @U@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ YACC = @YACC@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ RM = rm -f dbdir = $(localstatedir)/lyskomd/db exportdir = $(localstatedir)/lyskomd/exportdb noinst_LIBRARIES = liblyskom-server.a liblyskom_server_a_SOURCES = kom-errno.c misc-parser.c parser.c \ misc-parser.h parser.h EXTRA_DIST = .cvsignore ChangeLog.1 AM_CPPFLAGS = -I$(srcdir)/../../include -I$(srcdir)/../libmisc MOSTLYCLEANFILES = *.da *.bb *.gcov *.bbg subdir = src/libraries/libcommon ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) liblyskom_server_a_AR = $(AR) cru liblyskom_server_a_LIBADD = am_liblyskom_server_a_OBJECTS = kom-errno.$(OBJEXT) \ misc-parser.$(OBJEXT) parser.$(OBJEXT) liblyskom_server_a_OBJECTS = $(am_liblyskom_server_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/scripts/depcomp am__depfiles_maybe = depfiles @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/kom-errno.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/misc-parser.Po ./$(DEPDIR)/parser.Po COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ DIST_SOURCES = $(liblyskom_server_a_SOURCES) DIST_COMMON = README $(top_srcdir)/scripts/common.make Makefile.am \ Makefile.in SOURCES = $(liblyskom_server_a_SOURCES) all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/scripts/common.make $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/libraries/libcommon/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) liblyskom-server.a: $(liblyskom_server_a_OBJECTS) $(liblyskom_server_a_DEPENDENCIES) -rm -f liblyskom-server.a $(liblyskom_server_a_AR) liblyskom-server.a $(liblyskom_server_a_OBJECTS) $(liblyskom_server_a_LIBADD) $(RANLIB) liblyskom-server.a mostlyclean-compile: -rm -f *.$(OBJEXT) core *.core distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kom-errno.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc-parser.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parser.Po@am__quote@ distclean-depend: -rm -rf ./$(DEPDIR) .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ @am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ @am__fastdepCC_TRUE@ fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< .c.obj: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ @am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ @am__fastdepCC_TRUE@ fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` uninstall-info-am: ETAGS = etags ETAGSFLAGS = CTAGS = ctags CTAGSFLAGS = tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$tags$$unique" \ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = ../../.. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) $(mkinstalldirs) $(distdir)/../../../scripts @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am distclean-am: clean-am distclean-compile distclean-depend \ distclean-generic distclean-tags dvi: dvi-am dvi-am: info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags distclean distclean-compile \ distclean-depend distclean-generic distclean-tags distdir dvi \ dvi-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/src/libraries/libcommon/kom-errno.c0000664000015100472110000000243207721716123016623 /* * $Id: kom-errno.c,v 0.26 2003/08/23 16:38:20 ceder Exp $ * Copyright (C) 1991-1996, 1998-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * kom_errno.c * * Created by ceder 1990-05-13 * */ #ifdef HAVE_CONFIG_H # include #endif #include #include "kom-errno.h" enum kom_err kom_errno = KOM_NO_ERROR; /* Additional information about the error */ unsigned long err_stat = 0; lyskom-server-2.1.2/src/libraries/libcommon/misc-parser.c0000664000015100472110000001245207721716123017142 /* * $Id: misc-parser.c,v 0.21 2003/08/23 16:38:20 ceder Exp $ * Copyright (C) 1990-1991, 1993-1995, 1998-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * misc-parser.c * Parse a list of misc-items for LysKOM texts. * * * Copyright (C) 1990-1991, 1993-1995, 1998-1999, 2001-2003 Lysator Computer Club, * Linkoping University, Sweden * * Everyone is granted permission to copy, modify and redistribute * this code, provided the people they give it to can. * * * Author: Thomas Bellman * Lysator Computer Club * Linkoping University * Sweden * * email: Bellman@Lysator.LiU.SE * * * Any opinions expressed in this code are the author's PERSONAL opinions, * and does NOT, repeat NOT, represent any official standpoint of Lysator, * even if so stated. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include "s-string.h" #include "misc-types.h" #include "misc-parser.h" #define EXPORT /* * Return TRUE if the next misc-item exist, and it is of type * MTYPE, FALSE otherwise. Can only be used within the function * parse_next_misc(). */ #define NEXT_IS(mtype) \ (*info < stop_pointer && (*info)->type == (mtype)) #define BARF { result.type = m_error; return result; } /* * Parse out a "group" of misc-items from a list of them pointed * to by *INFO. *STOP_POINTER must point to the item directly * after the last in the list. **INFO will be incremented to * point to the item after the recently parsed out group. The * return value will have the TYPE field set to 'm_end_of_list' * when the end of the list has been reached. */ EXPORT Misc_info_group parse_next_misc (const Misc_info ** info, const Misc_info * stop_pointer) { Misc_info_group result; /* Clear the 'result' struct */ result.type = m_error; result.recipient = 0; result.cc_recipient = 0; result.local_no = 0; result.is_received = FALSE; result.comment_to = 0; result.commented_in = 0; result.footnote_to = 0; result.footnoted_in = 0; result.sender = 0; result.is_sent = FALSE; if (*info >= stop_pointer) { result.type = m_end_of_list; return result; } /* Now, do the real work... */ switch ((*info)->type) { case recpt: /* These two are so similar that they can */ case cc_recpt: /* Be handled in the same clause */ case bcc_recpt: if ((*info)->type == recpt) { result.type = m_recpt; result.recipient = (*(*info)++).datum.recipient; } else if ((*info)->type == cc_recpt) { result.type = m_cc_recpt; result.cc_recipient = (*(*info)++).datum.recipient; } else { result.type = m_bcc_recpt; result.bcc_recipient = (*(*info)++).datum.recipient; } /* There should follow a 'Local no', but check nevertheless */ if (! NEXT_IS (loc_no)) { BARF } else result.local_no = (*(*info)++).datum.local_no; if (NEXT_IS (rec_time)) { result.is_received = TRUE; result.received_at = (*(*info)++).datum.received_at; } if (NEXT_IS (sent_by)) { result.sender = (*(*info)++).datum.sender; /* There _should_ be a 'sent_at' here... */ if (! NEXT_IS (sent_at)) { BARF } /* Let the following if clause insert the 'sent_at' data. */ } if (NEXT_IS (sent_at)) { result.is_sent = TRUE; result.sent_at = (*(*info)++).datum.sent_at; } break; case comm_to: result.type = m_comm_to; result.comment_to = (*(*info)++).datum.text_link; if (NEXT_IS (sent_by)) { result.sender = (*(*info)++).datum.sender; /* There _should_ be a 'sent_at' here. */ if (! NEXT_IS (sent_at)) { BARF } /* Let the following if clause insert the 'sent_at' data. */ } if (NEXT_IS (sent_at)) { result.is_sent = TRUE; result.sent_at = (*(*info)++).datum.sent_at; } break; case footn_to: result.type = m_footn_to; result.footnote_to = (*(*info)++).datum.text_link; if (NEXT_IS (sent_at)) { result.is_sent = TRUE; result.sent_at = (*(*info)++).datum.sent_at; } break; case comm_in: result.type = m_comm_in; result.commented_in = (*(*info)++).datum.text_link; break; case footn_in: result.type = m_footn_in; result.footnoted_in = (*(*info)++).datum.text_link; break; #ifndef COMPILE_CHECKS default: #endif case unknown_info: case loc_no: case rec_time: case sent_by: case sent_at: result.type = m_error; break; } return result; } lyskom-server-2.1.2/src/libraries/libcommon/parser.c0000664000015100472110000002672007721716123016214 /* * $Id: parser.c,v 0.23 2003/08/23 16:38:20 ceder Exp $ * Copyright (C) 1990-1991, 1993-1995, 1998-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * client/parser.c -- Routines to parse commands * * * Copyright (C) 1990-1991, 1993-1995, 1998-1999, 2001-2003 Lysator Computer Club, * Linkoping University, Sweden * * Everyone is granted permission to copy, modify and redistribute * this code, provided the people they give it to can. * * * Author: Thomas Bellman * Lysator Computer Club * Linkoping University * Sweden * * email: Bellman@Lysator.LiU.SE * * * Any opinions expressed in this code are the author's PERSONAL opinions, * and does NOT, repeat NOT, represent any official standpoint of Lysator, * even if so stated. */ #ifdef HAVE_CONFIG_H # include #endif #ifdef HAVE_STDDEF_H # include #endif #include #include "s-string.h" #include "s-collat-tabs.h" #include "kom-types.h" #include "parser.h" #define EXPORT /* To emphasize export of objects */ #define PRIVATE static #include "server/smalloc.h" #define MALLOC smalloc #define REALLOC srealloc #define FREE sfree /* * Remove paranthesized "expressions" from the string STR. * E g if STR is "Foo (Bar (vfslck)) Gazonk", then it is reduced * to "Foo _ Gazonk", where '_' is the character in SEPARATOR. * Superflous close paranthesis are disregarded. */ EXPORT void remove_parenthesis (String * str, char blanker) { String_size i; /* Index in loop */ int nesting_depth; /* Match parantheses. Remove text inside parantheses. */ nesting_depth = 0; for ( i = 0 ; i < s_strlen(*str) ; i++ ) { if (str->string[i] == '(') nesting_depth++; if (str->string[i] == ')') { nesting_depth--; str->string[i] = blanker; /* Don't forget that... */ if (nesting_depth < 0) nesting_depth = 0; } if (nesting_depth > 0) str->string[i] = blanker; } return; } /* * Convert a String to a list of tokens (words). This list is * easier to parse than a string (since the string would have to * be tokenized first anyway). The last entry is EMPTY_STRING. * Returns NULL if any error occured (couldn't allocate memory). * The result from this function should be freed when it is no longer * used by a FREE(Parse_token *). Note that String (Parse_token *)[X].word * points into source, and should thus not be freed. */ EXPORT Parse_token * tokenize (const String source, const String separators) { Parse_token * tokens = NULL; Parse_token * temp_list; /* Temporary */ String work_string = EMPTY_STRING; String a_token; String a_temp_token; /* More temporaries... */ int no_of_tokens; int list_size; String_size pos_in_string; const int chunk_size = 10; /* Copy string to working area */ if (s_strcpy(&work_string, source) == FAILURE) { /* Couldn't allocate space for temporary string. */ return NULL; } remove_parenthesis (&work_string, separators.string[0]); no_of_tokens = 0; list_size = 0; pos_in_string = 0; while (a_token = s_strtok (work_string, &pos_in_string, separators), s_empty(a_token) == FALSE) { /* Make the token point into the original source string * instead of the working string */ a_temp_token = s_fsubstr (source, pos_in_string - s_strlen (a_token), pos_in_string - 1); #if 0 // * /* Get a real copy of the word */ // * a_temp_token = EMPTY_STRING; // * if (s_strcpy(&a_temp_token, a_token) == FAILURE) // * { // * /* Grumble... */ // * free_tokens (tokens); // * s_clear(&work_string); // * return NULL; // * } #endif /* Is the allocated list large enough? */ if (no_of_tokens++ >= list_size) { /* No, allocate more */ temp_list = REALLOC (tokens, (list_size += chunk_size) * sizeof(Parse_token)); if (temp_list == NULL) { /* Sigh. Out of memory. */ free_tokens (tokens); s_clear (&work_string); return NULL; } else { /* OK, we got what we asked for */ tokens = temp_list; } } /* Insert the new token in the list */ tokens [no_of_tokens-1].word = a_temp_token; tokens [no_of_tokens-1].start_in_string = pos_in_string - s_strlen(a_temp_token); } s_clear (&work_string); /* Is there room in the list for the 'stop' element? */ if (list_size <= no_of_tokens) { /* No, get some more memory */ temp_list = REALLOC (tokens, (++list_size) * sizeof(Parse_token)); if (temp_list == NULL) { /* Sigh. Out of memory. */ free_tokens (tokens); return NULL; } else { /* OK, we got what we asked for */ tokens = temp_list; } } /* OK, insert the 'stop' element. */ tokens [no_of_tokens].word = EMPTY_STRING; tokens [no_of_tokens].start_in_string = END_OF_STRING; return tokens; } /* * Count the number of tokens (words) in TOKEN_LIST. Used to * set the NUMBER_OF_WORDS field in a 'Matching_info' object. */ extern int count_words (const Parse_token * token_list) { int no_of_words; no_of_words = 0; while (! s_empty(token_list++ -> word)) no_of_words++; return no_of_words; } /* * Free the list of tokens (// and the strings they are pointing to //). * Free:ing NULL is a no-op. */ EXPORT void free_tokens (Parse_token * token_list) { if (token_list != NULL) { FREE (token_list); } } /* * Returns the number of the first word of SOURCE that does * not match PATTERN. A word "foo" in SOURCE matches "foobar" * in PATTERN, but not vice versa. */ EXPORT int match (Parse_token * source, Parse_token * pattern, unsigned char collat_tab[COLLAT_TAB_SIZE]) { int word_no; word_no = 0; while ( (! s_streq (pattern[word_no].word, EMPTY_STRING)) && (! s_streq (source[word_no].word, EMPTY_STRING)) && (s_usr_strhead (source[word_no].word, pattern[word_no].word, collat_tab) == TRUE)) { word_no++; } return word_no; } /* * Searches for a matching string in the table 'match_table'. * Some weird pattern matching is done. * parse().no_of_matches is -1 if an error occured (out of * memory). * * What? You want a description of how it matches? Forget it! BUG! * Try for yourself, and you'll find out! */ EXPORT Parse_info parse (String source_string, Matching_info * match_table, Bool allow_trailing_words, Bool number_of_words_must_match, String separators, unsigned char collat_tab[COLLAT_TAB_SIZE]) { Parse_info answer; int * temp_indexes; int index; int size_of_index_list; Parse_token * source_words; int no_of_source_words; int first_non_matching; int best_match; int highest_priority; const int chunk_size = 20; source_words = tokenize(source_string, separators); if (source_words == NULL) { answer.no_of_matches = -1; return answer; } no_of_source_words = count_words(source_words); /* Check if SOURCE_STRING was empty of words */ if (no_of_source_words == 0) { FREE (source_words); answer.indexes = MALLOC (1 * sizeof(int)); if (answer.indexes == NULL) { /* Gahh! Someone eats memory! */ answer.no_of_matches = -1; return answer; } answer.indexes[0] = -1; answer.no_of_matches = 1; return answer; } answer.no_of_matches = 0; answer.indexes = NULL; size_of_index_list = 0; index = -1; best_match = 1; /* At least one word */ highest_priority = 1; while (match_table[++index].conf_no != 0) { if (! s_empty (match_table[index].name)) { first_non_matching = match (source_words, match_table[index].tokens, collat_tab); if ( ( ! allow_trailing_words && first_non_matching < no_of_source_words) || ( number_of_words_must_match == TRUE && first_non_matching != count_words (match_table[index].tokens))) { continue; /* Try next entry in table */ } if (first_non_matching < best_match) continue; /* Try next entry in table */ if ( first_non_matching == best_match && highest_priority > match_table[index].priority) continue; /* If we reach this far, then we have a match that should be * inserted in the table. But if it is a better match than any * before, then we clear the table first. */ if ( first_non_matching > best_match || match_table[index].priority > highest_priority) { highest_priority = match_table[index].priority; best_match = first_non_matching; answer.no_of_matches = 0; } /* Insert the match in the table */ /* Increase the size if necessary */ if (answer.no_of_matches >= size_of_index_list) { temp_indexes = REALLOC (answer.indexes, (size_of_index_list += chunk_size) * sizeof(answer.indexes)); if (temp_indexes == NULL) { /* Grumble! Out of memory. */ FREE (source_words); FREE (answer.indexes); answer.no_of_matches = -1; return answer; } answer.indexes = temp_indexes; } highest_priority = match_table [index].priority; answer.indexes[answer.no_of_matches] = index; /* Find out where the arguments start. * This value should not be used if more than one match is found. */ /* Special hack needed if no parameters */ if (s_empty (source_words [first_non_matching].word)) answer.arguments = EMPTY_STRING; else answer.arguments = s_fsubstr(source_string, source_words[first_non_matching]. start_in_string, END_OF_STRING); answer.no_of_matches++; } } /* All matches found by now */ /* Strip trailing blanks from the argument */ if (answer.no_of_matches == 1) answer.arguments = s_strip_trailing (answer.arguments, separators); FREE (source_words); return answer; } /* END: parse() */ lyskom-server-2.1.2/src/libraries/libcommon/misc-parser.h0000664000015100472110000000563007721716123017147 /* * $Id: misc-parser.h,v 0.12 2003/08/23 16:38:20 ceder Exp $ * Copyright (C) 1990-1991, 1993-1995, 1997, 1999, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: misc-parser.h,v 0.12 2003/08/23 16:38:20 ceder Exp $ * * misc-parser.h * Parse a list of "misc-item":s for a text in LysKOM * * * Copyright (C) 1990-1991, 1993-1995, 1997, 1999, 2003 Lysator Computer Club, * Linkoping University, Sweden * * Everyone is granted permission to copy, modify and redistribute * this code, provided the people they give it to can. * * * Author: Thomas Bellman * Lysator Computer Club * Linkoping University * Sweden * * email: Bellman@Lysator.LiU.SE */ #include typedef enum { m_recpt, m_cc_recpt, m_bcc_recpt, m_comm_to, m_comm_in, m_footn_to, m_footn_in, m_end_of_list, /* End of list reached */ m_error /* Bad misc-items found */ } Misc_struct_type; typedef struct { Misc_struct_type type; Conf_no recipient; Conf_no cc_recipient; Conf_no bcc_recipient; Local_text_no local_no; Time received_at; Text_no comment_to; Text_no commented_in; Text_no footnote_to; Text_no footnoted_in; Pers_no sender; Time sent_at; Bool is_received; Bool is_sent; } Misc_info_group; #define IS_RECEIVED(mstruct) ((mstruct).is_received != FALSE) #define IS_SENT_BY(mstruct) ((mstruct).sender != 0) #define IS_SENT(mstruct) ((mstruct).is_sent != FALSE) /* * Parse out a "group" of misc-items from a list of them pointed * to by *INFO. *STOP_POINTER must point to the item directly * after the last in the list. **INFO will be incremented to * point to the item after the recently parsed out group. The * return value will have the TYPE field set to 'm_end_of_list' * when the end of the list has been reached. * * If the has a bad format, the TYPE field will be 'm_error', * and **INFO_POINTER will point to the item before the bad (or * missing) item. */ extern Misc_info_group parse_next_misc (const Misc_info ** info_pointer, const Misc_info * stop_pointer); lyskom-server-2.1.2/src/libraries/libcommon/parser.h0000664000015100472110000001162507721716123016217 /* * $Id: parser.h,v 0.14 2003/08/23 16:38:20 ceder Exp $ * Copyright (C) 1990-1991, 1994-1995, 1998-1999, 2002-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: parser.h,v 0.14 2003/08/23 16:38:20 ceder Exp $ * * client/parser.h -- Header file for LysKOM command parsing routines * * * Copyright (C) 1990-1991, 1994-1995, 1998-1999, 2002-2003 Lysator Computer Club, * Linkoping University, Sweden * * Everyone is granted permission to copy, modify and redistribute * this code, provided the people they give it to can. * * * Author: Thomas Bellman * Lysator Computer Club * Linkoping University * Sweden * * e-mail: Bellman@Lysator.LiU.SE */ #ifndef PARSER_H_ALREADY_INCLUDED__ #define PARSER_H_ALREADY_INCLUDED__ #include #include #include /* * Information about one word. If the field 'word' is * EMPTY_STRING, then the struct is considered to be the last * in an "array". BUG: "array" is wrong word */ typedef struct { String word; String_size start_in_string; } Parse_token; /* * Information about one string to match against during parse(). * A list of these should be passed to parse() as the CMD_TABLE * parameter. The 'tokens' field is set by doing * I.tokens = tokenize(I.name, Separators); */ typedef struct matching_info { Conf_no conf_no; /* Conference */ String name; /* Name to match against */ Parse_token * tokens; /* Tokenized version of name */ int priority; /* Normally in interval 1..15 */ } Matching_info; /* * Remove paranthesized "expressions" from the string STR by * replacing them with the character SEPARATOR. * Superflous close paranthesis are disregarded. */ extern void remove_parenthesis (String * str, char separator); /* * Convert a String to a list of tokens (words). This list is * easier to parse than a string (since the string would have to * be tokenized first anyway). * Returns NULL if any error occured (couldn't allocate memory). */ extern Parse_token * tokenize (const String source, const String separators); /* * Count the number of tokens (words) in TOKEN_LIST. Used to * set the NUMBER_OF_WORDS field in a 'Matching_info' object. */ extern int count_words (const Parse_token * token_list); /* * Free the list of tokens (// and the strings they are pointing to //). * Free:ing NULL is a no-op. */ extern void free_tokens (Parse_token * token_list); /* * Returns the number of the first word of SOURCE that does * not match PATTERN. A word "foo" in SOURCE matches "foobar" * in PATTERN, but not vice versa. */ extern int match (Parse_token * source, Parse_token * pattern, unsigned char collat_tab[COLLAT_TAB_SIZE]); /* * Contains the result of a parse(). */ typedef struct { int no_of_matches; /* Number of found matches */ int * indexes; /* List of indexes */ String arguments; /* The arguments... */ } Parse_info; /* * Searches for a matching string in the table 'match_table'. * Some weird pattern matching is done. The 'ARGUMENTS' field of * the result is not a separate String, but points into * SOURCE_STRING. * If ALLOW_TRAILING_WORDS is false, then SOURCE_STRING may not * contain any trailing words. * If NUMBER_OF_WORDS_MUST_MATCH is true, then all the words * in from the entry in MATCH_TABLE must be present (possibly * abbrevated) in SOURCE_STRING. * parse().no_of_matches is -1 if an error occured (out of * memory). * If SOURCE_STRING is empty, i e does not contain any words, * the 'no_of_matches' field is 1, and indexes[0] is -1. * * What? You want a description of how it matches? Forget it! BUG! * Try for yourself, and you'll find out! */ extern Parse_info parse (String source_string, Matching_info * match_tbl, Bool allow_trailing_words, Bool number_of_words_must_match, String separators, unsigned char collat_tab[COLLAT_TAB_SIZE]); #endif /* PARSER_H_ALREADY_INCLUDED__ */ lyskom-server-2.1.2/src/libraries/libcommon/.cvsignore0000664000015100472110000000006206650620443016542 .deps Makefile Makefile.in *.da *.bb *.bbg *.gcov lyskom-server-2.1.2/src/libraries/libcommon/ChangeLog.10000664000015100472110000000347006210047326016454 Tue Dec 27 00:34:49 1994 Per Cederqvist (ceder@lysator.liu.se) * kom-errno.c (kom_perror): KOM_SERVER_IS_CRAZY and KOM_CLIENT_IS_CRAZY no longer exists. Mon Aug 29 19:55:48 1994 Per Cederqvist (ceder@lysator.liu.se) * misc-parser.c (parse_next_misc): Initialize result.is_sent to FALSE, not 0. * kom-errno.c (kom_perror): KOM_PERS_EXISTS no longer exists. (kom_errno): Initialize to KOM_NO_ERROR, not to 0. Sat Oct 16 17:38:59 1993 Per Cederqvist (ceder@lysator.liu.se) * Changes for vcc: * kom-errno.c: Don't split string constants in two parts. * misc-parser.h (IS_RECEIVED, IS_SENT_BY, IS_SENT): Was formerly named is_received, is_sent_by and is_sent, which caused vcc to loop for a very long time. * parser.c: Include sys/types.h. Rewrite complex expressions so that vcc understands them. Fri Oct 8 00:34:23 1993 Per Cederqvist (ceder@lysator.liu.se) * kom-errno.c, parser.c: Tidied up include statements. Mon Jul 6 15:34:30 1992 Linus Tolke Y (linus@robin) * Makefile: Completed clean to cleaning the sub-dirs also. Wed Feb 26 19:51:37 1992 Per Cederqvist (ceder@lysator) * kom-errno.c: Lint from gcc 2.0 removed. Sat Sep 21 11:01:47 1991 Per Cederqvist (ceder at lysator) * parser.c (parse): FREE (source_words) before returning. Sat Jul 6 06:15:40 1991 Per Cederqvist (ceder at lysator) * Fixade makefilen s} att den kan generera b}de liblyskom-server.a och liblyskom-client.a. (Den ena kompilerad med SERVER definierad, den andra med CLIENT definierad). "make depend" kr{ver i nul{get manuella efterjusteringar. * misc-parser.h: "time_t" bytt mot "Time" (som {r "struct tm" i klienten och "time_t" i servern). * [ndrade "typedef struct {...} Matching_info" till "typedef struct matching_info {...} Matching_info". * parser.h: s-collat-tables.h -> s-collat-tabs.h. lyskom-server-2.1.2/src/libraries/libmisc/0000777000015100472110000000000007723710341014270 5lyskom-server-2.1.2/src/libraries/libmisc/README0000664000015100472110000000054505550015673015074 Functions of varying type. numlist - Routines for handling a list of numbers pom - A routine for calculating the phase of the moon s-collat-tabs - Tabs for sorting according to different alphabets s-string - String type handling routines for the type String zmalloc - reference counting malloc ldifftime - a difftime() returning long, not double lyskom-server-2.1.2/src/libraries/libmisc/Makefile.am0000664000015100472110000000250507721716124016247 # $Id: Makefile.am,v 1.14 2003/08/23 16:38:20 ceder Exp $ # Copyright (C) 1998-1999, 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # include $(top_srcdir)/scripts/common.make noinst_LIBRARIES = libmisc.a libmisc_a_SOURCES = s-collat-tabs.c s-string.c ldifftime.c \ s-collat-tabs.h s-string.h ldifftime.h \ timeval-util.h timeval-util.c EXTRA_DIST = .cvsignore ChangeLog.1 AM_CPPFLAGS = -I$(srcdir)/../../include -I$(srcdir)/../liboop MOSTLYCLEANFILES = *.da *.bb *.gcov *.bbg lyskom-server-2.1.2/src/libraries/libmisc/Makefile.in0000664000015100472110000003404507723707425016272 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # $Id: Makefile.am,v 1.14 2003/08/23 16:38:20 ceder Exp $ # Copyright (C) 1998-1999, 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEBUG_CALLS = @DEBUG_CALLS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EFENCE = @EFENCE@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FLEX = @FLEX@ HAVE_PYTHON_FALSE = @HAVE_PYTHON_FALSE@ HAVE_PYTHON_TRUE = @HAVE_PYTHON_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSURE = @INSURE@ LANGUAGE_SUFFIX = @LANGUAGE_SUFFIX@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ SED = @SED@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRACED_ALLOCATIONS = @TRACED_ALLOCATIONS@ U = @U@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ YACC = @YACC@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ RM = rm -f dbdir = $(localstatedir)/lyskomd/db exportdir = $(localstatedir)/lyskomd/exportdb noinst_LIBRARIES = libmisc.a libmisc_a_SOURCES = s-collat-tabs.c s-string.c ldifftime.c \ s-collat-tabs.h s-string.h ldifftime.h \ timeval-util.h timeval-util.c EXTRA_DIST = .cvsignore ChangeLog.1 AM_CPPFLAGS = -I$(srcdir)/../../include -I$(srcdir)/../liboop MOSTLYCLEANFILES = *.da *.bb *.gcov *.bbg subdir = src/libraries/libmisc ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) libmisc_a_AR = $(AR) cru libmisc_a_LIBADD = am_libmisc_a_OBJECTS = s-collat-tabs.$(OBJEXT) s-string.$(OBJEXT) \ ldifftime.$(OBJEXT) timeval-util.$(OBJEXT) libmisc_a_OBJECTS = $(am_libmisc_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/scripts/depcomp am__depfiles_maybe = depfiles @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/ldifftime.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/s-collat-tabs.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/s-string.Po ./$(DEPDIR)/timeval-util.Po COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ DIST_SOURCES = $(libmisc_a_SOURCES) DIST_COMMON = README $(top_srcdir)/scripts/common.make Makefile.am \ Makefile.in SOURCES = $(libmisc_a_SOURCES) all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/scripts/common.make $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/libraries/libmisc/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libmisc.a: $(libmisc_a_OBJECTS) $(libmisc_a_DEPENDENCIES) -rm -f libmisc.a $(libmisc_a_AR) libmisc.a $(libmisc_a_OBJECTS) $(libmisc_a_LIBADD) $(RANLIB) libmisc.a mostlyclean-compile: -rm -f *.$(OBJEXT) core *.core distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldifftime.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s-collat-tabs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s-string.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timeval-util.Po@am__quote@ distclean-depend: -rm -rf ./$(DEPDIR) .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ @am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ @am__fastdepCC_TRUE@ fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< .c.obj: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ @am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ @am__fastdepCC_TRUE@ fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` uninstall-info-am: ETAGS = etags ETAGSFLAGS = CTAGS = ctags CTAGSFLAGS = tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$tags$$unique" \ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = ../../.. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) $(mkinstalldirs) $(distdir)/../../../scripts @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am distclean-am: clean-am distclean-compile distclean-depend \ distclean-generic distclean-tags dvi: dvi-am dvi-am: info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags distclean distclean-compile \ distclean-depend distclean-generic distclean-tags distdir dvi \ dvi-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/src/libraries/libmisc/s-collat-tabs.c0000664000015100472110000002011607721716125017023 /* * $Id: s-collat-tabs.c,v 1.19 2003/08/23 16:38:19 ceder Exp $ * Copyright (C) 1990-1991, 1993-1995, 1998-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * s-collat-tables.c -- Collating tables used for the s_usr_strcmp() * routine in s-string.[ch] * * * Copyright (C) 1990-1991, 1993-1995, 1998-1999, 2001-2003 Lysator Computer Club, * Linkoping University, Sweden * * Everyone is granted permission to copy, modify and redistribute * this code, provided the people they give it to can. * * * Author: Thomas Bellman * Lysator Computer Club * Linkoping University * Sweden * * email: Bellman@Lysator.LiU.SE */ #ifdef HAVE_CONFIG_H # include #endif #include #include "s-collat-tabs.h" /* * Collating tables: * swedish_collate_tab: Swedish text. "][\}{|" in the right * order. Upper and lower case letters * are equal. * english_collate_tab: English text. Upper and lower case * letters are equal. */ /* * swedish_collate_tab is now in ISO-8859-1. */ unsigned char swedish_collate_tab [ COLLAT_TAB_SIZE ] = { /* NU SH SX EX ET EQ AK BL */ 0000, 0001, 0002, 0003, 0004, 0005, 0006, 0007, /* BS HT LF VT FF CR SO SI */ 0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017, /* DL D1 D2 D3 D4 NK SY EB */ 0020, 0021, 0022, 0023, 0024, 0025, 0026, 0027, /* CN EM SB EC FS GS RS US */ 0030, 0031, 0032, 0033, 0034, 0035, 0036, 0037, /* # $ */ /* SP ! " Nb DO % & ' */ 0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047, /* ( ) * + , - . / */ 0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057, /* 0 1 2 3 4 5 6 7 */ 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067, /* 8 9 : ; < = > ? */ 0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077, /* @ */ /* At A B C D E F G */ 0100, 0101, 0102, 0103, 0104, 0105, 0106, 0107, /* H I J K L M N O */ 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117, /* P Q R S T U V W */ 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127, /* [ \ ] ^ */ /* X Y Z <( // )> '> _ */ 0130, 0131, 0132, 0134, 0135, 0133, 0136, 0137, /* ` */ /* '! a b c d e f g */ /* 0140, 0141, 0142, 0143, 0144, 0145, 0146, 0147, */ 0140, 0101, 0102, 0103, 0104, 0105, 0106, 0107, /* h i j k l m n o */ /* 0150, 0151, 0152, 0153, 0154, 0155, 0156, 0157, */ 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117, /* p q r s t u v w */ /* 0160, 0161, 0162, 0163, 0164, 0165, 0166, 0167, */ 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127, /* { | } ~ */ /* x y z (! !! !) '? DT */ /* 0170, 0171, 0172, 0173, 0174, 0175, 0176, 0177, */ 0130, 0131, 0132, 0134, 0135, 0133, 0176, 0177, /* PA HO BH NH IN NL SA ES */ 0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207, /* HS HJ VS PD PU RI S2 S3 */ 0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217, /* DC P1 P2 TS CC MW SG EG */ 0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227, /* SS GC SC CI ST OC PM AC */ 0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237, /* NS !I Ct Pd Cu Ye BB SE */ 0240, 0041, 0242, 0243, 0244, 0245, 0246, 0247, /* ': Co -a << NO -- Rg '- */ 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257, /* DG +- 2S 3S '' My PI .M */ 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267, /* ', 1S -o >> 14 12 34 ?I */ 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277, /* A! A' A> A? A: AA AE C, */ /* 0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307, */ 0101, 0101, 0101, 0101, 0134, 0133, 0134, 0103, /* E! E' E> E: I! I' I> I: */ /* 0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317, */ 0105, 0105, 0105, 0105, 0111, 0111, 0111, 0111, /* D- N? O! O' O> O? O: *X */ /* 0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327, */ 0320, 0116, 0117, 0117, 0117, 0117, 0135, 0052, /* O/ U! U' U> U: Y' TH ss */ /* 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337, */ 0135, 0125, 0125, 0125, 0131, 0131, 0336, 0337, /* a! a' a> a? a: aa ae c, */ /* 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347, */ 0101, 0101, 0101, 0101, 0134, 0133, 0134, 0103, /* e! e' e> e: i! i' i> i: */ /* 0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357, */ 0105, 0105, 0105, 0105, 0111, 0111, 0111, 0111, /* d- n? o! o' o> o? o: -: */ /* 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367, */ 0360, 0116, 0117, 0117, 0117, 0117, 0135, 0057, /* o/ u! u' u> u: y' th y: */ /* 0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377, */ 0135, 0125, 0125, 0125, 0131, 0131, 0376, 0377 }; unsigned char english_collate_tab [ COLLAT_TAB_SIZE ] = { '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '[', '\\', ']', '~', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '', '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207', '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217', '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227', '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237', '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247', '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257', '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267', '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277', '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307', '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317', '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327', '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337', '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347', '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377' }; lyskom-server-2.1.2/src/libraries/libmisc/s-string.c0000664000015100472110000005573207721716125016140 /* * $Id: s-string.c,v 1.32 2003/08/23 16:38:19 ceder Exp $ * Copyright (C) 1990-1996, 1998-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * s-string.c -- Routines for manipulating objects of type String. * * * Copyright (C) 1990-1996, 1998-1999, 2001-2003 Lysator Computer Club, * Linkoping University, Sweden * * Everyone is granted permission to copy, modify and redistribute * this code, provided the people they give it to can. * * * Author: Thomas Bellman * Lysator Computer Club * Linkoping University * Sweden * * email: Bellman@Lysator.LiU.SE * * * Any opinions expressed in this code are the author's PERSONAL opinions, * and does NOT, repeat NOT, represent any official standpoint of Lysator, * even if so stated. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #ifdef HAVE_STDDEF_H # include #endif #if STDC_HEADERS || HAVE_STRING_H # include # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif #else /* not STDC_HEADERS and not HAVE_STRING_H */ # include /* memory.h and strings.h conflict on some systems. */ #endif /* not STDC_HEADERS and not HAVE_STRING_H */ #include "misc-types.h" #include "s-collat-tabs.h" #include "s-string.h" #define EXPORT /* To emphasize objects that are exported */ /* The empty String */ EXPORT const String EMPTY_STRING = EMPTY_STRING_i; static free_function x_free = NULL; static malloc_function x_malloc = NULL; static realloc_function x_realloc = NULL; /* * Functions to manipulate strings of type 'String'. * All these functions return a value of type Success, which is * an enum of OK an FAILURE (do NOT trust the order of these!). * * All functions automatically allocates (and deallocates) any * necessary storage, using the storage management functions * defined by the s_set_storage_management() call. */ /* Macro to reallocate new storage. Works even if PTR is a * nil pointer. */ #define REALLOC_0(ptr, size) (((ptr) == NULL) \ ? MALLOC_0 (size) \ : (*x_realloc) ((ptr), size)) /* Free storage. Works even if PTR is a nil pointer. */ #define FREE_0(ptr) (((ptr) == NULL) \ ? 0 \ : ((*x_free) (ptr), ptr)) #define MALLOC_0(size) ((*x_malloc) (size)) /* * Set the functions to use for storage management. These must * be call compatible with the normal functions malloc(), * realloc() and free(). */ EXPORT void s_set_storage_management (malloc_function new_malloc, realloc_function new_realloc, free_function new_free) { x_malloc = new_malloc; x_realloc = new_realloc; x_free = new_free; } /* * Create an object of type String from an ordinary C string. */ EXPORT Success s_crea_str (String * dest_string, const char * c_string ) { String_size length; void * temp_ptr; /* To hold result from malloc/realloc * before actually using it. */ length = strlen(c_string); temp_ptr = MALLOC_0 (length); if (temp_ptr == NULL) { return FAILURE; } FREE_0 (dest_string->string); dest_string->string = temp_ptr; strncpy((char *)dest_string->string, c_string, length); dest_string->len = length; return OK; } /* * Create a string from a buffer. The contents of the buffer * are copied into the new string. */ EXPORT Success s_mem_crea_str (String * dest_string, const unsigned char * buffer, String_size length) { void * temp_ptr; /* To hold result from malloc/realloc * before actually using it. */ temp_ptr = MALLOC_0 (length); if (temp_ptr == NULL) { return FAILURE; } FREE_0 (dest_string->string); dest_string->string = temp_ptr; memcpy(dest_string->string, buffer, length); dest_string->len = length; return OK; } /* * Create a string of a given size. The contents of the string * are unspecified. The LysKOM-server uses this to get a string * of a fixed size into which it can fread() data. This is probably * not a good idea since it relies heavily on the implementation * of strings. However, by using this function, those places are * easy to identify if the implementation should be done differently. */ EXPORT Success s_size_crea_str(String *result, String_size length) { void * temp_ptr; /* To hold result from malloc/realloc * before actually using it. */ temp_ptr = MALLOC_0 (length); if (temp_ptr == NULL) { return FAILURE; } FREE_0 (result->string); result->string = temp_ptr; result->len = length; return OK; } /* * Return a temporary String from a C string, i e return a struct * pointing to the actual C string. Suitable for sending a 'String' * object as parameter to a function (IF that function does not modify * its parameter). Note that normally String variables should be set * by s_crea_str(), to deallocate the memory used by it. */ EXPORT String s_fcrea_str (const char * c_string) { String temp; /* Cast needed to make compiler not warn about assignment from * const pointer to non-const pointer. Sigh... */ temp.string = (unsigned char *)c_string; temp.len = strlen(c_string); return temp; } /* * Free's the space used by a String object. The object is * set to EMPTY_STRING. */ EXPORT void s_clear (String * str) { FREE_0 (str->string); *str = EMPTY_STRING; } /* * Copy SOURCE_STRING to DEST_STRING. Old value of DEST_STRING is * retained if an error was encountered. If 'foo' is a separate * String, then it is legal to do 's_strcpy(&foo, foo)'. */ EXPORT Success s_strcpy (String * dest_string, const String source_string) { void * temp_ptr; /* To hold result from malloc/realloc * before actually using it. */ if (s_strlen(source_string) == 0) { s_clear (dest_string); return OK; } /* (Re-)allocate memory */ temp_ptr = REALLOC_0 (dest_string->string, s_strlen(source_string)); if (temp_ptr == NULL) return FAILURE; dest_string->string = temp_ptr; /* Copy the string */ memcpy (dest_string->string, source_string.string, s_strlen (source_string)); dest_string->len = s_strlen (source_string); return OK; } /* * In String STR remove the characters starting with number FIRST * and ending with number LAST, inclusive. If FIRST > LAST, then * no characters are removed. */ extern Success s_strdel (String * str, String_size first, String_size last ) { String_size i; /* Just an index in a loop */ assert ( first >= 0 && first <= s_strlen (*str) && last >= -1 && last < s_strlen (*str)); for ( i = last + 1 ; i < s_strlen(*str) ; i++ ) str->string [i-(last-first+1)] = str->string [i]; str->len -= last-first+1; return OK; } /* * Append SOURCE_STRING to the end of DEST_STRING. DEST_STRING is not * changed if an error is encountered. */ EXPORT Success s_strcat (String * dest_string, const String source_string) { void * temp_ptr; /* To hold result from malloc/realloc * before actually using it. */ /* (Re-)alloc space for new string */ temp_ptr = REALLOC_0 (dest_string->string, dest_string->len + source_string.len); if (temp_ptr == NULL) { return FAILURE; } dest_string->string = temp_ptr; /* Append SOURCE_STRING to *DEST_STRING */ memcpy (dest_string->string + s_strlen (*dest_string), source_string.string, s_strlen (source_string)); dest_string->len += source_string.len; return OK; } /* * Extract a substring from SOURCE_STRING, starting with char no * START_CHAR and ending with char no END_CHAR. First character * is character no 0. If END_CHAR < START_CHAR, then DEST_STRING * is set to 'EMPTY_STRING'. If END_CHAR is equal to the macro * 'END_OF_STRING', then the substring reaches to the last character * in SOURCE_STRING. */ EXPORT Success s_substr (String * dest_string, const String source_string, String_size start_char, String_size end_char) { String_size sub_len; /* Length of substring */ void * temp_ptr; /* To hold result from malloc/realloc * before really using it. */ if (end_char == END_OF_STRING) end_char = s_strlen(source_string)-1; assert ( start_char >= 0 && end_char >= -1 && start_char <= s_strlen (source_string) && end_char < s_strlen (source_string)); sub_len = end_char - start_char + 1; /* Will the substring be empty? */ if (sub_len <= 0) { s_clear (dest_string); /* Free and set to EMPTY_STRING */ return OK; } /* (Re-)allocate space for substring */ temp_ptr = REALLOC_0(dest_string->string, sub_len); if (temp_ptr == NULL) { return FAILURE; } dest_string->string = temp_ptr; /* Copy substring to DEST_STRING */ memcpy (dest_string->string, source_string.string + start_char, sub_len); dest_string->len = sub_len; return OK; } /* * Fast extraction of a substring. Returns an object of type * String wich points into SOURCE_STRING. Thus you should NEVER * modify the result of this function. (Raw character modifying * is OK if you know what you are doing, but never use anything * that might call free or realloc on it.) If END_CHAR is equal * to the macro 'END_OF_STRING', then the substring reaches to * the last character in SOURCE_STRING. */ EXPORT String s_fsubstr (const String source_string, String_size start_char, String_size end_char ) { String sub_string; /* Substring struct */ if (end_char == END_OF_STRING) end_char = s_strlen(source_string)-1; assert ( start_char >= 0 && end_char >= -1 && start_char <= s_strlen (source_string) && end_char < s_strlen (source_string)); sub_string.len = end_char - start_char + 1; /* Is the substring empty? */ if (sub_string.len < 1) { return EMPTY_STRING; } sub_string.string = source_string.string + start_char; return sub_string; } /* * Returns -1 if ARG is negative, 0 if 0 and +1 if positive. * Used in the string comparison routines. */ static int sign (int arg) { if (arg < 0) return -1; else if (arg == 0) return 0; else return 1; } /* * Compares two strings. Returns -1 if STR1 is lexically less * than STR2, +1 if STR1 is greater than STR2, and 0 if they are * equal. */ EXPORT int s_strcmp (String str1, String str2) { String_size index; String_size shortest; /* Length of the shortest string */ int retval_based_on_lengths; retval_based_on_lengths = sign(str1.len - str2.len); if (str1.len < str2.len) shortest = str1.len; else shortest = str2.len; /* If they point to the same string, then we only have to * compare the lengths. */ if (str1.string == str2.string) return retval_based_on_lengths; /* Find first diff:ing character (in [index]) */ index = 0; while ( (index < shortest) && (str1.string[index] == str2.string[index]) ) index++; /* If no diff:ing char, then the shortest is the "smallest" */ if (index >= shortest) return retval_based_on_lengths; else /* ...else check which character was the "smallest". */ return sign(str1.string[index] - str2.string[index]); } /* * Makes INDEX (type char) positive. Those that are negative, * result in a positive number above the other numbers. This * works as if bitcopying a 2's complement nuber to an unsigned * number. * * NOTE: This code might need to be modified for some architectures. */ #define POS_INDEX(index) ((unsigned char)(index)) /* * Compares two strings with user specified collation order. * Returns the same values as s_srcmp(). * COLLAT_TAB is a table of collating values for every char. */ EXPORT int s_usr_strcmp(String str1, String str2, unsigned char *collat_tab) { String_size index; String_size shortest; /* Length of the shortest string */ int retval_based_on_lengths; retval_based_on_lengths = sign(str1.len - str2.len); if (str1.len < str2.len) shortest = str1.len; else shortest = str2.len; /* If they point to the same string, then we only have to * compare the lengths. */ if (str1.string == str2.string) return retval_based_on_lengths; /* Find first diff:ing character (in [index-1]) */ index = 0; while ( (index < shortest) && ( collat_tab [ POS_INDEX( str1.string [index] )] == collat_tab [ POS_INDEX( str2.string [index] )]) ) index++; /* If no diff:ing char, then the shortest is the "smallest" */ if (index >= shortest) return retval_based_on_lengths; /* ...else check which character was the "smallest". */ else return sign( collat_tab [ POS_INDEX( str1.string[index] )] - collat_tab [ POS_INDEX( str2.string[index] )] ); } /* * Checks if STR1 is the exact beginning of STR2, e g if STR1 * is "foobar" and STR2 is "foobarf" then the result is TRUE. */ EXPORT Bool s_strhead (String str1, String str2) { String_size i; /* Index in comparison loop */ /* If STR1 is longer than STR2, then it can't be a head. */ if (s_strlen(str1) > s_strlen(str2)) return FALSE; /* If they point to the same string, then STR1 is a head * of STR2. (We have already compared the lengths.) */ if (str1.string == str2.string) return TRUE; /* Check character by character */ for ( i = 0 ; i < s_strlen(str1) ; i++) if (str1.string[i] != str2.string[i]) return FALSE; /* Diff. found, so not head. */ /* No differences found */ return TRUE; } /* * Checks if STR1 is the exact beginning of STR2, but uses a * user specified collating sequence for comparison (as in * s_usr_strcmp()). */ EXPORT Bool s_usr_strhead(String str1, String str2, unsigned char collat_tab[COLLAT_TAB_SIZE]) { String_size i; /* Index in comparison loop */ /* If STR1 is longer than STR2, then it can't be a head. */ if (s_strlen(str1) > s_strlen(str2)) return FALSE; /* If they point to the same string, then STR1 is a head * of STR2. (We have already compared the lengths.) */ if (str1.string == str2.string) return TRUE; /* Check character by character */ for ( i = 0 ; i < s_strlen(str1) ; i++) { if ( collat_tab [ POS_INDEX( str1.string[i] )] != collat_tab [ POS_INDEX( str2.string[i] )] ) { return FALSE; /* Diff. found, so not head. */ } } /* No differences found */ return TRUE; } /* * From STR strip all trailing characters that can be found * in STRIP_STRING. */ extern String s_strip_trailing (String str, const String strip_string) { while ( s_strlen (str) > 0 && s_strchr (strip_string, str.string[s_strlen(str) - 1], 0) != -1) str.len--; return str; } /* * Returns the index of the first occurrence in the String STR * of the character CH, starting at position STAR_POS. Returns * -1 if no occurrence. */ EXPORT String_size s_strchr (const String str, unsigned char ch, String_size start_pos) { unsigned char * ptr; assert (start_pos >= 0 && start_pos <= s_strlen (str)); ptr = memchr (str.string + start_pos, ch, s_strlen (str) - start_pos); if (ptr == NULL) return -1; else return ptr - str.string; } /* * Returns the index of the last occurrence in the String STR * of the character CH, starting at position START_POS. Returns * -1 if no occurrence. */ EXPORT String_size s_strrchr (const String str, unsigned char ch, String_size start_pos) { String_size index; if (start_pos == END_OF_STRING) start_pos = s_strlen (str) - 1; assert (start_pos >= -1 && start_pos < s_strlen (str)); index = start_pos; while (index >= 0 && str.string[index] != ch) index--; return index; /* This will be -1 if not found. */ } /* * Return the index of the first occurrence in the String LOOK_IN * of any of the characters in the String SEARCH_FOR, or -1 if none. */ extern String_size s_strpbrk (const String look_in, const String search_for) { String_size i; for ( i = 0 ; i < s_strlen (look_in) ; i++ ) if (s_strchr (search_for, look_in.string[i], 0) != -1) return i; return -1; } /* * Find the first character in LOOK_IN that *is* present in * SEARCH_FOR, and return its index, or the length of LOOK_IN if * it contains only characters that are not present in SEARCH_FOR. */ extern String_size s_strcspn (const String look_in, const String search_for) { String_size i; i = 0; while ( i < s_strlen (look_in) && s_strchr (search_for, look_in.string[i], 0) == -1) i++; return i; } /* * Find the first character in LOOK_IN that is *not* present in * SKIP_CHARS, and return its index, or the length of LOOK_IN if * it contains only characters that are present in SKIP_CHARS. */ extern String_size s_strspn (const String look_in, const String skip_chars) { String_size i; i = 0; while ( i < s_strlen (look_in) && s_strchr (skip_chars, look_in.string[i], 0) != -1) i++; return i; } /* * Pick out the first token from SOURCE separated by one or more * of the characters in SEPARATORS, starting in position START_POS. * * More specifically: start in position START_POS and skip over * separator characters (any of those present in SEPARATORS). * Extract the substring starting with the first non-separator, * and ending the character immediately before the first separator * following. *start_pos will be the index of the first separator * character after the token. * * Note that the return value actually points into SOURCE. It * is not separately allocated. */ EXPORT String s_strtok (const String source, String_size * start_pos, const String separators) { String_size first_char; /* First character in token */ String_size end_char; /* First character after token */ /* Check of parameters - we might save some time on this */ if ( (*start_pos >= s_strlen(source)) || ((s_empty(separators) == TRUE) || (s_empty(source) == TRUE)) ) { return EMPTY_STRING; } /* Skip leading separators */ first_char = *start_pos; while ( (first_char < s_strlen(source)) && (s_strchr (separators, source.string[first_char], 0) != -1) ) first_char++; /* End of source string? Then we can stop here. */ if (first_char >= s_strlen(source)) { *start_pos = first_char; return EMPTY_STRING; } /* Find next separator */ end_char = first_char; while ( (end_char < s_strlen(source)) && (s_strchr (separators, source.string[end_char], 0) == -1) ) end_char++; /* OK, we're practically done. */ *start_pos = end_char; return s_fsubstr(source, first_char, end_char-1); } /**************************************************** * Misc. routines using our String type. * ****************************************************/ /* * Convert a char to a number in base BASE. */ static int char2digit (const char ch) { int c = (unsigned char)ch; if (c < '0' || c > '9') return -1; else return c - '0'; } /* * Convert the String STR to a long, using base ten. * Leading blanks are skipped according to isblank() in . * The index of the first character that couldn't be used to form * the number is returned in *FIRST_ILL_CHAR. Returns -1 in * *first_ill_char if there was an error in the parameters. * Leading signs are not allowed. */ #define MAXBASE 36 EXPORT long s_strtol (const String str, String_size * first_ill_char) { long number = 0; /* The result */ String_size char_no; int digit; /* Skip all blanks */ char_no = 0; while ( (char_no < s_strlen(str)) && isspace(str.string[char_no]) ) char_no++; if (char_no == s_strlen(str)) { *first_ill_char = -1; return 0; } while ( (char_no < s_strlen(str)) && ((digit = char2digit(str.string[char_no])) != -1) ) { number = 10 * number + digit; char_no++; } *first_ill_char = char_no; return number; } extern Success s_trim_left(String *str, String_size rm) { String tmp_str = EMPTY_STRING; if (rm <= 0) return OK; if (rm >= s_strlen(*str)) { s_clear(str); return OK; } /* FIXME (bug XXX): in some cases, it might be more efficient to move the data in-place instead of allocating a new block. */ if (s_substr(&tmp_str, *str, rm, END_OF_STRING) != OK) return FAILURE; s_clear(str); *str = tmp_str; return OK; } void * s_reserve(String *str, String_size sz) { void *temp_ptr; if (sz < 1) return NULL; temp_ptr = REALLOC_0(str->string, s_strlen(*str) + sz); if (temp_ptr == NULL) return NULL; str->string = temp_ptr; return (char*)temp_ptr + s_strlen(*str); } extern void s_reserve_done(String *str, String_size sz) { str->len += sz; } /************************************************ * Input/Output routines for String * ************************************************/ /* * Outputs the string STR on the stream STREAM. No information * about the length of the string is output. */ EXPORT Success s_fputs (FILE * stream, const String str) { String_size i; for ( i = 0 ; i < str.len ; i++ ) putc (str.string[i], stream); return OK; } /* * Create an ordinary C string from a String. * The pointer returned will point to a '\0'-terminated character * array which is obtained with the malloc-function supplied to * s_set_storage_management(). It should be freed by the caller. * NULL is returned if there is an error. The String may contain * '\0's, but the resulting string will be truncated at the first * '\0'. Thou shalt not depend on this behaviour. Later versions * might substitute "foobar" for '\0's. */ EXPORT char * s_crea_c_str(const String source) { char *dest; dest = MALLOC_0( 1 + s_strlen(source) ); if ( dest == NULL ) return NULL; memcpy(dest, source.string, s_strlen(source)); dest[ s_strlen(source) ] = '\0'; return dest; } lyskom-server-2.1.2/src/libraries/libmisc/ldifftime.c0000664000015100472110000000254607721716124016327 /* * $Id: ldifftime.c,v 1.10 2003/08/23 16:38:20 ceder Exp $ * Copyright (C) 1994-1995, 1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ #ifdef HAVE_CONFIG_H # include #endif /* Some systems, e.g. Dynix 3, defines time_t in sys/types.h. */ #include #include /* time_t */ #include "ldifftime.h" /* We implement this. */ extern long ldifftime(time_t t1, time_t t2) { #ifdef HAVE_DIFFTIME return difftime (t1, t2); #else return t1 - t2; #endif } lyskom-server-2.1.2/src/libraries/libmisc/s-collat-tabs.h0000664000015100472110000000370207721716125017032 /* * $Id: s-collat-tabs.h,v 1.12 2003/08/23 16:38:19 ceder Exp $ * Copyright (C) 1990-1991, 1993-1995, 1999, 2002-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: s-collat-tabs.h,v 1.12 2003/08/23 16:38:19 ceder Exp $ * * s-collat-tables.h -- Declarations for collating tables * * * Copyright (C) 1990-1991, 1993-1995, 1999, 2002-2003 Lysator Computer Club, * Linkoping University, Sweden * * Everyone is granted permission to copy, modify and redistribute * this code, provided the people they give it to can. * * * Author: Thomas Bellman * Lysator Computer Club * Linkoping University * Sweden * * email: Bellman@Lysator.LiU.SE * * * Any opinions expressed in this code are the author's PERSONAL opinions, * and does NOT, repeat NOT, represent any official standpoint of Lysator, * even if so stated. */ #define COLLAT_TAB_SIZE (UCHAR_MAX+1) extern unsigned char swedish_collate_tab [ COLLAT_TAB_SIZE ]; extern unsigned char english_collate_tab [ COLLAT_TAB_SIZE ]; #if 0 extern unsigned char iso8859_1_collate_tab [ COLLAT_TAB_SIZE ]; #endif lyskom-server-2.1.2/src/libraries/libmisc/s-string.h0000664000015100472110000003177607721716125016147 /* * $Id: s-string.h,v 1.23 2003/08/23 16:38:19 ceder Exp $ * Copyright (C) 1990-1996, 1999, 2002-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: s-string.h,v 1.23 2003/08/23 16:38:19 ceder Exp $ * * s-string.h * Our own string type. Definition of string type, * and functions to manipulate these strings. * * * Copyright (C) 1990-1996, 1999, 2002-2003 Lysator Computer Club, * Linkoping University, Sweden * * Everyone is granted permission to copy, modify and redistribute * this code, provided the people they give it to can. * * * Author: Thomas Bellman * Lysator Computer Club * Linkoping University * Sweden * * email: Bellman@Lysator.LiU.SE */ #ifndef S_STRING_H_ALREADY_INCLUDED__ #define S_STRING_H_ALREADY_INCLUDED__ #include #include #include "misc-types.h" #include "s-collat-tabs.h" typedef long String_size; #define END_OF_STRING LONG_MAX /* * All objects of type String *must* be initialized to EMPTY_STRING * before using any destructive function on them. If you only use * non-destructive functions (s_strlen(), s_strcmp(), ...), you can * set them with * str = s_fcrea_str("Hej hopp i lingonskogen"); * But the value of this may *not* be used in any destructive call, * since str.string points to read-only memory. * Note also that you need to call s_clear() on any auto variables * of type String before exiting the block they are declared in, * since otherwise the memory they use will still be allocated. * This is of course the same rules as for normal pointers. * To make it possible for people to use their own storage * management routines, you can set the functions to use for * malloc(), realloc() and free() with the * s_set_storage_management() function. This MUST be called * before using any of the other functions, even if you want to * use the normal malloc(), realloc() and free(). * Terminology: * -- A "separate" String is an object that points to some memory * that is somehow obtained from malloc() or its cousins. This * means that it is legal to free() or realloc() it. */ typedef struct { String_size len; unsigned char * string; } String; /* * Note that the first character is String.string[0], and the last * character is String.string[String.len-1] */ /* This is the representation of the empty String */ #define EMPTY_STRING_i { 0, NULL } extern const String EMPTY_STRING; /* * Functions to manipulate strings of type 'String'. * All these functions return a value of type Success, which is * an enum of OK an FAILURE (do NOT trust the order of these!). * * All functions automatically allocates (and deallocates) any * necessary storage. */ typedef void (*free_function) (void *); typedef void * (*malloc_function) (size_t); typedef void * (*realloc_function) (void *, size_t); /* * Set the functions to use for storage management. These must * be call compatible with the normal functions malloc(), * realloc() and free(). */ extern void s_set_storage_management (malloc_function new_malloc, realloc_function new_realloc, free_function new_free); /* * Returns the number of characters in a String */ #define s_strlen(str) ((str).len) /* * Create an object of type String from an ordinary C string. */ extern Success s_crea_str (String * dest_string, const char * c_string ); /* * Create a string from a buffer. The contents of the buffer * are copied into the new string. */ extern Success s_mem_crea_str (String * dest_string, const unsigned char * buffer, String_size length); /* * Create a string of a given size. The contents of the string * are unspecified. The LysKOM-server uses this to get a string * of a fixed size into which it can fread() data. This is probably * not a good idea since it relies heavily on the implementation * of strings. However, by using this function, those places are * easy to identify if the implementation should be done differently. */ extern Success s_size_crea_str(String *result, String_size length); /* * Return a temporary String from a C string, i e return a struct * pointing to the actual C string. Suitable for sending a 'String' * object as parameter to a function (IF that function does not modify * its parameter). Note that normally String variables should be set * by s_crea_str(), to deallocate the memory used by it. */ extern String s_fcrea_str (const char * c_string); /* * Free's the space used by a String object. The object is * set to EMPTY_STRING. */ extern void s_clear (String * str); /* * Create an ordinary C string from a String. * The pointer returned will point to a '\0'-terminated character * array which is obtained with the malloc-function supplied to * s_set_storage_management(). It should be freed by the caller. * NULL is returned if there is an error. The String may contain * '\0's, but the resulting string will be truncated at the first * '\0'. Thou shalt not depend on this behaviour. Later versions * might substitute "foobar" for '\0's. */ extern char * s_crea_c_str(const String source); /* * Copy SOURCE_STRING to DEST_STRING. Old value of DEST_STRING is * retained if an error was encountered. Note that it is never * legal to do 's_strcpy(&foo, foo)', since the string 'foo' is * pointing to is reallocated before it is read. */ extern Success s_strcpy (String * dest_string, const String source_string); /* * In String STR remove the characters starting with number FIRST * and ending with number LAST, inclusive. If FIRST > LAST, then * no characters are removed. */ extern Success s_strdel (String * str, String_size first, String_size last ); /* * Append SOURCE_STRING to the end of DEST_STRING. DEST_STRING is not * changed if an error is encountered. */ extern Success s_strcat (String * dest_string, const String source_string); /* * Extract a substring from SOURCE_STRING, starting with char no * START_CHAR and ending with char no END_CHAR. First character * is character no 0. If END_CHAR < START_CHAR, then DEST_STRING * is set to 'EMPTY_STRING'. If END_CHAR is equal to the macro * 'END_OF_STRING', then the substring reaches to the last character * in SOURCE_STRING. */ extern Success s_substr (String * dest_string, const String source_string, String_size start_char, String_size end_char); /* * Fast extraction of a substring. Returns an object of type * String wich points into SOURCE_STRING. Thus you should NEVER * modify the result of this function. (Raw character modifying * is OK if you know what you are doing, but never use anything * that might call free or realloc on it.) If END_CHAR is equal * to the macro 'END_OF_STRING', then the substring reaches to * the last character in SOURCE_STRING. */ extern String s_fsubstr (const String source_string, String_size start_char, String_size end_char ); /* Check if a string is the empty string. Returns TRUE or FALSE. */ #define s_empty(str) (((str).len == 0) ? TRUE : FALSE) /* Check if two strings are equal. */ #define s_streq(str1, str2) (s_strcmp(str1, str2) == 0) #define s_usr_streq(str1, str2, collat_tab) \ (s_usr_strcmp(str1, str2, collat_tab) == 0) /* * Compares two strings. Returns -1 if STR1 is lexically less * than STR2, +1 if STR1 is greater than STR2, and 0 if they are * equal. */ extern int s_strcmp (String str1, String str2); /* * Compares two strings with user specified collation order. * Returns the same values as s_strcmp(). * COLLAT_TAB is a table of collating values for every char. */ extern int s_usr_strcmp(String str1, String str2, unsigned char collat_tab[COLLAT_TAB_SIZE]); /* * Checks if STR1 is the exact beginning of STR2, e g if STR1 * is "foobar" and STR2 is "foobarf" then the result is TRUE. */ extern Bool s_strhead (String str1, String str2); /* * Checks if STR1 is the exact beginning of STR2, but uses a * user specified collating sequence for comparison (as in * s_usr_strcmp()). */ extern Bool s_usr_strhead(String str1, String str2, unsigned char collat_tab[COLLAT_TAB_SIZE]); /* * From STR strip all trailing characters that can be found * in STRIP_STRING. STR isn't altered in any way. The returned * object points to the same string as STR, but with a possibly * shorter length. The pointer is unchanged *even* if the length * should be 0, which means you don't "lose" the storage but can * free it with s_clear(). */ extern String s_strip_trailing (String str, const String strip_string); /* * Returns the index of the first occurrence in the String STR * of the character CH. Returns -1 if no occurrence. */ extern String_size s_strchr (const String str, unsigned char ch, String_size start_pos); /* * Returns the index of the last occurrence in the String STR * of the character CH. Returns -1 if no occurrence. */ extern String_size s_strrchr (const String str, unsigned char ch, String_size start_pos); /* * Return the index of the first occurrence in the String LOOK_IN * of any of the characters in the String SEARCH_FOR, or -1 if none. */ extern String_size s_strpbrk (const String look_in, const String search_for); /* * Find the first character in LOOK_IN that *is* present in * SEARCH_FOR, and return its index, or the length of LOOK_IN if * it contains only characters that are not present in SEARCH_FOR. */ extern String_size s_strcspn (const String look_in, const String search_for); /* * Find the first character in LOOK_IN that is *not* present in * SKLIP_CHARS, and return its index, or the length of LOOK_IN if * it contains only characters that are present in SKIP_CHARS. */ extern String_size s_strspn (const String look_in, const String skip_chars); /* * Pick out the first token from SOURCE separated by one or more * of the characters in SEPARATORS, starting in position START_POS. * * More specifically: start in position START_POS and skip over * separator characters (any of those present in SEPARATORS). * Extract the substring starting with the first non-separator, * and ending the character immediately before the first separator * following. *start_pos will be the index of the first separator * character after the token. * * Note that the return value actually points into SOURCE. It * is not separately allocated. */ extern String s_strtok (const String source, String_size * start_pos, const String separators); /**************************************************** * Misc. routines using our String type. * ****************************************************/ /* * Convert the String STR to a long, using base ten. * Leading blanks are skipped according to isblank() in . * The index of the first character that couldn't be used to form * the number is returned in *FIRST_ILL_CHAR. Returns -1 in * *first_ill_char if there was an error in the parameters. * Leading signs are not allowed. */ extern long s_strtol (const String str, String_size * first_ill_char); /* * Remove the first RM characters from STR. May return FAILURE * if out of memory. */ extern Success s_trim_left(String *str, String_size rm); /* * Allocate space for SZ more bytes at the end of STR. Return a * pointer to the available space. You must later call * s_reserve_done() to tell how much of the space you actually used. */ extern void * s_reserve(String *str, String_size sz); extern void s_reserve_done(String *str, String_size sz); /************************************************ * Input/Output routines for String * ************************************************/ /* * Outputs the string STR on the stream STREAM. No information * about the length of the string is output. */ extern Success s_fputs (FILE * stream, const String str); /* * Outputs the string STR on stdout. No information * about the length of the string is output. */ #define s_puts(str) s_fputs(stdout, str) #endif /* _S_STRING_H_ALREADY_INCLUDED__ */ lyskom-server-2.1.2/src/libraries/libmisc/ldifftime.h0000664000015100472110000000214707721716124016331 /* * $Id: ldifftime.h,v 1.3 2003/08/23 16:38:20 ceder Exp $ * Copyright (C) 1994, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ #ifndef LDIFFTIME_H_INCLUDED #define LDIFFTIME_H_INCLUDED extern long ldifftime(time_t t1, time_t t2); #endif lyskom-server-2.1.2/src/libraries/libmisc/timeval-util.h0000664000015100472110000000402107717413242016773 /* * Copyright (C) 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ extern Bool timeval_nonzero(struct timeval t); extern Bool timeval_zero(struct timeval t); extern struct timeval timeval_ctor(time_t sec, int usec); /* Compute WANTED_INTERVAL - (NOW - START) and store it in REMAINING, assuming that it is positive. Return true if REMAINING is greater than zero. Don't use the value stored in REMAINING when this function returns false. */ extern Bool timeval_remaining(struct timeval *remaining, struct timeval wanted_interval, struct timeval start, struct timeval now); extern Bool timeval_greater(struct timeval a, struct timeval b); extern Bool timeval_less(struct timeval a, struct timeval b); /* Return the difference as a number of seconds, properly rounded. */ extern long timeval_diff_sec(struct timeval a, struct timeval b); /* Return the difference as a number of seconds, as a double. */ extern double timeval_diff_d(struct timeval a, struct timeval b); /* Set TV to the current time plus INTERVAL. Return -1 if gettimeofday() fails (check errno). */ extern int setup_timer(struct timeval *tv, struct timeval interval); lyskom-server-2.1.2/src/libraries/libmisc/timeval-util.c0000664000015100472110000000721407720646601016776 /* * Copyright (C) 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include "oop.h" #include "misc-types.h" #include "timeval-util.h" Bool timeval_nonzero(struct timeval t) { return t.tv_sec != 0 || t.tv_usec != 0; } Bool timeval_zero(struct timeval t) { return t.tv_sec == 0 && t.tv_usec == 0; } struct timeval timeval_ctor(time_t sec, int usec) { struct timeval res; res.tv_sec = sec; res.tv_usec = usec; return res; } /* This function is taken from the GNU libc manual, and modified so that it doesn't alter the x and y arguments. */ static int timeval_subtract(struct timeval *result, struct timeval x, struct timeval y) { /* Perform the carry for the later subtraction by updating Y. */ if (x.tv_usec < y.tv_usec) { int nsec = (y.tv_usec - x.tv_usec) / 1000000 + 1; y.tv_usec -= 1000000 * nsec; y.tv_sec += nsec; } if (x.tv_usec - y.tv_usec > 1000000) { int nsec = (x.tv_usec - y.tv_usec) / 1000000; y.tv_usec += 1000000 * nsec; y.tv_sec -= nsec; } /* Compute the time remaining to wait. `tv_usec' is certainly positive. */ result->tv_sec = x.tv_sec - y.tv_sec; result->tv_usec = x.tv_usec - y.tv_usec; /* Return 1 if result is negative. */ return x.tv_sec < y.tv_sec; } Bool timeval_remaining(struct timeval *remaining, struct timeval wanted_interval, struct timeval start, struct timeval now) { if (timeval_subtract(remaining, now, start)) return FALSE; if (timeval_subtract(remaining, wanted_interval, *remaining)) return FALSE; return TRUE; } Bool timeval_greater(struct timeval a, struct timeval b) { if (a.tv_sec > b.tv_sec) return TRUE; if (a.tv_sec < b.tv_sec) return FALSE; if (a.tv_usec > b.tv_usec) return TRUE; return FALSE; } Bool timeval_less(struct timeval a, struct timeval b) { if (a.tv_sec < b.tv_sec) return TRUE; if (a.tv_sec > b.tv_sec) return FALSE; if (a.tv_usec < b.tv_usec) return TRUE; return FALSE; } long timeval_diff_sec(struct timeval a, struct timeval b) { struct timeval res; timeval_subtract(&res, a, b); return res.tv_sec + (res.tv_usec >= 500000); } double timeval_diff_d(struct timeval a, struct timeval b) { return (a.tv_sec - b.tv_sec) + 1e-6 * (a.tv_usec - b.tv_usec); } int setup_timer(struct timeval *tv, struct timeval interval) { if (gettimeofday(tv, NULL) < 0) { *tv = OOP_TIME_NOW; return -1; } tv->tv_sec += interval.tv_sec; tv->tv_usec += interval.tv_usec; if (tv->tv_usec >= 1000000) { tv->tv_usec -= 1000000; tv->tv_sec++; } assert(tv->tv_usec >= 0); assert(tv->tv_usec < 1000000); return 0; } lyskom-server-2.1.2/src/libraries/libmisc/.cvsignore0000664000015100472110000000006206650620445016207 .deps Makefile Makefile.in *.da *.bb *.bbg *.gcov lyskom-server-2.1.2/src/libraries/libmisc/ChangeLog.10000664000015100472110000000516706210047333016122 Sat Jan 7 16:27:40 1995 Per Cederqvist (ceder@lysator.liu.se) * ldifftime.c: Include sys/types.h. Sun Jan 1 14:13:15 1995 Per Cederqvist (ceder@lysator.liu.se) * s-string.h, s-string.c (s_fcrea_str): Argument is a "const char *", not a "const unsigned char *". Mon Aug 29 20:19:07 1994 Per Cederqvist (ceder@lysator.liu.se) * s-collat-tabs.c (english_collate_tab): Don't use 8-bit characters in char constants. Mon Apr 4 15:50:38 1994 Per Cederqvist (ceder@lysator.liu.se) * ldifftime.h, ldifftime.c: New files. Makefile.src: Install ldifftime.h. Include ldifftime.o in libmisc.a. Sun Mar 6 20:49:10 1994 Per Cederqvist (ceder@lysator.liu.se) * missing.c: Deleted (superseded by libansi). Mon Oct 11 16:02:06 1993 Per Cederqvist (ceder@lysator.liu.se) * zmalloc.h, numlist.h, numlist2.h, s-collat-tabs.h: Don't use #include in .h files! Sun Oct 10 18:15:11 1993 Per Cederqvist (ceder@lysator.liu.se) * s-string.c, zmalloc.c: Still has a lot of strange configuration code in the inclucde section. Seems to be buggy. * s-string.c: Changed u_ to unsigned. Fri Oct 8 10:59:49 1993 Per Cederqvist (ceder@lysator.liu.se) * numlist.c, numlist2.c, s-string.c, zmalloc.c: Fixed include statements. Wed Feb 26 19:52:28 1992 Per Cederqvist (ceder@lysator) * (s-string.c s-string.h zmalloc.c): Lint from gcc 2.0 removed. Tue Aug 27 07:20:34 1991 Per Cederqvist (ceder at lysator) * pom.c: Tog bort variablerna ts och pmt som inte anv{nds. Sat Jul 6 05:43:41 1991 Per Cederqvist (ceder at lysator) * Fullbordade {ndringen fr}n char till unsigned char i s-string.[hc] som Peter p}b|rjade. * Skrev om Makefilen f|r att klara RCS. * Alla filer i libmisc.a placerade under RCS. * s-collat-tables.[hco] omd|pt till s-collat-tabs.[hco]. ar tycker inte om f|r l}nga namn. Thu Dec 20 04:59:36 1990 Thomas Bellman (bellman at lave) * s-string.[ch]: s_strchr() och s_strrchr(): Lade till en parameter som anger var s|kningen ska b|rja. * s-string.c: [ndrat fr}n if-satser f|r kontroll av parametrar till att anv{nda assert()-makrot. * s-string.[ch]: Lade till s_strrchr(). * zmalloc.c: Fixat en del buggar d{r pekare till z_info-structen returnerades i st f pekare efter denna, samt lite annat. Sat Dec 8 03:05:51 1990 Thomas Bellman (bellman at laila) * [ndrade tillbaka s_strcpy(). Den ska sl{ppa loss minnet {ven om den f}r en EMPTY_STRING. Sat Dec 1 12:09:35 1990 Lars Willf|r (willfor at nanny) * [ndrade s_strcpy s} att den med s{kerhet fungerar {ven om source_string == EMPTY_STRING. Thu Aug 9 05:12:52 1990 Thomas Bellman (bellman at laila) * Biblioteket skapat ig}r. lyskom-server-2.1.2/src/libraries/libeintr/0000777000015100472110000000000007723710342014457 5lyskom-server-2.1.2/src/libraries/libeintr/Makefile.am0000664000015100472110000000273507721716123016441 # $Id: Makefile.am,v 1.9 2003/08/23 16:38:20 ceder Exp $ # Copyright (C) 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # include $(top_srcdir)/scripts/common.make noinst_LIBRARIES = libeintr.a nodist_libeintr_a_SOURCES = eintr.h $(funcs) funcs = fopen.c fclose.c rename.c EXTRA_DIST = .cvsignore eintr.h.pre funcs.txt gen-wrapper.awk eintr.h $(funcs): funcs.txt gen-wrapper.awk eintr.h.pre $(RM) eintr.h cat $(srcdir)/eintr.h.pre > eintr.h sed -e 's/ / /g' -e 's/ *, */,/g' $(srcdir)/funcs.txt \ | $(AWK) -F, -f $(srcdir)/gen-wrapper.awk || $(RM) eintr.h $(funcs) MOSTLYCLEANFILES = *.da *.bb *.gcov *.bbg $(funcs) eintr.h lyskom-server-2.1.2/src/libraries/libeintr/Makefile.in0000664000015100472110000003404407723707424016456 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # $Id: Makefile.am,v 1.9 2003/08/23 16:38:20 ceder Exp $ # Copyright (C) 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEBUG_CALLS = @DEBUG_CALLS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EFENCE = @EFENCE@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FLEX = @FLEX@ HAVE_PYTHON_FALSE = @HAVE_PYTHON_FALSE@ HAVE_PYTHON_TRUE = @HAVE_PYTHON_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSURE = @INSURE@ LANGUAGE_SUFFIX = @LANGUAGE_SUFFIX@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ SED = @SED@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRACED_ALLOCATIONS = @TRACED_ALLOCATIONS@ U = @U@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ YACC = @YACC@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ RM = rm -f dbdir = $(localstatedir)/lyskomd/db exportdir = $(localstatedir)/lyskomd/exportdb noinst_LIBRARIES = libeintr.a nodist_libeintr_a_SOURCES = eintr.h $(funcs) funcs = fopen.c fclose.c rename.c EXTRA_DIST = .cvsignore eintr.h.pre funcs.txt gen-wrapper.awk MOSTLYCLEANFILES = *.da *.bb *.gcov *.bbg $(funcs) eintr.h subdir = src/libraries/libeintr ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) libeintr_a_AR = $(AR) cru libeintr_a_LIBADD = am__objects_1 = fopen.$(OBJEXT) fclose.$(OBJEXT) rename.$(OBJEXT) nodist_libeintr_a_OBJECTS = $(am__objects_1) libeintr_a_OBJECTS = $(nodist_libeintr_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/scripts/depcomp am__depfiles_maybe = depfiles @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/fclose.Po ./$(DEPDIR)/fopen.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/rename.Po COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ DIST_SOURCES = DIST_COMMON = $(top_srcdir)/scripts/common.make Makefile.am Makefile.in SOURCES = $(nodist_libeintr_a_SOURCES) all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/scripts/common.make $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/libraries/libeintr/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libeintr.a: $(libeintr_a_OBJECTS) $(libeintr_a_DEPENDENCIES) -rm -f libeintr.a $(libeintr_a_AR) libeintr.a $(libeintr_a_OBJECTS) $(libeintr_a_LIBADD) $(RANLIB) libeintr.a mostlyclean-compile: -rm -f *.$(OBJEXT) core *.core distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fclose.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fopen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rename.Po@am__quote@ distclean-depend: -rm -rf ./$(DEPDIR) .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ @am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ @am__fastdepCC_TRUE@ fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< .c.obj: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ @am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ @am__fastdepCC_TRUE@ fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` uninstall-info-am: ETAGS = etags ETAGSFLAGS = CTAGS = ctags CTAGSFLAGS = tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$tags$$unique" \ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = ../../.. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) $(mkinstalldirs) $(distdir)/../../../scripts @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am distclean-am: clean-am distclean-compile distclean-depend \ distclean-generic distclean-tags dvi: dvi-am dvi-am: info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags distclean distclean-compile \ distclean-depend distclean-generic distclean-tags distdir dvi \ dvi-am info info-am install install-am install-data \ install-data-am install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-info-am eintr.h $(funcs): funcs.txt gen-wrapper.awk eintr.h.pre $(RM) eintr.h cat $(srcdir)/eintr.h.pre > eintr.h sed -e 's/ / /g' -e 's/ *, */,/g' $(srcdir)/funcs.txt \ | $(AWK) -F, -f $(srcdir)/gen-wrapper.awk || $(RM) eintr.h $(funcs) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/src/libraries/libeintr/.cvsignore0000664000015100472110000000011507564237174016404 *.bb *.bbg *.da .deps Makefile Makefile.in eintr.h fclose.c fopen.c rename.c lyskom-server-2.1.2/src/libraries/libeintr/eintr.h.pre0000664000015100472110000000204007721716123016451 /* * Wrappers that check for errno == EINTR. * Copyright (C) 2002-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* The rest of this file is automatically generated. */ lyskom-server-2.1.2/src/libraries/libeintr/funcs.txt0000664000015100472110000000022407560173677016267 stdio.h, FILE *, NULL, fopen, const char*, const char* stdio.h, int, EOF, fclose, FILE * stdio.h, int, -1, rename, const char *, const char * lyskom-server-2.1.2/src/libraries/libeintr/gen-wrapper.awk0000664000015100472110000000364407721716123017340 # Generate wrapper functions that check for errno==EINTR. # Copyright (C) 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. { incl=$1 rettype=$2 errval=$3 fnc=$4 fn=fnc ".c" print "#include " > fn printf "#include <%s>\n\n", incl >> fn printf "#include \"eintr.h\"\n\n" >> fn print rettype >> fn printf "i_%s(", fnc >> fn for (i = 5; i <= NF; i++) { printf "%s %c", $i, 60+i >> fn if (i <= NF - 1) printf ", " >> fn } print ")" >> fn print "{" >> fn printf " %s ret;\n\n", rettype >> fn print " do {" >> fn print "\terrno = 0;" >> fn printf "\tret = %s(", fnc >> fn for (i = 5; i <= NF; i++) { printf "%c", 60+i >> fn if (i <= NF - 1) printf ", " >> fn } print ");" >> fn printf " } while (ret == %s && errno == EINTR);\n\n", errval >> fn print " return ret;" >> fn print "}" >> fn printf "%s i_%s(", rettype, fnc >> "eintr.h" for (i = 5; i <= NF; i++) { printf "%s", $i >> "eintr.h" if (i <= NF - 1) printf ", " >> "eintr.h" } print ");" >> "eintr.h" } lyskom-server-2.1.2/src/server/0000777000015100472110000000000007723710364012205 5lyskom-server-2.1.2/src/server/Makefile.am0000664000015100472110000003034307722446225014163 # $Id: Makefile.am,v 1.66 2003/08/25 17:24:31 ceder Exp $ # Copyright (C) 1998-1999, 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # include $(top_srcdir)/scripts/common.make SUBDIRS = testsuite AM_YFLAGS = -d EXTRA_DIST = .cvsignore ChangeLog.1 Magics \ call-switch.awk com-h.awk fnc-def-init.awk \ prot-a-parse-arg-c.awk prot-a-parse-arg-h.awk \ prot-a-is-legal-fnc.awk \ fncdef.txt \ handle-malloc-dump.el trace-mem.gdb MOSTLYCLEANFILES = .gdbinit call-switch.incl com.h fnc-def-init.incl \ fncdef-no-str-limit.txt prot-a-parse-arg.h version.incl \ prot-a-is-legal-fnc.incl *.da *.bb *.gcov *.bbg \ version-info.c prot-a-parse-arg.c aux-no.h paths.h AM_CPPFLAGS = \ -I../libraries/libeintr \ -I$(srcdir)/../include \ -I$(srcdir)/../libraries/libansi \ -I$(srcdir)/../libraries/libmisc \ -I$(srcdir)/../libraries/liboop \ -I$(srcdir)/../libraries/adns/src \ -I$(srcdir)/../libraries/libisc-new/src \ -I$(srcdir)/../libraries/regex \ -I$(srcdir)/../libraries/libcommon top_srcdir = @top_srcdir@ sbin_PROGRAMS = lyskomd dbck updateLysKOM komrunning splitkomdb check_LIBRARIES = libcheck.a libcheck_a_SOURCES = local-to-global.c ram-parse.c ram-output.c \ log.c ram-smalloc.c memory.c getopt.c getopt1.c \ misc-types.c lyskomd_SOURCES = $(DISKOBJS) $(GENOBJS) \ aux-item-def-parse.y \ aux-item-def-parse.h \ aux-item-def-scan.l \ admin.h async.h aux-items.h cache-node.h cache.h conf-file.h \ connections.h end-of-atomic.h exp.h internal-connections.h \ text.h isc-interface.h isc-malloc.h isc-parse.h \ kom-memory.h local-to-global.h log.h lyskomd.h manipulate.h \ minmax.h param.h prot-a-output.h prot-a-parse.h \ prot-a-send-async.h prot-a.h ram-output.h ram-parse.h \ rfc931.h send-async.h server-config.h string-malloc.h \ text-garb.h version-info.h sigflags.h trace-alloc.h \ lockdb.h lockdb.c server-time.h oop-malloc.h oop-malloc.c \ timewrap.h stats.h stats.c \ misc-types.c nodist_lyskomd_SOURCES = $(NODIST_DISKOBJS) $(NODIST_GENOBJS) READ_CONFIG = string-malloc.c ram-smalloc.c log.c conf-file.c server-config.c \ standalone.c komrunning_SOURCES = komrunning.c pidfile.c pidfile.h $(READ_CONFIG) \ misc-types.c updateLysKOM_SOURCES = updateLysKOM.c pidfile.c pidfile.h $(READ_CONFIG) \ misc-types.c dbck_SOURCES = $(DBCK) \ dbck-cache.h getopt.h standalone.c \ misc-types.c nodist_dbck_SOURCES = $(NODIST_DBCK) splitkomdb_SOURCES = splitkomdb.c $(READ_CONFIG) \ misc-types.c lyskomd_LDADD = ../libraries/libisc-new/src/libisc.a \ ../libraries/liboop/liboop.a \ ../libraries/adns/src/libadns.a \ ../libraries/libmisc/libmisc.a \ ../libraries/libcommon/liblyskom-server.a \ ../libraries/regex/libregex.a \ ../libraries/libeintr/libeintr.a \ ../libraries/libansi/libansi.a \ -lm dbck_LDADD = ../libraries/libmisc/libmisc.a \ ../libraries/libcommon/liblyskom-server.a \ ../libraries/libeintr/libeintr.a \ ../libraries/libansi/libansi.a LDADD = ../libraries/libmisc/libmisc.a \ ../libraries/libeintr/libeintr.a \ ../libraries/libansi/libansi.a # Files that implements protocol A. NODIST_PROTA = prot-a-parse-arg.c PROTA = prot-a-output.c prot-a-parse.c prot-a.c \ prot-a-send-async.c # Implementations of the atomic calls. ATOMS = text.c membership.c person.c conference.c session.c admin.c \ regex-match.c aux-items.c debug.c # These files are needed by all versions of the LysKOM server. NODIST_GENOBJS = $(NODIST_PROTA) aux-no.h GENOBJS = connections.c log.c $(ATOMS) \ send-async.c server-config.c text-garb.c \ isc-parse.c memory.c $(PROTA) \ internal-connections.c rfc931.c isc-malloc.c \ conf-file.c local-to-global.c # Files for lyskomd. NODIST_DISKOBJS = version-info.c DISKOBJS = ramkomd.c ram-smalloc.c simple-cache.c ram-parse.c ram-output.c \ disk-end-of-atomic.c cache-node.c string-malloc.c # Files for dbck. GETOPT = getopt.c getopt1.c NODIST_DBCK = version-info.c DBCK = dbck.c dbck-cache.c ram-smalloc.c ram-parse.c server-config.c \ ram-output.c memory.c conf-file.c $(GETOPT) \ local-to-global.c lockdb.h lockdb.c # Files for encrypt (a program to transform the database from unencrypted # apasswords to encrypted). No longer supported. ENCRYPT = encrypt-passwd.c dbck-cache.c ram-smalloc.c ram-parse.c \ server-config.c\ ram-output.c memory.c BUILT_SOURCES = prot-a-parse-arg.c version-info.c \ call-switch.incl com.h fnc-def-init.incl \ prot-a-parse-arg.h fncdef-no-str-limit.txt .gdbinit \ version.incl prot-a-is-legal-fnc.incl aux-no.h paths.h call-switch.incl: call-switch.awk fncdef-no-str-limit.txt $(AWK) -f $(srcdir)/call-switch.awk fncdef-no-str-limit.txt \ > call-switch.incl com.h: com-h.awk fncdef-no-str-limit.txt $(AWK) -f $(srcdir)/com-h.awk fncdef-no-str-limit.txt > com.h fnc-def-init.incl: fnc-def-init.awk fncdef-no-str-limit.txt $(AWK) -f $(srcdir)/fnc-def-init.awk fncdef-no-str-limit.txt \ > fnc-def-init.incl prot-a-is-legal-fnc.incl: fncdef-no-str-limit.txt prot-a-is-legal-fnc.awk $(AWK) -f $(srcdir)/prot-a-is-legal-fnc.awk fncdef-no-str-limit.txt \ > prot-a-is-legal-fnc.incl prot-a-parse-arg.c: prot-a-parse-arg-c.awk fncdef.txt prot-a-parse-arg.h $(AWK) -f $(srcdir)/prot-a-parse-arg-c.awk $(srcdir)/fncdef.txt \ > prot-a-parse-arg.c prot-a-parse-arg.h: prot-a-parse-arg-h.awk fncdef-no-str-limit.txt $(AWK) -f $(srcdir)/prot-a-parse-arg-h.awk \ fncdef-no-str-limit.txt > prot-a-parse-arg.h fncdef-no-str-limit.txt: fncdef.txt (echo \# Do not edit this file! It is generated from fncdef.txt.;\ cat $(srcdir)/fncdef.txt) \ | sed 's/([^)]*)//g' > fncdef-no-str-limit.txt version.incl: $(top_srcdir)/versions echo '/* Do not edit -- automatically generated file */' > $@.tmp sed -n 's/SERVER-COMPAT-VERSION: //p' $(top_srcdir)/versions >>$@.tmp echo '/* Do not edit -- automatically generated file */' >>$@.tmp mv $@.tmp $@ version-info.c: $(top_srcdir)/versions echo '/* Do not edit -- automatically generated file */' > $@.tmp echo '#ifdef HAVE_CONFIG_H' >>$@.tmp echo '# include ' >>$@.tmp echo '#endif' >>$@.tmp echo '#include ' >>$@.tmp echo '#include ' >>$@.tmp echo '#include "misc-types.h"' >>$@.tmp echo '#include "s-string.h"' >>$@.tmp echo '#include "kom-types.h"' >>$@.tmp echo '#include "version-info.h"' >>$@.tmp echo 'const Version_info_internal kom_version_info = {' >>$@.tmp sed -n 's/PROTOCOL-A-LEVEL: \(.*\)/ \1,/p' \ $(top_srcdir)/versions >>$@.tmp sed -n 's/SERVER-SOFTWARE: \(.*\)/ "\1",/p' \ $(top_srcdir)/versions >>$@.tmp sed -n 's/SERVER-VERSION: \(.*\)/ "\1"/p' \ $(top_srcdir)/versions >>$@.tmp echo '};' >>$@.tmp echo '/* Do not edit -- automatically generated file */' >>$@.tmp mv $@.tmp $@ aux-no.h: $(top_srcdir)/run-support/aux-items.conf Makefile $(RM) $@ $@.tmp echo '/* Do not edit -- automatically generated file */' >$@.tmp echo '#ifndef AUX_H_INCLUDED' >>$@.tmp echo '#define AUX_H_INCLUDED' >>$@.tmp echo 'enum aux_no {' >>$@.tmp LC_ALL=C LC_CTYPE=C LANG=C sed \ -e '/^#/d' \ -e '/^{/,/^}/d' \ -e 's/^\([0-9]*\) : \([a-z\-]*\) .*/aux_\2 \1/' \ -e '/^ *$$/d' \ -e 'y/-/_/' \ < $(top_srcdir)/run-support/aux-items.conf \ | awk '{printf " %-25s = %5s,\n", $$1, $$2}' >>$@.tmp echo '};' >>$@.tmp echo '#endif' >>$@.tmp echo '/* Do not edit -- automatically generated file */' >>$@.tmp chmod 444 $@.tmp mv -f $@.tmp $@ .gdbinit: Makefile $(RM) .gdbinit echo handle 13 nostop noprint >.gdbinit echo dir $(top_srcdir)/src/libraries/libcommon >>.gdbinit echo dir $(top_srcdir)/src/libraries/libansi >>.gdbinit echo dir $(top_srcdir)/src/libraries/libisc-new >>.gdbinit echo dir $(top_srcdir)/src/libraries/liboop >>.gdbinit echo dir $(top_srcdir)/src/libraries/libmisc >>.gdbinit DEFP = $(top_srcdir)/scripts/definepath "$(top_srcdir)" "$(prefix)" paths.h: $(top_srcdir)/scripts/unprefix $(top_srcdir)/scripts/definepath \ Makefile $(RM) $@ $@.tmp echo '/* Do not edit -- automatically generated file */' > $@.tmp echo '#define DEFAULT_PREFIX "'"$(prefix)"'"' >> $@.tmp $(DEFP) CONFIG_FILE "$(sysconfdir)/lyskomd.conf" >> $@.tmp $(DEFP) DATA_FILE "$(dbdir)/lyskomd-data" >> $@.tmp $(DEFP) BACKUP_FILE "$(dbdir)/lyskomd-backup" >> $@.tmp $(DEFP) PREV_BACKUP_FILE "$(dbdir)/lyskomd-backup-prev" >> $@.tmp $(DEFP) LOCK_FILE "$(dbdir)/lyskomd-lock" >> $@.tmp $(DEFP) TEXT_FILE "$(dbdir)/lyskomd-texts" >> $@.tmp $(DEFP) NUMBER_FILE "$(dbdir)/number.txt" >> $@.tmp $(DEFP) NUMBER_FILE_TMP "$(dbdir)/number.tmp" >> $@.tmp $(DEFP) TEXT_BACKUP_FILE "$(dbdir)/lyskomd-texts-backup" >> $@.tmp $(DEFP) EXPORT_DIR "$(exportdir)" >> $@.tmp $(DEFP) LYSKOMD_LOG "$(localstatedir)/lyskomd.log" >> $@.tmp $(DEFP) LYSKOMD_STATS "$(localstatedir)/lyskomd.stats" >> $@.tmp $(DEFP) LYSKOMD_PID "$(localstatedir)/run/lyskomd.pid" >> $@.tmp $(DEFP) MEMORY_USAGE "$(localstatedir)/lyskomd.memory" >> $@.tmp $(DEFP) AUX_FILE "$(sysconfdir)/aux-items.conf" >> $@.tmp $(DEFP) STATUS_FILE "$(dbdir)/status" >> $@.tmp $(DEFP) CONNECTIONS_FILE "$(localstatedir)/lyskomd.clients" >> $@.tmp $(DEFP) CONNECTIONS_TMP "$(localstatedir)/lyskomd.clnt.tmp">> $@.tmp $(DEFP) CORE_DIR "$(localstatedir)/lyskomd.cores" >> $@.tmp $(DEFP) LYSKOMD_PATH "$(sbindir)/lyskomd$(EXEEXT)" >> $@.tmp $(DEFP) SAVECORE_PATH "$(sbindir)/savecore-lyskom$(EXEEXT)" >> $@.tmp echo "/* External programs */" >> $@.tmp $(DEFP) SENDMAIL_PATH "$(SENDMAIL)" >> $@.tmp echo '/* Do not edit -- automatically generated file */' >> $@.tmp chmod 444 $@.tmp mv -f $@.tmp $@ check-lyskomd: libcheck.a lyskomd dbck cd testsuite && $(MAKE) check-lyskomd check-leaks: libcheck.a lyskomd dbck cd testsuite && $(MAKE) check-leaks check-l2g: libcheck.a cd testsuite && $(MAKE) check-l2g # Make sure these gets recompiled if $(prefix) changes. server-config.o: Makefile updateLysKOM.o: Makefile # After a "make clean" followed by "make check", these are needed. aux-items.o: aux-no.h text.o: aux-no.h admin.o: com.h aux-item-def-parse.o: com.h aux-items.o: com.h conference.o: com.h connections.o: com.h dbck.o: com.h debug.o: com.h internal-connections.o: com.h isc-parse.o: com.h membership.o: com.h person.o: com.h prot-a-output.o: com.h prot-a-parse-arg.o: com.h prot-a-parse.o: com.h prot-a-send-async.o: com.h prot-a.o: com.h ramkomd.o: com.h regex-match.o: com.h send-async.o: com.h server-config.o: com.h session.o: com.h simple-cache.o: com.h standalone.o: com.h text-garb.o: com.h text.o: com.h server-config.o: paths.h connections.o: fnc-def-init.incl call-switch.incl admin.o: version.incl prot-a.o: fnc-def-init.incl prot-a-is-legal-fnc.incl standalone.o: version.incl # "make install" without a prior "make" requires these. connections.o: prot-a-parse-arg.h # This dependency is needed after a "make maintainer-clean". aux-item-def-scan.o: aux-item-def-parse.h # all-recursive: lyskomd$(EXEEXT) dbck$(EXEEXT) check-recursive: libcheck.a lyskomd$(EXEEXT) dbck$(EXEEXT) lyskom-server-2.1.2/src/server/Makefile.in0000664000015100472110000012056307723707427014205 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # $Id: Makefile.am,v 1.66 2003/08/25 17:24:31 ceder Exp $ # Copyright (C) 1998-1999, 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # srcdir = @srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : top_srcdir = @top_srcdir@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEBUG_CALLS = @DEBUG_CALLS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EFENCE = @EFENCE@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FLEX = @FLEX@ HAVE_PYTHON_FALSE = @HAVE_PYTHON_FALSE@ HAVE_PYTHON_TRUE = @HAVE_PYTHON_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSURE = @INSURE@ LANGUAGE_SUFFIX = @LANGUAGE_SUFFIX@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ SED = @SED@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRACED_ALLOCATIONS = @TRACED_ALLOCATIONS@ U = @U@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ YACC = @YACC@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ RM = rm -f dbdir = $(localstatedir)/lyskomd/db exportdir = $(localstatedir)/lyskomd/exportdb SUBDIRS = testsuite AM_YFLAGS = -d EXTRA_DIST = .cvsignore ChangeLog.1 Magics \ call-switch.awk com-h.awk fnc-def-init.awk \ prot-a-parse-arg-c.awk prot-a-parse-arg-h.awk \ prot-a-is-legal-fnc.awk \ fncdef.txt \ handle-malloc-dump.el trace-mem.gdb MOSTLYCLEANFILES = .gdbinit call-switch.incl com.h fnc-def-init.incl \ fncdef-no-str-limit.txt prot-a-parse-arg.h version.incl \ prot-a-is-legal-fnc.incl *.da *.bb *.gcov *.bbg \ version-info.c prot-a-parse-arg.c aux-no.h paths.h AM_CPPFLAGS = \ -I../libraries/libeintr \ -I$(srcdir)/../include \ -I$(srcdir)/../libraries/libansi \ -I$(srcdir)/../libraries/libmisc \ -I$(srcdir)/../libraries/liboop \ -I$(srcdir)/../libraries/adns/src \ -I$(srcdir)/../libraries/libisc-new/src \ -I$(srcdir)/../libraries/regex \ -I$(srcdir)/../libraries/libcommon sbin_PROGRAMS = lyskomd dbck updateLysKOM komrunning splitkomdb check_LIBRARIES = libcheck.a libcheck_a_SOURCES = local-to-global.c ram-parse.c ram-output.c \ log.c ram-smalloc.c memory.c getopt.c getopt1.c \ misc-types.c lyskomd_SOURCES = $(DISKOBJS) $(GENOBJS) \ aux-item-def-parse.y \ aux-item-def-parse.h \ aux-item-def-scan.l \ admin.h async.h aux-items.h cache-node.h cache.h conf-file.h \ connections.h end-of-atomic.h exp.h internal-connections.h \ text.h isc-interface.h isc-malloc.h isc-parse.h \ kom-memory.h local-to-global.h log.h lyskomd.h manipulate.h \ minmax.h param.h prot-a-output.h prot-a-parse.h \ prot-a-send-async.h prot-a.h ram-output.h ram-parse.h \ rfc931.h send-async.h server-config.h string-malloc.h \ text-garb.h version-info.h sigflags.h trace-alloc.h \ lockdb.h lockdb.c server-time.h oop-malloc.h oop-malloc.c \ timewrap.h stats.h stats.c \ misc-types.c nodist_lyskomd_SOURCES = $(NODIST_DISKOBJS) $(NODIST_GENOBJS) READ_CONFIG = string-malloc.c ram-smalloc.c log.c conf-file.c server-config.c \ standalone.c komrunning_SOURCES = komrunning.c pidfile.c pidfile.h $(READ_CONFIG) \ misc-types.c updateLysKOM_SOURCES = updateLysKOM.c pidfile.c pidfile.h $(READ_CONFIG) \ misc-types.c dbck_SOURCES = $(DBCK) \ dbck-cache.h getopt.h standalone.c \ misc-types.c nodist_dbck_SOURCES = $(NODIST_DBCK) splitkomdb_SOURCES = splitkomdb.c $(READ_CONFIG) \ misc-types.c lyskomd_LDADD = ../libraries/libisc-new/src/libisc.a \ ../libraries/liboop/liboop.a \ ../libraries/adns/src/libadns.a \ ../libraries/libmisc/libmisc.a \ ../libraries/libcommon/liblyskom-server.a \ ../libraries/regex/libregex.a \ ../libraries/libeintr/libeintr.a \ ../libraries/libansi/libansi.a \ -lm dbck_LDADD = ../libraries/libmisc/libmisc.a \ ../libraries/libcommon/liblyskom-server.a \ ../libraries/libeintr/libeintr.a \ ../libraries/libansi/libansi.a LDADD = ../libraries/libmisc/libmisc.a \ ../libraries/libeintr/libeintr.a \ ../libraries/libansi/libansi.a # Files that implements protocol A. NODIST_PROTA = prot-a-parse-arg.c PROTA = prot-a-output.c prot-a-parse.c prot-a.c \ prot-a-send-async.c # Implementations of the atomic calls. ATOMS = text.c membership.c person.c conference.c session.c admin.c \ regex-match.c aux-items.c debug.c # These files are needed by all versions of the LysKOM server. NODIST_GENOBJS = $(NODIST_PROTA) aux-no.h GENOBJS = connections.c log.c $(ATOMS) \ send-async.c server-config.c text-garb.c \ isc-parse.c memory.c $(PROTA) \ internal-connections.c rfc931.c isc-malloc.c \ conf-file.c local-to-global.c # Files for lyskomd. NODIST_DISKOBJS = version-info.c DISKOBJS = ramkomd.c ram-smalloc.c simple-cache.c ram-parse.c ram-output.c \ disk-end-of-atomic.c cache-node.c string-malloc.c # Files for dbck. GETOPT = getopt.c getopt1.c NODIST_DBCK = version-info.c DBCK = dbck.c dbck-cache.c ram-smalloc.c ram-parse.c server-config.c \ ram-output.c memory.c conf-file.c $(GETOPT) \ local-to-global.c lockdb.h lockdb.c # Files for encrypt (a program to transform the database from unencrypted # apasswords to encrypted). No longer supported. ENCRYPT = encrypt-passwd.c dbck-cache.c ram-smalloc.c ram-parse.c \ server-config.c\ ram-output.c memory.c BUILT_SOURCES = prot-a-parse-arg.c version-info.c \ call-switch.incl com.h fnc-def-init.incl \ prot-a-parse-arg.h fncdef-no-str-limit.txt .gdbinit \ version.incl prot-a-is-legal-fnc.incl aux-no.h paths.h DEFP = $(top_srcdir)/scripts/definepath "$(top_srcdir)" "$(prefix)" subdir = src/server ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = libcheck_a_AR = $(AR) cru libcheck_a_LIBADD = am_libcheck_a_OBJECTS = local-to-global.$(OBJEXT) ram-parse.$(OBJEXT) \ ram-output.$(OBJEXT) log.$(OBJEXT) ram-smalloc.$(OBJEXT) \ memory.$(OBJEXT) getopt.$(OBJEXT) getopt1.$(OBJEXT) \ misc-types.$(OBJEXT) libcheck_a_OBJECTS = $(am_libcheck_a_OBJECTS) sbin_PROGRAMS = lyskomd$(EXEEXT) dbck$(EXEEXT) updateLysKOM$(EXEEXT) \ komrunning$(EXEEXT) splitkomdb$(EXEEXT) PROGRAMS = $(sbin_PROGRAMS) am__objects_1 = getopt.$(OBJEXT) getopt1.$(OBJEXT) am__objects_2 = dbck.$(OBJEXT) dbck-cache.$(OBJEXT) \ ram-smalloc.$(OBJEXT) ram-parse.$(OBJEXT) \ server-config.$(OBJEXT) ram-output.$(OBJEXT) memory.$(OBJEXT) \ conf-file.$(OBJEXT) $(am__objects_1) local-to-global.$(OBJEXT) \ lockdb.$(OBJEXT) am_dbck_OBJECTS = $(am__objects_2) standalone.$(OBJEXT) \ misc-types.$(OBJEXT) am__objects_3 = version-info.$(OBJEXT) nodist_dbck_OBJECTS = $(am__objects_3) dbck_OBJECTS = $(am_dbck_OBJECTS) $(nodist_dbck_OBJECTS) dbck_DEPENDENCIES = ../libraries/libmisc/libmisc.a \ ../libraries/libcommon/liblyskom-server.a \ ../libraries/libeintr/libeintr.a ../libraries/libansi/libansi.a dbck_LDFLAGS = am__objects_4 = string-malloc.$(OBJEXT) ram-smalloc.$(OBJEXT) \ log.$(OBJEXT) conf-file.$(OBJEXT) server-config.$(OBJEXT) \ standalone.$(OBJEXT) am_komrunning_OBJECTS = komrunning.$(OBJEXT) pidfile.$(OBJEXT) \ $(am__objects_4) misc-types.$(OBJEXT) komrunning_OBJECTS = $(am_komrunning_OBJECTS) komrunning_LDADD = $(LDADD) komrunning_DEPENDENCIES = ../libraries/libmisc/libmisc.a \ ../libraries/libeintr/libeintr.a ../libraries/libansi/libansi.a komrunning_LDFLAGS = am__objects_5 = ramkomd.$(OBJEXT) ram-smalloc.$(OBJEXT) \ simple-cache.$(OBJEXT) ram-parse.$(OBJEXT) ram-output.$(OBJEXT) \ disk-end-of-atomic.$(OBJEXT) cache-node.$(OBJEXT) \ string-malloc.$(OBJEXT) am__objects_6 = text.$(OBJEXT) membership.$(OBJEXT) person.$(OBJEXT) \ conference.$(OBJEXT) session.$(OBJEXT) admin.$(OBJEXT) \ regex-match.$(OBJEXT) aux-items.$(OBJEXT) debug.$(OBJEXT) am__objects_7 = prot-a-output.$(OBJEXT) prot-a-parse.$(OBJEXT) \ prot-a.$(OBJEXT) prot-a-send-async.$(OBJEXT) am__objects_8 = connections.$(OBJEXT) log.$(OBJEXT) $(am__objects_6) \ send-async.$(OBJEXT) server-config.$(OBJEXT) \ text-garb.$(OBJEXT) isc-parse.$(OBJEXT) memory.$(OBJEXT) \ $(am__objects_7) internal-connections.$(OBJEXT) \ rfc931.$(OBJEXT) isc-malloc.$(OBJEXT) conf-file.$(OBJEXT) \ local-to-global.$(OBJEXT) am_lyskomd_OBJECTS = $(am__objects_5) $(am__objects_8) \ aux-item-def-parse.$(OBJEXT) aux-item-def-scan.$(OBJEXT) \ lockdb.$(OBJEXT) oop-malloc.$(OBJEXT) stats.$(OBJEXT) \ misc-types.$(OBJEXT) am__objects_9 = prot-a-parse-arg.$(OBJEXT) am__objects_10 = $(am__objects_9) nodist_lyskomd_OBJECTS = $(am__objects_3) $(am__objects_10) lyskomd_OBJECTS = $(am_lyskomd_OBJECTS) $(nodist_lyskomd_OBJECTS) lyskomd_DEPENDENCIES = ../libraries/libisc-new/src/libisc.a \ ../libraries/liboop/liboop.a ../libraries/adns/src/libadns.a \ ../libraries/libmisc/libmisc.a \ ../libraries/libcommon/liblyskom-server.a \ ../libraries/regex/libregex.a ../libraries/libeintr/libeintr.a \ ../libraries/libansi/libansi.a lyskomd_LDFLAGS = am_splitkomdb_OBJECTS = splitkomdb.$(OBJEXT) $(am__objects_4) \ misc-types.$(OBJEXT) splitkomdb_OBJECTS = $(am_splitkomdb_OBJECTS) splitkomdb_LDADD = $(LDADD) splitkomdb_DEPENDENCIES = ../libraries/libmisc/libmisc.a \ ../libraries/libeintr/libeintr.a ../libraries/libansi/libansi.a splitkomdb_LDFLAGS = am_updateLysKOM_OBJECTS = updateLysKOM.$(OBJEXT) pidfile.$(OBJEXT) \ $(am__objects_4) misc-types.$(OBJEXT) updateLysKOM_OBJECTS = $(am_updateLysKOM_OBJECTS) updateLysKOM_LDADD = $(LDADD) updateLysKOM_DEPENDENCIES = ../libraries/libmisc/libmisc.a \ ../libraries/libeintr/libeintr.a ../libraries/libansi/libansi.a updateLysKOM_LDFLAGS = DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/scripts/depcomp am__depfiles_maybe = depfiles @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/admin.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/aux-item-def-parse.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/aux-item-def-scan.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/aux-items.Po ./$(DEPDIR)/cache-node.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/conf-file.Po ./$(DEPDIR)/conference.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/connections.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/dbck-cache.Po ./$(DEPDIR)/dbck.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/debug.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/disk-end-of-atomic.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/getopt.Po ./$(DEPDIR)/getopt1.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/internal-connections.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/isc-malloc.Po ./$(DEPDIR)/isc-parse.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/komrunning.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/local-to-global.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/lockdb.Po ./$(DEPDIR)/log.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/membership.Po ./$(DEPDIR)/memory.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/misc-types.Po ./$(DEPDIR)/oop-malloc.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/person.Po ./$(DEPDIR)/pidfile.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/prot-a-output.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/prot-a-parse-arg.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/prot-a-parse.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/prot-a-send-async.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/prot-a.Po ./$(DEPDIR)/ram-output.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/ram-parse.Po ./$(DEPDIR)/ram-smalloc.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/ramkomd.Po ./$(DEPDIR)/regex-match.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/rfc931.Po ./$(DEPDIR)/send-async.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/server-config.Po ./$(DEPDIR)/session.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/simple-cache.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/splitkomdb.Po ./$(DEPDIR)/standalone.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/stats.Po ./$(DEPDIR)/string-malloc.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/text-garb.Po ./$(DEPDIR)/text.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/updateLysKOM.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/version-info.Po COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS) YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS) DIST_SOURCES = $(libcheck_a_SOURCES) $(dbck_SOURCES) \ $(komrunning_SOURCES) $(lyskomd_SOURCES) $(splitkomdb_SOURCES) \ $(updateLysKOM_SOURCES) RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \ ps-recursive install-info-recursive uninstall-info-recursive \ all-recursive install-data-recursive install-exec-recursive \ installdirs-recursive install-recursive uninstall-recursive \ check-recursive installcheck-recursive DIST_COMMON = $(top_srcdir)/scripts/common.make Makefile.am Makefile.in \ aux-item-def-parse.c aux-item-def-parse.h aux-item-def-scan.c DIST_SUBDIRS = $(SUBDIRS) SOURCES = $(libcheck_a_SOURCES) $(dbck_SOURCES) $(nodist_dbck_SOURCES) $(komrunning_SOURCES) $(lyskomd_SOURCES) $(nodist_lyskomd_SOURCES) $(splitkomdb_SOURCES) $(updateLysKOM_SOURCES) all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: .SUFFIXES: .c .l .o .obj .y $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/scripts/common.make $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/server/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) clean-checkLIBRARIES: -test -z "$(check_LIBRARIES)" || rm -f $(check_LIBRARIES) libcheck.a: $(libcheck_a_OBJECTS) $(libcheck_a_DEPENDENCIES) -rm -f libcheck.a $(libcheck_a_AR) libcheck.a $(libcheck_a_OBJECTS) $(libcheck_a_LIBADD) $(RANLIB) libcheck.a sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM) install-sbinPROGRAMS: $(sbin_PROGRAMS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(sbindir) @list='$(sbin_PROGRAMS)'; for p in $$list; do \ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ if test -f $$p \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ echo " $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) $$p $(DESTDIR)$(sbindir)/$$f"; \ $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) $$p $(DESTDIR)$(sbindir)/$$f || exit 1; \ else :; fi; \ done uninstall-sbinPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(sbin_PROGRAMS)'; for p in $$list; do \ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ echo " rm -f $(DESTDIR)$(sbindir)/$$f"; \ rm -f $(DESTDIR)$(sbindir)/$$f; \ done clean-sbinPROGRAMS: -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) dbck$(EXEEXT): $(dbck_OBJECTS) $(dbck_DEPENDENCIES) @rm -f dbck$(EXEEXT) $(LINK) $(dbck_LDFLAGS) $(dbck_OBJECTS) $(dbck_LDADD) $(LIBS) komrunning$(EXEEXT): $(komrunning_OBJECTS) $(komrunning_DEPENDENCIES) @rm -f komrunning$(EXEEXT) $(LINK) $(komrunning_LDFLAGS) $(komrunning_OBJECTS) $(komrunning_LDADD) $(LIBS) aux-item-def-parse.h: aux-item-def-parse.c @if test ! -f $@; then \ rm -f aux-item-def-parse.c; \ $(MAKE) aux-item-def-parse.c; \ else :; fi lyskomd$(EXEEXT): $(lyskomd_OBJECTS) $(lyskomd_DEPENDENCIES) @rm -f lyskomd$(EXEEXT) $(LINK) $(lyskomd_LDFLAGS) $(lyskomd_OBJECTS) $(lyskomd_LDADD) $(LIBS) splitkomdb$(EXEEXT): $(splitkomdb_OBJECTS) $(splitkomdb_DEPENDENCIES) @rm -f splitkomdb$(EXEEXT) $(LINK) $(splitkomdb_LDFLAGS) $(splitkomdb_OBJECTS) $(splitkomdb_LDADD) $(LIBS) updateLysKOM$(EXEEXT): $(updateLysKOM_OBJECTS) $(updateLysKOM_DEPENDENCIES) @rm -f updateLysKOM$(EXEEXT) $(LINK) $(updateLysKOM_LDFLAGS) $(updateLysKOM_OBJECTS) $(updateLysKOM_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) core *.core distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/admin.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aux-item-def-parse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aux-item-def-scan.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aux-items.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cache-node.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf-file.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conference.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connections.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbck-cache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbck.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/disk-end-of-atomic.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/internal-connections.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isc-malloc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isc-parse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/komrunning.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/local-to-global.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lockdb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/membership.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memory.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc-types.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oop-malloc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/person.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pidfile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prot-a-output.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prot-a-parse-arg.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prot-a-parse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prot-a-send-async.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prot-a.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ram-output.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ram-parse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ram-smalloc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ramkomd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regex-match.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfc931.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/send-async.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server-config.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/session.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simple-cache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splitkomdb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/standalone.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stats.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string-malloc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/text-garb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/text.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/updateLysKOM.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version-info.Po@am__quote@ distclean-depend: -rm -rf ./$(DEPDIR) .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ @am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ @am__fastdepCC_TRUE@ fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< .c.obj: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ @am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ @am__fastdepCC_TRUE@ fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` .l.c: $(LEXCOMPILE) `test -f $< || echo '$(srcdir)/'`$< sed '/^#/ s|$(LEX_OUTPUT_ROOT)\.c|$@|' $(LEX_OUTPUT_ROOT).c >$@ rm -f $(LEX_OUTPUT_ROOT).c .y.c: $(YACCCOMPILE) `test -f '$<' || echo '$(srcdir)/'`$< if test -f y.tab.h; then \ to=`echo "$*_H" | sed \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \ -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'`; \ sed "/^#/ s/Y_TAB_H/$$to/g" y.tab.h >$*.ht; \ rm -f y.tab.h; \ if cmp -s $*.ht $*.h; then \ rm -f $*.ht ;\ else \ mv $*.ht $*.h; \ fi; \ fi if test -f y.output; then \ mv y.output $*.output; \ fi sed '/^#/ s|y\.tab\.c|$@|' y.tab.c >$@t && mv $@t $@ rm -f y.tab.c uninstall-info-am: # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ETAGS = etags ETAGSFLAGS = CTAGS = ctags CTAGSFLAGS = tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if (etags --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ else \ include_option=--include; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -f $$subdir/TAGS && \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$tags$$unique" \ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = ../.. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) $(mkinstalldirs) $(distdir)/../../scripts @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d $(distdir)/$$subdir \ || mkdir $(distdir)/$$subdir \ || exit 1; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" \ distdir=../$(distdir)/$$subdir \ distdir) \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_LIBRARIES) check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-recursive all-am: Makefile $(PROGRAMS) installdirs: installdirs-recursive installdirs-am: $(mkinstalldirs) $(DESTDIR)$(sbindir) install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) -rm -f aux-item-def-scan.c -rm -f aux-item-def-parse.h -rm -f aux-item-def-parse.c clean: clean-recursive clean-am: clean-checkLIBRARIES clean-generic clean-sbinPROGRAMS \ mostlyclean-am distclean: distclean-recursive distclean-am: clean-am distclean-compile distclean-depend \ distclean-generic distclean-tags dvi: dvi-recursive dvi-am: info: info-recursive info-am: install-data-am: install-exec-am: install-sbinPROGRAMS install-info: install-info-recursive install-man: installcheck-am: maintainer-clean: maintainer-clean-recursive maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-info-am uninstall-sbinPROGRAMS uninstall-info: uninstall-info-recursive .PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \ clean-checkLIBRARIES clean-generic clean-recursive \ clean-sbinPROGRAMS ctags ctags-recursive distclean \ distclean-compile distclean-depend distclean-generic \ distclean-recursive distclean-tags distdir dvi dvi-am \ dvi-recursive info info-am info-recursive install install-am \ install-data install-data-am install-data-recursive \ install-exec install-exec-am install-exec-recursive \ install-info install-info-am install-info-recursive install-man \ install-recursive install-sbinPROGRAMS install-strip \ installcheck installcheck-am installdirs installdirs-am \ installdirs-recursive maintainer-clean maintainer-clean-generic \ maintainer-clean-recursive mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-recursive pdf pdf-am \ pdf-recursive ps ps-am ps-recursive tags tags-recursive \ uninstall uninstall-am uninstall-info-am \ uninstall-info-recursive uninstall-recursive \ uninstall-sbinPROGRAMS call-switch.incl: call-switch.awk fncdef-no-str-limit.txt $(AWK) -f $(srcdir)/call-switch.awk fncdef-no-str-limit.txt \ > call-switch.incl com.h: com-h.awk fncdef-no-str-limit.txt $(AWK) -f $(srcdir)/com-h.awk fncdef-no-str-limit.txt > com.h fnc-def-init.incl: fnc-def-init.awk fncdef-no-str-limit.txt $(AWK) -f $(srcdir)/fnc-def-init.awk fncdef-no-str-limit.txt \ > fnc-def-init.incl prot-a-is-legal-fnc.incl: fncdef-no-str-limit.txt prot-a-is-legal-fnc.awk $(AWK) -f $(srcdir)/prot-a-is-legal-fnc.awk fncdef-no-str-limit.txt \ > prot-a-is-legal-fnc.incl prot-a-parse-arg.c: prot-a-parse-arg-c.awk fncdef.txt prot-a-parse-arg.h $(AWK) -f $(srcdir)/prot-a-parse-arg-c.awk $(srcdir)/fncdef.txt \ > prot-a-parse-arg.c prot-a-parse-arg.h: prot-a-parse-arg-h.awk fncdef-no-str-limit.txt $(AWK) -f $(srcdir)/prot-a-parse-arg-h.awk \ fncdef-no-str-limit.txt > prot-a-parse-arg.h fncdef-no-str-limit.txt: fncdef.txt (echo \# Do not edit this file! It is generated from fncdef.txt.;\ cat $(srcdir)/fncdef.txt) \ | sed 's/([^)]*)//g' > fncdef-no-str-limit.txt version.incl: $(top_srcdir)/versions echo '/* Do not edit -- automatically generated file */' > $@.tmp sed -n 's/SERVER-COMPAT-VERSION: //p' $(top_srcdir)/versions >>$@.tmp echo '/* Do not edit -- automatically generated file */' >>$@.tmp mv $@.tmp $@ version-info.c: $(top_srcdir)/versions echo '/* Do not edit -- automatically generated file */' > $@.tmp echo '#ifdef HAVE_CONFIG_H' >>$@.tmp echo '# include ' >>$@.tmp echo '#endif' >>$@.tmp echo '#include ' >>$@.tmp echo '#include ' >>$@.tmp echo '#include "misc-types.h"' >>$@.tmp echo '#include "s-string.h"' >>$@.tmp echo '#include "kom-types.h"' >>$@.tmp echo '#include "version-info.h"' >>$@.tmp echo 'const Version_info_internal kom_version_info = {' >>$@.tmp sed -n 's/PROTOCOL-A-LEVEL: \(.*\)/ \1,/p' \ $(top_srcdir)/versions >>$@.tmp sed -n 's/SERVER-SOFTWARE: \(.*\)/ "\1",/p' \ $(top_srcdir)/versions >>$@.tmp sed -n 's/SERVER-VERSION: \(.*\)/ "\1"/p' \ $(top_srcdir)/versions >>$@.tmp echo '};' >>$@.tmp echo '/* Do not edit -- automatically generated file */' >>$@.tmp mv $@.tmp $@ aux-no.h: $(top_srcdir)/run-support/aux-items.conf Makefile $(RM) $@ $@.tmp echo '/* Do not edit -- automatically generated file */' >$@.tmp echo '#ifndef AUX_H_INCLUDED' >>$@.tmp echo '#define AUX_H_INCLUDED' >>$@.tmp echo 'enum aux_no {' >>$@.tmp LC_ALL=C LC_CTYPE=C LANG=C sed \ -e '/^#/d' \ -e '/^{/,/^}/d' \ -e 's/^\([0-9]*\) : \([a-z\-]*\) .*/aux_\2 \1/' \ -e '/^ *$$/d' \ -e 'y/-/_/' \ < $(top_srcdir)/run-support/aux-items.conf \ | awk '{printf " %-25s = %5s,\n", $$1, $$2}' >>$@.tmp echo '};' >>$@.tmp echo '#endif' >>$@.tmp echo '/* Do not edit -- automatically generated file */' >>$@.tmp chmod 444 $@.tmp mv -f $@.tmp $@ .gdbinit: Makefile $(RM) .gdbinit echo handle 13 nostop noprint >.gdbinit echo dir $(top_srcdir)/src/libraries/libcommon >>.gdbinit echo dir $(top_srcdir)/src/libraries/libansi >>.gdbinit echo dir $(top_srcdir)/src/libraries/libisc-new >>.gdbinit echo dir $(top_srcdir)/src/libraries/liboop >>.gdbinit echo dir $(top_srcdir)/src/libraries/libmisc >>.gdbinit paths.h: $(top_srcdir)/scripts/unprefix $(top_srcdir)/scripts/definepath \ Makefile $(RM) $@ $@.tmp echo '/* Do not edit -- automatically generated file */' > $@.tmp echo '#define DEFAULT_PREFIX "'"$(prefix)"'"' >> $@.tmp $(DEFP) CONFIG_FILE "$(sysconfdir)/lyskomd.conf" >> $@.tmp $(DEFP) DATA_FILE "$(dbdir)/lyskomd-data" >> $@.tmp $(DEFP) BACKUP_FILE "$(dbdir)/lyskomd-backup" >> $@.tmp $(DEFP) PREV_BACKUP_FILE "$(dbdir)/lyskomd-backup-prev" >> $@.tmp $(DEFP) LOCK_FILE "$(dbdir)/lyskomd-lock" >> $@.tmp $(DEFP) TEXT_FILE "$(dbdir)/lyskomd-texts" >> $@.tmp $(DEFP) NUMBER_FILE "$(dbdir)/number.txt" >> $@.tmp $(DEFP) NUMBER_FILE_TMP "$(dbdir)/number.tmp" >> $@.tmp $(DEFP) TEXT_BACKUP_FILE "$(dbdir)/lyskomd-texts-backup" >> $@.tmp $(DEFP) EXPORT_DIR "$(exportdir)" >> $@.tmp $(DEFP) LYSKOMD_LOG "$(localstatedir)/lyskomd.log" >> $@.tmp $(DEFP) LYSKOMD_STATS "$(localstatedir)/lyskomd.stats" >> $@.tmp $(DEFP) LYSKOMD_PID "$(localstatedir)/run/lyskomd.pid" >> $@.tmp $(DEFP) MEMORY_USAGE "$(localstatedir)/lyskomd.memory" >> $@.tmp $(DEFP) AUX_FILE "$(sysconfdir)/aux-items.conf" >> $@.tmp $(DEFP) STATUS_FILE "$(dbdir)/status" >> $@.tmp $(DEFP) CONNECTIONS_FILE "$(localstatedir)/lyskomd.clients" >> $@.tmp $(DEFP) CONNECTIONS_TMP "$(localstatedir)/lyskomd.clnt.tmp">> $@.tmp $(DEFP) CORE_DIR "$(localstatedir)/lyskomd.cores" >> $@.tmp $(DEFP) LYSKOMD_PATH "$(sbindir)/lyskomd$(EXEEXT)" >> $@.tmp $(DEFP) SAVECORE_PATH "$(sbindir)/savecore-lyskom$(EXEEXT)" >> $@.tmp echo "/* External programs */" >> $@.tmp $(DEFP) SENDMAIL_PATH "$(SENDMAIL)" >> $@.tmp echo '/* Do not edit -- automatically generated file */' >> $@.tmp chmod 444 $@.tmp mv -f $@.tmp $@ check-lyskomd: libcheck.a lyskomd dbck cd testsuite && $(MAKE) check-lyskomd check-leaks: libcheck.a lyskomd dbck cd testsuite && $(MAKE) check-leaks check-l2g: libcheck.a cd testsuite && $(MAKE) check-l2g # Make sure these gets recompiled if $(prefix) changes. server-config.o: Makefile updateLysKOM.o: Makefile # After a "make clean" followed by "make check", these are needed. aux-items.o: aux-no.h text.o: aux-no.h admin.o: com.h aux-item-def-parse.o: com.h aux-items.o: com.h conference.o: com.h connections.o: com.h dbck.o: com.h debug.o: com.h internal-connections.o: com.h isc-parse.o: com.h membership.o: com.h person.o: com.h prot-a-output.o: com.h prot-a-parse-arg.o: com.h prot-a-parse.o: com.h prot-a-send-async.o: com.h prot-a.o: com.h ramkomd.o: com.h regex-match.o: com.h send-async.o: com.h server-config.o: com.h session.o: com.h simple-cache.o: com.h standalone.o: com.h text-garb.o: com.h text.o: com.h server-config.o: paths.h connections.o: fnc-def-init.incl call-switch.incl admin.o: version.incl prot-a.o: fnc-def-init.incl prot-a-is-legal-fnc.incl standalone.o: version.incl # "make install" without a prior "make" requires these. connections.o: prot-a-parse-arg.h # This dependency is needed after a "make maintainer-clean". aux-item-def-scan.o: aux-item-def-parse.h # all-recursive: lyskomd$(EXEEXT) dbck$(EXEEXT) check-recursive: libcheck.a lyskomd$(EXEEXT) dbck$(EXEEXT) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/src/server/aux-item-def-parse.c0000664000015100472110000014426007723710342015667 /* A Bison parser, made from aux-item-def-parse.y by GNU bison 1.35. */ #define YYBISON 1 /* Identify Bison output. */ #define YYLSP_NEEDED 1 # define NUMBER 257 # define BOOLEAN 258 # define ID 259 # define STRING 260 # define DISABLED 261 # define TEXT 262 # define CONFERENCE 263 # define LETTERBOX 264 # define TOK_SERVER 265 # define TOK_ANY 266 # define VOID 267 # define CREATE 268 # define MODIFY 269 #line 1 "aux-item-def-parse.y" /* * $Id: aux-item-def-parse.y,v 1.22 2003/08/23 16:38:18 ceder Exp $ * Copyright (C) 1994-1996, 1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* Rename hack from the automake 1.4 manual. */ #define yymaxdepth aid_maxdepth #define yyparse aid_parse #define yylex aid_lex #define yyerror aid_error #define yylval aid_lval #define yychar aid_char #define yydebug aid_debug #define yypact aid_pact #define yyr1 aid_r1 #define yyr2 aid_r2 #define yydef aid_def #define yychk aid_chk #define yypgo aid_pgo #define yyact aid_act #define yyexca aid_exca #define yyerrflag aid_errflag #define yynerrs aid_nerrs #define yyps aid_ps #define yypv aid_pv #define yys aid_s #define yy_yys aid_yys #define yystate aid_state #define yytmp aid_tmp #define yyv aid_v #define yy_yyv aid_yyv #define yyval aid_val #define yylloc aid_lloc #define yyreds aid_reds #define yytoks aid_toks #define yylhs aid_yylhs #define yylen aid_yylen #define yydefred aid_yydefred #define yydgoto aid_yydgoto #define yysindex aid_yysindex #define yyrindex aid_yyrindex #define yygindex aid_yygindex #define yytable aid_yytable #define yycheck aid_yycheck #define yyname aid_yyname #define yyrule aid_yyrule #ifdef HAVE_CONFIG_H # include #endif #if STDC_HEADERS || HAVE_STRING_H # include #else # include #endif #ifdef HAVE_STDARG_H # include #endif #include #include #include "timewrap.h" #include "kom-types.h" #include "com.h" #include "async.h" #include "connections.h" #include "aux-items.h" #include "s-string.h" #include "server/smalloc.h" #include "lyskomd.h" #include "debug.h" #include "log.h" #include "string-malloc.h" #include "eintr.h" BUGDECL; #define YYDEBUG 1 static Aux_item_definition def; static Bool errorFlag = FALSE; #define CHK_ASSIGN(_i_, _f_, _t_, _d_, _e_, _l_) \ found = found || aux_item_def_check_assign(_i_,_d_,&def._f_,_t_,&(_e_),_l_) #define CHK_FLAG_A(_i_, _f_, _d_, _e_, _l_) \ if (!s_strcmp(s_fcrea_str(_i_),_d_)) \ { \ found = 1; \ if (_e_.type != BOOLEAN ) \ { \ aux_item_def_error_line = _l_; \ yyerror("invalid type: expected %s, got %s", \ aux_item_def_typename(BOOLEAN), \ aux_item_def_typename(_e_.type)); \ } \ if (_e_.val.num) { def.set_flags._f_ = 1; } \ else { def.clear_flags._f_ = 1; } \ } extern int yylex(void); static char *inputFile; int aux_item_def_error_line; extern int yylineno; #if defined(HAVE_VFPRINTF) && defined(HAVE_STDARG_H) void yyerror(const char * format, ...) # if HAVE_ATTRIBUTE_FORMAT_PRINTF __attribute__ ((format (printf, 1, 2))) # endif ; #else void yyerror(); #endif struct aux_item_def_value_type; static int aux_item_def_check_assign(const char *, String, void *, int, struct aux_item_def_value_type *, int); static const char *aux_item_def_typename(int); static short aux_item_def_check_trigger(const char *check_name, int type, String trigger_name, String function_name, unsigned long *counter, Aux_item_trigger **triggers); static short aux_item_def_check_validate(const char *check_name, String field_name, int type, String data, Aux_item_definition *def); #define YYERROR_VERBOSE #line 168 "aux-item-def-parse.y" #ifndef YYSTYPE typedef union { String str; unsigned long num; struct aux_item_def_value_type { int type; union { String str; unsigned long num; } val; } value; } yystype; # define YYSTYPE yystype # define YYSTYPE_IS_TRIVIAL 1 #endif #ifndef YYLTYPE typedef struct yyltype { int first_line; int first_column; int last_line; int last_column; } yyltype; # define YYLTYPE yyltype # define YYLTYPE_IS_TRIVIAL 1 #endif #ifndef YYDEBUG # define YYDEBUG 0 #endif #define YYFINAL 39 #define YYFLAG -32768 #define YYNTBASE 24 /* YYTRANSLATE(YYLEX) -- Bison token number corresponding to YYLEX. */ #define YYTRANSLATE(x) ((unsigned)(x) <= 269 ? yytranslate[x] : 33) /* YYTRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX. */ static const char yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 19, 20, 2, 2, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 18, 23, 2, 22, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 2, 17, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; #if YYDEBUG static const short yyprhs[] = { 0, 0, 3, 4, 9, 16, 24, 28, 30, 33, 36, 39, 41, 44, 47, 50, 51, 54, 57, 58, 63, 65, 67, 69, 73 }; static const short yyrhs[] = { 24, 25, 0, 0, 26, 16, 30, 17, 0, 3, 18, 5, 19, 27, 20, 0, 3, 18, 5, 19, 27, 20, 7, 0, 27, 21, 28, 0, 28, 0, 29, 8, 0, 29, 9, 0, 29, 10, 0, 11, 0, 29, 12, 0, 29, 14, 0, 29, 15, 0, 0, 30, 31, 0, 30, 1, 0, 0, 5, 22, 32, 23, 0, 4, 0, 6, 0, 3, 0, 5, 19, 20, 0, 13, 0 }; #endif #if YYDEBUG /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const short yyrline[] = { 0, 193, 194, 197, 207, 220, 231, 232, 235, 236, 237, 239, 240, 249, 250, 251, 254, 255, 256, 259, 345, 346, 347, 348, 349 }; #endif #if (YYDEBUG) || defined YYERROR_VERBOSE /* YYTNAME[TOKEN_NUM] -- String name of the token TOKEN_NUM. */ static const char *const yytname[] = { "$", "error", "$undefined.", "NUMBER", "BOOLEAN", "ID", "STRING", "DISABLED", "TEXT", "CONFERENCE", "LETTERBOX", "TOK_SERVER", "TOK_ANY", "VOID", "CREATE", "MODIFY", "'{'", "'}'", "':'", "'('", "')'", "','", "'='", "';'", "items", "item", "head", "targets", "target", "action", "body", "assign", "value", 0 }; #endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const short yyr1[] = { 0, 24, 24, 25, 26, 26, 27, 27, 28, 28, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 32, 32, 32, 32, 32 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const short yyr2[] = { 0, 2, 0, 4, 6, 7, 3, 1, 2, 2, 2, 1, 2, 2, 2, 0, 2, 2, 0, 4, 1, 1, 1, 3, 1 }; /* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const short yydefact[] = { 2, 0, 0, 1, 0, 0, 18, 0, 0, 15, 17, 0, 3, 16, 11, 0, 7, 0, 0, 4, 15, 8, 9, 10, 12, 13, 14, 22, 20, 0, 21, 24, 0, 5, 6, 0, 19, 23, 0, 0 }; static const short yydefgoto[] = { 1, 3, 4, 15, 16, 17, 8, 13, 32 }; static const short yypact[] = { -32768, 10, -15,-32768, -7, 6,-32768, -5, -1, 1, -32768, -2,-32768,-32768,-32768, -19,-32768, 9, 2, 15, 1,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 7, -32768,-32768, 4,-32768,-32768, 5,-32768,-32768, 28,-32768 }; static const short yypgoto[] = { -32768,-32768,-32768,-32768, 11,-32768,-32768,-32768,-32768 }; #define YYLAST 31 static const short yytable[] = { 10, 19, 20, 5, 11, 27, 28, 29, 30, 6, 38, 7, 14, 2, 9, 31, 12, 21, 22, 23, 18, 24, 33, 25, 26, 37, 35, 36, 39, 0, 0, 34 }; static const short yycheck[] = { 1, 20, 21, 18, 5, 3, 4, 5, 6, 16, 0, 5, 11, 3, 19, 13, 17, 8, 9, 10, 22, 12, 7, 14, 15, 20, 19, 23, 0, -1, -1, 20 }; /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ #line 3 "/i/bison/1.35/share/bison/bison.simple" /* Skeleton output parser for bison, Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. 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 2, 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, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* As a special exception, when this file is copied by Bison into a Bison output file, you may use that output file without restriction. This special exception was added by the Free Software Foundation in version 1.24 of Bison. */ /* This is the parser code that is written into each bison parser when the %semantic_parser declaration is not specified in the grammar. It was written by Richard Stallman by simplifying the hairy parser used when %semantic_parser is specified. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ #if ! defined (yyoverflow) || defined (YYERROR_VERBOSE) /* The parser invokes alloca or malloc; define the necessary symbols. */ # if YYSTACK_USE_ALLOCA # define YYSTACK_ALLOC alloca # else # ifndef YYSTACK_USE_ALLOCA # if defined (alloca) || defined (_ALLOCA_H) # define YYSTACK_ALLOC alloca # else # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) # else # if defined (__STDC__) || defined (__cplusplus) # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # endif # define YYSTACK_ALLOC malloc # define YYSTACK_FREE free # endif #endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */ #if (! defined (yyoverflow) \ && (! defined (__cplusplus) \ || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { short yyss; YYSTYPE yyvs; # if YYLSP_NEEDED YYLTYPE yyls; # endif }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAX (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # if YYLSP_NEEDED # define YYSTACK_BYTES(N) \ ((N) * (sizeof (short) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ + 2 * YYSTACK_GAP_MAX) # else # define YYSTACK_BYTES(N) \ ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAX) # endif /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY # if 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else # define YYCOPY(To, From, Count) \ do \ { \ register YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ while (0) # endif # endif /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack, Stack, yysize); \ Stack = &yyptr->Stack; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAX; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (0) #endif #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) # define YYSIZE_T __SIZE_TYPE__ #endif #if ! defined (YYSIZE_T) && defined (size_t) # define YYSIZE_T size_t #endif #if ! defined (YYSIZE_T) # if defined (__STDC__) || defined (__cplusplus) # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # endif #endif #if ! defined (YYSIZE_T) # define YYSIZE_T unsigned int #endif #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY -2 #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrlab1 /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ yychar1 = YYTRANSLATE (yychar); \ YYPOPSTACK; \ goto yybackup; \ } \ else \ { \ yyerror ("syntax error: cannot back up"); \ YYERROR; \ } \ while (0) #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Compute the default location (before the actions are run). When YYLLOC_DEFAULT is run, CURRENT is set the location of the first token. By default, to implement support for ranges, extend its range to the last symbol. */ #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ Current.last_line = Rhs[N].last_line; \ Current.last_column = Rhs[N].last_column; #endif /* YYLEX -- calling `yylex' with the right arguments. */ #if YYPURE # if YYLSP_NEEDED # ifdef YYLEX_PARAM # define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM) # else # define YYLEX yylex (&yylval, &yylloc) # endif # else /* !YYLSP_NEEDED */ # ifdef YYLEX_PARAM # define YYLEX yylex (&yylval, YYLEX_PARAM) # else # define YYLEX yylex (&yylval) # endif # endif /* !YYLSP_NEEDED */ #else /* !YYPURE */ # define YYLEX yylex () #endif /* !YYPURE */ /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (0) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #if YYMAXDEPTH == 0 # undef YYMAXDEPTH #endif #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #ifdef YYERROR_VERBOSE # ifndef yystrlen # if defined (__GLIBC__) && defined (_STRING_H) # define yystrlen strlen # else /* Return the length of YYSTR. */ static YYSIZE_T # if defined (__STDC__) || defined (__cplusplus) yystrlen (const char *yystr) # else yystrlen (yystr) const char *yystr; # endif { register const char *yys = yystr; while (*yys++ != '\0') continue; return yys - yystr - 1; } # endif # endif # ifndef yystpcpy # if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ static char * # if defined (__STDC__) || defined (__cplusplus) yystpcpy (char *yydest, const char *yysrc) # else yystpcpy (yydest, yysrc) char *yydest; const char *yysrc; # endif { register char *yyd = yydest; register const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif #endif #line 315 "/i/bison/1.35/share/bison/bison.simple" /* The user can define YYPARSE_PARAM as the name of an argument to be passed into yyparse. The argument should have type void *. It should actually point to an object. Grammar actions can access the variable by casting it to the proper pointer type. */ #ifdef YYPARSE_PARAM # if defined (__STDC__) || defined (__cplusplus) # define YYPARSE_PARAM_ARG void *YYPARSE_PARAM # define YYPARSE_PARAM_DECL # else # define YYPARSE_PARAM_ARG YYPARSE_PARAM # define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; # endif #else /* !YYPARSE_PARAM */ # define YYPARSE_PARAM_ARG # define YYPARSE_PARAM_DECL #endif /* !YYPARSE_PARAM */ /* Prevent warning if -Wstrict-prototypes. */ #ifdef __GNUC__ # ifdef YYPARSE_PARAM int yyparse (void *); # else int yyparse (void); # endif #endif /* YY_DECL_VARIABLES -- depending whether we use a pure parser, variables are global, or local to YYPARSE. */ #define YY_DECL_NON_LSP_VARIABLES \ /* The lookahead symbol. */ \ int yychar; \ \ /* The semantic value of the lookahead symbol. */ \ YYSTYPE yylval; \ \ /* Number of parse errors so far. */ \ int yynerrs; #if YYLSP_NEEDED # define YY_DECL_VARIABLES \ YY_DECL_NON_LSP_VARIABLES \ \ /* Location data for the lookahead symbol. */ \ YYLTYPE yylloc; #else # define YY_DECL_VARIABLES \ YY_DECL_NON_LSP_VARIABLES #endif /* If nonreentrant, generate the variables here. */ #if !YYPURE YY_DECL_VARIABLES #endif /* !YYPURE */ int yyparse (YYPARSE_PARAM_ARG) YYPARSE_PARAM_DECL { /* If reentrant, generate the variables here. */ #if YYPURE YY_DECL_VARIABLES #endif /* !YYPURE */ register int yystate; register int yyn; int yyresult; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* Lookahead token as an internal (translated) token number. */ int yychar1 = 0; /* Three stacks and their tools: `yyss': related to states, `yyvs': related to semantic values, `yyls': related to locations. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ short yyssa[YYINITDEPTH]; short *yyss = yyssa; register short *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; register YYSTYPE *yyvsp; #if YYLSP_NEEDED /* The location stack. */ YYLTYPE yylsa[YYINITDEPTH]; YYLTYPE *yyls = yylsa; YYLTYPE *yylsp; #endif #if YYLSP_NEEDED # define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) #else # define YYPOPSTACK (yyvsp--, yyssp--) #endif YYSIZE_T yystacksize = YYINITDEPTH; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; #if YYLSP_NEEDED YYLTYPE yyloc; #endif /* When reducing, the number of symbols on the RHS of the reduced rule. */ int yylen; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; #if YYLSP_NEEDED yylsp = yyls; #endif goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. so pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyssp >= yyss + yystacksize - 1) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; short *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. */ # if YYLSP_NEEDED YYLTYPE *yyls1 = yyls; /* This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow ("parser stack overflow", &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yyls1, yysize * sizeof (*yylsp), &yystacksize); yyls = yyls1; # else yyoverflow ("parser stack overflow", &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); # endif yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyoverflowlab; # else /* Extend the stack our own way. */ if (yystacksize >= YYMAXDEPTH) goto yyoverflowlab; yystacksize *= 2; if (yystacksize > YYMAXDEPTH) yystacksize = YYMAXDEPTH; { short *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyoverflowlab; YYSTACK_RELOCATE (yyss); YYSTACK_RELOCATE (yyvs); # if YYLSP_NEEDED YYSTACK_RELOCATE (yyls); # endif # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; #if YYLSP_NEEDED yylsp = yyls + yysize - 1; #endif YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyssp >= yyss + yystacksize - 1) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. */ /* Read a lookahead token if we need one and don't already have one. */ /* yyresume: */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yyn == YYFLAG) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* yychar is either YYEMPTY or YYEOF or a valid token in external form. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } /* Convert token to internal form (in yychar1) for indexing tables with */ if (yychar <= 0) /* This means end of input. */ { yychar1 = 0; yychar = YYEOF; /* Don't call YYLEX any more */ YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yychar1 = YYTRANSLATE (yychar); #if YYDEBUG /* We have to keep this `#if YYDEBUG', since we use variables which are defined only if `YYDEBUG' is set. */ if (yydebug) { YYFPRINTF (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); /* Give the individual parser a way to print the precise meaning of a token, for further debugging info. */ # ifdef YYPRINT YYPRINT (stderr, yychar, yylval); # endif YYFPRINTF (stderr, ")\n"); } #endif } yyn += yychar1; if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) goto yydefault; yyn = yytable[yyn]; /* yyn is what to do for this token type in this state. Negative => reduce, -yyn is rule number. Positive => shift, yyn is new state. New state is final state => don't bother to shift, just return success. 0, or most negative number => error. */ if (yyn < 0) { if (yyn == YYFLAG) goto yyerrlab; yyn = -yyn; goto yyreduce; } else if (yyn == 0) goto yyerrlab; if (yyn == YYFINAL) YYACCEPT; /* Shift the lookahead token. */ YYDPRINTF ((stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1])); /* Discard the token being shifted unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; *++yyvsp = yylval; #if YYLSP_NEEDED *++yylsp = yylloc; #endif /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; yystate = yyn; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to the semantic value of the lookahead token. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; #if YYLSP_NEEDED /* Similarly for the default location. Let the user run additional commands if for instance locations are ranges. */ yyloc = yylsp[1-yylen]; YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); #endif #if YYDEBUG /* We have to keep this `#if YYDEBUG', since we use variables which are defined only if `YYDEBUG' is set. */ if (yydebug) { int yyi; YYFPRINTF (stderr, "Reducing via rule %d (line %d), ", yyn, yyrline[yyn]); /* Print the symbols being reduced, and their result. */ for (yyi = yyprhs[yyn]; yyrhs[yyi] > 0; yyi++) YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]); YYFPRINTF (stderr, " -> %s\n", yytname[yyr1[yyn]]); } #endif switch (yyn) { case 3: #line 198 "aux-item-def-parse.y" { if (def.tag != 0) { aux_item_definition_add(&def); } def = empty_aux_item_definition; } break; case 4: #line 208 "aux-item-def-parse.y" { def.tag = yyvsp[-5].num; def.name = s_crea_c_str(yyvsp[-3].str); if (buglevel) { kom_log("Parsing definition of aux-item %ld (%s)\n", def.tag, def.name); } s_clear(&(yyvsp[-3].str)); yyvsp[-3].str = EMPTY_STRING; yylval.str = EMPTY_STRING; } break; case 5: #line 221 "aux-item-def-parse.y" { def.tag = yyvsp[-6].num; def.name = s_crea_c_str(yyvsp[-4].str); def.disabled = TRUE; s_clear(&(yyvsp[-4].str)); yyvsp[-4].str = EMPTY_STRING; yylval.str = EMPTY_STRING; } break; case 8: #line 235 "aux-item-def-parse.y" { def.texts = TRUE; def.text_a = yyvsp[-1].num; } break; case 9: #line 236 "aux-item-def-parse.y" { def.confs = TRUE; def.conf_a = yyvsp[-1].num; } break; case 10: #line 237 "aux-item-def-parse.y" { def.letterboxes = TRUE; def.conf_a = yyvsp[-1].num; } break; case 11: #line 239 "aux-item-def-parse.y" { def.system = TRUE; } break; case 12: #line 241 "aux-item-def-parse.y" { def.texts = TRUE; def.text_a = yyvsp[-1].num; def.confs = TRUE; def.conf_a = yyvsp[-1].num; def.letterboxes = TRUE; def.system = TRUE; } break; case 13: #line 249 "aux-item-def-parse.y" { yyval.num = yyvsp[-1].num | AUX_ITEM_ADD_ON_CREATE; } break; case 14: #line 250 "aux-item-def-parse.y" { yyval.num = yyvsp[-1].num | AUX_ITEM_ADD_ON_MODIFY; } break; case 15: #line 251 "aux-item-def-parse.y" { yyval.num = 0; } break; case 19: #line 260 "aux-item-def-parse.y" { int found = 0; CHK_ASSIGN("author-only", author_only, BOOLEAN, yyvsp[-3].str, yyvsp[-1].value, yylsp[-1].first_line); CHK_ASSIGN("supervisor-only", supervisor_only, BOOLEAN, yyvsp[-3].str, yyvsp[-1].value, yylsp[-1].first_line); CHK_ASSIGN("system-only", system_only, BOOLEAN, yyvsp[-3].str, yyvsp[-1].value, yylsp[-1].first_line); CHK_ASSIGN("inherit-limit", inherit_limit, NUMBER, yyvsp[-3].str, yyvsp[-1].value, yylsp[-1].first_line); CHK_ASSIGN("unique", one_per_person, BOOLEAN, yyvsp[-3].str, yyvsp[-1].value, yylsp[-1].first_line); CHK_ASSIGN("unique-data", unique_data, BOOLEAN, yyvsp[-3].str, yyvsp[-1].value, yylsp[-1].first_line); CHK_ASSIGN("permanent", may_not_delete, BOOLEAN, yyvsp[-3].str, yyvsp[-1].value, yylsp[-1].first_line); CHK_ASSIGN("owner-delete", owner_delete, BOOLEAN, yyvsp[-3].str, yyvsp[-1].value, yylsp[-1].first_line); CHK_FLAG_A("inherit", inherit, yyvsp[-3].str, yyvsp[-1].value, yylsp[-1].first_line); CHK_FLAG_A("secret", secret, yyvsp[-3].str, yyvsp[-1].value, yylsp[-1].first_line); CHK_FLAG_A("hide-creator", hide_creator, yyvsp[-3].str, yyvsp[-1].value, yylsp[-1].first_line); CHK_FLAG_A("dont-garb", dont_garb, yyvsp[-3].str, yyvsp[-1].value, yylsp[-1].first_line); CHK_FLAG_A("reserved-2", reserved3, yyvsp[-3].str, yyvsp[-1].value, yylsp[-1].first_line); CHK_FLAG_A("reserved-3", reserved4, yyvsp[-3].str, yyvsp[-1].value, yylsp[-1].first_line); CHK_FLAG_A("reserved-4", reserved5, yyvsp[-3].str, yyvsp[-1].value, yylsp[-1].first_line); found = found ? 1 : aux_item_def_check_validate("validate", yyvsp[-3].str, yyvsp[-1].value.type, yyvsp[-1].value.val.str, &def); found = found ? 1 : aux_item_def_check_trigger("delete-trigger", yyvsp[-1].value.type, yyvsp[-3].str, yyvsp[-1].value.val.str, &def.num_delete_triggers, &def.delete_triggers); found = found ? 1 : aux_item_def_check_trigger("undelete-trigger", yyvsp[-1].value.type, yyvsp[-3].str, yyvsp[-1].value.val.str, &def.num_undelete_triggers, &def.undelete_triggers); found = found ? 1 : aux_item_def_check_trigger("add-trigger", yyvsp[-1].value.type, yyvsp[-3].str, yyvsp[-1].value.val.str, &def.num_add_triggers, &def.add_triggers); if (found == 0) { char *tmp; tmp = s_crea_c_str(yyvsp[-3].str); aux_item_def_error_line = yylsp[-3].first_line; yyerror("invalid field name: %s", tmp); string_free(tmp); } if (yyvsp[-1].value.type == STRING || yyvsp[-1].value.type == ID) { s_clear(&(yyvsp[-1].value).val.str); yyvsp[-1].value.val.str = EMPTY_STRING; yylval.value.val.str = EMPTY_STRING; } s_clear(&(yyvsp[-3].str)); yyvsp[-3].str = EMPTY_STRING; yylval.str = EMPTY_STRING; } break; case 20: #line 345 "aux-item-def-parse.y" { yyval.value.val.num = yyvsp[0].num; yyval.value.type = BOOLEAN; } break; case 21: #line 346 "aux-item-def-parse.y" { yyval.value.val.str = yyvsp[0].str; yyval.value.type = STRING; } break; case 22: #line 347 "aux-item-def-parse.y" { yyval.value.val.num = yyvsp[0].num; yyval.value.type = NUMBER; } break; case 23: #line 348 "aux-item-def-parse.y" { yyval.value.val.str = yyvsp[-2].str; yyval.value.type = ID;} break; case 24: #line 349 "aux-item-def-parse.y" { YYERROR; } break; } #line 705 "/i/bison/1.35/share/bison/bison.simple" yyvsp -= yylen; yyssp -= yylen; #if YYLSP_NEEDED yylsp -= yylen; #endif #if YYDEBUG if (yydebug) { short *yyssp1 = yyss - 1; YYFPRINTF (stderr, "state stack now"); while (yyssp1 != yyssp) YYFPRINTF (stderr, " %d", *++yyssp1); YYFPRINTF (stderr, "\n"); } #endif *++yyvsp = yyval; #if YYLSP_NEEDED *++yylsp = yyloc; #endif /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTBASE] + *yyssp; if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTBASE]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #ifdef YYERROR_VERBOSE yyn = yypact[yystate]; if (yyn > YYFLAG && yyn < YYLAST) { YYSIZE_T yysize = 0; char *yymsg; int yyx, yycount; yycount = 0; /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ for (yyx = yyn < 0 ? -yyn : 0; yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) if (yycheck[yyx + yyn] == yyx) yysize += yystrlen (yytname[yyx]) + 15, yycount++; yysize += yystrlen ("parse error, unexpected ") + 1; yysize += yystrlen (yytname[YYTRANSLATE (yychar)]); yymsg = (char *) YYSTACK_ALLOC (yysize); if (yymsg != 0) { char *yyp = yystpcpy (yymsg, "parse error, unexpected "); yyp = yystpcpy (yyp, yytname[YYTRANSLATE (yychar)]); if (yycount < 5) { yycount = 0; for (yyx = yyn < 0 ? -yyn : 0; yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) if (yycheck[yyx + yyn] == yyx) { const char *yyq = ! yycount ? ", expecting " : " or "; yyp = yystpcpy (yyp, yyq); yyp = yystpcpy (yyp, yytname[yyx]); yycount++; } } yyerror (yymsg); YYSTACK_FREE (yymsg); } else yyerror ("parse error; also virtual memory exhausted"); } else #endif /* defined (YYERROR_VERBOSE) */ yyerror ("parse error"); } goto yyerrlab1; /*--------------------------------------------------. | yyerrlab1 -- error raised explicitly by an action | `--------------------------------------------------*/ yyerrlab1: if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ /* return failure if at end of input */ if (yychar == YYEOF) YYABORT; YYDPRINTF ((stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1])); yychar = YYEMPTY; } /* Else will try to reuse lookahead token after shifting the error token. */ yyerrstatus = 3; /* Each real token shifted decrements this */ goto yyerrhandle; /*-------------------------------------------------------------------. | yyerrdefault -- current state does not do anything special for the | | error token. | `-------------------------------------------------------------------*/ yyerrdefault: #if 0 /* This is wrong; only states that explicitly want error tokens should shift them. */ /* If its default is to accept any token, ok. Otherwise pop it. */ yyn = yydefact[yystate]; if (yyn) goto yydefault; #endif /*---------------------------------------------------------------. | yyerrpop -- pop the current state because it cannot handle the | | error token | `---------------------------------------------------------------*/ yyerrpop: if (yyssp == yyss) YYABORT; yyvsp--; yystate = *--yyssp; #if YYLSP_NEEDED yylsp--; #endif #if YYDEBUG if (yydebug) { short *yyssp1 = yyss - 1; YYFPRINTF (stderr, "Error: state stack now"); while (yyssp1 != yyssp) YYFPRINTF (stderr, " %d", *++yyssp1); YYFPRINTF (stderr, "\n"); } #endif /*--------------. | yyerrhandle. | `--------------*/ yyerrhandle: yyn = yypact[yystate]; if (yyn == YYFLAG) goto yyerrdefault; yyn += YYTERROR; if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) goto yyerrdefault; yyn = yytable[yyn]; if (yyn < 0) { if (yyn == YYFLAG) goto yyerrpop; yyn = -yyn; goto yyreduce; } else if (yyn == 0) goto yyerrpop; if (yyn == YYFINAL) YYACCEPT; YYDPRINTF ((stderr, "Shifting error token, ")); *++yyvsp = yylval; #if YYLSP_NEEDED *++yylsp = yylloc; #endif yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; /*---------------------------------------------. | yyoverflowab -- parser overflow comes here. | `---------------------------------------------*/ yyoverflowlab: yyerror ("parser stack overflow"); yyresult = 2; /* Fall through. */ yyreturn: #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif return yyresult; } #line 352 "aux-item-def-parse.y" extern FILE *yyin; #if defined(HAVE_VFPRINTF) && defined(HAVE_STDARG_H) void yyerror(const char *format, ...) { va_list AP; va_start(AP, format); fprintf(stderr, "%s: %d: ", inputFile, aux_item_def_error_line); vfprintf(stderr, format, AP); fprintf(stderr, "\n"); fflush(stderr); errorFlag = TRUE; va_end(AP); } #else void yyerror(const char *s, int a, int b, int c, int d, int e, int f, int g) { fprintf(stderr, "%s: %d: ", inputFile, aux_item_def_error_line); fprintf(stderr, format, a, b, c, d, e, f, g); fprintf(stderr, "\n"); fflush(stderr); errorFlag = TRUE; } #endif static const char *aux_item_def_typename(int type) { switch (type) { case STRING: return "string"; case NUMBER: return "number"; case BOOLEAN: return "boolean"; case ID: return "identifier"; default: return "unknown"; } } static int aux_item_def_check_assign(const char *id, String field, void *data, int type, struct aux_item_def_value_type *val, int lineno) { if (!s_strcmp(s_fcrea_str(id), field)) { if (type != val->type) { aux_item_def_error_line = lineno; yyerror("invalid type: expected %s, got %s", aux_item_def_typename(type), aux_item_def_typename(val->type)); return 0; } else if (type == STRING) { *((char **)data) = s_crea_c_str(val->val.str); } else if (type == NUMBER) { *((unsigned long *)data) = val->val.num; } else if (type == BOOLEAN) { *((Bool *)data) = val->val.num ? TRUE : FALSE; } else { restart_kom("Internal error: bad type in aux-item definition " "assignment (can't happen.)\n"); } return 1; } else { return 0; } } static short aux_item_def_check_trigger(const char *check_name, int type, String trigger_name, String function_name, unsigned long *counter, Aux_item_trigger **triggers) { Aux_item_trigger trigger; char *tmp_string; if (s_strcmp(s_fcrea_str(check_name), trigger_name) == 0) { if (type != ID) { yyerror("invalid type: expected %s, got %s", aux_item_def_typename(ID), aux_item_def_typename(type)); return 0; } tmp_string = s_crea_c_str(function_name); trigger = aux_item_find_trigger(tmp_string); string_free(tmp_string); if (trigger == NULL) { yyerror("undefined function: %s", tmp_string); return 1; } *counter += 1; *triggers = srealloc(*triggers, *counter * sizeof(Aux_item_trigger)); *triggers[*counter-1] = trigger; return 1; } return 0; } void parse_aux_item_definitions(char *file) { inputFile = file; yyin = i_fopen(file, "r"); if (yyin == NULL) { perror(file); restart_kom("Unable to open aux-item definition file\n"); } def = empty_aux_item_definition; yyparse(); i_fclose(yyin); if (errorFlag == TRUE) { restart_kom("Errors reading aux-item definition file\n"); } /* { extern Aux_item_definition *aux_item_definition_list; extern unsigned long num_aux_item_definitions; Aux_item_definition *def; fprintf(stderr, "Number of defs: %ld\n", num_aux_item_definitions); def = aux_item_definition_list; while (def != NULL) { fprintf(stderr, "Name: '%s'\n", def->name); fprintf(stderr, "Tag: %ld\n", def->tag); fprintf(stderr, "Clear flags: "); if (def->clear_flags.deleted) fprintf(stderr, "deleted "); if (def->clear_flags.inherit) fprintf(stderr, "inherit "); if (def->clear_flags.secret) fprintf(stderr, "secret "); if (def->clear_flags.hide_creator) fprintf(stderr,"hide_creator "); if (def->clear_flags.reserved2) fprintf(stderr, "reserved2 "); if (def->clear_flags.reserved3) fprintf(stderr, "reserved3 "); if (def->clear_flags.reserved4) fprintf(stderr, "reserved4 "); if (def->clear_flags.reserved5) fprintf(stderr, "reserved5 "); fprintf(stderr, "\n"); fprintf(stderr, "Set flags: "); if (def->set_flags.deleted) fprintf(stderr, "deleted "); if (def->set_flags.inherit) fprintf(stderr, "inherit "); if (def->set_flags.secret) fprintf(stderr, "secret "); if (def->set_flags.hide_creator) fprintf(stderr,"hide_creator "); if (def->set_flags.reserved2) fprintf(stderr, "reserved2 "); if (def->set_flags.reserved3) fprintf(stderr, "reserved3 "); if (def->set_flags.reserved4) fprintf(stderr, "reserved4 "); if (def->set_flags.reserved5) fprintf(stderr, "reserved5 "); fprintf(stderr, "\n"); fprintf(stderr, "Author only: %d\n", def->author_only); fprintf(stderr, "Supervisor only: %d\n", def->supervisor_only); fprintf(stderr, "Unique: %d\n", def->one_per_person); fprintf(stderr, "Unique-data: %d\n", def->unique_data); fprintf(stderr, "Permanent: %d\n", def->may_not_delete); fprintf(stderr, "Inherit limit: %ld\n", def->inherit_limit); fprintf(stderr, "Texts: %d\n", def->texts); fprintf(stderr, "Conferences: %d\n", def->confs); fprintf(stderr, "Letterboxes: %d\n", def->letterboxes); fprintf(stderr, "Validate regexp: '%s'\n", def->validate_regexp?def->validate_regexp:"0x0"); def = def->next; } } */ } static short aux_item_def_check_validate(const char *check_name, String field_name, int type, String data, Aux_item_definition *def) { Aux_item_validation_function validator; char *tmp_string; if (s_strcmp(s_fcrea_str(check_name), field_name) == 0) { /* * Validator is a function */ if (type == ID) { tmp_string = s_crea_c_str(data); validator = aux_item_find_validator(tmp_string); string_free(tmp_string); if (validator == NULL) { yyerror("undefined function: %s", tmp_string); return 1; } def->num_validators += 1; def->validators = srealloc(def->validators, def->num_validators * sizeof(*def->validators)); def->validators[def->num_validators-1].type = AUX_VALIDATE_FUNCTION; def->validators[def->num_validators-1].v.fn.function = validator; return 1; } else if (type == STRING) { /* * Validator is a string (regexp) */ def->num_validators += 1; def->validators = srealloc(def->validators, def->num_validators * sizeof(*def->validators)); def->validators[def->num_validators-1].type = AUX_VALIDATE_REGEXP; def->validators[def->num_validators-1].v.re.regexp = s_crea_c_str(data); def->validators[def->num_validators-1].v.re.cached_re_buf = NULL; } else { yyerror("invalid type: expected %s or %s, got %s", aux_item_def_typename(ID), aux_item_def_typename(STRING), aux_item_def_typename(type)); return 0; } return 1; } return 0; } lyskom-server-2.1.2/src/server/aux-item-def-parse.h0000664000015100472110000000165507723710342015674 #ifndef BISON_AUX_ITEM_DEF_PARSE_H # define BISON_AUX_ITEM_DEF_PARSE_H #ifndef YYSTYPE typedef union { String str; unsigned long num; struct aux_item_def_value_type { int type; union { String str; unsigned long num; } val; } value; } yystype; # define YYSTYPE yystype # define YYSTYPE_IS_TRIVIAL 1 #endif #ifndef YYLTYPE typedef struct yyltype { int first_line; int first_column; int last_line; int last_column; } yyltype; # define YYLTYPE yyltype # define YYLTYPE_IS_TRIVIAL 1 #endif # define NUMBER 257 # define BOOLEAN 258 # define ID 259 # define STRING 260 # define DISABLED 261 # define TEXT 262 # define CONFERENCE 263 # define LETTERBOX 264 # define TOK_SERVER 265 # define TOK_ANY 266 # define VOID 267 # define CREATE 268 # define MODIFY 269 extern YYSTYPE yylval; #endif /* not BISON_AUX_ITEM_DEF_PARSE_H */ lyskom-server-2.1.2/src/server/aux-item-def-scan.c0000664000015100472110000014256007723710343015503 /* A lexical scanner generated by flex */ /* Scanner skeleton version: * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $ */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #include /* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ #ifdef c_plusplus #ifndef __cplusplus #define __cplusplus #endif #endif #ifdef __cplusplus #include #include /* Use prototypes in function declarations. */ #define YY_USE_PROTOS /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ #if __STDC__ #define YY_USE_PROTOS #define YY_USE_CONST #endif /* __STDC__ */ #endif /* ! __cplusplus */ #ifdef __TURBOC__ #pragma warn -rch #pragma warn -use #include #include #define YY_USE_CONST #define YY_USE_PROTOS #endif #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif #ifdef YY_USE_PROTOS #define YY_PROTO(proto) proto #else #define YY_PROTO(proto) () #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN yy_start = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START ((yy_start - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #define YY_BUF_SIZE 16384 typedef struct yy_buffer_state *YY_BUFFER_STATE; extern int yyleng; extern FILE *yyin, *yyout; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 /* The funky do-while in the following #define is used to turn the definition * int a single C statement (which needs a semi-colon terminator). This * avoids problems with code like: * * if ( condition_holds ) * yyless( 5 ); * else * do_something_else(); * * Prior to using the do-while the compiler would get upset at the * "else" because it interpreted the "if" statement as being all * done when it reached the ';' after the yyless() call. */ /* Return all but the first 'n' matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ *yy_cp = yy_hold_char; \ YY_RESTORE_YY_MORE_OFFSET \ yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, yytext_ptr ) /* The following is because we cannot portably get our hands on size_t * (without autoconf's help, which isn't available because we want * flex-generated scanners to compile on their own). */ typedef unsigned int yy_size_t; struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; static YY_BUFFER_STATE yy_current_buffer = 0; /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". */ #define YY_CURRENT_BUFFER yy_current_buffer /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; static int yy_n_chars; /* number of characters read into yy_ch_buf */ int yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = (char *) 0; static int yy_init = 1; /* whether we need to initialize */ static int yy_start = 0; /* start state number */ /* Flag which is used to allow yywrap()'s to do buffer switches * instead of setting up a fresh yyin. A bit of a hack ... */ static int yy_did_buffer_switch_on_eof; void yyrestart YY_PROTO(( FILE *input_file )); void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); void yy_load_buffer_state YY_PROTO(( void )); YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); #define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); static void *yy_flex_alloc YY_PROTO(( yy_size_t )); static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); static void yy_flex_free YY_PROTO(( void * )); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! yy_current_buffer ) \ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ yy_current_buffer->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! yy_current_buffer ) \ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ yy_current_buffer->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (yy_current_buffer->yy_at_bol) #define YY_USES_REJECT #define yywrap() 1 #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; typedef int yy_state_type; extern int yylineno; int yylineno = 1; extern char *yytext; #define yytext_ptr yytext static yy_state_type yy_get_previous_state YY_PROTO(( void )); static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); static int yy_get_next_buffer YY_PROTO(( void )); static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ yytext_ptr = yy_bp; \ yyleng = (int) (yy_cp - yy_bp); \ yy_hold_char = *yy_cp; \ *yy_cp = '\0'; \ yy_c_buf_p = yy_cp; #define YY_NUM_RULES 31 #define YY_END_OF_BUFFER 32 static yyconst short int yy_acclist[154] = { 0, 32, 30, 31, 12, 30, 31, 12, 31, 15, 30, 31, 11, 30, 31, 14, 30, 31, 13, 30, 31, 13, 30, 31, 13, 30, 31, 13, 30, 31, 13, 30, 31, 13, 30, 31, 13, 30, 31, 13, 30, 31, 13, 30, 31, 13, 30, 31, 13, 30, 31, 13, 30, 31, 28, 31, 29, 31, 17, 31, 28, 31, 31, 12, 11, 14, 13, 13, 13, 13, 13, 13, 13, 13, 2, 13, 13, 1, 13, 13, 13, 13, 13, 28, 28, 27, 25, 27, 24, 27, 18, 27, 22, 27, 23, 27, 19, 27, 21, 27, 20, 27, 8, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 28, 26, 18, 13, 13, 13, 13, 13, 13, 13, 4, 13, 18, 13, 13, 13, 13, 13, 13, 13, 9, 13, 13, 13, 10, 13, 7, 13, 16, 13, 13, 13, 13, 3, 13, 13, 13, 6, 13, 5, 13 } ; static yyconst short int yy_accept[107] = { 0, 1, 1, 1, 1, 1, 2, 4, 7, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 56, 58, 60, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 76, 77, 79, 80, 81, 82, 83, 84, 85, 86, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 125, 125, 126, 127, 128, 129, 130, 131, 132, 132, 133, 135, 136, 137, 139, 141, 142, 143, 144, 145, 146, 148, 149, 150, 152, 154, 154 } ; static yyconst int yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 5, 6, 1, 1, 1, 7, 1, 1, 8, 1, 1, 9, 1, 1, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 1, 1, 1, 1, 1, 1, 1, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 13, 14, 1, 9, 1, 15, 16, 17, 18, 19, 20, 11, 11, 21, 11, 11, 22, 23, 24, 25, 11, 11, 26, 27, 28, 29, 30, 11, 31, 32, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst int yy_meta[33] = { 0, 1, 1, 2, 1, 3, 1, 1, 1, 4, 4, 4, 1, 3, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 } ; static yyconst short int yy_base[111] = { 0, 0, 0, 30, 33, 143, 144, 37, 45, 144, 0, 132, 0, 117, 25, 119, 124, 119, 112, 111, 32, 116, 18, 115, 0, 144, 144, 129, 54, 51, 0, 122, 0, 99, 106, 110, 101, 105, 98, 107, 0, 104, 0, 97, 91, 92, 93, 0, 117, 144, 56, 144, 144, 108, 144, 144, 144, 144, 144, 0, 97, 101, 100, 87, 85, 91, 81, 82, 90, 105, 61, 97, 87, 77, 88, 84, 83, 81, 81, 0, 85, 144, 67, 73, 66, 55, 47, 51, 68, 56, 0, 54, 56, 0, 0, 144, 47, 51, 43, 50, 0, 35, 43, 0, 0, 144, 82, 86, 30, 90, 94 } ; static yyconst short int yy_def[111] = { 0, 105, 1, 106, 106, 105, 105, 105, 105, 105, 107, 105, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 109, 105, 105, 109, 110, 105, 107, 105, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 109, 109, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 109, 105, 105, 108, 108, 108, 108, 108, 108, 108, 108, 105, 105, 108, 108, 108, 108, 108, 108, 105, 108, 108, 108, 108, 108, 108, 105, 108, 108, 108, 108, 108, 108, 108, 108, 108, 0, 105, 105, 105, 105, 105 } ; static yyconst short int yy_nxt[177] = { 0, 6, 7, 8, 7, 9, 10, 6, 6, 6, 11, 12, 6, 6, 6, 13, 12, 14, 15, 12, 16, 12, 17, 18, 19, 20, 12, 21, 22, 12, 12, 12, 23, 25, 32, 26, 25, 44, 26, 29, 29, 29, 27, 28, 45, 27, 28, 29, 29, 29, 34, 35, 41, 29, 29, 29, 42, 50, 70, 51, 70, 52, 104, 70, 53, 70, 103, 102, 101, 100, 54, 99, 98, 97, 55, 96, 95, 94, 56, 93, 57, 92, 58, 24, 24, 24, 24, 30, 91, 30, 30, 47, 90, 89, 47, 49, 49, 49, 49, 88, 87, 86, 85, 40, 84, 83, 82, 81, 80, 42, 79, 78, 77, 76, 75, 74, 73, 72, 71, 69, 42, 68, 67, 66, 40, 65, 64, 63, 62, 61, 60, 59, 31, 48, 46, 43, 40, 39, 38, 37, 36, 33, 31, 105, 5, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105 } ; static yyconst short int yy_chk[177] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 108, 3, 4, 22, 4, 7, 7, 7, 3, 3, 22, 4, 4, 8, 8, 8, 14, 14, 20, 29, 29, 29, 20, 28, 50, 28, 50, 28, 102, 70, 28, 70, 101, 99, 98, 97, 28, 96, 92, 91, 28, 89, 88, 87, 28, 86, 28, 85, 28, 106, 106, 106, 106, 107, 84, 107, 107, 109, 83, 82, 109, 110, 110, 110, 110, 80, 78, 77, 76, 75, 74, 73, 72, 71, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 53, 48, 46, 45, 44, 43, 41, 39, 38, 37, 36, 35, 34, 33, 31, 27, 23, 21, 19, 18, 17, 16, 15, 13, 11, 5, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105 } ; static yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr; static char *yy_full_match; static int yy_lp; #define REJECT \ { \ *yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \ yy_cp = yy_full_match; /* restore poss. backed-over text */ \ ++yy_lp; \ goto find_rule; \ } #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET char *yytext; #line 1 "aux-item-def-scan.l" #define INITIAL 0 #line 2 "aux-item-def-scan.l" /* * $Id: aux-item-def-scan.l,v 1.7 2003/08/23 16:38:18 ceder Exp $ * Copyright (C) 1994-1996, 1999, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ #ifdef HAVE_CONFIG_H # include #endif #include #include /* Rename hack from the automake 1.4 manual. */ #define yymaxdepth aid_maxdepth #define yyparse aid_parse #define yylex aid_lex #define yyerror aid_error #define yylval aid_lval #define yychar aid_char #define yydebug aid_debug #define yypact aid_pact #define yyr1 aid_r1 #define yyr2 aid_r2 #define yydef aid_def #define yychk aid_chk #define yypgo aid_pgo #define yyact aid_act #define yyexca aid_exca #define yyerrflag aid_errflag #define yynerrs aid_nerrs #define yyps aid_ps #define yypv aid_pv #define yys aid_s #define yy_yys aid_yys #define yystate aid_state #define yytmp aid_tmp #define yyv aid_v #define yy_yyv aid_yyv #define yyval aid_val #define yylloc aid_lloc #define yyreds aid_reds #define yytoks aid_toks #define yylhs aid_yylhs #define yylen aid_yylen #define yydefred aid_yydefred #define yydgoto aid_yydgoto #define yysindex aid_yysindex #define yyrindex aid_yyrindex #define yygindex aid_yygindex #define yytable aid_yytable #define yycheck aid_yycheck #define yyname aid_yyname #define yyrule aid_yyrule extern int yylex(void); #include "s-string.h" #include "aux-item-def-parse.h" #include "server/smalloc.h" #if defined(HAVE_VFPRINTF) && defined(HAVE_STDARG_H) void yyerror(const char * format, int lineno, ...) # if HAVE_ATTRIBUTE_FORMAT_PRINTF __attribute__ ((format (printf, 1, 3))) # endif ; #else void yyerror(); #endif static String stringBuffer = EMPTY_STRING_i; extern YYLTYPE yylloc; extern int aux_item_def_error_line; #define RETURN aux_item_def_error_line = yylineno; return #define string 1 #line 564 "aux-item-def-scan.c" /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap YY_PROTO(( void )); #else extern int yywrap YY_PROTO(( void )); #endif #endif #ifndef YY_NO_UNPUT static void yyunput YY_PROTO(( int c, char *buf_ptr )); #endif #ifndef yytext_ptr static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen YY_PROTO(( yyconst char * )); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput YY_PROTO(( void )); #else static int input YY_PROTO(( void )); #endif #endif #if YY_STACK_USED static int yy_start_stack_ptr = 0; static int yy_start_stack_depth = 0; static int *yy_start_stack = 0; #ifndef YY_NO_PUSH_STATE static void yy_push_state YY_PROTO(( int new_state )); #endif #ifndef YY_NO_POP_STATE static void yy_pop_state YY_PROTO(( void )); #endif #ifndef YY_NO_TOP_STATE static int yy_top_state YY_PROTO(( void )); #endif #else #define YY_NO_PUSH_STATE 1 #define YY_NO_POP_STATE 1 #define YY_NO_TOP_STATE 1 #endif #ifdef YY_MALLOC_DECL YY_MALLOC_DECL #else #if __STDC__ #ifndef __cplusplus #include #endif #else /* Just try to get by without declaring the routines. This will fail * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) * or sizeof(void*) != sizeof(int). */ #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( yy_current_buffer->yy_is_interactive ) \ { \ int c = '*', n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) #endif /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL int yylex YY_PROTO(( void )) #endif /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; #line 105 "aux-item-def-scan.l" #line 718 "aux-item-def-scan.c" if ( yy_init ) { yy_init = 0; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! yy_start ) yy_start = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! yy_current_buffer ) yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); yy_load_buffer_state(); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = yy_c_buf_p; /* Support of yytext. */ *yy_cp = yy_hold_char; /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = yy_start; yy_state_ptr = yy_state_buf; *yy_state_ptr++ = yy_current_state; yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 106 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; *yy_state_ptr++ = yy_current_state; ++yy_cp; } while ( yy_base[yy_current_state] != 144 ); yy_find_action: yy_current_state = *--yy_state_ptr; yy_lp = yy_accept[yy_current_state]; find_rule: /* we branch to this label when backing up */ for ( ; ; ) /* until we find what rule we matched */ { if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] ) { yy_act = yy_acclist[yy_lp]; { yy_full_match = yy_cp; break; } } --yy_cp; yy_current_state = *--yy_state_ptr; yy_lp = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; if ( yy_act != YY_END_OF_BUFFER ) { int yyl; for ( yyl = 0; yyl < yyleng; ++yyl ) if ( yytext[yyl] == '\n' ) ++yylineno; } do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 1: YY_RULE_SETUP #line 107 "aux-item-def-scan.l" { yylval.num = 1; yylloc.first_line = yylineno; RETURN BOOLEAN; } YY_BREAK case 2: YY_RULE_SETUP #line 112 "aux-item-def-scan.l" { yylval.num = 0; yylloc.first_line = yylineno; RETURN BOOLEAN; } YY_BREAK case 3: YY_RULE_SETUP #line 117 "aux-item-def-scan.l" { yylloc.first_line = yylineno; RETURN DISABLED; } YY_BREAK case 4: YY_RULE_SETUP #line 121 "aux-item-def-scan.l" { yylloc.first_line = yylineno; RETURN TEXT; } YY_BREAK case 5: YY_RULE_SETUP #line 125 "aux-item-def-scan.l" { yylloc.first_line = yylineno; RETURN CONFERENCE; } YY_BREAK case 6: YY_RULE_SETUP #line 129 "aux-item-def-scan.l" { yylloc.first_line = yylineno; RETURN LETTERBOX; } YY_BREAK case 7: YY_RULE_SETUP #line 133 "aux-item-def-scan.l" { yylloc.first_line = yylineno; RETURN TOK_SERVER; } YY_BREAK case 8: YY_RULE_SETUP #line 137 "aux-item-def-scan.l" { yylloc.first_line = yylineno; RETURN TOK_ANY; } YY_BREAK case 9: YY_RULE_SETUP #line 141 "aux-item-def-scan.l" { yylloc.first_line = yylineno; RETURN CREATE; } YY_BREAK case 10: YY_RULE_SETUP #line 146 "aux-item-def-scan.l" { yylloc.first_line = yylineno; RETURN MODIFY; } YY_BREAK case 11: YY_RULE_SETUP #line 152 "aux-item-def-scan.l" /* Eat comments */ YY_BREAK case 12: YY_RULE_SETUP #line 153 "aux-item-def-scan.l" /* Eat whitespace */ YY_BREAK case 13: YY_RULE_SETUP #line 155 "aux-item-def-scan.l" { char *s = yytext; do { *s=tolower(*s); } while(*(++s)); yylval.str = EMPTY_STRING; s_crea_str(&yylval.str, yytext); yylloc.first_line = yylineno; RETURN ID; } YY_BREAK case 14: YY_RULE_SETUP #line 164 "aux-item-def-scan.l" { yylloc.first_line = yylineno; yylval.num = atoi(yytext); RETURN NUMBER; } YY_BREAK case 15: YY_RULE_SETUP #line 170 "aux-item-def-scan.l" { BEGIN(string); stringBuffer = EMPTY_STRING; yylloc.first_line = yylineno; } YY_BREAK case 16: YY_RULE_SETUP #line 177 "aux-item-def-scan.l" /* Concatenate strings */ YY_BREAK case 17: YY_RULE_SETUP #line 178 "aux-item-def-scan.l" { BEGIN(INITIAL); yylval.str = stringBuffer; stringBuffer = EMPTY_STRING; RETURN STRING; } YY_BREAK case 18: YY_RULE_SETUP #line 184 "aux-item-def-scan.l" { unsigned int tmp; sscanf(yytext+1, "%o", &tmp); if (tmp > 255) s_strcat(&stringBuffer, s_fcrea_str(yytext)); else { sprintf(yytext, "%c", (unsigned char)tmp); yytext[1] = '\0'; s_strcat(&stringBuffer, s_fcrea_str(yytext)); } } YY_BREAK case 19: YY_RULE_SETUP #line 199 "aux-item-def-scan.l" s_strcat(&stringBuffer, s_fcrea_str("\n")); YY_BREAK case 20: YY_RULE_SETUP #line 200 "aux-item-def-scan.l" s_strcat(&stringBuffer, s_fcrea_str("\t")); YY_BREAK case 21: YY_RULE_SETUP #line 201 "aux-item-def-scan.l" s_strcat(&stringBuffer, s_fcrea_str("\r")); YY_BREAK case 22: YY_RULE_SETUP #line 202 "aux-item-def-scan.l" s_strcat(&stringBuffer, s_fcrea_str("\b")); YY_BREAK case 23: YY_RULE_SETUP #line 203 "aux-item-def-scan.l" s_strcat(&stringBuffer, s_fcrea_str("\f")); YY_BREAK case 24: YY_RULE_SETUP #line 204 "aux-item-def-scan.l" s_strcat(&stringBuffer, s_fcrea_str("\'")); YY_BREAK case 25: YY_RULE_SETUP #line 205 "aux-item-def-scan.l" s_strcat(&stringBuffer, s_fcrea_str("\"")); YY_BREAK case 26: YY_RULE_SETUP #line 206 "aux-item-def-scan.l" /* Eat escaped whitespace */ YY_BREAK case 27: YY_RULE_SETUP #line 207 "aux-item-def-scan.l" s_strcat(&stringBuffer, s_fcrea_str(yytext+1)); YY_BREAK case 28: YY_RULE_SETUP #line 208 "aux-item-def-scan.l" s_strcat(&stringBuffer, s_fcrea_str(yytext)); YY_BREAK case 29: YY_RULE_SETUP #line 209 "aux-item-def-scan.l" { yyerror("unterminated string", yylloc.first_line); RETURN VOID; } YY_BREAK case 30: YY_RULE_SETUP #line 216 "aux-item-def-scan.l" RETURN yytext[0]; YY_BREAK case 31: YY_RULE_SETUP #line 218 "aux-item-def-scan.l" ECHO; YY_BREAK #line 1037 "aux-item-def-scan.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(string): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = yy_hold_char; YY_RESTORE_YY_MORE_OFFSET if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between yy_current_buffer and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ yy_n_chars = yy_current_buffer->yy_n_chars; yy_current_buffer->yy_input_file = yyin; yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) { /* This was really a NUL. */ yy_state_type yy_next_state; yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state(); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = yytext_ptr + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++yy_c_buf_p; yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = yy_c_buf_p; goto yy_find_action; } } else switch ( yy_get_next_buffer() ) { case EOB_ACT_END_OF_FILE: { yy_did_buffer_switch_on_eof = 0; if ( yywrap() ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! yy_did_buffer_switch_on_eof ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state(); yy_cp = yy_c_buf_p; yy_bp = yytext_ptr + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: yy_c_buf_p = &yy_current_buffer->yy_ch_buf[yy_n_chars]; yy_current_state = yy_get_previous_state(); yy_cp = yy_c_buf_p; yy_bp = yytext_ptr + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer() { register char *dest = yy_current_buffer->yy_ch_buf; register char *source = yytext_ptr; register int number_to_move, i; int ret_val; if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( yy_current_buffer->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ yy_current_buffer->yy_n_chars = yy_n_chars = 0; else { int num_to_read = yy_current_buffer->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ #ifdef YY_USES_REJECT YY_FATAL_ERROR( "input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); #else /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = yy_current_buffer; int yy_c_buf_p_offset = (int) (yy_c_buf_p - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yy_flex_realloc( (void *) b->yy_ch_buf, b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = yy_current_buffer->yy_buf_size - number_to_move - 1; #endif } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), yy_n_chars, num_to_read ); yy_current_buffer->yy_n_chars = yy_n_chars; } if ( yy_n_chars == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; yy_current_buffer->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; yy_n_chars += number_to_move; yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state() { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = yy_start; yy_state_ptr = yy_state_buf; *yy_state_ptr++ = yy_current_state; for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 106 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; *yy_state_ptr++ = yy_current_state; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ #ifdef YY_USE_PROTOS static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) #else static yy_state_type yy_try_NUL_trans( yy_current_state ) yy_state_type yy_current_state; #endif { register int yy_is_jam; register YY_CHAR yy_c = 1; while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 106 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 105); if ( ! yy_is_jam ) *yy_state_ptr++ = yy_current_state; return yy_is_jam ? 0 : yy_current_state; } #ifndef YY_NO_UNPUT #ifdef YY_USE_PROTOS static void yyunput( int c, register char *yy_bp ) #else static void yyunput( c, yy_bp ) int c; register char *yy_bp; #endif { register char *yy_cp = yy_c_buf_p; /* undo effects of setting up yytext */ *yy_cp = yy_hold_char; if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register int number_to_move = yy_n_chars + 2; register char *dest = &yy_current_buffer->yy_ch_buf[ yy_current_buffer->yy_buf_size + 2]; register char *source = &yy_current_buffer->yy_ch_buf[number_to_move]; while ( source > yy_current_buffer->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); yy_current_buffer->yy_n_chars = yy_n_chars = yy_current_buffer->yy_buf_size; if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; if ( c == '\n' ) --yylineno; yytext_ptr = yy_bp; yy_hold_char = *yy_cp; yy_c_buf_p = yy_cp; } #endif /* ifndef YY_NO_UNPUT */ #ifdef __cplusplus static int yyinput() #else static int input() #endif { int c; *yy_c_buf_p = yy_hold_char; if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) /* This was really a NUL. */ *yy_c_buf_p = '\0'; else { /* need more input */ int offset = yy_c_buf_p - yytext_ptr; ++yy_c_buf_p; switch ( yy_get_next_buffer() ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin ); /* fall through */ case EOB_ACT_END_OF_FILE: { if ( yywrap() ) return EOF; if ( ! yy_did_buffer_switch_on_eof ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: yy_c_buf_p = yytext_ptr + offset; break; } } } c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ *yy_c_buf_p = '\0'; /* preserve yytext */ yy_hold_char = *++yy_c_buf_p; if ( c == '\n' ) ++yylineno; return c; } #ifdef YY_USE_PROTOS void yyrestart( FILE *input_file ) #else void yyrestart( input_file ) FILE *input_file; #endif { if ( ! yy_current_buffer ) yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); yy_init_buffer( yy_current_buffer, input_file ); yy_load_buffer_state(); } #ifdef YY_USE_PROTOS void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) #else void yy_switch_to_buffer( new_buffer ) YY_BUFFER_STATE new_buffer; #endif { if ( yy_current_buffer == new_buffer ) return; if ( yy_current_buffer ) { /* Flush out information for old buffer. */ *yy_c_buf_p = yy_hold_char; yy_current_buffer->yy_buf_pos = yy_c_buf_p; yy_current_buffer->yy_n_chars = yy_n_chars; } yy_current_buffer = new_buffer; yy_load_buffer_state(); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ yy_did_buffer_switch_on_eof = 1; } #ifdef YY_USE_PROTOS void yy_load_buffer_state( void ) #else void yy_load_buffer_state() #endif { yy_n_chars = yy_current_buffer->yy_n_chars; yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; yyin = yy_current_buffer->yy_input_file; yy_hold_char = *yy_c_buf_p; } #ifdef YY_USE_PROTOS YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) #else YY_BUFFER_STATE yy_create_buffer( file, size ) FILE *file; int size; #endif { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file ); return b; } #ifdef YY_USE_PROTOS void yy_delete_buffer( YY_BUFFER_STATE b ) #else void yy_delete_buffer( b ) YY_BUFFER_STATE b; #endif { if ( ! b ) return; if ( b == yy_current_buffer ) yy_current_buffer = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yy_flex_free( (void *) b->yy_ch_buf ); yy_flex_free( (void *) b ); } #ifndef YY_ALWAYS_INTERACTIVE #ifndef YY_NEVER_INTERACTIVE extern int isatty YY_PROTO(( int )); #endif #endif #ifdef YY_USE_PROTOS void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) #else void yy_init_buffer( b, file ) YY_BUFFER_STATE b; FILE *file; #endif { yy_flush_buffer( b ); b->yy_input_file = file; b->yy_fill_buffer = 1; #if YY_ALWAYS_INTERACTIVE b->yy_is_interactive = 1; #else #if YY_NEVER_INTERACTIVE b->yy_is_interactive = 0; #else b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; #endif #endif } #ifdef YY_USE_PROTOS void yy_flush_buffer( YY_BUFFER_STATE b ) #else void yy_flush_buffer( b ) YY_BUFFER_STATE b; #endif { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == yy_current_buffer ) yy_load_buffer_state(); } #ifndef YY_NO_SCAN_BUFFER #ifdef YY_USE_PROTOS YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) #else YY_BUFFER_STATE yy_scan_buffer( base, size ) char *base; yy_size_t size; #endif { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return 0; b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = 0; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer( b ); return b; } #endif #ifndef YY_NO_SCAN_STRING #ifdef YY_USE_PROTOS YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) #else YY_BUFFER_STATE yy_scan_string( yy_str ) yyconst char *yy_str; #endif { int len; for ( len = 0; yy_str[len]; ++len ) ; return yy_scan_bytes( yy_str, len ); } #endif #ifndef YY_NO_SCAN_BYTES #ifdef YY_USE_PROTOS YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) #else YY_BUFFER_STATE yy_scan_bytes( bytes, len ) yyconst char *bytes; int len; #endif { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = len + 2; buf = (char *) yy_flex_alloc( n ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < len; ++i ) buf[i] = bytes[i]; buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer( buf, n ); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #endif #ifndef YY_NO_PUSH_STATE #ifdef YY_USE_PROTOS static void yy_push_state( int new_state ) #else static void yy_push_state( new_state ) int new_state; #endif { if ( yy_start_stack_ptr >= yy_start_stack_depth ) { yy_size_t new_size; yy_start_stack_depth += YY_START_STACK_INCR; new_size = yy_start_stack_depth * sizeof( int ); if ( ! yy_start_stack ) yy_start_stack = (int *) yy_flex_alloc( new_size ); else yy_start_stack = (int *) yy_flex_realloc( (void *) yy_start_stack, new_size ); if ( ! yy_start_stack ) YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); } yy_start_stack[yy_start_stack_ptr++] = YY_START; BEGIN(new_state); } #endif #ifndef YY_NO_POP_STATE static void yy_pop_state() { if ( --yy_start_stack_ptr < 0 ) YY_FATAL_ERROR( "start-condition stack underflow" ); BEGIN(yy_start_stack[yy_start_stack_ptr]); } #endif #ifndef YY_NO_TOP_STATE static int yy_top_state() { return yy_start_stack[yy_start_stack_ptr - 1]; } #endif #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif #ifdef YY_USE_PROTOS static void yy_fatal_error( yyconst char msg[] ) #else static void yy_fatal_error( msg ) char msg[]; #endif { (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ yytext[yyleng] = yy_hold_char; \ yy_c_buf_p = yytext + n; \ yy_hold_char = *yy_c_buf_p; \ *yy_c_buf_p = '\0'; \ yyleng = n; \ } \ while ( 0 ) /* Internal utility routines. */ #ifndef yytext_ptr #ifdef YY_USE_PROTOS static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) #else static void yy_flex_strncpy( s1, s2, n ) char *s1; yyconst char *s2; int n; #endif { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN #ifdef YY_USE_PROTOS static int yy_flex_strlen( yyconst char *s ) #else static int yy_flex_strlen( s ) yyconst char *s; #endif { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif #ifdef YY_USE_PROTOS static void *yy_flex_alloc( yy_size_t size ) #else static void *yy_flex_alloc( size ) yy_size_t size; #endif { return (void *) malloc( size ); } #ifdef YY_USE_PROTOS static void *yy_flex_realloc( void *ptr, yy_size_t size ) #else static void *yy_flex_realloc( ptr, size ) void *ptr; yy_size_t size; #endif { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } #ifdef YY_USE_PROTOS static void yy_flex_free( void *ptr ) #else static void yy_flex_free( ptr ) void *ptr; #endif { free( ptr ); } #if YY_MAIN int main() { yylex(); return 0; } #endif #line 218 "aux-item-def-scan.l" lyskom-server-2.1.2/src/server/local-to-global.c0000664000015100472110000010630107721716127015241 /* * File: local_to_global.c * * Copyright 1996-1999, 2001-2003 Inge Wallin, Per Cederqvist */ #ifdef HAVE_CONFIG_H # include #endif #include #ifdef HAVE_STDLIB_H # include #endif #ifndef NULL # include #endif #include #include "timewrap.h" #include "s-string.h" #include "kom-types.h" #include "local-to-global.h" #include "log.h" #include "ram-parse.h" #include "ram-output.h" #include "lyskomd.h" #include "server/smalloc.h" /* The test suite requires L2G_BLOCKSIZE to be 10, but that small blocks will result in far too much malloc-overhead. A value of at least 100 is probably needed for reasonable performance. The user can call l2g_set_block_size to set this to a reasonable value. */ static int L2G_BLOCKSIZE = -1; struct l2g_block_info { /* An index into key_block and value_block that indicates the first free spot. This can also be thought of as the number of entries in key_block and value_block that are actually in use. */ int first_free; /* Number of entries in the block that contain the value 0. For purposes of calculating this value, data past the end of the block is counted as zeroes, so that this->first_free + this->zeroes is always at least L2G_BLOCKSIZE. */ int zeroes; /* First local text no in this block. Note: this does not increase if the first entry of the block is removed. */ Local_text_no start; /* NULL if this is a dense block, or a block of L2G_BLOCKSIZE Local_text_nos if this is a sparse block. */ Local_text_no *key_block; /* A block of L2G_BLOCKSIZE Text_nos. */ Text_no *value_block; }; static long nr_constructs = 0; static long nr_l2gs = 0; static long nr_l2gs_peak = 0; static long nr_destructs = 0; static long nr_clears = 0; static long nr_copies = 0; static long nr_joins = 0; static long nr_joined_blocks = 0; static long nr_blocks = 0; static long nr_blocks_peak = 0; static long nr_blocks_sparse = 0; static long nr_blocks_sparse_peak = 0; static long sparse_skip_cost = 0; static long nr_sparse_compactions = 0; static long nr_sparsifications = 0; /* ================================================================ */ /* ==== Static functions ==== */ /* ================================================================ */ static inline int is_dense(const struct l2g_block_info *binfo) { return binfo->key_block == NULL; } static inline int is_empty(const struct l2g_block_info *binfo) { return binfo->zeroes == L2G_BLOCKSIZE; } static inline Local_text_no key_value(const struct l2g_block_info *binfo, int index) { if (is_dense(binfo)) return binfo->start + index; else return binfo->key_block[index]; } static inline int sparse_skip_deleted(const struct l2g_block_info *binfo, int i) { while (i < binfo->first_free && binfo->value_block[i] == 0) { ++sparse_skip_cost; ++i; } return i; } /* Search for LNO in BINFO, and return the index for it. BINFO must be a non-empty sparse block. If LNO isn't present in the block this will return the index of next higher entry. If LNO is larger than the last entry, the index past the largest entry will be returned. This function never returns the index of a deleted entry. */ static inline int sparse_locate_value(const struct l2g_block_info *binfo, Local_text_no lno) { int i; assert(!is_empty(binfo)); assert(!is_dense(binfo)); /* We could to this as a binary search instead, but since a block is fairly small, it isn't certain that it would be a gain. If profiling shows that this is a hot spot, a binary search should be tried. */ for (i = 0; i < binfo->first_free && binfo->key_block[i] < lno; ++i) continue; /* Skip any lingering deleted entries. */ i = sparse_skip_deleted(binfo, i); assert(i == binfo->first_free || binfo->key_block[i] >= lno); assert(i == binfo->first_free || binfo->value_block[i] != 0); return i; } static void sparse_compact(struct l2g_block_info *binfo) { int from, to; if (binfo->first_free + binfo->zeroes == L2G_BLOCKSIZE) return; assert(binfo->first_free + binfo->zeroes > L2G_BLOCKSIZE); for (from = to = 0; from < binfo->first_free; ++from) if (binfo->value_block[from] != 0) { if (from != to) { binfo->value_block[to] = binfo->value_block[from]; binfo->key_block[to] = binfo->key_block[from]; } ++to; } binfo->first_free = to; assert(binfo->first_free + binfo->zeroes == L2G_BLOCKSIZE); ++nr_sparse_compactions; } /* * Add a new block to the Local_to_global L2G. * Since we always add consecutively, we always start out by making * a new block dense. * * Return a pointer to the newly created block info. */ static struct l2g_block_info * add_block(Local_to_global *l2g) { struct l2g_block_info * binfo; #ifndef NDEBUG int i; #endif /* Realloc the block pointer array. */ l2g->num_blocks++; l2g->blocks = srealloc(l2g->blocks, l2g->num_blocks * sizeof(struct l2g_block_info)); /* Create a new block info and fill it in. */ binfo = &(l2g->blocks[l2g->num_blocks - 1]); binfo->first_free = 0; binfo->zeroes = L2G_BLOCKSIZE; #ifndef NDEBUG binfo->start = 0xdeadbeef; #endif binfo->key_block = NULL; binfo->value_block = smalloc(L2G_BLOCKSIZE * sizeof(Text_no)); #ifndef NDEBUG for (i = 0; i < L2G_BLOCKSIZE; ++i) binfo->value_block[i] = 0xdeadbeef; #endif if (++nr_blocks > nr_blocks_peak) nr_blocks_peak = nr_blocks; return binfo; } /* Insert a new block in the middle of an l2g structure. This is only used by l2g_expensive_set, so it doesn't have to be optimally efficient. */ static void add_block_before(Local_to_global *l2g, int position) { struct l2g_block_info * binfo; struct l2g_block_info * new_blocks; int ix; /* Allocate a new block pointer array. */ new_blocks = smalloc((l2g->num_blocks+1) * sizeof(struct l2g_block_info)); /* Copy blocks before and after position. */ for (ix = 0; ix < position; ix++) new_blocks[ix] = l2g->blocks[ix]; for (ix = position; ix < l2g->num_blocks; ix++) new_blocks[ix+1] = l2g->blocks[ix]; /* Discard the old block pointers. */ sfree(l2g->blocks); l2g->blocks = new_blocks; l2g->num_blocks++; /* Initialize the new block. */ binfo = &new_blocks[position]; binfo->first_free = 0; binfo->zeroes = L2G_BLOCKSIZE; #ifndef NDEBUG binfo->start = 0xdeadbeef; #endif binfo->key_block = NULL; binfo->value_block = smalloc(L2G_BLOCKSIZE * sizeof(Text_no)); #ifndef NDEBUG for (ix = 0; ix < L2G_BLOCKSIZE; ++ix) binfo->value_block[ix] = 0xdeadbeef; #endif if (++nr_blocks > nr_blocks_peak) nr_blocks_peak = nr_blocks; } /* * Delete a block from the Local_to_global L2G. The pointer BINFO * points at the block, which is supposed to be empty. */ static void delete_block(Local_to_global *l2g, struct l2g_block_info *binfo) { assert(is_empty(binfo)); if (!is_dense(binfo)) --nr_blocks_sparse; --nr_blocks; /* Remove the blocks from the Block Info */ if (binfo->key_block != NULL) sfree(binfo->key_block); sfree(binfo->value_block); /* Compact the remaining blocks. */ while (++binfo < l2g->blocks + l2g->num_blocks) *(binfo - 1) = *binfo; l2g->num_blocks--; l2g->blocks = srealloc(l2g->blocks, l2g->num_blocks * sizeof(struct l2g_block_info)); } /* * Make a sparse block from a dense one. */ static void make_sparse(struct l2g_block_info *binfo) { int next; int i; assert(is_dense(binfo)); if (++nr_blocks_sparse > nr_blocks_sparse_peak) nr_blocks_sparse_peak = nr_blocks_sparse; ++nr_sparsifications; /* Allocate the room for the key block. */ binfo->key_block = smalloc(L2G_BLOCKSIZE * sizeof(Local_text_no)); #ifndef NDEBUG for (i = 0; i < L2G_BLOCKSIZE; ++i) binfo->key_block[i] = (Local_text_no)0xdeadbeefUL; #endif /* Compact the block. */ next = 0; for (i = 0; i < binfo->first_free; ++i) if (binfo->value_block[i] != 0) { binfo->key_block[next] = binfo->start + i; binfo->value_block[next] = binfo->value_block[i]; next++; } /* Set the rest of the fields. */ binfo->first_free = next; binfo->zeroes = L2G_BLOCKSIZE - next; } /* * Find the block where the local text no LNO should be and return a * pointer to it. Returning a pointer does not necessarily mean that * the text exists, so a search within the block must also be done * later. If LNO is smaller than the smallest number in the structure * a pointer to the first block will be returned. If LNO is larger * than the largest number in the structure a pointer to the last * block will be returned. * * Return NULL if (and only if) the structure is empty. */ static struct l2g_block_info * find_block(const Local_to_global *l2g, Local_text_no lno) { struct l2g_block_info * binfo; /* If empty, the number can not be in here. */ if (l2g->num_blocks == 0) return NULL; /* Let binfo point to the last block. */ binfo = &(l2g->blocks[l2g->num_blocks - 1]); /* Find the block where lno *could* be. */ /* FIXME (bug 152): Binary search? */ while (binfo > l2g->blocks) { if (lno >= binfo->start) return binfo; binfo--; } return binfo; } /* Find the first local text number higher than LNO and return it. Return 0 if LNO is higher than any local text number in the structure. The block where the returned value was found is stored in BINFO_OUT, and the position within the block is stored in INDEX_OUT. BINFO_OUT and INDEX_OUT are only filled in if the return value is non-zero. */ static Local_text_no find_block_index_key(const Local_to_global *l2g, Local_text_no lno, const struct l2g_block_info **binfo_out, int *index_out) { const struct l2g_block_info * binfo; int i; /* If the number is not to be found, return 0. */ binfo = find_block(l2g, lno); if (binfo == NULL) return 0; /* If lno is lower than the first existing entry, return the first existing entry. The search in the first block is performed the same way as when no entry was found after LNO in binfo. */ if (lno >= binfo->start) { /* Check the found block. See if there is another entry after the entry for LNO. If so, return it. */ if (is_dense(binfo)) { for (i = lno - binfo->start + 1; i < binfo->first_free; ++i) if (binfo->value_block[i] != 0) { *binfo_out = binfo; *index_out = i; return binfo->start + i; } } else { i = sparse_locate_value(binfo, lno); if (i < binfo->first_free && binfo->key_block[i] == lno) ++i; i = sparse_skip_deleted(binfo, i); if (i < binfo->first_free) { *binfo_out = binfo; *index_out = i; return binfo->key_block[i]; } } /* * If the block didn't contain anything more, try the next * block, if there is one. */ binfo++; } /* * We want the first existing entry in the block that binfo points * to. However, binfo may point past the last block. */ if (binfo >= l2g->blocks + l2g->num_blocks) return 0; for (i = 0; i < binfo->first_free; ++i) if (binfo->value_block[i] != 0) { *binfo_out = binfo; *index_out = i; return key_value(binfo, i); } restart_kom("find_block_index_key found nothing\n"); } /* Find the first local text number lower than LNO and return it. Return 0 if LNO is lower than any local text number in the structure. The block where the returned value was found is stored in BINFO_OUT, and the position within the block is stored in INDEX_OUT. BINFO_OUT and INDEX_OUT are only filled in if the return value is non-zero. */ static Local_text_no find_block_index_key_reverse(const Local_to_global *l2g, Local_text_no lno, const struct l2g_block_info **binfo_out, int *index_out) { const struct l2g_block_info *binfo; int i; /* Adjust lno to the local number we are hunting for. */ if (lno > 0) --lno; /* If the number is not to be found, return 0. */ binfo = find_block(l2g, lno); if (binfo == NULL) return 0; /* Check if not present in the first block. */ if (lno < binfo->start) return 0; /* Check the found block and return the last entry found, if any. */ if (is_dense(binfo)) { i = lno - binfo->start; if (i >= binfo->first_free) i = binfo->first_free - 1; for (; i >= 0; --i) if (binfo->value_block[i] != 0) { *binfo_out = binfo; *index_out = i; return binfo->start + i; } } else { i = sparse_locate_value(binfo, lno); if (i >= binfo->first_free) i = binfo->first_free - 1; while (i > 0 && (binfo->value_block[i] == 0 || binfo->key_block[i] > lno)) { ++sparse_skip_cost; --i; } if (binfo->value_block[i] != 0 && binfo->key_block[i] <= lno) { *binfo_out = binfo; *index_out = i; return binfo->key_block[i]; } } /* * Try the previous block, if there is one. */ if (binfo == l2g->blocks) return 0; binfo--; /* * We want the last existing entry in the block that binfo points * to. */ for (i = binfo->first_free - 1; i >= 0; --i) if (binfo->value_block[i] != 0) { *binfo_out = binfo; *index_out = i; return key_value(binfo, i); } restart_kom("find_block_index_key_reverse found nothing\n"); } static void join_range(Local_to_global *l2g, struct l2g_block_info *first, struct l2g_block_info *last) { int next; int i; struct l2g_block_info *binfo; assert(first < last); assert(l2g->blocks <= first && first < l2g->blocks + l2g->num_blocks); assert(l2g->blocks <= last && last < l2g->blocks + l2g->num_blocks); if (is_dense(first)) make_sparse(first); else sparse_compact(first); ++nr_joins; next = first->first_free; for (binfo = first + 1; binfo <= last; ++binfo) { ++nr_joined_blocks; for (i = 0; i < binfo->first_free; ++i) if (binfo->value_block[i] != 0) { first->value_block[next] = binfo->value_block[i]; first->key_block[next] = key_value(binfo, i); next++; } if (!is_dense(binfo)) { --nr_blocks_sparse; sfree(binfo->key_block); } sfree(binfo->value_block); } while (binfo < l2g->blocks + l2g->num_blocks) { assert(binfo - (last - first) > first); *(binfo - (last - first)) = *binfo; ++binfo; } assert(next <= L2G_BLOCKSIZE); first->first_free = next; first->zeroes = L2G_BLOCKSIZE - next; nr_blocks -= last - first; l2g->num_blocks -= last - first; l2g->blocks = srealloc(l2g->blocks, l2g->num_blocks * sizeof(struct l2g_block_info)); } static int join_blocks(Local_to_global *l2g, struct l2g_block_info *binfo) { int zeroes; int gain; int best; int i; if (binfo->zeroes == 0) /* This block is full. */ return 0; /* Note: on rare occasions we might be able to create one dense block from two (dense or sparse) blocks or one sparse block. We don't bother. The gain would probably be small, and it would complicate the algorithm significantly. */ zeroes = L2G_BLOCKSIZE; gain = 0; best = 0; for (i = 0; zeroes > 0 && i <= binfo - l2g->blocks; ++i) { zeroes -= (L2G_BLOCKSIZE - (binfo-i)->zeroes); gain += (is_dense(binfo-i) ? 1 : 2); if (gain > 2 && zeroes >= 0) best = i; } if (best > 0) { join_range(l2g, binfo - best, binfo); return 1; } zeroes = L2G_BLOCKSIZE; gain = 0; best = 0; for (i = 0; zeroes > 0 && i < l2g->num_blocks - (binfo - l2g->blocks); ++i) { zeroes -= (L2G_BLOCKSIZE - (binfo+i)->zeroes); gain += (is_dense(binfo+i) ? 1 : 2); if (gain > 2 && zeroes >= 0) best = i; } if (best > 0) { join_range(l2g, binfo, binfo + best); return 1; } return 0; } /* ================================================================ */ /* ==== Outside accessible functions ==== */ /* ================================================================ */ void l2g_set_block_size(int sz) { assert(L2G_BLOCKSIZE == -1); L2G_BLOCKSIZE = sz; } void l2g_destruct(Local_to_global *l2g) { l2g_clear(l2g); ++nr_destructs; --nr_l2gs; #ifndef NDEBUG l2g->num_blocks = 0xdeadbeef; l2g->first_unused = 0xdeadbeef; l2g->blocks = (void*)0xdeadbeef; #endif } void l2g_init(Local_to_global *l2g) { if (L2G_BLOCKSIZE == -1) L2G_BLOCKSIZE = 250; /* Initialize the main structure */ l2g->num_blocks = 0; l2g->first_unused = 1; l2g->blocks = NULL; ++nr_constructs; if (++nr_l2gs > nr_l2gs_peak) nr_l2gs_peak = nr_l2gs; } void l2g_clear(Local_to_global *l2g) { struct l2g_block_info * binfo; int i; /* Free the block info structures. */ binfo = l2g->blocks; for (i = 0; i < l2g->num_blocks; ++i) { if (binfo->key_block != NULL) { --nr_blocks_sparse; sfree(binfo->key_block); } sfree(binfo->value_block); binfo++; } nr_blocks -= l2g->num_blocks; /* Free the block pointers. */ l2g->num_blocks = 0; l2g->first_unused = 1; if (l2g->blocks != NULL) { sfree(l2g->blocks); l2g->blocks = NULL; } ++nr_clears; } /* * Copy everything from one l2g structure (FROM) into another (TO). * TO has to be an initialized structure. */ void l2g_copy(Local_to_global *dest, const Local_to_global *src) { const struct l2g_block_info *binfo; int i; /* FIXME (bug 153): More efficient code */ l2g_clear(dest); for (binfo = src->blocks; binfo < src->blocks + src->num_blocks; ++binfo) for (i = 0; i < binfo->first_free; ++i) l2g_append(dest, key_value(binfo, i), binfo->value_block[i]); assert(src->first_unused >= dest->first_unused); dest->first_unused = src->first_unused; ++nr_copies; } typedef Local_text_no Local_text_no_iter; void l2g_append(Local_to_global *l2g, Local_text_no lno, Text_no tno) { struct l2g_block_info * binfo; Local_text_no_iter ix; if (lno < l2g->first_unused) { kom_log("l2g_append: won't add %lu<%lu> when first_unused=%lu\n", (unsigned long)tno, (unsigned long)lno, (unsigned long)l2g->first_unused); return; } l2g->first_unused = lno + 1; /* Don't add anything if tno == 0. */ if (tno == 0) return; if (l2g->num_blocks == 0) { /* If totally empty, add the first block and set binfo to it. */ binfo = add_block(l2g); binfo->start = lno; } else { /* else let binfo point to the last block. */ binfo = &(l2g->blocks[l2g->num_blocks - 1]); } /* Try to make room for the new data in the last block (pointed to by binfo). If that fails, allocate a new block and let binfo point to it. */ if (is_dense(binfo)) { if (lno - binfo->start >= (Local_text_no)L2G_BLOCKSIZE) { /* The last block is a dense block, and this text does not fit in it. Or is there anything we can do to make it fit? */ if (binfo->zeroes >= L2G_BLOCKSIZE / 2) /* Arbitrary limit: make the block sparse if at least half of it contains zeroes. (Remeber that any unused entries past binfo->first_free are counted in binfo->zeroes). */ make_sparse(binfo); else /* There is no way to make room in the last block, so allocate a new one. (There *could* be ways to make this entry fit into the last block: if the next to last block is sparse and has room for an entry, we might be able to slide the last block, and fit in the new entry. However, we never move data between blocks. That would be too complex and error-prone, and the gain would be very small.) */ binfo = add_block(l2g); } } else { /* The last block was sparse. */ sparse_compact(binfo); if (binfo->first_free == L2G_BLOCKSIZE) binfo = add_block(l2g); } /* Enter the new value into the last block. */ if (binfo->first_free == 0) binfo->start = lno; if (is_dense(binfo)) { for (ix = binfo->first_free; ix < lno - binfo->start; ++ix) binfo->value_block[ix] = 0; binfo->value_block[lno - binfo->start] = tno; binfo->first_free = lno - binfo->start + 1; } else { binfo->key_block [binfo->first_free] = lno; binfo->value_block[binfo->first_free] = tno; binfo->first_free++; } binfo->zeroes--; } void l2g_expensive_set(Local_to_global *l2g, Local_text_no lno, Text_no tno) { struct l2g_block_info * binfo; Local_text_no_iter ix; int block_no; if (lno >= l2g->first_unused) { l2g_append(l2g, lno, tno); return; } if (tno == 0) { l2g_delete(l2g, lno); return; } binfo = find_block(l2g, lno); if (binfo == NULL) { assert(l2g->num_blocks == 0); /* Append a new block. */ binfo = add_block(l2g); assert(binfo->first_free == 0); assert(binfo->key_block == NULL); binfo->start = lno; binfo->value_block[0] = tno; binfo->first_free = 1; binfo->zeroes--; } else if (lno < binfo->start) { assert(binfo == l2g->blocks); /* Prepend a new block. */ add_block_before(l2g, 0); binfo = l2g->blocks; binfo->start = lno; binfo->value_block[0] = tno; binfo->first_free = 1; binfo->zeroes--; } else if (is_dense(binfo)) { assert(binfo->start <= lno); if (lno < binfo->start + L2G_BLOCKSIZE) { /* The number can be entered into this block. */ while (binfo->start + binfo->first_free <= lno) { binfo->value_block[binfo->first_free++] = 0; assert(binfo->first_free <= L2G_BLOCKSIZE); } assert(lno < binfo->start + binfo->first_free); assert(binfo->first_free <= L2G_BLOCKSIZE); if (binfo->value_block[lno - binfo->start] == 0) binfo->zeroes--; binfo->value_block[lno - binfo->start] = tno; } else { /* There is no room within this block. Insert a new block after binfo. */ block_no = 1 + binfo - l2g->blocks; add_block_before(l2g, block_no); binfo = l2g->blocks + block_no; binfo->start = lno; binfo->value_block[0] = tno; binfo->first_free = 1; binfo->zeroes--; } } else { ix = sparse_locate_value(binfo, lno); if (ix < (Local_text_no_iter)binfo->first_free && binfo->key_block[ix] == lno) { /* We found the value in this sparse block. */ assert(binfo->value_block[ix] != 0); binfo->value_block[ix] = tno; } else { if (binfo->zeroes == 0) { /* Split the sparse block to make room. */ block_no = 1 + binfo - l2g->blocks; add_block_before(l2g, block_no); binfo = l2g->blocks + block_no; assert(binfo[-1].first_free == L2G_BLOCKSIZE); if (lno > binfo[-1].key_block[L2G_BLOCKSIZE-1]) { /* Insert the mapping into the new block. */ binfo->start = lno; binfo->value_block[0] = tno; binfo->first_free = 1; binfo->zeroes--; return; } else { /* Move the last mapping from the block into the new block, and enter the new mapping into the old block. */ /* Set up the new block. */ binfo->start = binfo[-1].key_block[L2G_BLOCKSIZE-1]; binfo->value_block[0] = binfo[-1].value_block[ L2G_BLOCKSIZE-1]; binfo->first_free = 1; binfo->zeroes--; /* Fix the old block. */ binfo--; binfo->zeroes++; binfo->first_free--; /* The old block is now compact. Let the code below enter the new mapping into it. */ } assert(binfo->zeroes == 1); } else sparse_compact(binfo); /* There is room for a new mapping in this block. */ assert(binfo->zeroes > 0); for (ix = binfo->first_free; ix > 0; --ix) { assert(binfo->key_block[ix-1] != lno); if (binfo->key_block[ix-1] > lno) { binfo->key_block[ix] = binfo->key_block[ix-1]; binfo->value_block[ix] = binfo->value_block[ix-1]; } else break; } assert(ix == 0 || binfo->key_block[ix-1] < lno); assert(ix == (Local_text_no_iter)binfo->first_free || binfo->key_block[ix+1] > lno); binfo->key_block[ix] = lno; binfo->value_block[ix] = tno; binfo->first_free++; binfo->zeroes--; } } } /* * Delete the local text LNO from the structure L2G. */ void l2g_delete(Local_to_global *l2g, Local_text_no lno) { struct l2g_block_info *binfo; int i; /* Find block where LNO might be and return if not there. */ binfo = find_block(l2g, lno); if (binfo == NULL) return; /* Go through the block where it might be and delete LNO */ if (is_dense(binfo)) { if (binfo->start <= lno && lno < binfo->start + L2G_BLOCKSIZE) if (binfo->value_block[lno - binfo->start] != 0) { binfo->value_block[lno - binfo->start] = 0; binfo->zeroes++; } } else { i = sparse_locate_value(binfo, lno); if (i < binfo->first_free && binfo->key_block[i] == lno) { assert(binfo->value_block[i] != 0); /* See sparse_locate_value. */ binfo->value_block[i] = 0; binfo->zeroes++; } } /* Delete the block if it became empty. */ if (is_empty(binfo)) { delete_block(l2g, binfo); return; } /* Check if we can save space by joining adjoining blocks. */ if (!join_blocks(l2g, binfo)) /* Could not join. Compact this block if it is a sparse block with more than half of the entries zeroes. */ if (!is_dense(binfo) && binfo->zeroes + binfo->first_free/2 > L2G_BLOCKSIZE) { sparse_compact(binfo); } } Text_no l2g_lookup(const Local_to_global *l2g, Local_text_no lno) { const struct l2g_block_info * binfo; int i; binfo = find_block(l2g, lno); if (binfo == NULL) return 0; if (is_dense(binfo)) { if (binfo->start <= lno && lno < binfo->start + binfo->first_free) return binfo->value_block[lno - binfo->start]; } else { i = sparse_locate_value(binfo, lno); if (i < binfo->first_free && binfo->key_block[i] == lno) return binfo->value_block[i]; } return 0; } Local_text_no l2g_next_key(const Local_to_global *l2g, Local_text_no lno) { const struct l2g_block_info * binfo; int i; return find_block_index_key(l2g, lno, &binfo, &i); } Local_text_no l2g_first_appendable_key(const Local_to_global *l2g) { return l2g->first_unused; } void l2g_set_first_appendable_key(Local_to_global *l2g, Local_text_no key) { if (key < l2g->first_unused) { kom_log("l2g_append: won't decrease first_unused from %lu to %lu\n", (unsigned long)l2g->first_unused, (unsigned long)key); return; } l2g->first_unused = key; } void l2g_delete_global_in_sorted(Local_to_global *l2g, Text_no tno) { /* This implementation performs a linear search through the list, but since we know that both the key and the data are sorted in ascending order we could do a binary search instead. FIXME (bug 154): profile the code and se if it is worthwhile to implement something fancier. */ L2g_iterator iter; for (l2gi_searchall(&iter, l2g); !iter.search_ended; l2gi_next(&iter)) if (iter.tno == tno) { l2g_delete(l2g, iter.lno); return; } } void l2g_dump(FILE *file, const Local_to_global *l2g) { struct l2g_block_info * binfo; int i, j; fprintf(file, "Number of blocks: %d\n", l2g->num_blocks); fprintf(file, "First unused: %lu\n", l2g->first_unused); binfo = l2g->blocks; for (i = 0; i < l2g->num_blocks; ++i) { fprintf(file, "%d: %d %d %d (%s) [", i, binfo->first_free, binfo->zeroes, (int) binfo->start, (is_dense(binfo) ? "dense" : "sparse")); if (is_dense(binfo)) { for (j = 0; j < binfo->first_free; ++j) { fprintf(file, "%d ", (int) binfo->value_block[j]); } } else { for (j = 0; j < binfo->first_free; ++j) { fprintf(file, "%d:%d ", (int) binfo->key_block[j], (int) binfo->value_block[j]); } } fprintf(file, "]\n"); binfo++; } } Success l2g_read(FILE *fp, Local_to_global *l2g) { int c; Local_text_no lno = 0; Text_no tno; Local_text_no first_unused; l2g_clear(l2g); /* Read past the start marker */ fskipwhite(fp); if ( (c = getc(fp)) == EOF || c != '[') { kom_log("l2g_read() failed to find ``['' marker at pos %lu.\n", (unsigned long) ftell(fp)); return FAILURE; } first_unused = fparse_long(fp); /* Read numbers until the EOL (end-of-l2g :-) ) marker is read. */ while (1) { if ((c = getc(fp)) == EOF) { kom_log("l2g_read(): unexpected EOF at pos %lu.\n", (unsigned long) ftell(fp)); return FAILURE; } switch (c) { case ' ': lno = fparse_long(fp); if (lno == 0) { kom_log("l2g_read(): got local number 0 at pos %lu.\n", (unsigned long) ftell(fp)); return FAILURE; } break; case ',': if (lno == 0) { kom_log("l2g_read(): missing local number at pos %lu.\n", (unsigned long)ftell(fp)); return FAILURE; } ++lno; /*FALLTHROUGH*/ case ':': if (lno == 0) { kom_log("l2g_read(): missing local number at pos %lu.\n", (unsigned long)ftell(fp)); return FAILURE; } tno = fparse_long(fp); l2g_append(l2g, lno, tno); break; case ']': assert(first_unused >= l2g->first_unused); l2g->first_unused = first_unused; return OK; default: kom_log("l2g_read(): unexpected character ``%c'' at pos %lu.\n", c, (unsigned long) ftell(fp)); return FAILURE; } } } /* Write the unsigned long value ``l'' to ``fp''. */ static void put_ulong(unsigned long l, FILE *fp) { static char buf[sizeof(unsigned long) * 3 + 1]; char *cp; if (l < 10) putc("0123456789"[l], fp); else { cp = buf + sizeof(buf); while (l > 0) { *--cp = (l % 10) + '0'; l /= 10; } fwrite(cp, buf + sizeof(buf) - cp, 1, fp); } } void l2g_write(FILE *fp, const Local_to_global *l2g) { const struct l2g_block_info *binfo; int ix; Local_text_no key; Text_no val; Local_text_no current = 0; putc('[', fp); put_ulong(l2g->first_unused, fp); for (binfo = l2g->blocks; binfo < l2g->blocks + l2g->num_blocks; ++binfo) for (ix = 0; ix < binfo->first_free; ++ix) if ((val = binfo->value_block[ix]) != 0) { key = key_value(binfo, ix); if (key > current + 3 || current == 0) { putc(' ', fp); put_ulong(key, fp); putc(':', fp); put_ulong(val, fp); current = key; } else { while (++current < key) { putc(',', fp); putc('0', fp); } putc(',', fp); put_ulong(val, fp); } } putc(']', fp); } /* ================================================================ */ /* === Iterator code === */ /* ================================================================ */ void l2gi_searchall (L2g_iterator *l2gi, const Local_to_global *l2g) { l2gi_searchsome(l2gi, l2g, 1, 0); } void l2gi_searchsome(L2g_iterator *l2gi, const Local_to_global *l2g, Local_text_no begin, Local_text_no end) { const struct l2g_block_info * binfo; int index; if (begin < 1) { kom_log("l2gi_searchsome(%lu, %lu) called: min is 1\n", (unsigned long)begin, (unsigned long)end); begin = 1; } l2gi->l2g = l2g; l2gi->beginval = begin; l2gi->endval = end; l2gi->search_ended = 1; if (end != 0 && begin >= end) return; if (find_block_index_key(l2g, begin-1, &binfo, &index) == 0) return; l2gi->binfo = binfo; l2gi->arrindex = index; assert(binfo != NULL); l2gi->lno = key_value(binfo, index); l2gi->tno = binfo->value_block[index]; if (end == 0) l2gi->search_ended = 0; else l2gi->search_ended = l2gi->lno >= end; } void l2gi_next(L2g_iterator *l2gi) { const Local_to_global *l2g; const struct l2g_block_info *binfo; int arrindex; assert(!l2gi->search_ended); l2g = l2gi->l2g; arrindex = l2gi->arrindex + 1; for (binfo = l2gi->binfo; binfo < l2g->blocks + l2g->num_blocks; ++binfo, arrindex = 0) { for (; arrindex < binfo->first_free; ++arrindex) { if (l2gi->endval != 0 && key_value(binfo, arrindex) >= l2gi->endval) { l2gi->search_ended = 1; return; } if (binfo->value_block[arrindex] != 0) { l2gi->binfo = binfo; l2gi->arrindex = arrindex; l2gi->lno = key_value(binfo, arrindex); l2gi->tno = binfo->value_block[arrindex]; return; } } } l2gi->search_ended = 1; return; } Local_text_no l2gi_begin(const L2g_iterator *l2gi) { return l2gi->beginval; } Local_text_no l2gi_end(const L2g_iterator *l2gi) { return l2gi->endval; } /* ================================================================ */ /* === Reverse Iterator code === */ /* ================================================================ */ void l2gi_searchsome_reverse(L2g_reverse_iterator *l2gi, const Local_to_global *l2g, Local_text_no begin, Local_text_no end) { const struct l2g_block_info * binfo; int index; l2gi->l2g = l2g; l2gi->beginval = begin; l2gi->endval = end; l2gi->search_ended = 1; if (begin >= end) return; if (find_block_index_key_reverse(l2g, end, &binfo, &index) == 0) return; l2gi->binfo = binfo; l2gi->arrindex = index; assert(binfo != NULL); l2gi->lno = key_value(binfo, index); l2gi->tno = binfo->value_block[index]; l2gi->search_ended = l2gi->lno < begin; } void l2gi_prev(L2g_reverse_iterator *l2gi) { const Local_to_global *l2g; const struct l2g_block_info *binfo; int arrindex; assert(!l2gi->search_ended); l2g = l2gi->l2g; arrindex = l2gi->arrindex - 1; binfo = l2gi->binfo; while (1) { for (; arrindex >= 0; --arrindex) { if (key_value(binfo, arrindex) < l2gi->beginval) { l2gi->search_ended = 1; return; } if (binfo->value_block[arrindex] != 0) { l2gi->binfo = binfo; l2gi->arrindex = arrindex; l2gi->lno = key_value(binfo, arrindex); l2gi->tno = binfo->value_block[arrindex]; return; } } if (binfo == l2g->blocks) { l2gi->search_ended = 1; return; } --binfo; arrindex = binfo->first_free - 1; } } /* ---------- */ extern void dump_l2g_stats(FILE *file) { fprintf(file, "---%s:\n\tExisting l2gs: %ld\n", __FILE__, nr_l2gs); fprintf(file, "\tExisting sparse blocks: %ld\n", nr_blocks_sparse); fprintf(file, "\tExisting blocks (total): %ld\n", nr_blocks); fprintf(file, "\tPeak l2gs: %ld\n", nr_l2gs_peak); fprintf(file, "\tPeak sparse blocks: %ld\n", nr_blocks_sparse_peak); fprintf(file, "\tPeak blocks (total): %ld\n", nr_blocks_peak); fprintf(file, "\tctor calls: %ld\n", nr_constructs); fprintf(file, "\tdtor calls: %ld\n", nr_destructs); fprintf(file, "\tclear calls: %ld\n", nr_clears); fprintf(file, "\tcopy calls: %ld\n", nr_copies); fprintf(file, "\tjoin operations: %ld\n", nr_joins); fprintf(file, "\tjoined blocks: %ld\n", nr_joined_blocks); fprintf(file, "\tsparse skip cost: %ld\n", sparse_skip_cost); fprintf(file, "\tsparse compactions: %ld\n", nr_sparse_compactions); fprintf(file, "\tsparsifications: %ld\n", nr_sparsifications); } lyskom-server-2.1.2/src/server/ram-parse.c0000664000015100472110000012110207723506147014155 /* * $Id: ram-parse.c,v 0.58 2003/08/28 23:11:02 ceder Exp $ * Copyright (C) 1991, 1993-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * ram-parse.c -- parse objects from disk file. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #ifdef HAVE_STRING_H # include #endif #include "timewrap.h" #include #include "s-string.h" #include "kom-types.h" #include "ram-parse.h" #include "log.h" #include "lyskomd.h" #include "server/smalloc.h" #include "kom-errno.h" #include "kom-memory.h" #include "local-to-global.h" static int input_format = 2; static Success fparse_text_list(FILE *fp, Local_to_global *result); void set_input_format(int fmt) { input_format = fmt; switch(fmt) { case 0: case 1: case 2: break; default: restart_kom("unknown input format selected: %d\n", fmt); break; } } /* * FIXME (bug 340): Not all functions are needed. * FIXME (bug 341): The method for checking errors in fparse_long is * ugly, and not all callers check for errors properly. */ #define REALLOC(ptr, size) srealloc(ptr, size) static int fparse_long_errors = 0; void fskipwhite(FILE *fp) { int c; while ( (c = getc(fp)) != EOF && /* isascii(c) && */ isspace(c) ) ; ungetc(c, fp); } extern unsigned long fparse_long(FILE *fp) { unsigned long res = 0; int foo = 0; int c; fskipwhite(fp); while ( (c = getc(fp)) != EOF && /* isascii(c) && */ isdigit(c)) { foo = 1; res = 10 * res + c - '0'; } if ( foo == 0 ) { kom_log("fparse_long() failed at pos %lu.\n", (unsigned long)ftell(fp)); ++fparse_long_errors; } ungetc(c, fp); return res; } extern time_t fparse_time(FILE *fp) { return fparse_long(fp); } static Success fparse_info_0(FILE *fp, Info *info) { info->conf_pres_conf = fparse_long(fp); info->pers_pres_conf = fparse_long(fp); info->motd_conf = fparse_long(fp); info->kom_news_conf = fparse_long(fp); info->motd_of_lyskom = fparse_long(fp); return OK; } static Success fparse_info_2(FILE *fp, Info *info) { info->conf_pres_conf = fparse_long(fp); info->pers_pres_conf = fparse_long(fp); info->motd_conf = fparse_long(fp); info->kom_news_conf = fparse_long(fp); info->motd_of_lyskom = fparse_long(fp); info->highest_aux_no = fparse_long(fp); free_aux_item_list(&info->aux_item_list); return fparse_aux_item_list(fp, &info->aux_item_list); } extern Success fparse_info(FILE *fp, Info *info) { if ( fparse_long_errors != 0 ) { kom_log("fparse_info(): fparse_long_errors == %d on entry. Reset.\n", fparse_long_errors); fparse_long_errors = 0; } switch (input_format) { case 0: case 1: return fparse_info_0(fp, info); break; case 2: return fparse_info_2(fp, info); break; default: restart_kom("unknown input format: %d\n", input_format); return FAILURE; break; } } static Success fparse_conference_2(FILE *fp, Conference *result) { if ( fparse_long_errors != 0 ) { kom_log("fparse_conference(): fparse_long_errors == %d on entry. Reset.\n", fparse_long_errors); fparse_long_errors = 0; } if ( fparse_string(fp, &result->name) != OK ) { kom_log("fparse_conference(): Can't parse name.\n"); return FAILURE; } if ( fparse_member_list(fp, &result->members) != OK || l2g_read(fp, &result->texts) != OK || fparse_conf_type(fp, &result->type) != OK ) { kom_log("fparse_conference: file is corrupt.\n"); return FAILURE; } result->creation_time = fparse_time(fp); result->last_written = fparse_time(fp); result->creator = fparse_long(fp); result->presentation = fparse_long(fp); result->supervisor = fparse_long(fp); result->permitted_submitters = fparse_long(fp); result->super_conf = fparse_long(fp); result->msg_of_day = fparse_long(fp); if ( fparse_long_errors != 0 ) { kom_log("fparse_conference(): %d %s before 'nice'. Reset.\n", fparse_long_errors, "fparse_long_errors"); fparse_long_errors = 0; return FAILURE; } result->nice = fparse_long(fp); result->keep_commented = fparse_long(fp); result->expire = fparse_long(fp); result->highest_aux = fparse_long(fp); if (fparse_aux_item_list(fp, &result->aux_item_list) != OK) return FAILURE; fskipwhite(fp); return OK; } static Success fparse_conference_0(FILE *fp, Conference *result) { if ( fparse_long_errors != 0 ) { kom_log("fparse_conference(): fparse_long_errors == %d on entry. Reset.\n", fparse_long_errors); fparse_long_errors = 0; } if ( fparse_string(fp, &result->name) != OK ) { kom_log("fparse_conference(): Can't parse name.\n"); return FAILURE; } if ( fparse_member_list(fp, &result->members) != OK || fparse_text_list(fp, &result->texts) != OK || fparse_conf_type(fp, &result->type) != OK ) { kom_log("fparse_conference: file is corrupt.\n"); return FAILURE; } result->creation_time = fparse_time(fp); result->last_written = fparse_time(fp); result->creator = fparse_long(fp); result->presentation = fparse_long(fp); result->supervisor = fparse_long(fp); result->permitted_submitters = fparse_long(fp); result->super_conf = fparse_long(fp); result->msg_of_day = fparse_long(fp); if ( fparse_long_errors != 0 ) { kom_log("fparse_conference(): %d %s before 'nice'. Reset.\n", fparse_long_errors, "fparse_long_errors"); fparse_long_errors = 0; return FAILURE; } result->nice = fparse_long(fp); result->highest_aux = 0; result->aux_item_list.length = 0; result->aux_item_list.items = 0; fskipwhite(fp); return OK; } extern Success fparse_conference(FILE *fp, Conference *result) { switch (input_format) { case 0: case 1: return fparse_conference_0(fp, result); break; case 2: return fparse_conference_2(fp, result); break; default: restart_kom("unknown input format: %d\n", input_format); return FAILURE; break; } } static Success fparse_person_0(FILE *fp, Person *person) { String pwd = EMPTY_STRING; if ( fparse_long_errors != 0 ) { kom_log("fparse_person(): fparse_long_errors == %d on entry. Reset.\n", fparse_long_errors); fparse_long_errors = 0; } if ( fparse_string(fp, &pwd) != OK ) { kom_log("fparse_person(): Failed to parse password.\n"); return FAILURE; } memcpy(person->pwd, pwd.string, PASSWD_LEN); s_clear(&pwd); if ( fparse_string(fp, &person->username) != OK || fparse_priv_bits(fp, &person->privileges) != OK || fparse_personal_flags(fp, &person->flags) != OK || fparse_text_list(fp, &person->created_texts) != OK || fparse_mark_list(fp, &person->marks) != OK || fparse_membership_list(fp, &person->conferences) != OK ) { kom_log("fparse_person(): parse error.\n"); return FAILURE; } person->last_login = fparse_time(fp); person->user_area = fparse_long(fp); person->total_time_present = fparse_long(fp); person->sessions = fparse_long(fp); person->created_lines = fparse_long(fp); person->created_bytes = fparse_long(fp); person->read_texts = fparse_long(fp); person->no_of_text_fetches = fparse_long(fp); person->created_persons = fparse_long(fp); if ( fparse_long_errors != 0 ) { kom_log("fparse_person(): %d %s before 'created_confs'. Reset.\n", fparse_long_errors, "fparse_long_errors"); fparse_long_errors = 0; return FAILURE; } person->created_confs = fparse_long(fp); fskipwhite(fp); return OK; } static Success fparse_person_2(FILE *fp, Person *person) { String pwd = EMPTY_STRING; if ( fparse_long_errors != 0 ) { kom_log("fparse_person(): fparse_long_errors == %d on entry. Reset.\n", fparse_long_errors); fparse_long_errors = 0; } if ( fparse_string(fp, &pwd) != OK ) { kom_log("fparse_person(): Failed to parse password.\n"); return FAILURE; } memcpy(person->pwd, pwd.string, PASSWD_LEN); s_clear(&pwd); if ( fparse_string(fp, &person->username) != OK || fparse_priv_bits(fp, &person->privileges) != OK || fparse_personal_flags(fp, &person->flags) != OK || l2g_read(fp, &person->created_texts) != OK || fparse_mark_list(fp, &person->marks) != OK || fparse_membership_list(fp, &person->conferences) != OK ) { kom_log("fparse_person(): parse error.\n"); return FAILURE; } person->last_login = fparse_time(fp); person->user_area = fparse_long(fp); person->total_time_present = fparse_long(fp); person->sessions = fparse_long(fp); person->created_lines = fparse_long(fp); person->created_bytes = fparse_long(fp); person->read_texts = fparse_long(fp); person->no_of_text_fetches = fparse_long(fp); person->created_persons = fparse_long(fp); if ( fparse_long_errors != 0 ) { kom_log("fparse_person(): %d %s before 'created_confs'. Reset.\n", fparse_long_errors, "fparse_long_errors"); fparse_long_errors = 0; return FAILURE; } person->created_confs = fparse_long(fp); fskipwhite(fp); return OK; } extern Success fparse_person(FILE *fp, Person *result) { switch(input_format) { case 0: case 1: return fparse_person_0(fp, result); break; case 2: return fparse_person_2(fp, result); break; default: restart_kom("unknown input format: %d\n", input_format); return FAILURE; break; } } static Success fparse_membership_type(FILE *fp, Membership_type *result) { fskipwhite(fp); result->invitation = getc(fp) != '0'; result->passive = getc(fp) != '0'; result->secret = getc(fp) != '0'; result->passive_message_invert = getc(fp) != '0'; result->reserved2 = getc(fp) != '0'; result->reserved3 = getc(fp) != '0'; result->reserved4 = getc(fp) != '0'; result->reserved5 = getc(fp) != '0'; return OK; } static Success fparse_read_range_0(FILE *fp, Membership *mship) { Local_text_no last_text_read; unsigned int no_of_read; unsigned int i; unsigned int n; struct read_range *res; struct read_range *tail; Local_text_no tmp; last_text_read = fparse_long(fp); no_of_read = fparse_long(fp); sfree(mship->read_ranges); if (last_text_read == 0) { mship->read_ranges = NULL; mship->no_of_read_ranges = 0; } else { mship->no_of_read_ranges = 1; mship->read_ranges = smalloc(sizeof(mship->read_ranges[0])); mship->read_ranges->first_read = 1; mship->read_ranges->last_read = last_text_read; } if (no_of_read > 0) { fskipwhite(fp); switch(getc(fp)) { case '{': n = mship->no_of_read_ranges; tail = res = mship->read_ranges; for (i = 0; i < no_of_read; i++) { tmp = fparse_long(fp); if (tail != NULL && tmp <= tail->last_read) { kom_log("fparse_read_range_0: discarded out-of-order" " local number %lu probably introduced by" " bug 1121\n", (unsigned long)tmp); } else if (tail != NULL && tmp == tail->last_read + 1) tail->last_read = tmp; else { res = REALLOC(res, ++n * sizeof(*res)); tail = &res[n-1]; tail->first_read = tail->last_read = tmp; } } mship->no_of_read_ranges = n; mship->read_ranges = res; fskipwhite(fp); if (getc(fp) != '}') { err_stat = 1; kom_errno = KOM_LDB_ERR; kom_log("fparse_read_range_0(): expected '}' at pos %lu.\n", (unsigned long)ftell(fp)); return FAILURE; } break; case '*': kom_log("fparse_read_range_0(): " "empty read_ranges with %lu elements (corrected)\n", (unsigned long)no_of_read); mship->no_of_read_ranges = 0; break; default: kom_log("fparse_read_range_0(): expected '*' or '{' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 2; kom_errno = KOM_LDB_ERR; return FAILURE; } } else { fskipwhite(fp); if ( getc(fp) != '*' ) { kom_log("fparse_read_range_0(): expected '*' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 3; kom_errno = KOM_LDB_ERR; return FAILURE; } } return OK; } static Success fparse_membership_2(FILE *fp, Membership *mship) { mship->last_time_read = fparse_time(fp); mship->conf_no = fparse_long(fp); mship->priority = fparse_long(fp); if (fparse_read_range_0(fp, mship) != OK) return FAILURE; mship->added_by = fparse_long(fp); mship->added_at = fparse_time(fp); if (fparse_membership_type(fp, &mship->type) != OK) return FAILURE; return OK; } static Success fparse_membership_0(FILE *fp, Membership *mship) { mship->last_time_read = fparse_time(fp); mship->conf_no = fparse_long(fp); mship->priority = fparse_long(fp); if (fparse_read_range_0(fp, mship) != OK) return FAILURE; return OK; } static Success fparse_membership(FILE *fp, Membership *mship) { switch(input_format) { case 0: case 1: return fparse_membership_0(fp, mship); break; case 2: return fparse_membership_2(fp, mship); break; default: restart_kom("unknown input format: %d\n", input_format); return FAILURE; break; } } static Success fparse_membership_list_0(FILE *fp, Membership_list *result) { int i; /* First free all the read_texts. */ if ( result->confs != NULL ) { for ( i = 0; i < result->no_of_confs; i++) sfree(result->confs[ i ].read_ranges); } result->no_of_confs = fparse_long(fp); if ( result->no_of_confs > 0 ) { fskipwhite(fp); switch(getc(fp)) { case '{': result->confs = REALLOC(result->confs, (result->no_of_confs * sizeof(Membership))); if ( result->confs == NULL && result->no_of_confs > 0 ) { err_stat = 0; kom_errno = KOM_OUT_OF_MEMORY; return FAILURE; } for ( i = 0; i < result->no_of_confs; i++) { init_membership(&result->confs[ i ]); if ( fparse_membership_0(fp, &result->confs[i]) != OK ) return FAILURE; } fskipwhite(fp); if ( getc(fp) != '}' ) { kom_log("fparse_membership_list(): expected '}' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 4; kom_errno = KOM_LDB_ERR; return FAILURE; } break; case '*': if ( result->confs != NULL ) { sfree(result->confs); result->confs = NULL; } kom_log("%s empty list with %lu elements (corrected).\n", "fparse_membership_list():", (unsigned long)result->no_of_confs); result->no_of_confs = 0; break; default: kom_log("fparse_membership_list(): expected '*' or '{' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 5; kom_errno = KOM_LDB_ERR; return FAILURE; } } else { fskipwhite(fp); if ( getc(fp) != '*' ) { kom_log("fparse_membership_list(): expected '*' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 6; kom_errno = KOM_LDB_ERR; return FAILURE; } if ( result->confs != NULL ) { sfree(result->confs); result->confs = NULL; } } return OK; } static Success fparse_membership_list_2(FILE *fp, Membership_list *result) { int i; /* First free all the read_texts. */ if ( result->confs != NULL ) { for ( i = 0; i < result->no_of_confs; i++) sfree(result->confs[ i ].read_ranges); } result->no_of_confs = fparse_long(fp); if ( result->no_of_confs > 0 ) { fskipwhite(fp); switch(getc(fp)) { case '{': result->confs = REALLOC(result->confs, (result->no_of_confs * sizeof(Membership))); if ( result->confs == NULL && result->no_of_confs > 0 ) { err_stat = 0; kom_errno = KOM_OUT_OF_MEMORY; return FAILURE; } for ( i = 0; i < result->no_of_confs; i++) { init_membership(&result->confs[ i ]); if ( fparse_membership(fp, &result->confs[i]) != OK ) return FAILURE; } fskipwhite(fp); if ( getc(fp) != '}' ) { kom_log("fparse_membership_list(): expected '}' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 4; kom_errno = KOM_LDB_ERR; return FAILURE; } break; case '*': if ( result->confs != NULL ) { sfree(result->confs); result->confs = NULL; } kom_log("%s empty list with %lu elements (corrected).\n", "fparse_membership_list():", (unsigned long)result->no_of_confs); result->no_of_confs = 0; break; default: kom_log("fparse_membership_list(): expected '*' or '{' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 5; kom_errno = KOM_LDB_ERR; return FAILURE; } } else { fskipwhite(fp); if ( getc(fp) != '*' ) { kom_log("fparse_membership_list(): expected '*' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 6; kom_errno = KOM_LDB_ERR; return FAILURE; } if ( result->confs != NULL ) { sfree(result->confs); result->confs = NULL; } } return OK; } extern Success fparse_membership_list(FILE *fp, Membership_list *result) { switch(input_format) { case 0: case 1: return fparse_membership_list_0(fp, result); break; case 2: return fparse_membership_list_2(fp, result); break; default: restart_kom("unknown input format: %d\n", input_format); return FAILURE; break; } } extern Success fparse_conf_list(FILE *fp, Conf_list_old *result) { unsigned long i; result->no_of_conf_nos = fparse_long(fp); if ( result->no_of_conf_nos > 0 ) { fskipwhite(fp); switch(getc(fp)) { case '{': result->conf_nos = REALLOC(result->conf_nos, (result->no_of_conf_nos * sizeof(Conf_no))); if ( result->conf_nos == NULL ) { err_stat = 0; kom_errno = KOM_OUT_OF_MEMORY; return FAILURE; } for ( i = 0; i < result->no_of_conf_nos; i++) result->conf_nos[ i ] = fparse_long(fp); fskipwhite(fp); if ( getc(fp) != '}' ) { kom_log("fparse_conf_list(): expected '}' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 7; kom_errno = KOM_LDB_ERR; return FAILURE; } break; case '*': if ( result->conf_nos != NULL ) { sfree(result->conf_nos); result->conf_nos = NULL; } break; default: kom_log("fparse_conf_list(): expected '*' or '{' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 8; kom_errno = KOM_LDB_ERR; return FAILURE; } } else { fskipwhite(fp); if ( getc(fp) != '*' ) { kom_log("fparse_conf_list(): expected '*' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 9; kom_errno = KOM_LDB_ERR; return FAILURE; } if ( result->conf_nos != NULL ) { sfree(result->conf_nos); result->conf_nos = NULL; } } if ( result->no_of_conf_nos > 0 ) { fskipwhite(fp); switch(getc(fp)) { case '{': result->type_of_conf = REALLOC(result->type_of_conf, (result->no_of_conf_nos * sizeof(Conf_type))); if ( result->type_of_conf == NULL ) { err_stat = 0; kom_errno = KOM_OUT_OF_MEMORY; return FAILURE; } for ( i = 0; i < result->no_of_conf_nos; i++) if ( fparse_conf_type(fp, &result->type_of_conf[i]) != OK ) { return FAILURE; } fskipwhite(fp); if ( getc(fp) != '}' ) { kom_log("fparse_conf_list(): expected '}' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 10; kom_errno = KOM_LDB_ERR; return FAILURE; } break; case '*': if ( result->type_of_conf != NULL ) { sfree(result->type_of_conf); result->type_of_conf = NULL; } break; default: kom_log("fparse_conf_list(): expected '*' or '+' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 11; kom_errno = KOM_LDB_ERR; return FAILURE; } } else { fskipwhite(fp); if ( getc(fp) != '*' ) { kom_log("fparse_conf_list(): expected '*' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 12; kom_errno = KOM_LDB_ERR; return FAILURE; } if ( result->type_of_conf != NULL ) { sfree(result->type_of_conf); result->type_of_conf = NULL; } } return OK; } extern Success fparse_mark_list(FILE *fp, Mark_list *result) { int i; result->no_of_marks = fparse_long(fp); if ( result->no_of_marks > 0 ) { fskipwhite(fp); switch(getc(fp)) { case '{': result->marks = REALLOC(result->marks, (result->no_of_marks * sizeof(Mark))); if ( result->marks == NULL ) { err_stat = 0; kom_errno = KOM_OUT_OF_MEMORY; return FAILURE; } for ( i = 0; i < result->no_of_marks; i++) if ( fparse_mark(fp, &result->marks[ i ] ) != OK ) { return FAILURE; } fskipwhite(fp); if ( getc(fp) != '}' ) { kom_log("fparse_mark_list(): expected '}' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 13; kom_errno = KOM_LDB_ERR; return FAILURE; } break; case '*': if ( result->marks != NULL ) { sfree(result->marks); result->marks = NULL; } break; default: kom_log("fparse_mark_list(): expected '*' or '{' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 14; kom_errno = KOM_LDB_ERR; return FAILURE; } } else { fskipwhite(fp); if ( getc(fp) != '*' ) { kom_log("fparse_mark_list(): expected '*' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 15; kom_errno = KOM_LDB_ERR; return FAILURE; } if ( result->marks != NULL ) { sfree(result->marks); result->marks = NULL; } } return OK; } static Success fparse_text_stat_2(FILE *fp, Text_stat *result) { int i; int c; if ( fparse_long_errors != 0 ) { kom_log("fparse_text_stat(): fparse_long_errors == %d on entry. Reset.\n", fparse_long_errors); fparse_long_errors = 0; } result->creation_time = fparse_time(fp); result->author = fparse_long(fp); result->file_pos = fparse_long(fp); result->no_of_lines = fparse_long(fp); result->no_of_chars = fparse_long(fp); result->no_of_marks = fparse_long(fp); result->no_of_misc = fparse_long(fp); if ( fparse_long_errors != 0 ) { kom_log("%s(): %d fparse_long_errors before 'misc_items'. Reset.\n", "fparse_text_stat", fparse_long_errors); fparse_long_errors = 0; return FAILURE; } if ( result->no_of_misc > 0 ) { fskipwhite(fp); switch( c = getc(fp) ) { case '{': result->misc_items = REALLOC(result->misc_items, (result->no_of_misc * sizeof(Misc_info))); if ( result->misc_items == NULL ) { err_stat = 0; kom_errno = KOM_OUT_OF_MEMORY; return FAILURE; } for ( i = 0; i < result->no_of_misc; i++) if ( fparse_misc_info(fp, &result->misc_items[ i ]) != OK ) return FAILURE; fskipwhite(fp); if ( (c = getc(fp)) != '}' ) { kom_log("fparse_text_stat(): expected '}' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 16; kom_errno = KOM_LDB_ERR; return FAILURE; } break; case '@': case '+': ungetc(c, fp); kom_log("fparse_text_stat(): got '%c'; expected '{' or '*'\n.", c); kom_log("Character ungetc'd and interpreted as a '*'. (pos %lu).\n", (unsigned long)ftell(fp)); /* Fall through */ case '*': if ( result->misc_items != NULL ) { sfree(result->misc_items); result->misc_items = NULL; } break; default: kom_log("fparse_text_stat(): expected '*' or '}' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 17; kom_errno = KOM_LDB_ERR; return FAILURE; } } else { fskipwhite(fp); if ( (c = getc(fp)) != '*' ) { kom_log("fparse_text_stat(): expected '*' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 18; kom_errno = KOM_LDB_ERR; return FAILURE; } if ( result->misc_items != NULL ) { sfree(result->misc_items); result->misc_items = NULL; } } result->highest_aux = fparse_long(fp); if (fparse_aux_item_list(fp, &result->aux_item_list) != OK) return FAILURE; fskipwhite(fp); return OK; } static Success fparse_text_stat_0(FILE *fp, Text_stat *result) { int i; int c; if ( fparse_long_errors != 0 ) { kom_log("fparse_text_stat(): fparse_long_errors == %d on entry. Reset.\n", fparse_long_errors); fparse_long_errors = 0; } result->creation_time = fparse_time(fp); result->author = fparse_long(fp); result->file_pos = fparse_long(fp); result->no_of_lines = fparse_long(fp); result->no_of_chars = fparse_long(fp); result->no_of_marks = fparse_long(fp); result->no_of_misc = fparse_long(fp); if ( fparse_long_errors != 0 ) { kom_log("%s(): %d fparse_long_errors before 'misc_items'. Reset.\n", "fparse_text_stat", fparse_long_errors); fparse_long_errors = 0; return FAILURE; } if ( result->no_of_misc > 0 ) { fskipwhite(fp); switch( c = getc(fp) ) { case '{': result->misc_items = REALLOC(result->misc_items, (result->no_of_misc * sizeof(Misc_info))); if ( result->misc_items == NULL ) { err_stat = 0; kom_errno = KOM_OUT_OF_MEMORY; return FAILURE; } for ( i = 0; i < result->no_of_misc; i++) if ( fparse_misc_info(fp, &result->misc_items[ i ]) != OK ) return FAILURE; fskipwhite(fp); if ( (c = getc(fp)) != '}' ) { kom_log("fparse_text_stat(): expected '}' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 19; kom_errno = KOM_LDB_ERR; return FAILURE; } break; case '@': case '+': ungetc(c, fp); kom_log("fparse_text_stat(): got '%c'; expected '{' or '*'\n.", c); kom_log("Character ungetc'd and interpreted as a '*'. (pos %lu).\n", (unsigned long)ftell(fp)); /* Fall through */ case '*': if ( result->misc_items != NULL ) { sfree(result->misc_items); result->misc_items = NULL; } break; default: kom_log("fparse_text_stat(): expected '*' or '}' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 20; kom_errno = KOM_LDB_ERR; return FAILURE; } } else { fskipwhite(fp); if ( (c = getc(fp)) != '*' ) { kom_log("fparse_text_stat(): expected '*' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 21; kom_errno = KOM_LDB_ERR; return FAILURE; } if ( result->misc_items != NULL ) { sfree(result->misc_items); result->misc_items = NULL; } } result->highest_aux = 0; result->aux_item_list.length = 0; result->aux_item_list.items = NULL; fskipwhite(fp); return OK; } extern Success fparse_text_stat(FILE *fp, Text_stat *result) { switch(input_format) { case 0: case 1: return fparse_text_stat_0(fp, result); break; case 2: return fparse_text_stat_2(fp, result); break; default: restart_kom("unknown input format: %d\n", input_format); return FAILURE; break; } } static Success fparse_text_list(FILE *fp, Local_to_global *result) { unsigned long i; Local_text_no lno; Local_text_no no_of_texts; lno = fparse_long(fp); no_of_texts = fparse_long(fp); l2g_clear(result); if (no_of_texts > 0) { fskipwhite(fp); switch(getc(fp)) { case '{': for ( i = 0; i < no_of_texts; i++) l2g_append(result, lno++, fparse_long(fp)); fskipwhite(fp); if ( getc(fp) != '}' ) { kom_log("fparse_text_list(): expected '}' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 22; kom_errno = KOM_LDB_ERR; return FAILURE; } break; default: kom_log("fparse_text_list(): expected '{' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 23; kom_errno = KOM_LDB_ERR; return FAILURE; } } else { fskipwhite(fp); if ( getc(fp) != '*' ) { kom_log("fparse_text_list(): expected '*' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 24; kom_errno = KOM_LDB_ERR; return FAILURE; } l2g_set_first_appendable_key(result, lno); } return OK; } extern Success fparse_string(FILE *fp, String *result) { String_size length; length = fparse_long(fp); if ( getc(fp) != 'H' ) { kom_log("fparse_string(): expected 'H' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 25; kom_errno = KOM_LDB_ERR; return FAILURE; } s_size_crea_str(result, length); if ( result->string == NULL ) { err_stat = 0; kom_errno = KOM_OUT_OF_MEMORY; return FAILURE; } if ( fread(result->string, sizeof(char), result->len, fp) != (size_t)result->len ) { kom_log("fparse_string(): unexpected eof at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 26; kom_errno = KOM_LDB_ERR; return FAILURE; } return OK; } extern Success fparse_member_list(FILE *fp, Member_list *result) { int i; result->no_of_members = fparse_long(fp); if ( result->no_of_members > 0 ) { fskipwhite(fp); switch(getc(fp)) { case '{': result->members = REALLOC(result->members, (result->no_of_members * sizeof(Member))); if ( result->members == NULL ) { err_stat = 0; kom_errno = KOM_OUT_OF_MEMORY; return FAILURE; } for ( i = 0; i < result->no_of_members; i++) { init_member(&result->members[i]); if ( fparse_member(fp, &result->members[ i ]) != OK ) { return FAILURE; } } fskipwhite(fp); if ( getc(fp) != '}' ) { kom_log("fparse_member_list(): expected '}' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 27; kom_errno = KOM_LDB_ERR; return FAILURE; } break; case '*': if ( result->members != NULL ) { sfree(result->members); result->members = NULL; } break; default: kom_log("fparse_member_list(): expected '*' or '{' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 28; kom_errno = KOM_LDB_ERR; return FAILURE; } } else { fskipwhite(fp); if ( getc(fp) != '*' ) { kom_log("fparse_member_list(): expected '*' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 29; kom_errno = KOM_LDB_ERR; return FAILURE; } if ( result->members != NULL ) { sfree(result->members); result->members = NULL; } } return OK; } static Success fparse_member_0(FILE *fp, Member *result) { result->member = fparse_long(fp); return OK; } static Success fparse_member_2(FILE *fp, Member *result) { result->member = fparse_long(fp); result->added_by = fparse_long(fp); result->added_at = fparse_time(fp); return fparse_membership_type(fp, &result->type); } extern Success fparse_member(FILE *fp, Member *result) { switch (input_format) { case 0: case 1: return fparse_member_0(fp, result); break; case 2: return fparse_member_2(fp, result); break; default: restart_kom("unknown database format: %d", input_format); return FAILURE; } } extern Success fparse_mark(FILE *fp, Mark *result) { result->text_no = fparse_long(fp); result->mark_type = fparse_long(fp); return OK; } extern Success fparse_priv_bits(FILE *fp, Priv_bits *result) { fskipwhite(fp); result->wheel = getc(fp) != '0'; result->admin = getc(fp) != '0'; result->statistic = getc(fp) != '0'; result->create_pers = getc(fp) != '0'; result->create_conf = getc(fp) != '0'; result->change_name = getc(fp) != '0'; result->flg7 = getc(fp) != '0'; result->flg8 = getc(fp) != '0'; result->flg9 = getc(fp) != '0'; result->flg10 = getc(fp) != '0'; result->flg11 = getc(fp) != '0'; result->flg12 = getc(fp) != '0'; result->flg13 = getc(fp) != '0'; result->flg14 = getc(fp) != '0'; result->flg15 = getc(fp) != '0'; result->flg16 = getc(fp) != '0'; return OK; } extern Success fparse_personal_flags(FILE *fp, Personal_flags *result) { fskipwhite(fp); result->unread_is_secret = getc(fp) != '0'; result->flg2 = getc(fp) != '0'; result->flg3 = getc(fp) != '0'; result->flg4 = getc(fp) != '0'; result->flg5 = getc(fp) != '0'; result->flg6 = getc(fp) != '0'; result->flg7 = getc(fp) != '0'; result->flg8 = getc(fp) != '0'; return OK; } extern Success fparse_conf_type(FILE *fp, Conf_type *result) { char c; fskipwhite(fp); result->rd_prot = getc(fp) != '0'; result->original = getc(fp) != '0'; result->secret = getc(fp) != '0'; result->letter_box = getc(fp) != '0'; c = getc(fp); if (c != '0' && c != '1') { result->allow_anon = 1; result->forbid_secret = 0; result->reserved2 = 0; result->reserved3 = 0; ungetc(c, fp); return(OK); } result->allow_anon = ( c != '0' ); result->forbid_secret = ( getc(fp) != '0' ); result->reserved2 = ( getc(fp) != '0' ); result->reserved3 = ( getc(fp) != '0' ); return OK; } extern Success fparse_who_info(FILE *fp, Who_info *result) { result->person = fparse_long(fp); result->working_conference = fparse_long(fp); if ( fparse_string(fp, &result->what_am_i_doing) != OK ) { kom_log("fparse_who_info(): parse error.\n"); err_stat = 30; kom_errno = KOM_LDB_ERR; return FAILURE; } return OK; } extern Success fparse_who_info_list(FILE *fp, Who_info_list *result) { int i; fskipwhite(fp); result->no_of_persons = fparse_long(fp); if ( result->no_of_persons > 0 ) { fskipwhite(fp); switch(getc(fp)) { case '{': result->info = REALLOC(result->info, (result->no_of_persons * sizeof(Who_info))); if ( result->info == NULL ) { err_stat = 0; kom_errno = KOM_OUT_OF_MEMORY; return FAILURE; } for ( i = 0; i < result->no_of_persons; i++) { init_who_info(&result->info[ i ]); if ( fparse_who_info(fp, &result->info[ i ]) != OK ) return FAILURE; } fskipwhite(fp); if ( getc(fp) != '}' ) { kom_log("fparse_who_info_list(): expected '}' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 31; kom_errno = KOM_LDB_ERR; return FAILURE; } break; case '*': if ( result->info != NULL ) { sfree(result->info); result->info = NULL; } break; default: kom_log("fparse_who_info_list(): expected '*' or '{' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 32; kom_errno = KOM_LDB_ERR; return FAILURE; } } else { fskipwhite(fp); if ( getc(fp) != '*' ) { kom_log("fparse_who_info_list(): expected '*' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 33; kom_errno = KOM_LDB_ERR; return FAILURE; } if ( result->info != NULL ) { sfree(result->info); result->info = NULL; } } return OK; } extern Success fparse_aux_item_flags(FILE *fp, Aux_item_flags *f) { fskipwhite(fp); f->deleted = getc(fp) != '0'; f->inherit = getc(fp) != '0'; f->secret = getc(fp) != '0'; f->hide_creator = getc(fp) != '0'; f->dont_garb = getc(fp) != '0'; f->reserved3 = getc(fp) != '0'; f->reserved4 = getc(fp) != '0'; f->reserved5 = getc(fp) != '0'; return OK; } extern Success fparse_aux_item_link(FILE *fp, Aux_item_link *link) { link->target_type = (enum object_type)(long)fparse_long(fp); link->target_item = fparse_long(fp); switch (link->target_type) { case CONF_OBJECT_TYPE: link->target_object.conf = (Conf_no)fparse_long(fp); break; case TEXT_OBJECT_TYPE: link->target_object.text = (Text_no)fparse_long(fp); break; default: ; } return OK; } extern Success fparse_aux_item(FILE *fp, Aux_item *item) { item->aux_no = fparse_long(fp); item->tag = fparse_long(fp); item->creator = fparse_long(fp); item->sent_at = fparse_time(fp); fparse_aux_item_flags(fp, &item->flags); item->inherit_limit = fparse_long(fp); item->data = EMPTY_STRING; if (fparse_string(fp, &item->data) != OK) { kom_log("fparse_aux_item(): Can't parse name.\n"); return FAILURE; } if (fparse_aux_item_link(fp, &(item->linked_item)) != OK) { kom_log("fparse_aux_item(): Can't parse link.\n"); return FAILURE; } return OK; } extern Success fparse_aux_item_list(FILE *fp, Aux_item_list *result) { int c, i; result->items = NULL; result->length = fparse_long(fp); if ( fparse_long_errors != 0 ) { kom_log("%s(): %d fparse_long_errors before 'aux_items'. Reset.\n", "fparse_text_stat", fparse_long_errors); fparse_long_errors = 0; return FAILURE; } if ( result->length > 0 ) { fskipwhite(fp); switch( c = getc(fp) ) { case '{': result->items = REALLOC(result->items, (result->length * sizeof(Aux_item))); if ( result->items == NULL ) { err_stat = 0; kom_errno = KOM_OUT_OF_MEMORY; return FAILURE; } for (i = 0; i < result->length; i++) if ( fparse_aux_item(fp, &result->items[ i ]) != OK ) return FAILURE; fskipwhite(fp); if ( (c = getc(fp)) != '}' ) { kom_log("fparse_aux_item_list(): expected '}' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 34; kom_errno = KOM_LDB_ERR; return FAILURE; } break; case '*': if ( result->items != NULL ) { sfree(result->items); result->items = NULL; result->length = 0; } break; default: kom_log("fparse_aux_item_list(): expected '*' or '}' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 35; kom_errno = KOM_LDB_ERR; return FAILURE; } } else { fskipwhite(fp); if ( (c = getc(fp)) != '*' ) { kom_log("fparse_aux_item_list(): expected '*' at pos %lu.\n", (unsigned long)ftell(fp)); err_stat = 36; kom_errno = KOM_LDB_ERR; return FAILURE; } result->items = NULL; result->length = 0; } return OK; } extern Success fparse_misc_info(FILE *fp, Misc_info *result) { long typ; typ = fparse_long(fp); switch(typ) { case recpt: case cc_recpt: case bcc_recpt: result->datum.recipient = fparse_long(fp); break; case loc_no: result->datum.local_no = fparse_long(fp); break; case rec_time: result->datum.received_at = fparse_time(fp); break; case comm_to: case comm_in: case footn_to: case footn_in: result->datum.text_link = fparse_long(fp); break; case sent_by: result->datum.sender = fparse_long(fp); break; case sent_at: result->datum.sent_at = fparse_time(fp); break; default: kom_log("fparse_misc_info(): illegal info_type %d at pos %lu.\n", result->type, (unsigned long)ftell(fp)); err_stat = 37; kom_errno = KOM_LDB_ERR; return FAILURE; } result->type = (enum info_type)typ; return OK; } lyskom-server-2.1.2/src/server/ram-output.c0000664000015100472110000005311407721716130014403 /* * $Id: ram-output.c,v 0.45 2003/08/23 16:38:14 ceder Exp $ * Copyright (C) 1991, 1993-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * ram-output.c - write objects to disk. * * This is a hack. It shouldn't be used except for debugging and as a * temporary substitute for what Willf|r is (or should:-) be doing. * * Written by ceder 1990-07-13. Rewritten 1990-08-31. * Some functions rewritten for speed by Inge Wallin. * (It worked - now saving is twice as fast.) */ #ifdef HAVE_CONFIG_H # include #endif #include #include "timewrap.h" #include #include "s-string.h" #include "kom-types.h" #include "ram-output.h" #include "lyskomd.h" #include "log.h" #include "local-to-global.h" /* Forward declarations. */ static void foutput_aux_item_list(FILE *, const Aux_item_list *); static void foutput_conf_type (FILE *, Conf_type); static void foutput_mark(FILE *, Mark); static void foutput_mark_list(FILE *, const Mark_list); static void foutput_member(FILE *, Member); static void foutput_member_list(FILE *, Member_list); static void foutput_membership_list(FILE *, Membership_list); static void foutput_misc_info(FILE *, Misc_info); static void foutput_personal_flags(FILE *, Personal_flags); static void foutput_priv_bits(FILE *, Priv_bits); static void foutput_string(FILE *, String); static void foutput_text_list(FILE *, const Local_to_global *); static void foutput_time(FILE *, time_t); static void foutput_ulong(unsigned long, FILE *); static int output_format = 2; void set_output_format(int fmt) { output_format = fmt; switch (fmt) { case 0: case 1: case 2: break; default: restart_kom("unknown output format selected: %d\n", fmt); break; } } static void foutput_info_0(FILE *fp, Info *info) { fprintf(fp, " %lu %lu %lu %lu %lu", (unsigned long)info->conf_pres_conf, (unsigned long)info->pers_pres_conf, (unsigned long)info->motd_conf, (unsigned long)info->kom_news_conf, (unsigned long)info->motd_of_lyskom); } static void foutput_info_2(FILE *fp, Info *info) { fprintf(fp, " %lu %lu %lu %lu %lu %lu", (unsigned long)info->conf_pres_conf, (unsigned long)info->pers_pres_conf, (unsigned long)info->motd_conf, (unsigned long)info->kom_news_conf, (unsigned long)info->motd_of_lyskom, (unsigned long)info->highest_aux_no); foutput_aux_item_list(fp, &info->aux_item_list); } void foutput_info(FILE *fp, Info *info) { switch(output_format) { case 0: case 1: foutput_info_0(fp, info); break; case 2: foutput_info_2(fp, info); break; default: restart_kom("unknown database format: %d", output_format); break; } } static void foutput_person_0 (FILE *fp, const Person *person) { foutput_string (fp, person->username); foutput_priv_bits (fp, person->privileges); foutput_personal_flags (fp, person->flags); foutput_text_list (fp, &person->created_texts); foutput_mark_list (fp, person->marks); foutput_membership_list (fp, person->conferences); foutput_time(fp, person->last_login); fprintf (fp, " %lu %lu %lu %lu %lu %lu %lu %lu %lu", (unsigned long) person -> user_area, (unsigned long) person -> total_time_present, /* This is not a time, * but a number of seconds. */ (unsigned long) person -> sessions, (unsigned long) person -> created_lines, (unsigned long) person -> created_bytes, (unsigned long) person -> read_texts, (unsigned long) person -> no_of_text_fetches, (unsigned long) person -> created_persons, (unsigned long) person -> created_confs); } static void foutput_person_2(FILE *fp, const Person *person) { foutput_string (fp, person->username); foutput_priv_bits (fp, person->privileges); foutput_personal_flags (fp, person->flags); putc(' ', fp); l2g_write (fp, &person->created_texts); foutput_mark_list (fp, person->marks); foutput_membership_list (fp, person->conferences); foutput_time(fp, person->last_login); fprintf (fp, " %lu %lu %lu %lu %lu %lu %lu %lu %lu", (unsigned long) person -> user_area, (unsigned long) person -> total_time_present, /* This is not a time, * but a number of seconds. */ (unsigned long) person -> sessions, (unsigned long) person -> created_lines, (unsigned long) person -> created_bytes, (unsigned long) person -> read_texts, (unsigned long) person -> no_of_text_fetches, (unsigned long) person -> created_persons, (unsigned long) person -> created_confs); } extern void foutput_person (FILE *fp, const Person *person) { switch(output_format) { case 0: case 1: foutput_person_0(fp, person); break; case 2: foutput_person_2(fp, person); break; default: restart_kom("unknown database format: %d", output_format); break; } } static void foutput_conference_2(FILE *fp, const Conference *conf_c) { foutput_string(fp, conf_c->name); foutput_member_list(fp, conf_c->members); putc(' ', fp); l2g_write(fp, &conf_c->texts); foutput_conf_type(fp, conf_c->type); foutput_time(fp, conf_c -> creation_time ); foutput_time(fp, conf_c -> last_written ); fprintf (fp, " %lu %lu %lu %lu %lu %lu %lu", (unsigned long) conf_c -> creator, (unsigned long) conf_c -> presentation, (unsigned long) conf_c -> supervisor, (unsigned long) conf_c -> permitted_submitters, (unsigned long) conf_c -> super_conf, (unsigned long) conf_c -> msg_of_day, (unsigned long) conf_c -> nice); foutput_ulong((unsigned long) conf_c->keep_commented, fp); foutput_ulong((unsigned long) conf_c->expire, fp); foutput_ulong((unsigned long) conf_c->highest_aux, fp); foutput_aux_item_list(fp, &conf_c->aux_item_list); } static void foutput_conference_1 (FILE *fp, Conference *conf_c) { foutput_string(fp, conf_c->name); foutput_member_list(fp, conf_c->members); foutput_text_list(fp, &conf_c->texts); foutput_conf_type(fp, conf_c->type); foutput_time(fp, conf_c -> creation_time ); foutput_time(fp, conf_c -> last_written ); fprintf (fp, " %lu %lu %lu %lu %lu %lu %lu", (unsigned long) conf_c -> creator, (unsigned long) conf_c -> presentation, (unsigned long) conf_c -> supervisor, (unsigned long) conf_c -> permitted_submitters, (unsigned long) conf_c -> super_conf, (unsigned long) conf_c -> msg_of_day, (unsigned long) conf_c -> nice); } static void foutput_conference_0 (FILE *fp, Conference *conf_c) { foutput_string(fp, conf_c->name); foutput_member_list(fp, conf_c->members); foutput_text_list(fp, &conf_c->texts); foutput_conf_type(fp, conf_c->type); foutput_time(fp, conf_c -> creation_time ); foutput_time(fp, conf_c -> last_written ); fprintf (fp, " %lu %lu %lu %lu %lu %lu %lu", (unsigned long) conf_c -> creator, (unsigned long) conf_c -> presentation, (unsigned long) conf_c -> supervisor, (unsigned long) conf_c -> permitted_submitters, (unsigned long) conf_c -> super_conf, (unsigned long) conf_c -> msg_of_day, (unsigned long) conf_c -> nice); } void foutput_conference(FILE *fp, Conference *conf_c) { switch(output_format) { case 0: foutput_conference_0(fp, conf_c); break; case 1: foutput_conference_1(fp, conf_c); break; case 2: foutput_conference_2(fp, conf_c); break; default: restart_kom("unknown database format: %d", output_format); break; } } static void foutput_text_stat_0(FILE *fp, Text_stat *t_stat) { int i; foutput_time(fp, t_stat->creation_time); foutput_ulong((unsigned long) t_stat->author, fp); foutput_ulong((unsigned long) t_stat->file_pos, fp); foutput_ulong((unsigned long) t_stat->no_of_lines, fp); foutput_ulong((unsigned long) t_stat->no_of_chars, fp); foutput_ulong((unsigned long) t_stat->no_of_marks, fp); foutput_ulong((unsigned long) t_stat->no_of_misc, fp); if ( t_stat->misc_items != NULL && t_stat->no_of_misc > 0 ) { fputs(" {", fp); for ( i = 0; i < t_stat->no_of_misc; i++ ) foutput_misc_info(fp, t_stat->misc_items[ i ]); fputs(" }", fp); } else fputs(" *", fp); } static void foutput_text_stat_2(FILE *fp, Text_stat *t_stat) { int i; foutput_time(fp, t_stat->creation_time); foutput_ulong((unsigned long) t_stat->author, fp); foutput_ulong((unsigned long) t_stat->file_pos, fp); foutput_ulong((unsigned long) t_stat->no_of_lines, fp); foutput_ulong((unsigned long) t_stat->no_of_chars, fp); foutput_ulong((unsigned long) t_stat->no_of_marks, fp); foutput_ulong((unsigned long) t_stat->no_of_misc, fp); if ( t_stat->misc_items != NULL && t_stat->no_of_misc > 0 ) { fputs(" {", fp); for ( i = 0; i < t_stat->no_of_misc; i++ ) foutput_misc_info(fp, t_stat->misc_items[ i ]); fputs(" }", fp); } else fputs(" *", fp); foutput_ulong((unsigned long) t_stat->highest_aux, fp); foutput_aux_item_list(fp, &t_stat->aux_item_list); } void foutput_text_stat(FILE *fp, Text_stat *t_stat) { switch (output_format) { case 0: case 1: foutput_text_stat_0(fp, t_stat); break; case 2: foutput_text_stat_2(fp, t_stat); break; default: restart_kom("unknown database format: %d\n", output_format); break; } } static void foutput_aux_flags(FILE *fp, Aux_item_flags f) { putc(' ', fp); putc(f.deleted + '0', fp); putc(f.inherit + '0', fp); putc(f.secret + '0', fp); putc(f.hide_creator + '0', fp); putc(f.dont_garb + '0', fp); putc(f.reserved3 + '0', fp); putc(f.reserved4 + '0', fp); putc(f.reserved5 + '0', fp); } static void foutput_aux_item_link(FILE *fp, Aux_item_link *link) { foutput_ulong((unsigned long) link->target_type, fp); foutput_ulong((unsigned long) link->target_item, fp); switch (link->target_type) { case CONF_OBJECT_TYPE: foutput_ulong((unsigned long) link->target_object.conf, fp); break; case TEXT_OBJECT_TYPE: foutput_ulong((unsigned long) link->target_object.text, fp); break; default: ; } } static void foutput_aux_item(FILE *fp, Aux_item *a_item) { foutput_ulong((unsigned long) a_item->aux_no, fp); foutput_ulong((unsigned long) a_item->tag, fp); foutput_ulong((unsigned long) a_item->creator, fp); foutput_time(fp, a_item->sent_at); foutput_aux_flags(fp, a_item->flags); foutput_ulong((unsigned long) a_item->inherit_limit, fp); foutput_string(fp, a_item->data); foutput_aux_item_link(fp, &a_item->linked_item); } static void foutput_aux_item_list(FILE *fp, const Aux_item_list *aux) { int i; foutput_ulong((unsigned long) aux->length, fp); if (aux->items && aux->length > 0) { fputs(" {", fp); for (i = 0; i < aux->length; i++) foutput_aux_item(fp, &aux->items[i]); fputs(" }", fp); } else fputs(" *", fp); } static void foutput_membership_type(FILE *fp, Membership_type type) { putc(' ', fp); putc(type.invitation + '0', fp); putc(type.passive + '0', fp); putc(type.secret + '0', fp); putc(type.passive_message_invert + '0', fp); putc(type.reserved2 + '0', fp); putc(type.reserved3 + '0', fp); putc(type.reserved4 + '0', fp); putc(type.reserved5 + '0', fp); } static void foutput_read_ranges_0(FILE *fp, Membership *mship) { if (mship->read_ranges == NULL && mship->no_of_read_ranges != 0 ) { kom_log("foutput_read_ranges_0(): no_of_read_ranges forced to 0" " in a membership in %lu.\n", (unsigned long)mship->conf_no); mship->no_of_read_ranges = 0; } if (mship->no_of_read_ranges == 0) fprintf(fp, " 0 0 *"); else { struct read_range *begin; struct read_range *end; begin = &mship->read_ranges[0]; end = begin + mship->no_of_read_ranges; if (begin->first_read == 1) { fprintf(fp, " %lu", begin->last_read); begin++; } else fprintf(fp, " 0"); if (begin == end) fprintf(fp, " 0 *"); else { unsigned long no_of_read = 0; const struct read_range *ptr; for (ptr = begin; ptr < end; ++ptr) no_of_read += ptr->last_read - ptr->first_read + 1; fprintf(fp, " %lu {", no_of_read); for (ptr = begin; ptr < end; ++ptr) { Local_text_no lno; for (lno = ptr->first_read; lno <= ptr->last_read; lno++) fprintf(fp, " %lu", (unsigned long)lno); } fprintf(fp, " }"); } } } static void foutput_membership_0(FILE *fp, Membership *mship) { foutput_time(fp, mship->last_time_read ); fprintf(fp, " %lu %lu", (unsigned long)mship->conf_no, (unsigned long)mship->priority); foutput_read_ranges_0(fp, mship); } static void foutput_membership_2(FILE *fp, Membership *mship) { foutput_time(fp, mship->last_time_read ); fprintf(fp, " %lu %lu", (unsigned long)mship->conf_no, (unsigned long)mship->priority); foutput_read_ranges_0(fp, mship); fprintf(fp, " %lu", (unsigned long)mship->added_by); foutput_time(fp, mship->added_at); foutput_membership_type(fp, mship->type); } extern void foutput_membership(FILE *fp, Membership *mship) { switch (output_format) { case 0: case 1: foutput_membership_0(fp, mship); break; case 2: foutput_membership_2(fp, mship); break; default: restart_kom("unknown database format: %d", output_format); break; } } static void foutput_string(FILE *fp, String str) { foutput_ulong((unsigned long)str.len, fp); putc('H', fp); if (str.len) fwrite(str.string, str.len, 1, fp); } static void foutput_priv_bits(FILE *fp, Priv_bits bits) { putc(' ', fp); putc(bits.wheel + '0', fp); putc(bits.admin + '0', fp); putc(bits.statistic + '0', fp); putc(bits.create_pers + '0', fp); putc(bits.create_conf + '0', fp); putc(bits.change_name + '0', fp); putc(bits.flg7 + '0', fp); putc(bits.flg8 + '0', fp); putc(bits.flg9 + '0', fp); putc(bits.flg10 + '0', fp); putc(bits.flg11 + '0', fp); putc(bits.flg12 + '0', fp); putc(bits.flg13 + '0', fp); putc(bits.flg14 + '0', fp); putc(bits.flg15 + '0', fp); putc(bits.flg16 + '0', fp); } static void foutput_personal_flags(FILE *fp, Personal_flags flags) { putc(' ', fp); putc(flags.unread_is_secret + '0', fp); putc(flags.flg2 + '0', fp); putc(flags.flg3 + '0', fp); putc(flags.flg4 + '0', fp); putc(flags.flg5 + '0', fp); putc(flags.flg6 + '0', fp); putc(flags.flg7 + '0', fp); putc(flags.flg8 + '0', fp); } static void foutput_text_list(FILE *fp, const Local_to_global *text_list) { Local_text_no first; Local_text_no end; first = l2g_next_key(text_list, 0); end = l2g_first_appendable_key(text_list); if (first == 0) first = end; foutput_ulong((unsigned long)first, fp); foutput_ulong((unsigned long)(end - first), fp); if (first < end) { fputs(" {", fp); while (first < end) foutput_ulong((unsigned long)l2g_lookup(text_list, first++), fp); fputs(" }", fp); } else fprintf(fp, " *"); } static void foutput_mark_list(FILE *fp, const Mark_list mark_list) { int i; fprintf(fp, " %lu", (unsigned long)mark_list.no_of_marks); if ( mark_list.marks != NULL && mark_list.no_of_marks > 0 ) { fprintf(fp, " {"); for ( i = 0; i < mark_list.no_of_marks; i++ ) foutput_mark(fp, mark_list.marks[ i ]); fprintf(fp, " }"); } else fprintf(fp, " *"); } static void foutput_mark(FILE *fp, Mark mark) { fprintf(fp, " %lu %lu", (unsigned long)mark.text_no, (unsigned long)mark.mark_type); } static void foutput_membership_list_0 (FILE * fp, Membership_list mlist) { int i; fprintf(fp, " %lu", (unsigned long)mlist.no_of_confs); if ( mlist.confs != NULL && mlist.no_of_confs > 0 ) { fprintf(fp, " {"); for ( i = 0; i < mlist.no_of_confs; i++) foutput_membership_0(fp, mlist.confs + i); fprintf(fp, " }"); } else fprintf(fp, " *"); } static void foutput_membership_list_2 (FILE * fp, Membership_list mlist) { int i; fprintf(fp, " %lu", (unsigned long)mlist.no_of_confs); if ( mlist.confs != NULL && mlist.no_of_confs > 0 ) { fprintf(fp, " {"); for ( i = 0; i < mlist.no_of_confs; i++) foutput_membership_2(fp, mlist.confs + i); fprintf(fp, " }"); } else fprintf(fp, " *"); } static void foutput_membership_list(FILE * fp, Membership_list mlist) { switch (output_format) { case 0: case 1: foutput_membership_list_0(fp, mlist); break; case 2: foutput_membership_list_2(fp, mlist); break; default: restart_kom("unknown database format: %d", output_format); break; } } static void foutput_time(FILE *fp, time_t clk) { foutput_ulong((unsigned long) clk, fp); } static void foutput_member_list(FILE *fp, Member_list m_list) { int i; fprintf(fp, " %lu", (unsigned long)m_list.no_of_members); if ( m_list.members != NULL && m_list.no_of_members > 0 ) { fprintf(fp, " {"); for ( i = 0; i < m_list.no_of_members; i++ ) foutput_member(fp, m_list.members[ i ]); fprintf(fp, " }"); } else fprintf(fp, " *"); } static void foutput_member_0(FILE *fp, Member member) { fprintf(fp, " %lu", (unsigned long)member.member); } static void foutput_member_2(FILE *fp, Member member) { fprintf(fp, " %lu %lu", (unsigned long)member.member, (unsigned long)member.added_by); foutput_time(fp, member.added_at); foutput_membership_type(fp, member.type); } static void foutput_member(FILE *fp, Member member) { switch (output_format) { case 0: case 1: foutput_member_0(fp, member); break; case 2: foutput_member_2(fp, member); break; default: restart_kom("unknown database format: %d", output_format); break; } } static void foutput_conf_type_1(FILE *fp, Conf_type type) { putc(' ', fp); putc(type.rd_prot + '0', fp); putc(type.original + '0', fp); putc(type.secret + '0', fp); putc(type.letter_box + '0', fp); putc(type.allow_anon + '0', fp); putc(type.forbid_secret + '0', fp); putc(type.reserved2 + '0', fp); putc(type.reserved3 + '0', fp); } static void foutput_conf_type_0(FILE *fp, Conf_type type) { putc(' ', fp); putc(type.rd_prot + '0', fp); putc(type.original + '0', fp); putc(type.secret + '0', fp); putc(type.letter_box + '0', fp); } static void foutput_conf_type (FILE *fp, Conf_type type) { switch (output_format) { case 0: foutput_conf_type_0(fp, type); break; case 1: case 2: foutput_conf_type_1(fp, type); break; default: restart_kom("unknown database format: %d", output_format); break; } } static void foutput_misc_info(FILE *fp, Misc_info misc) { foutput_ulong((unsigned long)misc.type, fp); switch(misc.type) { case recpt: case cc_recpt: case bcc_recpt: foutput_ulong((unsigned long)misc.datum.recipient, fp); break; case loc_no: foutput_ulong((unsigned long)misc.datum.local_no, fp); break; case rec_time: foutput_time(fp, misc.datum.received_at); break; case comm_to: case comm_in: case footn_to: case footn_in: foutput_ulong((unsigned long)misc.datum.text_link, fp); break; case sent_by: foutput_ulong((unsigned long)misc.datum.sender, fp); break; case sent_at: foutput_time(fp, misc.datum.sent_at); break; #ifndef COMPILE_CHECKS default: #endif case unknown_info: restart_kom("prot_a_output_misc_info: Illegal misc\n"); } } /* * Output the unsigned long L in the fastest way possible to the file * FP. Ok, it's ugly, but it's fast (or is it?). */ static void foutput_ulong (unsigned long l, FILE *fp) { static char buf[sizeof(unsigned long) * 3 + 1]; char *cp; putc(' ', fp); if (l < 10) putc("0123456789"[l], fp); else { cp = buf + sizeof(buf); while (l > 0) { *--cp = (l % 10) + '0'; l /= 10; } fwrite(cp, buf + sizeof(buf) - cp, 1, fp); } } lyskom-server-2.1.2/src/server/log.c0000664000015100472110000000745307721716127013062 /* * $Id: log.c,v 0.29 2003/08/23 16:38:16 ceder Exp $ * Copyright (C) 1991-1995, 1998-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * log.c * * File created by ceder 1990-05-25. */ #ifdef HAVE_CONFIG_H # include #endif #ifdef HAVE_STDARG_H # include #endif #ifdef HAVE_STDLIB_H # include #endif #include #include #include "timewrap.h" #include #include #include "log.h" #include "lyskomd.h" /* * Add a string to the log file. */ #if defined(HAVE_VFPRINTF) && defined(HAVE_STDARG_H) static void kom_logv(const char * format, va_list AP); extern void kom_log (const char * format, ...) { va_list AP; va_start(AP, format); kom_logv(format, AP); va_end(AP); } static void kom_logv (const char *format, va_list AP) { time_t clk; struct tm *t; time(&clk); t = localtime(&clk); fprintf(stderr, "%02d%02d%02d %02d:%02d:%02d %ld ", t->tm_year % 100, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, (long)getpid()); vfprintf(stderr, format, AP); fflush(stderr); } #else /* !HAVE_VFPRINTF */ extern void kom_log (const char * format, int a, int b, int c, int d, int e, int f, int g) { time_t clk; struct tm *t; time(&clk); t = localtime(&clk); fprintf(stderr, "%02d%02d%02d %02d:%02d:%02d %ld ", t->tm_year % 100, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, (long)getpid()); fprintf(stderr, format, a, b, c, d, e, f, g); fflush(stderr); } #endif /* !HAVE_VFPRINTF */ void #if defined(HAVE_VFPRINTF) && defined(HAVE_STDARG_H) restart_kom(const char * format, ...) #else restart_kom(format, a, b, c, d, e, f, g) const char *format; int a, b, c, d, e, f, g; #endif { #if defined(HAVE_VFPRINTF) && defined(HAVE_STDARG_H) va_list AP; #endif #if defined(HAVE_GETCWD) char pathname[1026]; #else /* !defined(HAVE_GETCWD) */ /* getwd should be in sys/param.h, but if we are on such an old system that it doesn't have getcwd, we can probably not count on that. */ char *getwd(char *); # if defined(MAXPATHLEN) char pathname[MAXPATHLEN]; # else char pathname[1024]; # endif /* !defined(MAXPATHLEN) */ #endif /* !defined(HAVE_GETCWD) */ #if defined(HAVE_VFPRINTF) && defined(HAVE_STDARG_H) va_start(AP, format); kom_logv(format, AP); va_end(AP); #else kom_log(format, a, b, c, d, e, f, g); #endif kom_log("Previous message is fatal. Will dump core now.\n"); #ifdef HAVE_GETCWD /* getcwd is POSIX, so try that first. */ if (getcwd(pathname, 1026) == NULL) kom_log("getcwd failed: errno %d\n", errno); else kom_log("Search for the core in %s\n", pathname); #else if ( getwd(pathname) == NULL ) kom_log("getwd failed: %s\n", pathname); else kom_log("Search for the core in %s\n", pathname); #endif #ifdef AVOID_ABORTS exit(255); #else abort(); #endif } lyskom-server-2.1.2/src/server/ram-smalloc.c0000664000015100472110000002571607721716130014504 /* * $Id: ram-smalloc.c,v 0.41 2003/08/23 16:38:14 ceder Exp $ * Copyright (C) 1991-1996, 1998-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * smalloc.c * * Contains memory allocator routines * * TEST VERSION by ceder */ #ifdef HAVE_CONFIG_H # include #endif /* * Finding memory leaks * ==================== * * This code contains some stubs that can be useful when hunting for * memory leaks. To use it, you must configure with * --with-traced-allocations and recompile. You actually only need to * recompile ram-smalloc.c, ramkomd.c and the programs in testsuite * after changing it, so "make -t; rm src/server/ram-smalloc.o \ * src/server/ramkomd.o src/server/testsuite/test-*.o; make" is the * fastest way to change between tracing and a normal compile. * * Run the resulting lyskomd under gdb, like this: * bash$ gdb lyskomd * (gdb) source trace-mem.gdb * (gdb) run * Where does the trace want to go today? [stderr] RET * gdb will print a backtrace and continue whenever memory is * allocated, reallocated or released. The program itself will also * print out some information. The result is a long log file. * * Run M-x resolve-trace (from handle-malloc-dump.el on the resulting * output. Look in the *Result* buffer for the result. * * Using the test suite to find memory leaks * ========================================= * * This code can also be used together with the test suite, even * though that is slightly more complicated. Begin by starting a gdb * whose output is saved, for example by running it in a shell buffer * in emacs (note: do not use M-x gdb -- that will slow down the * process and it is slow enough as it is): * bash$ gdb lyskomd * (gdb) source trace-mem.gdb * (gdb) shell tty * /dev/ttypd * Pass ATTACH=yes and MEMTRACE to runtest. MEMTRACE should be set * to the tty where gdb is running. Start the test suite: * bash$ runtest --tool lyskomd leaks.0/99.exp ATTACH=yes MEMTRACE=/dev/ttypd * [...] * Please attach to lyskomd pid 4711 and hit RETURN * Attach to the process: * (gdb) attach 4711 * (gdb) continue * Press enter to resume the test suite. Lots of output should appear * from gdb. * * You can do all this automatically for test cases that succeed in * starting the server and only start it once. * * emacs -batch -l handle-malloc-dump.el --tool leaks --test 99.exp * * This will do the above in an Emacs, then run the trace analysis * and print the results on standard output. Use --usage to get a * summary of available options (--help was already taken by Emacs.) * * This does not work with all Emacs versions. * */ #ifdef HAVE_STDLIB_H # include #endif #include #include #include #include /* The order between inttypes.h and stdint.h is mandated by autoconf-2.57. */ #if HAVE_INTTYPES_H # include #else # if HAVE_STDINT_H # include # endif #endif #include "exp.h" #include "s-string.h" #include "kom-types.h" #include "lyskomd.h" #include "server/smalloc.h" #ifdef TRACED_ALLOCATIONS # include "trace-alloc.h" #endif #include "eintr.h" static int no_of_allocated_blocks = 0; /* When using our own malloc guard areas, the memory layout looks like this, where U is sizeof(union overhead), and S is the size of the requested block. offset what ====== ==== 0: magic cookie (stored in an union overhead) (see below) U: the size S (an union overhead) 2*U: S bytes of data returned to the user. S+2*U: guard byte: 0x89 1+S+2*U: guard byte: 0xA7 2+S+2*U: one past the end of the block allocated with malloc(). The total overhead is thus 2*U + 2. The macro OVERHEAD adds the specified overead to S and returns the size we request from the system malloc. The magic cookie reflects the status of the block and is used for defensive checks. The constants are defined below: SMALLOC_MAGIC_ALLOC: an allocated block. SMALLOC_MAGIC_FREE: a block that was previously allocated. */ #ifdef USE_MALLOC_GUARDS /* A union of "all types", used to get the maximum alignment needed for any type. */ union overhead { /* We prefer to store stuf in a size_t, since we are storing a size. Use an unsigned int if size_t isn't available. */ # ifdef HAVE_SIZE_T size_t val; unsigned int a; # else unsigned int val; # endif void *b; long c; long *d; long long e; long long *f; float g; double h; void (*i)(void); long double j; # ifdef HAVE_INTPTR_T intptr_t k; # endif # ifdef HAVE_INTMAX_T intmax_t l; # endif }; # define OVERHEAD(s) ((s) + (2*sizeof(union overhead) + 2)) # define SMALLOC_MAGIC_ALLOC 0x12FE56A0u # define SMALLOC_MAGIC_FREE 0xCA348E63u #else /* When malloc() or realloc() is asked to allocate a 0-sized area, they may return NULL to indicate success. We are not prepared for that behaviour, so we always allocate at least 1 byte. */ # define OVERHEAD(s) (((s) == 0) ? 1 : s) #endif #ifdef TRACED_ALLOCATIONS static FILE *malloc_fp = NULL; void trace_alloc_file(const char *loc) { if (loc[0] == '\0') malloc_fp = stderr; else malloc_fp = i_fopen(loc, "w"); if (malloc_fp == NULL) restart_kom("init_malloc_fp failed: %s, %d\n", loc, errno); fprintf(malloc_fp, "A new trace from lyskomd starts here\n"); } static void trace_smalloc(size_t size, void *result) { assert(malloc_fp != NULL); fprintf(malloc_fp, "smalloc:\nArg: 0x%lx\nRes: 0x%lx\n", (long)size, (long)result); fprintf(malloc_fp, "==== end ====\n"); fflush(malloc_fp); } #endif /* * "safe" malloc. Handles the case when malloc returns NULL. * smalloc cannot fail. */ EXPORT void * smalloc(size_t size) { union overhead *p; p = malloc(OVERHEAD(size)); if (p == NULL) restart_kom("Can't allocate %lu bytes.\n", (unsigned long)size); ++no_of_allocated_blocks; #ifdef USE_MALLOC_GUARDS p->val = SMALLOC_MAGIC_ALLOC; p++; p->val = size; p++; ((unsigned char *) p)[size] = 0x89; ((unsigned char *) p)[size+1] = 0xA7; #endif #ifdef TRACED_ALLOCATIONS trace_smalloc(size, p); #endif return p; } #ifdef TRACED_ALLOCATIONS static void trace_free(void *block) { assert(malloc_fp != NULL); fprintf(malloc_fp, "sfree:\nArg: 0x%lx\n", (long)block); fprintf(malloc_fp, "==== end ====\n"); fflush(malloc_fp); } #endif EXPORT void sfree(void * ptr) /* it is legal to sfree a NULL pointer */ { #ifdef USE_MALLOC_GUARDS union overhead *ip; #endif if ( ptr != NULL ) { #ifdef TRACED_ALLOCATIONS trace_free(ptr); #endif #ifndef USE_MALLOC_GUARDS free(ptr); --no_of_allocated_blocks; #else ip = (union overhead *)ptr; ip -= 2; switch (ip->val) { case SMALLOC_MAGIC_ALLOC: if (((unsigned char *) (ip+2))[ip[1].val] != 0x89 || ((unsigned char *) (ip+2))[ip[1].val+1] != 0xA7) restart_kom("SFREE: Buffer overflow, bsize = %ul\n", ip[1].val); --no_of_allocated_blocks; ip->val = SMALLOC_MAGIC_FREE; free(ip); break; case SMALLOC_MAGIC_FREE: restart_kom("SFREE: Trying to free already freed block\n"); default: restart_kom("SFREE: Illegal magic number\n"); } #endif } } #ifdef TRACED_ALLOCATIONS static void trace_srealloc(size_t size, void *arg, void *result) { assert(malloc_fp != NULL); fprintf(malloc_fp, "srealloc:\nSize: 0x%lx\nArg: 0x%lx\nRes: 0x%lx\n", (long)size, (long)arg, (long)result); fprintf(malloc_fp, "==== end ====\n"); fflush(malloc_fp); } #endif EXPORT void * srealloc(void * ptr, size_t size) /* Never fails. It is legal to */ { /* realloc the NULL ptr. */ union overhead * ip; union overhead * new_ptr; if ( ptr == NULL ) return smalloc(size); ip = (union overhead *)ptr; #ifdef USE_MALLOC_GUARDS ip -= 2; switch (ip->val) { case SMALLOC_MAGIC_ALLOC: break; case SMALLOC_MAGIC_FREE: restart_kom("SREALLOC: Trying to realloc freed block\n"); default: restart_kom("SREALLOC: Illegal magic number\n"); } if (((unsigned char *) (ip+2))[ip[1].val] != 0x89 || ((unsigned char *) (ip+2))[ip[1].val+1] != 0xA7) restart_kom("SREALLOC: Buffer overflow, osize = %ul, nsize = %lu.\n", ip[1].val, (unsigned long)size); ip->val = SMALLOC_MAGIC_FREE; #endif if ((new_ptr = realloc(ip, OVERHEAD(size))) == NULL) { restart_kom("Out of memory - can't realloc. ptr = %lu size = %lu.\n", (unsigned long)ptr, (unsigned long)size); } #ifdef USE_MALLOC_GUARDS new_ptr->val = SMALLOC_MAGIC_ALLOC; new_ptr++; new_ptr->val = size; new_ptr++; ((unsigned char *) new_ptr)[size] = 0x89; ((unsigned char *) new_ptr)[size+1] = 0xA7; #endif #ifdef TRACED_ALLOCATIONS trace_srealloc(size, ptr, new_ptr); #endif return (void *) new_ptr; } /* * Allocate temporary memory, which is automatically freed after this * atomic call. */ static void **tmp_alloc_table = NULL; static int tmp_alloc_table_size = 0; /* Size */ static int tmp_alloc_table_use = 0; /* Used size */ EXPORT void * tmp_alloc(unsigned long size) { if ( tmp_alloc_table_size <= tmp_alloc_table_use ) { /* Need to increas table. */ tmp_alloc_table = srealloc (tmp_alloc_table, ((++tmp_alloc_table_size) * sizeof (void *))); } return (tmp_alloc_table[ tmp_alloc_table_use++ ] = smalloc (size)); } /* * Free all core which is allocated with tmp_alloc(). This is called from * end_of_atomic(). */ EXPORT void free_tmp(void) { int i; for ( i = 0; i < tmp_alloc_table_use; i++ ) { sfree ( tmp_alloc_table[ i ] ); tmp_alloc_table[ i ] = NULL; } tmp_alloc_table_use = 0; } EXPORT void free_all_tmp(void) { free_tmp(); sfree( tmp_alloc_table ); tmp_alloc_table = NULL; tmp_alloc_table_size = 0; } EXPORT void dump_smalloc_counts(FILE *stat_file) { fprintf(stat_file, "---ram-smalloc.c:\n%s%d\n", "\tAllocated blocks (grand total): ", no_of_allocated_blocks); } lyskom-server-2.1.2/src/server/memory.c0000664000015100472110000003775307721716127013617 /* * $Id: memory.c,v 0.48 2003/08/23 16:38:15 ceder Exp $ * Copyright (C) 1991-1994, 1996-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * Memory allocators/deallocators/initializers. * * These functions should be used instead of smalloc/srealloc. */ #if HAVE_CONFIG_H # include #endif #include #ifdef HAVE_STRING_H # include #endif #include #include "timewrap.h" #include "s-string.h" #include "kom-types.h" #include "kom-memory.h" #include "server/smalloc.h" #include "log.h" #include "lyskomd.h" #include "local-to-global.h" static int person_cnt = 0; static int conference_cnt = 0; static int text_stat_cnt = 0; /* Forward declarations */ static void clear_mark_list (Mark_list *mark_list); static Mark_list copy_mark_list (Mark_list ml); static void clear_member_list (Member_list *m); static Member_list copy_member_list (Member_list ml); static void clear_membership (Membership *mship); static Membership copy_membership (Membership m); static void clear_membership_list (Membership_list *mlist); static Membership_list copy_membership_list (Membership_list ml); static void copy_aux_item_list(Aux_item_list *dest, const Aux_item_list *src); /* Conf_type */ void init_conf_type(Conf_type *ct) { ct->rd_prot = 0; ct->original = 0; ct->secret = 0; ct->letter_box = 0; ct->allow_anon = 1; ct->forbid_secret = 0; ct->reserved2 = 0; ct->reserved3 = 0; } /* Conference */ Conference * alloc_conference(void) { Conference *c; conference_cnt++; c = smalloc(sizeof(Conference)); init_conference(c); return c; } void free_conference(Conference *confp) { if ( confp == NULL ) return; conference_cnt--; clear_conference(confp); l2g_destruct(&confp->texts); sfree(confp); } void clear_conference(Conference *confp) { s_clear(&confp->name); clear_member_list(&confp->members); l2g_clear(&confp->texts); free_aux_item_list(&confp->aux_item_list); init_conference(confp); } Conference * copy_conference (const Conference *o) { Conference *c; c = alloc_conference(); c->type = o->type; c->creator = o->creator; c->supervisor = o->supervisor; c->permitted_submitters = o->permitted_submitters; c->super_conf = o->super_conf; c->creation_time = o->creation_time; c->presentation = o->presentation; c->last_written = o->last_written; c->msg_of_day = o->msg_of_day; c->nice = o->nice; c->keep_commented = o->keep_commented; c->expire = o->expire; s_strcpy(&c->name, o->name); c->highest_aux = o->highest_aux; copy_aux_item_list(&c->aux_item_list, &o->aux_item_list); c->members = copy_member_list(o->members); l2g_copy(&c->texts, &o->texts); return c; } void init_conference (Conference *c) { init_conf_type(&c->type); c->creator = 0; c->supervisor = 0; c->permitted_submitters = 0; c->super_conf = 0; c->creation_time = NO_TIME; c->presentation = 0; c->last_written = NO_TIME; c->msg_of_day = 0; c->nice = 0; c->keep_commented = 0; c->highest_aux = 0; c->expire = 0; c->name = EMPTY_STRING; init_member_list(&c->members); l2g_init(&c->texts); init_aux_item_list(&c->aux_item_list); } /* Dynamic_session_info */ void init_dynamic_session_info (Dynamic_session_info *d) { d->session = 0; d->person = 0; d->working_conference = 0; d->idle_time = 0; d->flags.invisible = FALSE; d->flags.user_active_used = FALSE; d->flags.user_absent = FALSE; d->flags.reserved3 = FALSE; d->flags.reserved4 = FALSE; d->flags.reserved5 = FALSE; d->flags.reserved6 = FALSE; d->flags.reserved7 = FALSE; d->what_am_i_doing = EMPTY_STRING; } /* Mark_list */ static void clear_mark_list(Mark_list *mark_list) { if ( mark_list == NULL ) { kom_log("clear_mark_list(): mark_list == NULL.\n"); return; } sfree(mark_list->marks); init_mark_list(mark_list); } static Mark_list copy_mark_list(Mark_list ml) { Mark_list r; r.no_of_marks = ml.no_of_marks; r.marks = smalloc(r.no_of_marks * sizeof(Mark)); memcpy(r.marks, ml.marks, r.no_of_marks * sizeof(Mark)); return r; } void init_mark_list (Mark_list *ml) { ml->no_of_marks = 0; ml->marks = NULL; } /* Member_list */ static void clear_member_list(Member_list *m) { if ( m == NULL ) return; sfree(m->members); init_member_list(m); } static Member_list copy_member_list(Member_list ml) { Member_list res; res.no_of_members = ml.no_of_members; res.members = smalloc(res.no_of_members * sizeof ( Member )); memcpy(res.members, ml.members, res.no_of_members * sizeof ( Member )); return res; } void init_member_list (Member_list *ml) { ml->no_of_members = 0; ml->members = NULL; } /* Member */ void init_member(Member *mem) { if (mem == NULL) { kom_log("init_member(): mem == NULL.\n"); return; } mem->member = 0; mem->added_by = 0; mem->added_at = NO_TIME; init_membership_type(&mem->type); } /* Membership */ static void clear_membership(Membership *mship) { if ( mship == NULL ) { kom_log("clear_membership(): mship == NULL.\n"); return; } sfree(mship->read_ranges); init_membership(mship); } static Membership copy_membership(Membership m) { Membership res; res = m; if (m.no_of_read_ranges != 0) { res.read_ranges = smalloc(m.no_of_read_ranges * sizeof(res.read_ranges[0])); memcpy(res.read_ranges, m.read_ranges, m.no_of_read_ranges * sizeof(res.read_ranges[0])); } else if (m.read_ranges != NULL) { kom_log("copy_membership(): " "read_ranges != NULL but no_of_read_ranges == 0\n"); res.read_ranges = NULL; } return res; } void init_membership_type(Membership_type *m) { m->invitation = 0; m->passive = 0; m->secret = 0; m->passive_message_invert = 0; m->reserved2 = 0; m->reserved3 = 0; m->reserved4 = 0; m->reserved5 = 0; } void init_membership(Membership *m) { m->conf_no = 0; m->priority = 0; m->no_of_read_ranges = 0; m->read_ranges = NULL; m->last_time_read = NO_TIME; m->added_by = 0; m->position = 0; m->added_at = NO_TIME; init_membership_type(&m->type); m->skip_read_texts = FALSE; } /* Membership_list */ static void clear_membership_list(Membership_list *mlist) { int i; if ( mlist == NULL ) { kom_log("clear_membership_list(): membership_list == NULL.\n"); return; } for ( i = 0; i < mlist->no_of_confs; i++ ) { clear_membership(&mlist->confs[i]); } sfree(mlist->confs); init_membership_list(mlist); } static Membership_list copy_membership_list(Membership_list ml) { Membership_list r; int i; r.no_of_confs = ml.no_of_confs; r.confs = smalloc(ml.no_of_confs * sizeof(Membership)); for ( i = 0; i < r.no_of_confs; i++ ) { r.confs[i] = copy_membership(ml.confs[i]); } return r; } void init_membership_list (Membership_list *m) { m->no_of_confs = 0; m->confs = NULL; } /* Static_session_info */ void init_static_session_info (Static_session_info *d) { d->username = EMPTY_STRING; d->hostname = EMPTY_STRING; d->ident_user = EMPTY_STRING; d->connection_time = NO_TIME; } /* Person */ Person * alloc_person(void) { Person *p; person_cnt++; p = smalloc(sizeof(Person)); init_person(p); return p; } void free_person(Person *person) { if ( person == NULL ) return; person_cnt--; clear_person(person); l2g_destruct(&person->created_texts); sfree(person); } void clear_person(Person *person) { s_clear(&person->username); l2g_clear(&person->created_texts); clear_mark_list(&person->marks); clear_membership_list(&person->conferences); init_person(person); } Person * copy_person(const Person *p) { Person *c; c = alloc_person(); c->user_area = p->user_area; c->privileges = p->privileges; c->flags = p->flags; c->last_login = p->last_login; c->total_time_present = p->total_time_present; c->sessions = p->sessions; c->created_lines = p->created_lines; c->created_bytes = p->created_bytes; c->read_texts = p->read_texts; c->no_of_text_fetches = p->no_of_text_fetches; c->created_persons = p->created_persons; c->created_confs = p->created_confs; s_strcpy(&c->username, p->username); l2g_copy(&c->created_texts, &p->created_texts); c->marks = copy_mark_list(p->marks); c->conferences = copy_membership_list(p->conferences); memcpy(&c->pwd, &p->pwd, sizeof(Password)); return c; } void init_person (Person *p) { p->user_area = 0; p->total_time_present = 0; p->sessions = 0; p->created_lines = 0; p->created_bytes = 0; p->read_texts = 0; p->no_of_text_fetches = 0; p->created_persons = 0; p->created_confs = 0; p->username = EMPTY_STRING; p->last_login = NO_TIME; init_priv_bits(&p->privileges); init_personal_flags(&p->flags); l2g_init(&p->created_texts); init_mark_list(&p->marks); init_membership_list(&p->conferences); /* No initialization of pwd is really needed, but this shuts up valgrind. */ memset(p->pwd, 0, PASSWD_LEN); } /* Personal_flags */ void init_personal_flags (Personal_flags *p) { p->unread_is_secret = 0; p->flg2 = 0; p->flg3 = 0; p->flg4 = 0; p->flg5 = 0; p->flg6 = 0; p->flg7 = 0; p->flg8 = 0; } /* Priv_bits */ void init_priv_bits (Priv_bits *pb) { pb->wheel = 0; pb->admin = 0; pb->statistic = 0; pb->create_pers = 0; pb->create_conf = 0; pb->change_name = 0; pb->flg7 = 0; pb->flg8 = 0; pb->flg9 = 0; pb->flg10 = 0; pb->flg11 = 0; pb->flg12 = 0; pb->flg13 = 0; pb->flg14 = 0; pb->flg15 = 0; pb->flg16 = 0; } /* Session_info */ void init_session_info (Session_info *s) { s->person = 0; s->what_am_i_doing = EMPTY_STRING; s->username = EMPTY_STRING; s->working_conference = 0; s->session = 0; s->connection_time = NO_TIME; s->idle_time = 0; } /* Session_info_ident */ void init_session_info_ident (Session_info_ident *s) { s->person = 0; s->what_am_i_doing = EMPTY_STRING; s->username = EMPTY_STRING; s->ident_user = EMPTY_STRING; s->hostname = EMPTY_STRING; s->working_conference = 0; s->session = 0; s->connection_time = NO_TIME; s->idle_time = 0; } /* Text_stat */ Text_stat * alloc_text_stat(void) { Text_stat *t; text_stat_cnt++; t = smalloc(sizeof(Text_stat)); init_text_stat(t); return t; } void free_text_stat(Text_stat *t) { if ( t == NULL ) return; text_stat_cnt--; clear_text_stat(t); sfree(t); } void clear_text_stat(Text_stat *t) { int i; for ( i = 0; i < t->no_of_misc; i++ ) { switch ( t->misc_items[ i ].type ) { case recpt: case cc_recpt: case bcc_recpt: case comm_to: case comm_in: case footn_to: case footn_in: case loc_no: case rec_time: case sent_by: case sent_at: /* No need to free anything for these. */ break; default: restart_kom("clear_text_stat(): unknown enum info_type %d.", t->misc_items[ i ].type); } } sfree(t->misc_items); free_aux_item_list(&t->aux_item_list); init_text_stat(t); } Text_stat * copy_text_stat(const Text_stat *t) { Text_stat *c; c = alloc_text_stat(); c->creation_time = t->creation_time; c->file_pos = t->file_pos; c->author = t->author; c->no_of_lines = t->no_of_lines; c->no_of_chars = t->no_of_chars; c->no_of_marks = t->no_of_marks; c->no_of_misc = t->no_of_misc; c->highest_aux = t->highest_aux; c->misc_items = smalloc(c->no_of_misc * sizeof(Misc_info)); memcpy(c->misc_items, t->misc_items, c->no_of_misc * sizeof(Misc_info)); copy_aux_item_list(&c->aux_item_list, &t->aux_item_list); return c; } void init_text_stat (Text_stat *t) { t->creation_time = NO_TIME; t->file_pos = 0; t->author = 0; t->no_of_lines = 0; t->no_of_chars = 0; t->no_of_marks = 0; t->no_of_misc = 0; t->highest_aux = 0; t->misc_items = NULL; init_aux_item_list(&t->aux_item_list); } /* struct tm */ void init_struct_tm (struct tm *t) { t->tm_sec = 0; t->tm_min = 0; t->tm_hour = 0; t->tm_mday = 0; t->tm_mon = 0; t->tm_year = 0; t->tm_wday = 0; t->tm_yday = 0; t->tm_isdst = 0; } /* Who_info */ void init_who_info (Who_info *w) { w->person = 0; w->what_am_i_doing = EMPTY_STRING; w->username = EMPTY_STRING; w->working_conference = 0; w->session_no = 0; } /* Who_info_ident */ void init_who_info_ident (Who_info_ident *w) { w->person = 0; w->what_am_i_doing = EMPTY_STRING; w->username = EMPTY_STRING; w->ident_user = EMPTY_STRING; w->hostname = EMPTY_STRING; w->working_conference = 0; w->session_no = 0; } /* Who_info_old */ void init_who_info_old (Who_info_old *w) { w->person = 0; w->what_am_i_doing = EMPTY_STRING; w->working_conference = 0; } /* Aux_item_list */ void free_aux_item_list(Aux_item_list *list) { unsigned long i; if (list->items != NULL) { for (i = 0; i < list->length; i++) clear_aux_item(&list->items[i]); } list->length = 0; sfree(list->items); list->items = NULL; } static void copy_aux_item_list(Aux_item_list *dest, const Aux_item_list *src) { unsigned long i; dest->length = src->length; dest->items = smalloc(sizeof(Aux_item) * src->length); for (i = 0; i < src->length; i++) { copy_aux_item(&dest->items[i], &src->items[i]); } } void init_aux_item_list(Aux_item_list *list) { list->length = 0; list->items = NULL; } void init_aux_item_link(Aux_item_link *dest) { dest->target_type = NO_OBJECT_TYPE; dest->target_item = 0; dest->target_object.conf = 0; dest->target_object.text = 0; } void init_aux_item_flags(Aux_item_flags *dest) { dest->deleted = 0; dest->inherit = 0; dest->secret = 0; dest->hide_creator = 0; dest->dont_garb = 0; dest->reserved3 = 0; dest->reserved4 = 0; dest->reserved5 = 0; } void init_aux_item(Aux_item *dest) { dest->aux_no = 0; dest->creator = 0; dest->sent_at = 0; dest->inherit_limit = 0; dest->tag = 0; dest->data = EMPTY_STRING; init_aux_item_flags(&dest->flags); init_aux_item_link(&dest->linked_item); } void clear_aux_item(Aux_item *item) { s_clear(&item->data); init_aux_item(item); } void copy_aux_item(Aux_item *dest, const Aux_item *src) { dest->aux_no = src->aux_no; dest->creator = src->creator; dest->sent_at = src->sent_at; dest->flags = src->flags; dest->inherit_limit = src->inherit_limit; dest->tag = src->tag; dest->data = EMPTY_STRING; s_strcpy(&dest->data, src->data); dest->linked_item = src->linked_item; } /* * Other kind of functions */ void dump_alloc_counts(FILE *fp) { fprintf(fp, "---memory.c:\n\tperson: %d\n\tconference: %d\n", person_cnt, conference_cnt); fprintf(fp, "\ttext_stat: %d\n", text_stat_cnt); } lyskom-server-2.1.2/src/server/getopt.c0000664000015100472110000005066106200776335013600 /* Getopt for GNU. NOTE: getopt is now part of the C library, so if you don't know what "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu before changing it! Copyright (C) 1987, 1993, 1996 Free Software Foundation, Inc. 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 2, 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, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* NOTE!!! AIX requires this to be the first thing in the file. Do not put ANYTHING before it! */ #if !defined (__GNUC__) && defined (_AIX) #pragma alloca #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef __GNUC__ #define alloca __builtin_alloca #else /* not __GNUC__ */ #if defined (HAVE_ALLOCA_H) || (defined(sparc) && (defined(sun) || (!defined(USG) && !defined(SVR4) && !defined(__svr4__)))) #include #else #ifndef _AIX char *alloca (); #endif #endif /* alloca.h */ #endif /* not __GNUC__ */ #if !__STDC__ && !defined(const) && IN_GCC #define const #endif /* This tells Alpha OSF/1 not to define a getopt prototype in . */ #ifndef _NO_PROTO #define _NO_PROTO #endif #include #ifdef HAVE_STRING_H # include #endif /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #if defined (_LIBC) || !defined (__GNU_LIBRARY__) /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ #undef alloca /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ #include #else /* Not GNU C library. */ #define __alloca alloca #endif /* GNU C library. */ /* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a long-named option. Because this is not POSIX.2 compliant, it is being phased out. */ /* #define GETOPT_COMPAT */ /* This version of `getopt' appears to the caller like standard Unix `getopt' but it behaves differently for the user, since it allows the user to intersperse the options with the other arguments. As `getopt' works, it permutes the elements of ARGV so that, when it is done, all the options precede everything else. Thus all application programs are extended to handle flexible argument order. Setting the environment variable POSIXLY_CORRECT disables permutation. Then the behavior is completely standard. GNU application programs can use a third alternative mode in which they can distinguish the relative order of options and other arguments. */ #include "getopt.h" /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ char *optarg = 0; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ /* XXX 1003.2 says this must be 1 before any call. */ int optind = 0; /* The next char to be scanned in the option-element in which the last option character we returned was found. This allows us to pick up the scan where we left off. If this is zero, or a null string, it means resume the scan by advancing to the next ARGV-element. */ static char *nextchar; /* Callers store zero here to inhibit the error message for unrecognized options. */ int opterr = 1; /* Set to an option character which was unrecognized. This must be initialized on some systems to avoid linking in the system's own getopt implementation. */ int optopt = '?'; /* Describe how to deal with options that follow non-option ARGV-elements. If the caller did not specify anything, the default is REQUIRE_ORDER if the environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise. REQUIRE_ORDER means don't recognize them as options; stop option processing when the first non-option is seen. This is what Unix does. This mode of operation is selected by either setting the environment variable POSIXLY_CORRECT, or using `+' as the first character of the list of option characters. PERMUTE is the default. We permute the contents of ARGV as we scan, so that eventually all the non-options are at the end. This allows options to be given in any order, even with programs that were not written to expect this. RETURN_IN_ORDER is an option available to programs that were written to expect options and other ARGV-elements in any order and that care about the ordering of the two. We describe each non-option ARGV-element as if it were the argument of an option with character code 1. Using `-' as the first character of the list of option characters selects this mode of operation. The special argument `--' forces an end of option-scanning regardless of the value of `ordering'. In the case of RETURN_IN_ORDER, only `--' can cause `getopt' to return EOF with `optind' != ARGC. */ static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; #ifdef __GNU_LIBRARY__ /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. On some systems, it contains special magic macros that don't work in GCC. */ #include #define my_index strchr #define my_bcopy(src, dst, n) memcpy ((dst), (src), (n)) #else /* Avoid depending on library functions or files whose names are inconsistent. */ char *getenv (); static char * my_index (str, chr) const char *str; int chr; { while (*str) { if (*str == chr) return (char *) str; str++; } return 0; } static void my_bcopy (from, to, size) const char *from; char *to; int size; { int i; for (i = 0; i < size; i++) to[i] = from[i]; } #endif /* GNU C library. */ /* Handle permutation of arguments. */ /* Describe the part of ARGV that contains non-options that have been skipped. `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is the index after the last of them. */ static int first_nonopt; static int last_nonopt; /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) which contains all the non-options that have been skipped so far. The other is elements [last_nonopt,optind), which contains all the options processed since those non-options were skipped. `first_nonopt' and `last_nonopt' are relocated so that they describe the new indices of the non-options in ARGV after they are moved. */ static void exchange (argv) char **argv; { int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *); char **temp = (char **) __alloca (nonopts_size); /* Interchange the two blocks of data in ARGV. */ my_bcopy ((char *) &argv[first_nonopt], (char *) temp, nonopts_size); my_bcopy ((char *) &argv[last_nonopt], (char *) &argv[first_nonopt], (optind - last_nonopt) * sizeof (char *)); my_bcopy ((char *) temp, (char *) &argv[first_nonopt + optind - last_nonopt], nonopts_size); /* Update records for the slots the non-options now occupy. */ first_nonopt += (optind - last_nonopt); last_nonopt = optind; } /* Scan elements of ARGV (whose length is ARGC) for option characters given in OPTSTRING. If an element of ARGV starts with '-', and is not exactly "-" or "--", then it is an option element. The characters of this element (aside from the initial '-') are option characters. If `getopt' is called repeatedly, it returns successively each of the option characters from each of the option elements. If `getopt' finds another option character, it returns that character, updating `optind' and `nextchar' so that the next call to `getopt' can resume the scan with the following option character or ARGV-element. If there are no more option characters, `getopt' returns `EOF'. Then `optind' is the index in ARGV of the first ARGV-element that is not an option. (The ARGV-elements have been permuted so that those that are not options now come last.) OPTSTRING is a string containing the legitimate option characters. If an option character is seen that is not listed in OPTSTRING, return '?' after printing an error message. If you set `opterr' to zero, the error message is suppressed but we still return '?'. If a char in OPTSTRING is followed by a colon, that means it wants an arg, so the following text in the same ARGV-element, or the text of the following ARGV-element, is returned in `optarg'. Two colons mean an option that wants an optional arg; if there is text in the current ARGV-element, it is returned in `optarg', otherwise `optarg' is set to zero. If OPTSTRING starts with `-' or `+', it requests different methods of handling the non-option ARGV-elements. See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. Long-named options begin with `--' instead of `-'. Their names may be abbreviated as long as the abbreviation is unique or is an exact match for some defined option. If they have an argument, it follows the option name in the same ARGV-element, separated from the option name by a `=', or else the in next ARGV-element. When `getopt' finds a long-named option, it returns 0 if that option's `flag' field is nonzero, the value of the option's `val' field if the `flag' field is zero. The elements of ARGV aren't really const, because we permute them. But we pretend they're const in the prototype to be compatible with other systems. LONGOPTS is a vector of `struct option' terminated by an element containing a name which is zero. LONGIND returns the index in LONGOPT of the long-named option found. It is only valid when a long-named option has been found by the most recent call. If LONG_ONLY is nonzero, '-' as well as '--' can introduce long-named options. */ int _getopt_internal (argc, argv, optstring, longopts, longind, long_only) int argc; char *const *argv; const char *optstring; const struct option *longopts; int *longind; int long_only; { int option_index; optarg = 0; /* Initialize the internal data when the first call is made. Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped non-option ARGV-elements is empty. */ if (optind == 0) { first_nonopt = last_nonopt = optind = 1; nextchar = NULL; /* Determine how to handle the ordering of options and nonoptions. */ if (optstring[0] == '-') { ordering = RETURN_IN_ORDER; ++optstring; } else if (optstring[0] == '+') { ordering = REQUIRE_ORDER; ++optstring; } else if (getenv ("POSIXLY_CORRECT") != NULL) ordering = REQUIRE_ORDER; else ordering = PERMUTE; } if (nextchar == NULL || *nextchar == '\0') { if (ordering == PERMUTE) { /* If we have just processed some options following some non-options, exchange them so that the options come first. */ if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (last_nonopt != optind) first_nonopt = optind; /* Now skip any additional non-options and extend the range of non-options previously skipped. */ while (optind < argc && (argv[optind][0] != '-' || argv[optind][1] == '\0') #ifdef GETOPT_COMPAT && (longopts == NULL || argv[optind][0] != '+' || argv[optind][1] == '\0') #endif /* GETOPT_COMPAT */ ) optind++; last_nonopt = optind; } /* Special ARGV-element `--' means premature end of options. Skip it like a null option, then exchange with previous non-options as if it were an option, then skip everything else like a non-option. */ if (optind != argc && !strcmp (argv[optind], "--")) { optind++; if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (first_nonopt == last_nonopt) first_nonopt = optind; last_nonopt = argc; optind = argc; } /* If we have done all the ARGV-elements, stop the scan and back over any non-options that we skipped and permuted. */ if (optind == argc) { /* Set the next-arg-index to point at the non-options that we previously skipped, so the caller will digest them. */ if (first_nonopt != last_nonopt) optind = first_nonopt; return EOF; } /* If we have come to a non-option and did not permute it, either stop the scan or describe it to the caller and pass it by. */ if ((argv[optind][0] != '-' || argv[optind][1] == '\0') #ifdef GETOPT_COMPAT && (longopts == NULL || argv[optind][0] != '+' || argv[optind][1] == '\0') #endif /* GETOPT_COMPAT */ ) { if (ordering == REQUIRE_ORDER) return EOF; optarg = argv[optind++]; return 1; } /* We have found another option-ARGV-element. Start decoding its characters. */ nextchar = (argv[optind] + 1 + (longopts != NULL && argv[optind][1] == '-')); } if (longopts != NULL && ((argv[optind][0] == '-' && (argv[optind][1] == '-' || long_only)) #ifdef GETOPT_COMPAT || argv[optind][0] == '+' #endif /* GETOPT_COMPAT */ )) { const struct option *p; char *s = nextchar; int exact = 0; int ambig = 0; const struct option *pfound = NULL; int indfound; while (*s && *s != '=') s++; /* Test all options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, s - nextchar)) { if (s - nextchar == strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (opterr) fprintf (stderr, "%s: option `%s' is ambiguous\n", argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; return '?'; } if (pfound != NULL) { option_index = indfound; optind++; if (*s) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = s + 1; else { if (opterr) { if (argv[optind - 1][1] == '-') /* --option */ fprintf (stderr, "%s: option `--%s' doesn't allow an argument\n", argv[0], pfound->name); else /* +option or -option */ fprintf (stderr, "%s: option `%c%s' doesn't allow an argument\n", argv[0], argv[optind - 1][0], pfound->name); } nextchar += strlen (nextchar); return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (opterr) fprintf (stderr, "%s: option `%s' requires an argument\n", argv[0], argv[optind - 1]); nextchar += strlen (nextchar); return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } /* Can't find it as a long option. If this is not getopt_long_only, or the option starts with '--' or is not a valid short option, then it's an error. Otherwise interpret it as a short option. */ if (!long_only || argv[optind][1] == '-' #ifdef GETOPT_COMPAT || argv[optind][0] == '+' #endif /* GETOPT_COMPAT */ || my_index (optstring, *nextchar) == NULL) { if (opterr) { if (argv[optind][1] == '-') /* --option */ fprintf (stderr, "%s: unrecognized option `--%s'\n", argv[0], nextchar); else /* +option or -option */ fprintf (stderr, "%s: unrecognized option `%c%s'\n", argv[0], argv[optind][0], nextchar); } nextchar = (char *) ""; optind++; return '?'; } } /* Look at and handle the next option-character. */ { char c = *nextchar++; char *temp = my_index (optstring, c); /* Increment `optind' when we start to process its last character. */ if (*nextchar == '\0') ++optind; if (temp == NULL || c == ':') { if (opterr) { #if 0 if (c < 040 || c >= 0177) fprintf (stderr, "%s: unrecognized option, character code 0%o\n", argv[0], c); else fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c); #else /* 1003.2 specifies the format of this message. */ fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c); #endif } optopt = c; return '?'; } if (temp[1] == ':') { if (temp[2] == ':') { /* This is an option that accepts an argument optionally. */ if (*nextchar != '\0') { optarg = nextchar; optind++; } else optarg = 0; nextchar = NULL; } else { /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (opterr) { #if 0 fprintf (stderr, "%s: option `-%c' requires an argument\n", argv[0], c); #else /* 1003.2 specifies the format of this message. */ fprintf (stderr, "%s: option requires an argument -- %c\n", argv[0], c); #endif } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; nextchar = NULL; } } return c; } } int getopt (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { return _getopt_internal (argc, argv, optstring, (const struct option *) 0, (int *) 0, 0); } #endif /* _LIBC or not __GNU_LIBRARY__. */ #ifdef TEST /* Compile with -DTEST to make an executable for use in testing the above definition of `getopt'. */ int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; c = getopt (argc, argv, "abc:d:0123456789"); if (c == EOF) break; switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ lyskom-server-2.1.2/src/server/getopt1.c0000664000015100472110000001004006200525730013633 /* getopt_long and getopt_long_only entry points for GNU getopt. Copyright (C) 1987, 1993, 1996 Free Software Foundation, Inc. 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 2, 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, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "getopt.h" #if !__STDC__ && !defined(const) && IN_GCC #define const #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #if defined (_LIBC) || !defined (__GNU_LIBRARY__) /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ #include #else char *getenv (); #endif #ifndef NULL #define NULL 0 #endif int getopt_long (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 0); } /* Like getopt_long, but '-' as well as '--' can indicate a long option. If an option that starts with '-' (not '--') doesn't match a long option, but does match a short option, it is parsed as a short option instead. */ int getopt_long_only (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 1); } #endif /* _LIBC or not __GNU_LIBRARY__. */ #ifdef TEST #include int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; int option_index = 0; static struct option long_options[] = { {"add", 1, 0, 0}, {"append", 0, 0, 0}, {"delete", 1, 0, 0}, {"verbose", 0, 0, 0}, {"create", 0, 0, 0}, {"file", 1, 0, 0}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "abc:d:0123456789", long_options, &option_index); if (c == EOF) break; switch (c) { case 0: printf ("option %s", long_options[option_index].name); if (optarg) printf (" with arg %s", optarg); printf ("\n"); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case 'd': printf ("option d with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ lyskom-server-2.1.2/src/server/misc-types.c0000664000015100472110000000270707720622472014371 /* * Copyright (C) 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * Implementation of the types in misc-type.h. */ #ifdef HAVE_CONFIG_H # include #endif #include "misc-types.h" #if defined(SUCCESS_AS_PTR) || defined(TYPE_CHECK_COMPILATION) static struct success succ_ok; static struct success succ_failure; const struct success *const OK = &succ_ok; const struct success *const FAILURE = &succ_failure; #else /* Some compilers requires translation units to be non-empty. */ extern int misc_types_must_be_nonempty; extern int misc_types_must_be_nonempty = 'm'; #endif lyskom-server-2.1.2/src/server/dbck.c0000664000015100472110000012035407721716126013177 /* * $Id: dbck.c,v 0.76 2003/08/23 16:38:17 ceder Exp $ * Copyright (C) 1991-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * dbck.c - A simple database checker and corrector. * * Author: Per Cederqvist. */ #ifdef HAVE_CONFIG_H # include #endif #ifdef HAVE_STDLIB_H # include #endif #include #ifdef HAVE_STDARG_H # include #endif #include "timewrap.h" #include #ifdef HAVE_CRYPT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif #ifdef HAVE_STRING_H # include #endif #include #include #include #include "getopt.h" #include "misc-types.h" #include "s-string.h" #include "kom-types.h" #include "lyskomd.h" #include "log.h" #include "server/smalloc.h" #include "misc-parser.h" #include "cache.h" #include "kom-config.h" #include "debug.h" #include "dbck-cache.h" #include "param.h" #include "server-config.h" #include "async.h" #include "com.h" #include "connections.h" #include "kom-errno.h" #include "manipulate.h" #include "version-info.h" #include "ram-output.h" #include "unused.h" #include "local-to-global.h" #include "lockdb.h" #include "linkansi.h" #include "eintr.h" #define OPT_PERS_PRESENTATION_CONF 1 #define OPT_CONF_PRESENTATION_CONF 2 #define OPT_MOTD_CONF 3 #define OPT_MOTD_OF_KOM 4 #define OPT_KOM_NEWS_CONF 5 static struct option longopts[] = { {"compact-text-mass", 0, 0, 'g' }, {"interactive", 0, 0, 'i' }, {"auto-repair", 0, 0, 'r' }, {"verbose", 0, 0, 'v' }, {"print-statistics", 0, 0, 's' }, {"list-text-no", 0, 0, 't' }, {"set-change-name", 0, 0, 'c' }, {"clear-password", required_argument, 0, 'P' }, {"grant-all", required_argument, 0, 'G' }, {"output-version", required_argument, 0, 'o' }, {"force-output", 0, 0, 'F' }, {"pers-pres-conf", required_argument, 0, OPT_PERS_PRESENTATION_CONF }, {"conf-pres-conf", required_argument, 0, OPT_CONF_PRESENTATION_CONF }, {"motd-conf", required_argument, 0, OPT_MOTD_CONF }, {"motd-of-kom", required_argument, 0, OPT_MOTD_OF_KOM }, {"kom-news-conf", required_argument, 0, OPT_KOM_NEWS_CONF }, {"help", 0, 0, 'h' }, { 0, 0, 0, 0 } }; extern Info kom_info; /* This is set to TRUE if init_cache finds out that the last part of the database is missing. */ Bool truncated_texts = FALSE; int vflag=0; /* Verbose - list statistics also. */ static int iflag=0; /* Interactive - prompt user and repair. */ static int rflag=0; /* Repair simple error without confirmation. */ static int gflag=0; /* Garbage collect text-file. */ static int sflag=0; /* Statistic flag. */ static Pers_no reset_pwd=0; /* Person whose password should be cleared. */ static Pers_no grant_all=0; /* Person which should receive all bits. */ /* The following variable holds the output format */ long oformat=-1; /* Output format */ static long force_output=0; /* Force sync (for conversions) */ /* The following variables hold kom_info modifications */ int pers_pres_conf = -1; int conf_pres_conf = -1; int motd_conf = -1; Text_no motd_of_lyskom = (Text_no)-1; int kom_news_conf = -1; /* The following variable corresponds to the -c flag, and is present here due to a bug in lyskomd 1.6.1. */ static int unset_change_name_is_error=0; /* A list of all available text numbers was useful when developing new data structures in lyskomd in 1995. Option: -t. */ static int dump_text_numbers=0; int modifications = 0; typedef struct { int created_confs; } Person_scratchpad; static const Person_scratchpad EMPTY_PERSON_SCRATCHPAD = { 0 }; static Person_scratchpad **person_scratchpad = NULL; int buglevel = 0; BUGDECL; struct delete_list { struct delete_list *next; Local_text_no lno; }; static void delete_list_append(struct delete_list **head, Local_text_no lno) { struct delete_list *item = smalloc(sizeof(struct delete_list)); item->next = *head; item->lno = lno; *head = item; } static void execute_deletions(Local_to_global *l2g, struct delete_list **head) { struct delete_list *item; while (*head != NULL) { item = *head; *head = item->next; l2g_delete(l2g, item->lno); sfree(item); } } #if defined(HAVE_VFPRINTF) && defined(HAVE_STDARG_H) extern void kom_log (const char * format, ...) { va_list AP; va_start(AP, format); vfprintf(stdout, format, AP); va_end(AP); } #else extern void kom_log (format, a, b, c, d, e, f, g) const char * format; int a, b, c, d, e, f, g; { fprintf(stdout, format, a, b, c, d, e, f, g); } #endif #if defined(HAVE_VFPRINTF) && defined(HAVE_STDARG_H) extern void restart_kom (const char * format, ...) { va_list AP; va_start(AP, format); vfprintf(stdout, format, AP); va_end(AP); exit(1); } #else extern void restart_kom (format, a, b, c, d, e, f, g) const char * format; int a, b, c, d, e, f, g; { fprintf(stdout, format, a, b, c, d, e, f, g); exit(1); } #endif static Person_scratchpad * alloc_person_scratchpad(void) { Person_scratchpad *p; p = smalloc(sizeof(Person_scratchpad)); *p = EMPTY_PERSON_SCRATCHPAD; return p; } static Bool is_comment_to(Text_no comment, Text_stat *parent) { int i; for ( i = 0; i < parent->no_of_misc; i++ ) { switch( parent->misc_items[ i ].type ) { case comm_in: if ( parent->misc_items[ i ].datum.text_link == comment ) return TRUE; break; default: break; } } return FALSE; } static Bool is_commented_in(Text_no parent, Text_stat *child) { int i; for ( i = 0; i < child->no_of_misc; i++ ) { switch( child->misc_items[ i ].type ) { case comm_to: if ( child->misc_items[ i ].datum.text_link == parent ) return TRUE; break; default: break; } } return FALSE; } static Bool is_footnote_to(Text_no footnote, Text_stat *parent) { int i; for ( i = 0; i < parent->no_of_misc; i++ ) { switch( parent->misc_items[ i ].type ) { case footn_in: if ( parent->misc_items[ i ].datum.text_link == footnote ) return TRUE; break; default: break; } } return FALSE; } static Bool is_footnoted_in(Text_no parent, Text_stat *child) { int i; for ( i = 0; i < child->no_of_misc; i++ ) { switch( child->misc_items[ i ].type ) { case footn_to: if ( child->misc_items[ i ].datum.text_link == parent ) return TRUE; break; default: break; } } return FALSE; } Member * locate_member(Pers_no pers_no, Conference * conf_c) { Member * mbr; int i; for(mbr = conf_c->members.members, i = conf_c->members.no_of_members; i > 0; i--, mbr++) { if ( mbr->member == pers_no ) { return mbr; } } return NULL; } /* * Delete a misc_info. * If it is a recpt, cc_recpt, comm_to or footn_to delete any * loc_no, rec_time, sent_by or sent_at that might follow it. * * Note that the Misc_info is not reallocated. */ static void delete_misc (Text_stat *tstat, Misc_info *misc) /* Pointer to first misc_item to delete. */ { int del = 1; /* Number of items to delete. */ /* Always delete at least one item. */ Bool ready = FALSE; /* Check range of misc */ if (misc < tstat->misc_items || misc >= tstat->misc_items + tstat->no_of_misc ) { restart_kom("delete_misc() - misc out of range\n"); } while (ready == FALSE && misc + del < tstat->misc_items + tstat->no_of_misc ) { switch ( misc[ del ].type ) { case loc_no: case rec_time: case sent_by: case sent_at: del++; break; case recpt: case cc_recpt: case bcc_recpt: case footn_to: case footn_in: case comm_to: case comm_in: ready = TRUE; break; #ifndef COMPILE_CHECKS default: #endif case unknown_info: restart_kom("delete_misc() - illegal misc found.\n"); } } tstat->no_of_misc -= del; /* Move items beyond the deleted ones. */ while ( misc < tstat->misc_items + tstat->no_of_misc ) { misc[ 0 ] = misc[ del ]; misc++; } } static int confirm(const char *question) { if ( iflag ) { fputs(question, stdout); fputs(" (y/n) ", stdout); while(1) switch(getchar()) { case 'y': case 'Y': return 1; case 'n': case 'N': case EOF: return 0; default: break; } } else return 0; } static long check_misc_any_recipient(Text_no tno, Text_stat *tstat, const char *pretty_type, Conf_no rcpt, Local_text_no lno, Misc_info *previous, const Misc_info **misc) { Conference *c; long errors = 0; Local_text_no conf_min; Local_text_no conf_max; c = cached_get_conf_stat(rcpt); if (c == NULL && rcpt == 0) { kom_log("Conference 0 is a %s of text %lu.\n", pretty_type, (unsigned long)tno); if (rflag || confirm("Repair by deleting misc_item? ")) { delete_misc(tstat, previous); kom_log("Repaired: Conference 0 is no longer a %s.\n", pretty_type); mark_text_as_changed(tno); modifications++; *misc = previous; } else errors++; return errors; } if (c == NULL) return errors; /* Check loc_no */ conf_min = l2g_lookup(&c->texts, 0); conf_max = l2g_first_appendable_key(&c->texts); if (lno < conf_min) { kom_log("Text %lu: %s %lu<%lu>: loc_no is less than %lu\n", (unsigned long)tno, pretty_type, (unsigned long)rcpt, (unsigned long)lno, (unsigned long)conf_min); errors++; } else if (lno >= conf_max) { kom_log("Text %lu: %s %lu<%lu>: loc_no is greater than %lu\n", (unsigned long)tno, pretty_type, (unsigned long)rcpt, (unsigned long)lno, (unsigned long)conf_max); errors++; } else if (l2g_lookup(&c->texts, lno) != tno) { kom_log("Text %lu: %s %lu<%lu>: that local number is mapped to %lu.\n", (unsigned long)tno, pretty_type, (unsigned long)rcpt, (unsigned long)lno, (unsigned long)l2g_lookup(&c->texts, lno)); errors++; } return errors; } static long check_misc_infos(Text_no tno, Text_stat *tstat) { const Misc_info * misc = tstat->misc_items; Misc_info * previous; Misc_info_group group; Text_stat *t; long errors=0; while (previous = (Misc_info *)misc, group = parse_next_misc(&misc, tstat->misc_items + tstat->no_of_misc), group.type != m_end_of_list && group.type != m_error ) { switch ( group.type ) { case m_recpt: check_misc_any_recipient(tno, tstat, "recipient", group.recipient, group.local_no, previous, &misc); break; case m_cc_recpt: check_misc_any_recipient(tno, tstat, "cc_recipient", group.cc_recipient, group.local_no, previous, &misc); break; case m_bcc_recpt: check_misc_any_recipient(tno, tstat, "bcc_recipient", group.bcc_recipient, group.local_no, previous, &misc); break; case m_comm_to: t = cached_get_text_stat(group.comment_to); if ( t == NULL ) { kom_log("Text %lu is a comment to %lu, which doesn't exist.\n", (unsigned long)tno, (unsigned long)group.comment_to); if (rflag || confirm("Repair by deleting misc_item? ")) { delete_misc(tstat, previous); mark_text_as_changed(tno); modifications++; kom_log("Repaired: Comment-link deleted.\n"); misc = previous; } else errors++; errors++; } else if (!is_comment_to(tno, t)) { kom_log("Text %lu is a comment to %lu, but not the reverse.\n", (unsigned long)tno, (unsigned long)group.comment_to); errors++; } break; case m_comm_in: t = cached_get_text_stat(group.commented_in); if ( t == NULL ) { kom_log("Text %lu is commented in %lu, which doesn't exist.\n", (unsigned long)tno, (unsigned long)group.commented_in); if (rflag || confirm("Repair by deleting misc_item? ")) { delete_misc(tstat, previous); mark_text_as_changed(tno); modifications++; kom_log("Repaired: Comment-link deleted.\n"); misc = previous; } else errors++; } else if (!is_commented_in(tno, t)) { kom_log("Text %lu is commented in %lu, but not the reverse.\n", (unsigned long)tno, (unsigned long)group.commented_in); errors++; } break; case m_footn_to: t = cached_get_text_stat(group.footnote_to); if ( t == NULL ) { kom_log("Text %lu is a footnote to %lu, which doesn't exist.\n", (unsigned long)tno, (unsigned long)group.footnote_to); if (rflag || confirm("Repair by deleting misc_item? ")) { delete_misc(tstat, previous); mark_text_as_changed(tno); modifications++; kom_log("Repaired: Footnote-link deleted.\n"); misc = previous; } else errors++; } else if (!is_footnote_to(tno, t)) { kom_log("Text %lu is a footnote to %lu, but not the reverse.\n", (unsigned long)tno, (unsigned long)group.footnote_to); errors++; } break; case m_footn_in: t = cached_get_text_stat(group.footnoted_in); if ( t == NULL ) { kom_log("Text %lu is footnoted in %lu, which doesn't exist.\n", (unsigned long)tno, (unsigned long)group.footnoted_in); if (rflag || confirm("Repair by deleting misc_item? ")) { delete_misc(tstat, previous); mark_text_as_changed(tno); modifications++; kom_log("Repaired: Footnote-link deleted.\n"); misc = previous; } else errors++; } else if (!is_footnoted_in(tno, t)) { kom_log("Text %lu is footnoted in %lu, but not the reverse.\n", (unsigned long)tno, (unsigned long)group.footnoted_in); errors++; } break; default: kom_log("check_misc_infos(): parse_next_misc returned type %lu\n", (unsigned long)group.type); break; } } if ( group.type == m_error ) { kom_log("Text %lu has a bad misc_info_list.\n", (unsigned long)tno); errors++; } return errors; } static long check_texts(void) { Text_no ct = 0; Text_stat *ctp=NULL; long errors = 0; Text_no number_of_texts = 0; unsigned long bytes=0; unsigned long max_bytes=0; Text_no max_text=0; while ( (ct = traverse_text(ct)) != 0 ) { number_of_texts++; ctp = cached_get_text_stat( ct ); if ( ctp == NULL ) { kom_log("Text %lu nonexistent.\n", ct); errors++; } else { if (dump_text_numbers) kom_log("Checking text_no %ld\n", (unsigned long)ct); bytes += ctp->no_of_chars; if ( (unsigned long)ctp->no_of_chars > max_bytes ) { max_bytes = ctp->no_of_chars; max_text = ct; } /* FIXME (bug 147): no_of_marks is not yet checked. */ errors += check_misc_infos(ct, ctp); } } if (vflag) { if ( number_of_texts == 0 ) kom_log("WARNING: No texts found.\n"); else { kom_log("Total of %lu texts (total %lu bytes, avg. %lu bytes/text).\n", (unsigned long)number_of_texts, (unsigned long)bytes, (unsigned long)(bytes/number_of_texts)); kom_log("Longest text is %lu (%lu bytes).\n", (unsigned long)max_text, (unsigned long)max_bytes); } } return errors; } static int check_created_texts(Pers_no pno, Local_to_global *created) { Text_stat *t; int errors=0; L2g_iterator iter; struct delete_list *del_list = NULL; for (l2gi_searchall(&iter, created); !iter.search_ended; l2gi_next(&iter)) { assert(iter.tno != 0); assert(iter.lno != 0); t = cached_get_text_stat(iter.tno); if ( t != NULL && t->author != pno) { kom_log("Person %lu is author of text %lu whose author is %lu.\n", (unsigned long)pno, (unsigned long)iter.tno, (unsigned long)t->author); errors++; } if ( t == NULL ) { kom_log("Person %lu is author of text %lu, which doesn't exist.\n", (unsigned long)pno, (unsigned long)iter.tno); if ( rflag || confirm("Repair by setting to text_no to 0 in local map")) { delete_list_append(&del_list, iter.lno); mark_person_as_changed(pno); modifications++; kom_log("Repaired: created_texts corrected.\n"); } else errors++; } } execute_deletions(created, &del_list); return errors; } static int check_membership(Pers_no pno, Membership *mship) { int errors=0; Conference *conf; Local_text_no last=0; Member *mem; struct read_range *begin; struct read_range *end; struct read_range *ptr; conf = cached_get_conf_stat(mship->conf_no); if ( conf == NULL ) { kom_log("Person %lu is a member in the non-existing conference %lu.\n", (unsigned long)pno, (unsigned long)mship->conf_no); errors++; } else { /* Check read texts */ last = 0; if (mship->no_of_read_ranges > 0) { begin = &mship->read_ranges[0]; end = begin + mship->no_of_read_ranges; for (ptr = begin; ptr < end; ptr++) { if (ptr->first_read > ptr->last_read) { kom_log("Person %lu's membership in %lu is corrupt: " "bad range: %lu-%lu.\n", (unsigned long)pno, (unsigned long)mship->conf_no, (unsigned long)ptr->first_read, (unsigned long)ptr->last_read); errors++; } if (ptr != begin && last + 1 == ptr->first_read) { kom_log("Person %lu's membership in %lu is corrupt: " "adjoining ranges not joined at around %lu.\n", (unsigned long)pno, (unsigned long)mship->conf_no, (unsigned long)ptr->first_read); errors++; } if (ptr != begin && last >= ptr->first_read) { kom_log("Person %lu's membership in %lu is corrupt: " "overlapping ranges: %lu-%lu, %lu-%lu.\n", (unsigned long)pno, (unsigned long)mship->conf_no, (unsigned long)(ptr-1)->first_read, (unsigned long)(ptr-1)->last_read, (unsigned long)ptr->first_read, (unsigned long)ptr->last_read); errors++; } last = ptr->last_read; } } if (last >= l2g_first_appendable_key(&conf->texts)) { kom_log("Person %lu has read text %lu in conf %lu, " "which only has %lu texts.\n", (unsigned long)pno, (unsigned long)last, (unsigned long)mship->conf_no, (unsigned long)(l2g_first_appendable_key(&conf->texts)-1)); errors++; } /* Check that he is a member */ if ( (mem = locate_member(pno, conf)) == NULL ) { kom_log("Person %lu is a member in %lu in which he isn't a member.\n", (unsigned long)pno, (unsigned long)mship->conf_no); errors++; } else { /* Check duplicated information Short circuit and in each check sets foo_e if an error has been detected */ if (mem->type.invitation != mship->type.invitation || mem->type.passive != mship->type.passive || mem->type.secret != mship->type.secret || mem->type.passive_message_invert != mship->type.passive_message_invert || mem->type.reserved2 != mship->type.reserved2 || mem->type.reserved3 != mship->type.reserved3 || mem->type.reserved4 != mship->type.reserved4 || mem->type.reserved5 != mship->type.reserved5 || mem->added_at != mship->added_at || mem->added_by != mship->added_by) { kom_log("Person %lu membership in %lu does not match member record.\n", (unsigned long)pno, (unsigned long)mship->conf_no ); errors++; fputs("Membership:", stdout); printf(" type: %s%s%s%s%s%s%s%s\n", mship->type.invitation ? "invitation " : "", mship->type.passive ? "passive " : "", mship->type.secret ? "secret " : "", mship->type.passive_message_invert ? "passive_message_invert " : "", mship->type.reserved2 ? "rsv2 " : "", mship->type.reserved3 ? "rsv3 " : "", mship->type.reserved4 ? "rsv4 " : "", mship->type.reserved5 ? "rsv5" : ""); printf(" added_by: %lu\n", (unsigned long)mship->added_by); printf(" added_at: %lu\n", (unsigned long)mship->added_at); fputs("Member:", stdout); printf(" type: %s%s%s%s%s%s%s%s\n", mem->type.invitation ? "invitation " : "", mem->type.passive ? "passive " : "", mem->type.secret ? "secret " : "", mem->type.passive_message_invert ? "passive_message_invert " : "", mem->type.reserved2 ? "rsv2 " : "", mem->type.reserved3 ? "rsv3 " : "", mem->type.reserved4 ? "rsv4 " : "", mem->type.reserved5 ? "rsv5" : ""); printf(" added_by: %lu\n", (unsigned long)mem->added_by); printf(" added_at: %lu\n", (unsigned long)mem->added_at); if (confirm("Copy membership to member")) { mem->added_at = mship->added_at; mem->added_by = mship->added_by; mem->type = mship->type; modifications++; } else if (confirm("Copy member to membership")) { mship->added_at = mem->added_at; mship->added_by = mem->added_by; mship->type = mem->type; modifications++; } } } } return errors; } static int check_membership_list(Pers_no pno, const Membership_list *mlist) { int errors=0; int i; for (i = 0; i < mlist->no_of_confs; i++) errors += check_membership(pno, &mlist->confs[i]); return errors; } static int check_persons(void) { static char crypt_seed[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./"; Pers_no cp = 0; Person *pstat=NULL; Conference *cstat=NULL; long errors = 0; Pers_no number_of_persons=0; while ( (cp = traverse_person(cp)) != 0 ) { number_of_persons++; pstat = cached_get_person_stat (cp); cstat = cached_get_conf_stat (cp); if ( pstat == NULL ) { kom_log("Person %lu nonexistent.\n", (unsigned long)cp); errors++; } else if (cstat == NULL) { kom_log("Person %lu has no conference.\n", (unsigned long)cp); errors++; } else if (!cstat->type.letter_box) { kom_log("Person %lu's conference is not a letter_box.\n", (unsigned long)cp); errors++; } else { errors += (check_created_texts(cp, &pstat->created_texts) + check_membership_list(cp, &pstat->conferences)); } if (unset_change_name_is_error == 1 && pstat->privileges.change_name == 0) { kom_log("Person %lu has no change_name capability.\n", (unsigned long)cp); if (rflag || confirm("Grant him the capability")) { pstat->privileges.change_name = 1; mark_person_as_changed(cp); modifications++; } else errors++; } if (cp == reset_pwd) { char salt[3]; salt[0] = crypt_seed [rand() % (sizeof (crypt_seed) - 1)]; salt[1] = crypt_seed [rand() % (sizeof (crypt_seed) - 1)]; salt[2] = '\0'; strcpy((char *)pstat->pwd, (const char *)crypt("", salt)); mark_person_as_changed(cp); modifications++; } if (cp == grant_all) { pstat->privileges.wheel = 1; pstat->privileges.admin = 1; pstat->privileges.statistic = 1; pstat->privileges.create_pers = 1; pstat->privileges.create_conf = 1; pstat->privileges.change_name = 1; pstat->privileges.flg7 = 1; pstat->privileges.flg8 = 1; pstat->privileges.flg9 = 1; pstat->privileges.flg10 = 1; pstat->privileges.flg11 = 1; pstat->privileges.flg12 = 1; pstat->privileges.flg13 = 1; pstat->privileges.flg14 = 1; pstat->privileges.flg15 = 1; pstat->privileges.flg16 = 1; mark_person_as_changed(cp); modifications++; } } if (vflag) kom_log("Total of %lu persons.\n", (unsigned long)number_of_persons); return errors; } static Bool is_recipient(Conf_no conf_no, Text_stat * t_stat) { int i; for ( i = 0; i < t_stat->no_of_misc; i++ ) { switch( t_stat->misc_items[ i ].type ) { case recpt: case cc_recpt: case bcc_recpt: if ( t_stat->misc_items[ i ].datum.recipient == conf_no ) { return TRUE; } break; case rec_time: case comm_to: case comm_in: case footn_to: case footn_in: case sent_by: case sent_at: case loc_no: break; #ifndef COMPILE_CHECKS default: #endif case unknown_info: restart_kom("is_recipient(): illegal misc_item\n"); } } return FALSE; } static int check_texts_in_conf(Conf_no cc, Local_to_global *tlist) { Text_stat *t; int errors=0; L2g_iterator iter; struct delete_list *del_list = NULL; for (l2gi_searchall(&iter, tlist); !iter.search_ended; l2gi_next(&iter)) { assert(iter.lno != 0); assert(iter.tno != 0); t = cached_get_text_stat(iter.tno); if (t == NULL) { kom_log("Text %lu<%lu> in conference %lu is non-existent.\n", (unsigned long)iter.tno, (unsigned long)iter.lno, (unsigned long)cc); if (rflag || confirm("Repair by deleting the Text_no in the map?")) { delete_list_append(&del_list, iter.lno); mark_conference_as_changed(cc); modifications++; kom_log("Repaired: %lu is no longer a recipient.\n", (unsigned long)cc); } else errors++; } else { if (!is_recipient(cc, t)) { kom_log("Text %lu<%lu> in conference %lu %s.\n", (unsigned long)iter.tno, (unsigned long)iter.lno, (unsigned long)cc, "doesn't have the conference as recipient"); if (confirm("Repair by deleting Text_no from the map?") ) { delete_list_append(&del_list, iter.lno); mark_conference_as_changed(cc); modifications++; kom_log("Repaired: %lu is no longer a recipient.\n", (unsigned long)cc); } else errors++; } } } execute_deletions(tlist, &del_list); return errors; } Membership * locate_membership(Conf_no conf_no, const Person *pers_p) { Membership * confp; int i; for(confp = pers_p->conferences.confs, i = pers_p->conferences.no_of_confs; i > 0; i--, confp++) { if ( confp->conf_no == conf_no ) { return confp; } } return NULL; } static int check_member(Conf_no cc, Member *memb) { Person *pp; int errors=0; pp = cached_get_person_stat(memb->member); if ( pp == NULL ) { kom_log("Person %lu, supposedly a member in conf %lu, is nonexistent.\n", (unsigned long)memb->member, (unsigned long)cc); errors++; } else { if ( locate_membership(cc, pp) == NULL ) { kom_log("Person %lu is not a member in conf %lu.\n", (unsigned long)memb->member, (unsigned long)cc); errors++; } } return errors; } static int check_member_list(Conf_no cc, const Member_list *mlist) { int errors=0; int i; for (i = 0; i < mlist->no_of_members; i++) errors += check_member(cc, &mlist->members[i]); return errors; } static int check_confs(void) { Conf_no cc = 0; Person *pstat=NULL; Conference *cstat=NULL; long errors = 0; Conf_no number_of_confs = 0; while ( (cc = traverse_conference(cc)) != 0 ) { number_of_confs++; cstat = cached_get_conf_stat (cc); if ( cstat == NULL ) { kom_log("Conference %lu nonexistent.\n", (unsigned long)cc); errors++; } else { if (cstat->type.letter_box) { pstat = cached_get_person_stat(cc); if (pstat == NULL) { kom_log("Mailbox %lu has no person.\n", (unsigned long)cc); errors++; } } else /* not letter_box */ { /* Remember that the creator might no longer exist. */ if ( person_scratchpad[ cstat->creator ] != NULL ) ++person_scratchpad[ cstat->creator ]->created_confs; } errors += (check_texts_in_conf(cc, &cstat->texts) + check_member_list(cc, &cstat->members)); } } if ( vflag ) kom_log("Total of %lu conferences.\n", (unsigned long)number_of_confs); return errors; } static void init_person_scratch(void) { Pers_no pno = 0; Pers_no i = 0; if (person_scratchpad == NULL) { person_scratchpad = smalloc(sizeof(*person_scratchpad) * param.max_conf); for (i = 0; i < param.max_conf; i++) person_scratchpad[i] = NULL; } while( (pno = traverse_person(pno)) != 0 ) { person_scratchpad[pno] = alloc_person_scratchpad(); } } static long post_check_persons(void) { long errors = 0; Pers_no pers_no = 0; Person *pstat; while ((pers_no = traverse_person(pers_no)) != 0) { if ((pstat = cached_get_person_stat(pers_no)) == NULL) { kom_log("%s(): can't cached_get_person_stat(%d).\n", "INTERNAL DBCK ERROR: post_check_persons", pers_no); } } return errors; } /* * Returns 0 if the database seems to be correct. */ static long check_data_base(void) { long errors; init_person_scratch(); errors = check_texts() + check_persons() + check_confs(); return errors + post_check_persons(); } static void init_data_base(void) { if ( vflag ) { kom_log("Database = %s\n", param.datafile_name); kom_log("Backup = %s\n", param.backupfile_name); kom_log("Text = %s\n", param.textfile_name); kom_log("Textback = %s\n", param.textbackupfile_name); } if ( init_cache() == FAILURE ) restart_kom("Can't find database.\n"); } static void garb_text_file(void) { Text_no tno = 0; String text; kom_log("Renaming %s to %s\n", param.textfile_name, param.textbackupfile_name); if (i_rename(param.textfile_name, param.textbackupfile_name) < 0) { restart_kom("rename failed: %s\n", strerror(errno)); } kom_log("Writing texts to (new) %s\n", param.textfile_name); fflush(stdout); fflush(stderr); cache_open_new_text_file(); while ( (tno = traverse_text(tno)) != 0 ) { text = cached_get_text(tno); cached_flush_text(tno, text); free_tmp(); } kom_log("Writing datafile with new indexes.\n"); fflush(stdout); fflush(stderr); cache_sync_all(); } static void print_statistics(void) { Text_stat *ts; Text_no t; int *hist; int i; hist = calloc(param.text_len, sizeof(int)); if (hist == NULL) { perror("dbck: print_statistics(): can't calloc()"); return; } for (t=0; (t=traverse_text(t)) != 0;) { ts = cached_get_text_stat(t); if (ts == NULL) { kom_log("print_statistics(): Can't get text_stat.\n"); return; } hist[ts->no_of_chars]++; } kom_log("Length Frequency\n"); for(i=0; i 0) give_help(get_default_config_file_name()); /* Continue reading in the configuration file. */ if (optind < argc) config_file = argv[optind++]; else config_file = get_default_config_file_name(); read_configuration(config_file); free_default_config_file_name(); /* * Override configuration with command-line options */ if (pers_pres_conf != -1) { kom_info.pers_pres_conf = pers_pres_conf; modifications++; } if (conf_pres_conf != -1) { kom_info.conf_pres_conf = conf_pres_conf; modifications++; } if (motd_conf != -1) { kom_info.motd_conf = motd_conf; modifications++; } if (kom_news_conf != -1) { kom_info.kom_news_conf = kom_news_conf; modifications++; } if (motd_of_lyskom != (Text_no)-1) { kom_info.motd_of_lyskom = motd_of_lyskom; modifications++; } if (optind != argc) restart_kom("%s: too many arguments. %s --help for usage.\n", argv[0], argv[0]); s_set_storage_management(smalloc, srealloc, sfree); if (need_rw) { if (lock_db() < 0) { /* Don't actually die until something is entered on stdin in debug mode. This is mainly here for the benefit of the test suite, but is could also be useful to be able to attach a debugger and do pre-mortem debugging of the process at this point. */ if (buglevel > 0) { kom_log("Press enter to terminate dbck\n"); getchar(); } exit(1); } have_lock = 1; } init_data_base(); errors = check_data_base(); if (truncated_texts == TRUE) modifications++; if ( iflag ) kom_log("Total of %d error%s remains.\n", errors, errors == 1 ? "" : "s"); else if ( vflag && errors > 0 ) kom_log("%d error%s found.\n", errors, errors == 1 ? "" : "s"); if ( modifications > 0 || force_output) { kom_log("%d modification%s made. Syncing...\n", modifications, modifications == 1 ? "" : "s"); fflush(stdout); fflush(stderr); if (have_lock) cache_sync_all(); else kom_log("Database not saved since the lock was not obtained.\n"); kom_log("ready.\n"); } if ( sflag ) print_statistics(); if (gflag && have_lock) { if ( modifications == 0 && errors == 0 ) { kom_log("No errors found. Compressing textfile.\n"); fflush(stdout); fflush(stderr); garb_text_file(); kom_log("ready.\n"); } else { kom_log("Found %d errors; performed %d modifications.\n", errors, modifications); fflush(stdout); fflush(stderr); if (confirm ("garb texts anyhow?")) { garb_text_file(); kom_log("ready.\n"); } else { kom_log("Compression not done since errors was found.\n"); } } } if (have_lock) unlock_db(); /* Don't actually die until something is entered on stdin in debug mode. This is mainly here for the benefit of the test suite, but is could also be useful to be able to attach a debugger and do pre-mortem debugging of the process at this point. */ if (buglevel > 0) { kom_log("Press enter to terminate dbck\n"); getchar(); } return errors != 0; } lyskom-server-2.1.2/src/server/dbck-cache.c0000664000015100472110000010134107721716126014233 /* * $Id: dbck-cache.c,v 0.56 2003/08/23 16:38:17 ceder Exp $ * Copyright (C) 1991-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * This module contains some very simple simulations of the routines in * cache.c. * * Extracted from ram-cache.c and rewritten by ceder. * * New database format with texts in their own file by Inge Wallin. * Also save time as a time_t instead of a struct tm. */ #ifdef HAVE_CONFIG_H # include #endif #include #ifndef SEEK_END # include #endif #ifndef SEEK_END # include #endif #ifndef SEEK_END # define SEEK_SET 0 # define SEEK_END 2 #endif #ifdef HAVE_STDLIB_H # include #endif #include "timewrap.h" #include #ifdef TIME_SYNC # include #endif #include "ldifftime.h" #include "exp.h" #include "misc-types.h" #include "s-string.h" #include "kom-types.h" #include "kom-errno.h" #include "cache.h" #include "debug.h" #include "server/smalloc.h" #include "log.h" #include "lyskomd.h" #include "kom-memory.h" #include "ram-parse.h" #include "ram-output.h" #include "param.h" #include "dbck-cache.h" #include "local-to-global.h" #include "unused.h" #include "eintr.h" /* * All functions that can fail sets kom_errno to a suitable value * if they fail. */ Person ** pers_arr; Conference ** conf_arr; String * name_list; /* "cache" list */ /* Global var auto init to NULL */ static Conf_no next_free_num = 1; Text_stat ** text_arr; static Text_no next_text_num = 1; /* Defined in standalone.c */ extern Info kom_info; /* Defined in ramkomd.c */ static FILE *text_file = NULL; static FILE *new_text_file = NULL; /* Used when garbage collecting. */ BUGDECL; /* Macros */ #define TRACE2(format, arg) if ( buglevel > 2 ) printf(format, arg) #define TRACE1(format) if ( buglevel > 2 ) printf(format) #define TRACESTR(str) if ( buglevel > 2 ) s_puts(str) #define INRANGE(str, num, retval) if ( num == 0 || num >= next_free_num ) \ { \ return retval; \ printf("%s: conf_no %d out of range 1 ... %d ", str, num, next_free_num); \ fflush(stdout); \ fflush(stderr); \ abort(); \ } #define TEXT_RANGE(str, num, retval) if ( num == 0 || num >= next_text_num ) \ { \ return retval;\ printf("Text_no out of range 1 ... %ld ", next_text_num); \ printf(str); \ fflush(stdout); \ fflush(stderr); \ abort(); \ } #define VOID_TEXT_RANGE(str, num) if ( num == 0 || num >= next_text_num ) \ { \ return;\ printf("Text_no out of range 1 ... %ld ", next_text_num); \ printf(str); \ fflush(stdout); \ fflush(stderr); \ abort(); \ } extern Conf_type cached_get_conf_type (Conf_no conf_no) { return conf_arr [ conf_no ]->type; } /* * Various function calls to tell the cache that something is changed. */ void mark_person_as_changed(Pers_no pers_no) { TRACE2("Person %d is changed\n", pers_no); return; } void mark_conference_as_changed(Conf_no conf_no) { TRACE2("Conf. %d is changed\n", conf_no); return; } void mark_text_as_changed( Text_no text_no ) { TRACE2("Text %lu is changed.\n", text_no); VOID_TEXT_RANGE("mark_text_as_changed\n", text_no); } /* * Person-related calls */ extern Success cached_create_person( Pers_no person ) { TRACE2("Person %d is being created.\n", person); INRANGE("cached_create_person\n", person, FAILURE); if ( pers_arr[ person ] != NULL ) { TRACE1("pers_arr not NULL"); fflush(stdout); fflush(stderr); abort(); } pers_arr[ person ] = alloc_person(); return OK; } extern Person * cached_get_person_stat( Pers_no person ) { INRANGE("cached_get_person_stat\n", person, NULL); TRACE2("cached_get_person_stat %d\n", person); err_stat = person; kom_errno = KOM_UNDEF_PERS; return pers_arr[ person ]; } /* * Conference-related calls */ extern Conf_no /* Also cache the name */ cached_create_conf (String name) { Conference * conf_c; Conf_no conf_no; TRACE1("cached_create_conf( "); TRACESTR(name); TRACE1(" )\n"); if ( next_free_num >= param.max_conf ) { err_stat = next_free_num; kom_errno = KOM_INDEX_OUT_OF_RANGE; return 0; } conf_no = next_free_num++; conf_c = alloc_conference(); conf_c->name = EMPTY_STRING; s_strcpy(&conf_c->name, name); TRACE2(" number %d\n", conf_no); conf_arr[ conf_no ] = conf_c; pers_arr[ conf_no ] = NULL; return conf_no; } extern Success cached_delete_conf( Conf_no conf ) { INRANGE("cached_delete_conf()", conf, FAILURE); if ( conf_arr[ conf ] == NULL ) { err_stat = conf; kom_errno = KOM_UNDEF_CONF; return FAILURE; } free_conference(conf_arr[ conf ]); conf_arr[ conf ] = NULL; return OK; } Success cached_delete_person(Pers_no pers) { INRANGE("cached_delete_person()", pers, FAILURE); if ( pers_arr[ pers ] == NULL ) { err_stat = pers; kom_errno = KOM_UNDEF_PERS; return FAILURE; } pers_arr[ pers ] = NULL; return OK; } Success cached_delete_text(Text_no text) { TEXT_RANGE("cached_delete_text()", text, FAILURE); if ( text_arr[ text ] == NULL ) { err_stat = text; kom_errno = KOM_NO_SUCH_TEXT; return FAILURE; } free_text_stat(text_arr[ text ]); text_arr[ text ] = NULL; return OK; } extern Conference * cached_get_conf_stat( Conf_no conf_no ) { INRANGE("cached_get_conf_stat\n", conf_no, NULL); TRACE2("cached_get_conf_stat %d\n", conf_no); kom_errno = KOM_UNDEF_CONF; err_stat = conf_no; return conf_arr[ conf_no ]; } /* * Return TRUE if conf_no exists. */ Bool cached_conf_exists(Conf_no conf_no) { return conf_arr[ conf_no ] != NULL ? TRUE : FALSE; } /* * Calls to handle texts */ extern String cached_get_text( Text_no text ) { String the_string; TEXT_RANGE("cached_get_text\n", text, EMPTY_STRING); TRACE2("cached_get_text %lu\n", text); if ( text_arr[ text ] == NULL ) return EMPTY_STRING; else { the_string.string = tmp_alloc( text_arr[text]->no_of_chars ); the_string.len = text_arr[text]->no_of_chars; fseek(text_file, text_arr[ text ]->file_pos, SEEK_SET); if ( fread(the_string.string, sizeof(char), the_string.len, text_file) != (size_t)the_string.len ) { kom_log("%s read enough characters of text %lu\n", "WARNING: cached_get_text: couldn't", (unsigned long)text); } return the_string; } } extern Text_stat * /* NULL on error */ cached_get_text_stat( Text_no text ) { kom_errno = KOM_NO_SUCH_TEXT; err_stat = text; TEXT_RANGE("cached_get_text_stat\n", text, NULL); TRACE2("cached_get_text_stat %lu\n", text); return text_arr[ text ]; } /* * The text is set up with an empty misc-field. The misc field is * later initialized by create_text. */ #if 0 extern Text_no cached_create_text( String message) { Text_no tno; tno = next_text_num++; TRACE2("cached_create_text (len=%d)\n", message.len); if ( tno >= param.max_text ) { next_text_num = param.max_text; kom_errno = KOM_INDEX_OUT_OF_RANGE; err_stat = next_text_num; return 0; } text_arr[ tno ] = alloc_text_stat(); text_arr[ tno ]->no_of_misc = 0; text_arr[ tno ]->misc_items = NULL; text_arr[ tno ]->no_of_marks = 0; text_arr[ tno ]->no_of_lines = 0; text_arr[ tno ]->no_of_chars = 0; fseek(text_file, 0, SEEK_END); text_arr[ tno ]->file_pos = ftell(text_file); if ( fwrite(message.string, sizeof(char), message.len, text_file) != message.len ) { kom_log("WARNING: cached_create_text: Couldn't write the text %d\n", tno); } fflush(text_file); TRACE2("cached_create_text -> %d\n", tno); return tno; } #endif void cached_flush_text(Text_no text_no, String message) { if ( text_no >= next_text_num ) { kom_log("cached_flush_text(%lu, string): only text %lu exists.\n", (u_long) text_no, (u_long) next_text_num); return; } fseek(new_text_file, 0, SEEK_END); text_arr[ text_no ]->file_pos = ftell(new_text_file); if ( fwrite(message.string, sizeof(char), message.len, new_text_file) != (size_t)message.len ) { kom_log("WARNING: cached_flush_text: Couldn't write the text %ld\n", (unsigned long)text_no); } fflush(new_text_file); } Text_no traverse_text(Text_no seed) { seed++; while ( seed < next_text_num && text_arr[ seed ] == NULL ) seed++; return (seed == next_text_num) ? 0 : seed ; } Pers_no traverse_person(Pers_no seed) { seed++; while ( seed < next_free_num && pers_arr[ seed ] == NULL ) seed++; return (seed == next_free_num) ? 0 : seed ; } Conf_no traverse_conference(Conf_no seed) { seed++; while ( seed < next_free_num && conf_arr[ seed ] == NULL ) seed++; return (seed == next_free_num) ? 0 : seed ; } extern Garb_nice cached_get_garb_nice (Conf_no conf_no) { return conf_arr [ conf_no ]->nice; } extern Garb_nice cached_get_keep_commented(Conf_no conf_no) { return conf_arr[conf_no]->keep_commented; } extern Local_text_no cached_get_highest_local_no (Conf_no conf_no) { return l2g_first_appendable_key(&conf_arr[conf_no]->texts) - 1; } /* Lock a person struct in memory. Increase a referenc count. */ void cached_lock_person(Pers_no UNUSED(pers_no)) {} /* Decrease reference count. If zero, unlock person. */ void cached_unlock_person(Pers_no UNUSED(pers_no)) {} /* Lock a conf struct in memory. Increase a referenc count. */ void cached_lock_conf(Conf_no UNUSED(conf_no)) {} /* Decrease reference count. If zero, unlock conf. */ void cached_unlock_conf(Conf_no UNUSED(conf_no)) {} static long get_version(const char *fn) { FILE *fp; char c; long version; if ((fp = i_fopen(fn, "rb")) == NULL) return -1; fseek(fp, 5, SEEK_SET); if ( (c = getc(fp)) == '\n') { i_fclose(fp); return 0; } version = fparse_long(fp); i_fclose(fp); return version; } static Bool is_clean(const char *fn) { FILE *fp; if ((fp = i_fopen(fn, "rb")) == NULL) return FALSE; if ( getc(fp) == 'C' && getc(fp) == 'L' && getc(fp) == 'E' && getc(fp) == 'A' && getc(fp) == 'N' ) { i_fclose(fp); return TRUE; } else { i_fclose(fp); return FALSE; } } static void sync_output_header(FILE* fp, const char *state, int oformat) { switch (oformat) { case 0: fprintf(fp, "%s\n", state); break; case 1: fprintf(fp, "%s:%05ld\n", state, (long)oformat); break; case 2: fprintf(fp, "%s:%05ld\n", state, (long)oformat); fprintf(fp, "%020lu\n", (unsigned long)time(NULL)); break; default: restart_kom("sync_output_header(): Unknown output format %d", oformat); } } #ifdef TIME_SYNC static long timerdiff(struct timeval a, struct timeval b) { /* Ignore the tv_usec parts. One second more or less doesn't matter. */ return a.tv_sec - b.tv_sec; } #endif extern void /* Write out everything. */ cache_sync_all(void) { FILE *fp; Conf_no ic; Text_no it; #ifdef TIME_SYNC struct rusage start, after_confs, after_persons, after_text_stats, after_text_masses; time_t st, ac, ap, ats, atm; void getrusage(int who, struct rusage *rusage); #endif #ifdef TIME_SYNC getrusage(0, &start); time(&st); #endif if ( is_clean(param.datafile_name) ) { if (is_clean(param.backupfile_name)) { if (i_rename(param.backupfile_name, param.backupfile_name_2) != 0) { kom_log("pre_sync: can't do extra backup.\n"); } } if (i_rename(param.datafile_name, param.backupfile_name) != 0) kom_log("WARNING: cache_sync_all: can't backup.\n"); } else kom_log("cache_sync_all: datafile not clean. No backup taken.\n"); if ((fp = i_fopen(param.datafile_name, "w")) == NULL) { kom_log("WARNING: cache_sync_all: can't open file to save in.\n"); return; } /* * Print file header and other things that go before the conferences. */ switch (oformat) { case 0: sync_output_header(fp, "DIRTY", oformat); fprintf(fp, "%d\n", next_free_num); /* NEXT_FREE_NUM */ break; case 1: case 2: sync_output_header(fp, "DIRTY", oformat); fprintf(fp, "#C %d\n", next_free_num); fprintf(fp, "#T %ld\n", next_text_num); fprintf(fp, "I"); foutput_info(fp, &kom_info); fprintf(fp, "\n"); break; default: restart_kom("Unknown output file format: %ld\n", oformat); } for (ic = 1; ic < next_free_num; ic++) /* CONFS */ { switch (oformat) { case 0: if (conf_arr[ic] == NULL) fprintf(fp, "@"); else { fprintf(fp, "+ "); foutput_conference(fp, conf_arr[ic]); } putc('\n', fp); break; case 1: case 2: if (conf_arr[ic] != NULL) { fprintf(fp, "C %lu", (unsigned long)ic); foutput_conference(fp, conf_arr[ic]); putc('\n', fp); } break; default: restart_kom("Bad output file format: %ld\n", oformat); } } #ifdef TIME_SYNC getrusage(0, &after_confs); time(&ac); #endif for (ic = 1; ic < next_free_num; ic++) /* PERSONS */ { switch (oformat) { case 0: if (pers_arr[ic] == NULL) fprintf(fp, "@"); else { fprintf(fp, "+ "); fprintf(fp, "%dH", PASSWD_LEN); fwrite(pers_arr[ic]->pwd, PASSWD_LEN, 1, fp); foutput_person(fp, pers_arr[ic]); } putc('\n', fp); break; case 1: case 2: if (pers_arr[ic] != NULL ) { fprintf(fp, "P %lu", (unsigned long)ic); fprintf(fp, " %dH", PASSWD_LEN); fwrite(pers_arr[ic]->pwd, PASSWD_LEN, 1, fp); foutput_person(fp, pers_arr[ic]); putc('\n', fp); } break; default: restart_kom("Bad output file format: %ld\n", oformat); } } #ifdef TIME_SYNC getrusage(0, &after_persons); time(&ap); #endif /* * Print things that go between persons and texts */ switch (oformat) { case 0: fprintf(fp, "%ld\n", next_text_num); /* NEXT_TEXT_NUM */ break; case 1: case 2: break; default: restart_kom("Unknown output file format: %ld\n", oformat); } for (it = 1; it < next_text_num; it++) /* TEXT_STATS */ { switch (oformat) { case 0: if (text_arr[it] == NULL) fprintf(fp, "@"); else { fprintf(fp, "+ "); foutput_text_stat(fp, text_arr[it]); } putc('\n', fp); break; case 1: case 2: if (text_arr[it] != NULL) { fprintf(fp, "T %lu", it); foutput_text_stat(fp, text_arr[it]); putc('\n', fp); } break; default: restart_kom("Unknown output file format: %ld\n", oformat); } } /* * Print file footer * * Ho-hum. I thought there was supposed to be a newline at the end * of a version zero file, but it seems I was wrong, so this code * basically does...absolutely nothing. */ switch (oformat) { case 0: break; case 1: case 2: break; default: restart_kom("Unknown output file format: %ld\n", oformat); } #ifdef TIME_SYNC getrusage(0, &after_text_stats); time(&ats); getrusage(0, &after_text_masses); time(&atm); #endif rewind(fp); sync_output_header(fp, "CLEAN", oformat); i_fclose(fp); #ifdef TIME_SYNC kom_log("Sync ready.\n" "User: %4ld sec (%4ld conf, %4ld pers, %4ld stat, %4ld text)\n" "Sys: %4ld sec (%4ld conf, %4ld pers, %4ld stat, %4ld text)\n" "Real: %4ld sec (%4ld conf, %4ld pers, %4ld stat, %4ld text)\n" "Page faults: %4ld. Swapped: %4ld. Outblocked: %4ld.\n", timerdiff(after_text_masses.ru_utime, start.ru_utime), timerdiff(after_confs.ru_utime, start.ru_utime), timerdiff(after_persons.ru_utime, after_confs.ru_utime), timerdiff(after_text_stats.ru_utime, after_persons.ru_utime), timerdiff(after_text_masses.ru_utime, after_text_stats.ru_utime), timerdiff(after_text_masses.ru_stime, start.ru_stime), timerdiff(after_confs.ru_stime, start.ru_stime), timerdiff(after_persons.ru_stime, after_confs.ru_stime), timerdiff(after_text_stats.ru_stime, after_persons.ru_stime), timerdiff(after_text_masses.ru_stime, after_text_stats.ru_stime), (u_long)ldifftime(atm, st), (u_long)ldifftime(ac, st), (u_long)ldifftime(ap, ac), (u_long)ldifftime(ats, ap), (u_long)ldifftime(atm, ats), after_text_masses.ru_majflt - start.ru_majflt, after_text_masses.ru_nswap - start.ru_nswap, after_text_masses.ru_oublock - start.ru_oublock); #endif } void cache_open_new_text_file(void) { if ((new_text_file = i_fopen(param.textfile_name, "w")) == NULL) { kom_log("Can't open file to save new texts. Goodbye.\n"); exit(1); } } extern Success init_cache(void) { FILE *fp = NULL; unsigned long i; extern int vflag; /* from dbck.c */ extern Bool truncated_texts; /* from dbck.c */ long num; long data_file_version; char done, read_text_num, read_conf_num; int c; extern int modifications; extern int pers_pres_conf; extern int conf_pres_conf; extern int motd_conf; extern Text_no motd_of_lyskom; extern int kom_news_conf; read_text_num = 0; read_conf_num = 0; pers_arr = smalloc(sizeof(*pers_arr) * param.max_conf); conf_arr = smalloc(sizeof(*conf_arr) * param.max_conf); text_arr = smalloc(sizeof(*text_arr) * param.max_text); name_list = smalloc(sizeof(*name_list) * param.max_conf); for (i = 0; i < param.max_conf; i++) conf_arr[i] = NULL; for (i = 0; i < param.max_conf; i++) pers_arr[i] = NULL; for (i = 0; i < param.max_text; i++) text_arr[i] = NULL; new_text_file = NULL; if ((text_file = i_fopen(param.textfile_name, "rb")) == NULL) { perror(param.textfile_name); restart_kom("ERROR: init_cache: can't open text file %s.\n", param.textfile_name); } if ( is_clean(param.datafile_name) ) { data_file_version = get_version(param.datafile_name); if ((fp = i_fopen(param.datafile_name, "rb")) == NULL) { kom_log("WARNING: init_cache: can't open datafile.\n"); return FAILURE; } kom_log("MSG: init_cache: using datafile.\n"); } else if ( is_clean(param.backupfile_name) ) { data_file_version = get_version(param.backupfile_name); if ((fp = i_fopen(param.backupfile_name, "rb")) == NULL) { kom_log("WARNING: init_cache: can't open backupfile.\n"); return FAILURE; } kom_log("MSG: init_cache: using backup file.\n"); } else { kom_log("WARNING: init_cache: can't find old data base.\n"); return FAILURE; } /* * If no output format has been selected, use the input format */ if (oformat == -1) oformat = data_file_version; /* * Read file header */ set_input_format(data_file_version); switch (data_file_version) { case 0: fseek(fp, 6, SEEK_SET); /* skip clean/dirty flag. */ next_free_num = fparse_long(fp); /* NEXT_FREE_NUM */ read_conf_num = 1; if (vflag) { kom_log("Data file version is '%ld'\n", data_file_version); kom_log("Reading %d conferences, starting at pos %ld.\n", next_free_num-1, (unsigned long)ftell(fp)); } break; case 1: fseek(fp, 12, SEEK_SET); if (vflag) kom_log("Data file version is '%ld'\n", data_file_version); break; case 2: fseek(fp, 33, SEEK_SET); if (vflag) kom_log("Data file version is '%ld'\n", data_file_version); break; default: restart_kom("Unknown input file format: %ld\n", data_file_version); } done = 0; /* * Loop over records in the database. For a version zero database, * loop next_free_num times and for a version one database, loop * until the end of the file or until done is set */ for ( i = 1; (data_file_version == 0 && i < next_free_num && !feof(fp)) || (data_file_version == 1 && !done) || (data_file_version == 2 && !done); i++ ) { num = i; fskipwhite(fp); switch(c = getc(fp)) { case EOF: switch (data_file_version) { case 0: restart_kom("Unexpected end-of-file reading conferences " "in data file version %ld.", data_file_version); break; case 1: case 2: done = 1; break; default: restart_kom("Unknown input file format: %ld\n", data_file_version); } break; case '@': switch (data_file_version) { case 0: conf_arr[num] = NULL; break; case 1: case 2: restart_kom("@ record in data file version %ld at %lu.\n", data_file_version, (unsigned long)ftell(fp)); break; default: restart_kom("Unknown input file format: %ld\n", data_file_version); } break; case 'I': switch (data_file_version) { case 0: restart_kom("I record in data file version %ld at %lu.\n", data_file_version, (unsigned long)ftell(fp)); break; case 1: case 2: if (fparse_info(fp, &kom_info) != OK) restart_kom("Invalid I record in data file version %ld at %lu.\n", data_file_version, (unsigned long)ftell(fp)); if (pers_pres_conf != -1) { modifications += (kom_info.pers_pres_conf != pers_pres_conf); kom_info.pers_pres_conf = pers_pres_conf; } if (conf_pres_conf != -1) { modifications += (kom_info.conf_pres_conf != conf_pres_conf); kom_info.conf_pres_conf = conf_pres_conf; } if (motd_conf != -1) { modifications += (kom_info.motd_conf != motd_conf); kom_info.motd_conf = motd_conf; } if (kom_news_conf != -1) { modifications += (kom_info.kom_news_conf != kom_news_conf); kom_info.kom_news_conf = kom_news_conf; } if (motd_of_lyskom != (Text_no)-1) { modifications += (kom_info.motd_of_lyskom != motd_of_lyskom); kom_info.motd_of_lyskom = motd_of_lyskom; } break; default: restart_kom("Unknown input file format: %ld\n", data_file_version); } break; case 'C': switch (data_file_version) { case 0: restart_kom("C record in data file version %ld at %lu.\n", data_file_version, (unsigned long)ftell(fp)); break; case 1: case 2: num = fparse_long(fp); if (conf_arr[num]) free_conference(conf_arr[num]); conf_arr[num] = alloc_conference(); if (fparse_conference(fp, conf_arr[num]) != OK) restart_kom("init_cache(): %s. i == %lu\n", "fparse_conference failed", i); name_list[num] = EMPTY_STRING; s_strcpy(&name_list[num], conf_arr[ num ]->name); break; default: restart_kom("Unknown input file format: %ld\n", data_file_version); } break; case 'P': switch (data_file_version) { case 0: restart_kom("P record in data file version %ld at %lu.\n", data_file_version, (unsigned long)ftell(fp)); break; case 1: case 2: num = fparse_long(fp); if (pers_arr[num]) free_person(pers_arr[num]); pers_arr[num] = alloc_person(); if ( fparse_person(fp, pers_arr[ num ]) != OK ) restart_kom("init_cache: fparse_person failed. num==%ld\n", num); break; default: restart_kom("Unknown input file format: %ld\n", data_file_version); } break; case 'T': switch (data_file_version) { case 0: restart_kom("T record in data file version %ld at %lu\n", data_file_version, (unsigned long)ftell(fp)); break; case 1: case 2: num = fparse_long(fp); if (text_arr[num]) free_text_stat(text_arr[num]); text_arr[ num ] = alloc_text_stat(); if ( fparse_text_stat(fp, text_arr[ num ]) != OK ) { /* Simply ignore everything else. The cause of this error might be that the file has been truncated (maybe due to an overfull disk). */ kom_log("init_cache(): fparse_text_stat failed " "for text %ld.\n%s", num, "Everything remaining is lost.\n"); next_text_num = i; read_text_num = 1; truncated_texts = TRUE; done = 1; } break; default: restart_kom("Unknown input file format: %ld\n", data_file_version); } break; case '+': switch (data_file_version) { case 0: conf_arr[ i ] = alloc_conference(); if ( fparse_conference(fp, conf_arr[ i ]) != OK ) restart_kom("init_cache(): %s. i == %lu\n", "fparse_conference failed", i); name_list[i] = EMPTY_STRING; s_strcpy(&name_list[i], conf_arr[ i ]->name); break; case 1: case 2: restart_kom("+ record in data file version %ld at %lu.\n", data_file_version, (unsigned long)ftell(fp)); break; default: restart_kom("Unknown input file format: %ld\n", data_file_version); } break; case '#': switch (data_file_version) { case 0: restart_kom("#record in data file version %ld at %lu.\n", data_file_version, (unsigned long)ftell(fp)); break; case 1: case 2: switch (c = getc(fp)) { case 'C': next_free_num = fparse_long(fp); read_conf_num = 1; break; case 'T': next_text_num = fparse_long(fp); read_text_num = 1; break; default: restart_kom("Unknown # record (#%c) in data " "file version %ld at %lu.\n", c, data_file_version, (unsigned long)ftell(fp)); } break; default: restart_kom("Unknown input file format: %ld\n", data_file_version); } break; case '-': switch (data_file_version) { case 0: restart_kom("- record in data file version %ld at %lu.\n", data_file_version, (unsigned long)ftell(fp)); break; case 1: case 2: switch(c = getc(fp)) { case 'C': num = fparse_long(fp); if (conf_arr[num] != NULL) free_conference(conf_arr[num]); conf_arr[num] = NULL; break; case 'P': num = fparse_long(fp); if (pers_arr[num] != NULL) free_person(pers_arr[num]); pers_arr[num] = NULL; break; case 'T': num = fparse_long(fp); if (text_arr[num] != NULL) free_text_stat(text_arr[num]); text_arr[num] = NULL; break; default: restart_kom("Unknown - record (%c) in data file " "version %ld at %lu.\n", c, data_file_version, (unsigned long)ftell(fp)); } break; default: restart_kom("Unknown input file format %ld\n", data_file_version); } break; default: restart_kom("Unknown record type in data file version " "%ld at %lu.\n", data_file_version, (unsigned long)ftell(fp)); } } /* * The rest is only for data file version 0 */ if (data_file_version == 0) { if ( vflag ) kom_log("Reading %d persons, starting at pos %lu.\n", next_free_num-1, (unsigned long)ftell(fp)); for ( i = 1; i < next_free_num; i++ ) /* PERSONS */ { fskipwhite(fp); switch(getc(fp)) { case '@': pers_arr[ i ] = NULL; break; case '+': pers_arr[ i ] = alloc_person(); if ( fparse_person(fp, pers_arr[ i ]) != OK ) restart_kom("init_cache: fparse_person failed. i == %ld\n", i); break; } } next_text_num = fparse_long(fp); /* NEXT_TEXT_NUM */ read_text_num = 1; if ( vflag ) kom_log("Reading %ld texts, starting at pos %lu.\n", next_text_num-1, (unsigned long)ftell(fp)); for ( i = 1; i < next_text_num; i++ ) /* TEXT_STATS */ { fskipwhite(fp); switch(getc(fp)) { case '@': text_arr[ i ] = NULL; break; case '+': text_arr[ i ] = alloc_text_stat(); if ( fparse_text_stat(fp, text_arr[ i ]) != OK ) { /* Simply ignore the following texts. The cause of this error might be that the file has been truncated (maybe due to an overfull disk). */ kom_log("init_cache(): fparse_text_stat failed for text %ld.\n" "All remaining texts are lost.\n", i); next_text_num = i; truncated_texts = TRUE; } break; } } } /* if (datafile_version == 0) */ kom_log("Read %d confs/persons and %ld texts, eof at %lu\n", next_free_num-1, next_text_num-1, (unsigned long)ftell(fp)); if (read_text_num == 0 || read_conf_num == 0) restart_kom("init_cache(): Failed to read next_conf or text num.\n"); i_fclose(fp); return OK; } lyskom-server-2.1.2/src/server/server-config.c0000664000015100472110000006236207723627265015060 /* * $Id: server-config.c,v 0.100 2003/08/29 10:40:46 ceder Exp $ * Copyright (C) 1991-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * server-config.c * * This is in a .c file to make it possible to change a value without having * to recompile the entire server (or, in fact, anything!) */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #ifdef HAVE_STRING_H # include #endif #include "timewrap.h" #include #include #include "server/smalloc.h" #include "kom-config.h" #include "kom-types.h" #include "com.h" #include "async.h" #include "connections.h" #include "kom-errno.h" #include "manipulate.h" #include "server-config.h" #include "misc-types.h" #include "s-string.h" #include "kom-types.h" #include "param.h" #include "conf-file.h" #include "admin.h" #include "log.h" #include "lyskomd.h" #include "unused.h" #include "timeval-util.h" #ifdef DEBUG_CALLS # include "services.h" #endif #include "paths.h" struct kom_par param; static Success log_param(const char *val, const struct parameter *par); static Success jubel(const char *val, const struct parameter *par); static Success ident_param(const char *val, const struct parameter *par); /* Paths are a special kind of strings. For now, just use these defines to make it easier to spot paths in the table below. */ #define assign_path assign_string #define unassign_path unassign_string /* See lyskomd.texi for more info about the parameters. Please remember to update lyskomd.texi if you add more parameters! Try to keep this list and the list in lyskomd.texi in the same order. */ static const struct parameter parameters[] = { /* "Normal" configuration */ {"Locale", assign_string, unassign_string, 0, 1, NULL, ¶m.use_locale, NULL}, {"Force ISO 8859-1", assign_bool, NULL, 0, 1, "no", ¶m.force_iso_8859_1, NULL}, {"Prefix", assign_path, unassign_path, 0, 1, DEFAULT_PREFIX, ¶m.dbase_dir, NULL}, {"Send async", assign_bool, NULL, 0, 1, "1", ¶m.send_async_messages, NULL}, {"Client host", assign_string, unassign_string, 0, 1, NULL, ¶m.ip_client_host, NULL}, {"Client port", assign_string, unassign_string, 1, 1, NULL, ¶m.ip_client_port, NULL}, {"Presentation of conferences", assign_conf_no, NULL, 0, 1, "1", &kom_info.conf_pres_conf, NULL}, {"Presentation of persons", assign_conf_no, NULL, 0, 1, "2", &kom_info.pers_pres_conf, NULL}, {"Motd-conference", assign_conf_no, NULL, 0, 1, "3", &kom_info.motd_conf, NULL}, {"News-conference", assign_conf_no, NULL, 0, 1, "4", &kom_info.kom_news_conf, NULL}, {"Message of the day", assign_text_no, NULL, 0, 1, "0", &kom_info.motd_of_lyskom, NULL}, {"Garb", assign_bool, NULL, 0, 1, "on", ¶m.garb_enable, NULL}, {"Never save", assign_bool, NULL, 0, 1, "no", ¶m.never_save, NULL}, #ifdef LOGACCESSES {"Log accesses", assign_path, unassign_path, 0, 1, NULL, ¶m.logaccess_file, NULL}, #endif /* The database files. */ {"Data file", assign_path, unassign_path, 0, 1, DATA_FILE, ¶m.datafile_name, NULL}, {"Backup file", assign_path, unassign_path, 0, 1, BACKUP_FILE, ¶m.backupfile_name, NULL}, {"Backup file 2", assign_path, unassign_path, 0, 1, PREV_BACKUP_FILE, ¶m.backupfile_name_2, NULL}, {"Lock file", assign_path, unassign_path, 0, 1, LOCK_FILE, ¶m.lockfile_name, NULL}, {"Text file", assign_path, unassign_path, 0, 1, TEXT_FILE, ¶m.textfile_name, NULL}, {"Number file", assign_path, unassign_path, 0, 1, NUMBER_FILE, ¶m.numberfile_name, NULL}, {"Number temp file", assign_path, unassign_path, 0, 1, NUMBER_FILE_TMP, ¶m.numberfile_tmp_name, NULL}, {"Text backup file", assign_path, unassign_path, 0, 1, TEXT_BACKUP_FILE, ¶m.textbackupfile_name, NULL}, {"Backup export directory", assign_path, unassign_path, 0, 1, EXPORT_DIR, ¶m.backup_dir, NULL}, /* Various log files */ {"Log file", assign_path, unassign_path, 0, 1, LYSKOMD_LOG, ¶m.logfile_name, NULL}, {"Log statistics", assign_path, unassign_path, 0, 1, LYSKOMD_STATS, ¶m.statistic_name, NULL}, {"Pid file", assign_path, unassign_path, 0, 1, LYSKOMD_PID, ¶m.pid_name, NULL}, {"Memory usage file", assign_path, unassign_path, 0, 1, MEMORY_USAGE, ¶m.memuse_name, NULL}, /* Other files. */ {"Aux-item definition file", assign_path, unassign_path, 0, 1, AUX_FILE, ¶m.aux_def_file, NULL}, {"Status file", assign_path, unassign_path, 0, 1, STATUS_FILE, ¶m.status_file, NULL}, {"Connection status file", assign_path, unassign_path, 0, 1, CONNECTIONS_FILE, ¶m.connection_status_file, NULL}, {"Connection status temp file", assign_path, unassign_path, 0, 1, CONNECTIONS_TMP, ¶m.connection_status_file_tmp, NULL}, /* Where to dump core. */ {"Core directory", assign_path, unassign_path, 0, 1, CORE_DIR, ¶m.core_dir, NULL}, {"Nologin file", assign_path, unassign_path, 0, 1, "/etc/nologin", ¶m.nologin_file, NULL}, /* Performance tuning parameters (milliseconds) */ {"Garb busy postponement", assign_timeval, NULL, 0, 1, "50", ¶m.garb_busy_postponement, "milliseconds"}, {"Garb timeout", assign_timeval, NULL, 0, 1, "0", ¶m.garbtimeout, "milliseconds"}, {"Sync timeout", assign_timeval, NULL, 0, 1, "0", ¶m.synctimeout, "milliseconds"}, /* Performance tuning parameters (minutes) */ {"Garb interval", assign_timeval, NULL, 0, 1, "1440", ¶m.garb_interval, "minutes"}, {"Permissive sync", assign_bool, NULL, 0, 1, "off", ¶m.permissive_sync, NULL}, {"Sync interval", assign_timeval, NULL, 0, 1, "5", ¶m.sync_interval, "minutes"}, {"Sync retry interval", assign_timeval, NULL, 0, 1, "1", ¶m.sync_retry_interval, "minutes"}, {"Saved items per call", assign_int, NULL, 0, 1, "5", ¶m.saved_items_per_call, NULL}, {"Penalty per call", assign_uint, NULL, 0, 1, "10", ¶m.penalty_per_call, NULL}, {"Penalty per read", assign_uint, NULL, 0, 1, "1", ¶m.penalty_per_read, NULL}, {"Max penalty", assign_uint, NULL, 0, 1, "100", ¶m.max_penalty, NULL}, {"Low penalty", assign_uint, NULL, 0, 1, "20", ¶m.low_penalty, NULL}, {"Default priority", assign_uint, NULL, 0, 1, "0", ¶m.default_priority, NULL}, {"Max priority", assign_uint, NULL, 0, 1, "0", ¶m.max_priority, NULL}, {"Default weight", assign_uint, NULL, 0, 1, "20", ¶m.default_weight, NULL}, {"Max weight", assign_uint, NULL, 0, 1, "100", ¶m.max_weight, NULL}, /* Client inactivity timeouts. */ {"Connect timeout", assign_timeval, NULL, 0, 1, "30", ¶m.connect_timeout, "seconds"}, {"Login timeout", assign_timeval, NULL, 0, 1, "30", ¶m.login_timeout, "minutes"}, {"Active timeout", assign_timeval, NULL, 0, 1, "11.5", ¶m.active_timeout, "days"}, /* More performance tuning. */ {"Max client message size", assign_int, NULL, 0, 1, "8176", ¶m.maxmsgsize, NULL}, {"Max client transmit queue messages", assign_int, NULL, 0, 1, "50", ¶m.maxqueuedsize, NULL}, {"Max client transmit queue bytes", assign_int, NULL, 0, 1, "100000", ¶m.maxqueuedsize_bytes, NULL}, {"Stale timeout", assign_timeval, NULL, 0, 1, "60", ¶m.stale_timeout, "minutes"}, {"Max simultaneous client replies", assign_int, NULL, 0, 1, "10", ¶m.maxdequeuelen, NULL}, {"Open files", assign_int, NULL, 0, 1, "-1", ¶m.no_files, NULL}, {"Use DNS", assign_bool, NULL, 0, 1, "yes", ¶m.use_dns, NULL}, {"DNS log threshold", assign_double, NULL, 0, 1, "1.5", ¶m.dns_log_threshold, NULL}, /* String limits */ {"Max conference name length", assign_int, NULL, 0, 1, "60", ¶m.conf_name_len, NULL}, {"Max client data length", assign_int, NULL, 0, 1, "60", ¶m.client_data_len, NULL}, {"Max password length", assign_int, NULL, 0, 1, "128", ¶m.pwd_len, NULL}, {"Max what am I doing length", assign_int, NULL, 0, 1, "60", ¶m.what_do_len, NULL}, {"Max username length", assign_int, NULL, 0, 1, "128", ¶m.username_len, NULL}, {"Max text length", assign_int, NULL, 0, 1, "131072", ¶m.text_len, NULL}, {"Max aux_item length", assign_int, NULL, 0, 1, "16384", ¶m.aux_len, NULL}, {"Max broadcast length", assign_int, NULL, 0, 1, "1024", ¶m.broadcast_len, NULL}, {"Max regexp length", assign_int, NULL, 0, 1, "1024", ¶m.regexp_len, NULL}, {"Statistic name length", assign_int, NULL, 0, 1, "64", ¶m.stat_name_len, NULL}, /* Text_stat limits */ {"Max marks per person", assign_int, NULL, 0, 1, "2048", ¶m.max_marks_person, NULL}, {"Max marks per text", assign_int, NULL, 0, 1, "1024", ¶m.max_marks_text, NULL}, {"Max recipients per text", assign_int, NULL, 0, 1, "512", ¶m.max_recipients, NULL}, {"Max comments per text", assign_int, NULL, 0, 1, "128", ¶m.max_comm, NULL}, {"Max footnotes per text", assign_int, NULL, 0, 1, "32", ¶m.max_foot, NULL}, {"Max links per text", assign_int, NULL, 0, 1, "512", ¶m.max_crea_misc, NULL}, /* Other client-visible configuration */ {"Max mark_as_read chunks", assign_int, NULL, 0, 1, "128", ¶m.mark_as_read_chunk, NULL}, {"Max accept_async len", assign_int, NULL, 0, 1, "128", ¶m.accept_async_len, NULL}, {"Max aux_items added per call", assign_int, NULL, 0, 1, "128", ¶m.max_add_aux, NULL}, {"Max aux_items deleted per call", assign_int, NULL, 0, 1, "128", ¶m.max_delete_aux, NULL}, {"Max read_ranges per call", assign_int, NULL, 0, 1, "512", ¶m.max_read_ranges, NULL}, {"Max super_conf loop", assign_int, NULL, 0, 1, "17", ¶m.max_super_conf_loop, NULL}, {"Default garb nice", assign_int, NULL, 0, 1, "77", ¶m.default_nice, NULL}, {"Default keep commented nice", assign_int, NULL, 0, 1, "77", ¶m.default_keep_commented, NULL}, /* Security options */ {"Anyone can create new persons", assign_bool, NULL, 0, 1, "yes", ¶m.anyone_can_create_new_persons, NULL}, {"Anyone can create new conferences", assign_bool, NULL, 0, 1, "yes", ¶m.anyone_can_create_new_confs, NULL}, {"Allow creation of persons before login", assign_bool, NULL, 0, 1, "yes", ¶m.create_person_before_login, NULL}, {"Default change name capability", assign_bool, NULL, 0, 1, "on", ¶m.default_change_name, NULL}, {"Add members by invitation", assign_bool, NULL, 0, 1, "on", ¶m.invite_by_default, NULL}, {"Allow secret memberships", assign_bool, NULL, 0, 1, "on", ¶m.secret_memberships, NULL}, {"Allow reinvitations", assign_bool, NULL, 0, 1, "off", ¶m.allow_reinvite, NULL}, {"Log login", assign_bool, NULL, 0, 1, "off", ¶m.log_login, NULL}, {"Ident-authentication", ident_param, NULL, 0, 1, "try", ¶m.authentication_level, NULL}, /* Cache configuration */ {"Cache conference limit", assign_int, NULL, 0, 1, "20", ¶m.cache_conferences, NULL}, {"Cache person limit", assign_int, NULL, 0, 1, "20", ¶m.cache_persons, NULL}, {"Cache text_stat limit", assign_int, NULL, 0, 1, "20", ¶m.cache_text_stats, NULL}, /* Echo the value to the log. */ {"Echo", log_param, NULL, 0, -1, NULL, NULL, NULL}, /* Register a forbidden text number. */ {"Jubel", jubel, NULL, 0, -1, NULL, NULL, NULL}, {"Max conferences", assign_ulong, NULL, 1, 1, "4765", ¶m.max_conf, NULL}, {"Max texts", assign_ulong, NULL, 1, 1, "2000000", ¶m.max_text, NULL}, /* Configuration for support programs. */ {"Normal shutdown time", assign_int, NULL, 0, 1, "21", ¶m.normal_shutdown_time, NULL}, {"Mail after downtime", assign_int, NULL, 0, 1, "60", ¶m.downtime_mail_start, NULL}, {"Mail until downtime", assign_int, NULL, 0, 1, "120", ¶m.downtime_mail_end, NULL}, {"sendmail path", assign_path, unassign_path, 0, 1, SENDMAIL_PATH, ¶m.sendmail_path, NULL}, {"lyskomd path", assign_path, unassign_path, 0, 1, LYSKOMD_PATH, ¶m.lyskomd_path, NULL}, {"savecore path", assign_path, unassign_path, 0, 1, SAVECORE_PATH, ¶m.savecore_path, NULL}, /* end marker */ {NULL, NULL, NULL, 0, 0, NULL, NULL, NULL}}; /* Where to save things. */ static const char compiled_config_file[] = CONFIG_FILE; static const char *default_config = NULL; const char * get_default_config_file_name(void) { if (default_config == NULL) { if (compiled_config_file[0] == '/') default_config = compiled_config_file; else { char *cfg = smalloc(strlen(DEFAULT_PREFIX) + strlen(compiled_config_file) + 2); sprintf(cfg, "%s/%s", DEFAULT_PREFIX, compiled_config_file); default_config = cfg; } } return default_config; } void free_default_config_file_name(void) { if (default_config != NULL && default_config != compiled_config_file) { /* cast away const; this string was allocated by get_default_config_file_name(). */ sfree((char*)default_config); } default_config = NULL; } /* This file descriptor, and any above it, will not be used by lyskomd. */ int fd_ceiling = 0; /* Initialized by main(). */ /* What is whitespace? */ const char *WHITESPACE = " \t\n\r"; static Success log_param(const char *val, const struct parameter *UNUSED(par)) { if (val != NULL) kom_log ("config: %s\n", val); return OK; } static Success jubel(const char *val, const struct parameter *par) { long a, b, c; int res; Bool public = FALSE; if (val == NULL) return OK; if (!strncmp(val, "public ", 7)) { public = TRUE; val += 7; } res = sscanf(val, "%ld %ld %ld", &a, &b, &c); switch (res) { case 3: register_jubel(a, b, c, public); break; case 2: register_jubel(a, 0, b, public); break; default: kom_log("%s expecting [public ] x y [z]\n", par->name); return FAILURE; } return OK; } static Success ident_param(const char *val, const struct parameter *par) { if (val == NULL) restart_kom("ident_param(): val == NULL\n"); if (!strcmp(val, "off") || !strcmp(val, "never")) { *(int*)par->value = 0; } else if (!strcmp(val, "on") || !strcmp(val, "try")) { *(int*)par->value = 1; } else if (!strcmp(val, "require") || !strcmp(val, "required")) { *(int*)par->value = 2; } else { kom_log ("%s expects \"never\", \"try\" or \"required\" as argument\n", par->name); return FAILURE; } return OK; } static void add_prefix(char **name) { char *s; if (**name == '/') return; /* Don't alter full paths. */ s = smalloc(2 + strlen(param.dbase_dir) + strlen(*name)); sprintf(s, "%s/%s", param.dbase_dir, *name); sfree(*name); *name = s; } static const char * param_name(void *value) { int ix; for (ix = 0; parameters[ix].name != NULL; ix++) if (parameters[ix].value == value) return parameters[ix].name; restart_kom("Internal error: non-existing config param in param_name.\n"); /* notreached */ return NULL; } static Bool check_abs_path(char **path) { if (**path == '/') return FALSE; kom_log("Parameter '%s' must be an absolute path when 'Prefix' is empty.\n", param_name(path)); return TRUE; } static void require_less(void *low, void *high) { kom_log("Parameter '%s' must be less than parameter '%s'.\n", param_name(low), param_name(high)); } static void require_less_eq(void *low, void *high) { kom_log("Parameter '%s' must be less than or equal to parameter '%s'.\n", param_name(low), param_name(high)); } void read_configuration(const char *conf_file) { Bool err = FALSE; read_config(conf_file, parameters); assert(param.dbase_dir != NULL); assert(param.datafile_name != NULL); assert(param.backupfile_name != NULL); assert(param.backupfile_name_2 != NULL); assert(param.lockfile_name != NULL); assert(param.textfile_name != NULL); assert(param.numberfile_name != NULL); assert(param.numberfile_tmp_name != NULL); assert(param.textbackupfile_name != NULL); assert(param.backup_dir != NULL); assert(param.statistic_name != NULL); assert(param.pid_name != NULL); assert(param.memuse_name != NULL); assert(param.logfile_name != NULL); assert(param.connection_status_file != NULL); assert(param.connection_status_file_tmp != NULL); assert(param.aux_def_file != NULL); assert(param.status_file != NULL); assert(param.core_dir != NULL); assert(param.lyskomd_path != NULL); assert(param.savecore_path != NULL); assert(param.sendmail_path != NULL); if (strlen(param.dbase_dir) > 0) { if (param.dbase_dir[0] != '/') { kom_log("The 'Prefix' parameter must be an absolute path.\n"); err = TRUE; } add_prefix(¶m.datafile_name); add_prefix(¶m.backupfile_name); add_prefix(¶m.backupfile_name_2); add_prefix(¶m.lockfile_name); add_prefix(¶m.textfile_name); add_prefix(¶m.numberfile_name); add_prefix(¶m.numberfile_tmp_name); add_prefix(¶m.textbackupfile_name); add_prefix(¶m.backup_dir); add_prefix(¶m.statistic_name); add_prefix(¶m.pid_name); add_prefix(¶m.memuse_name); add_prefix(¶m.logfile_name); add_prefix(¶m.connection_status_file); add_prefix(¶m.connection_status_file_tmp); add_prefix(¶m.aux_def_file); add_prefix(¶m.status_file); add_prefix(¶m.core_dir); add_prefix(¶m.lyskomd_path); add_prefix(¶m.savecore_path); if (strcmp(param.sendmail_path, ":") != 0) add_prefix(¶m.sendmail_path); } else { err |= check_abs_path(¶m.datafile_name); err |= check_abs_path(¶m.backupfile_name); err |= check_abs_path(¶m.backupfile_name_2); err |= check_abs_path(¶m.lockfile_name); err |= check_abs_path(¶m.textfile_name); err |= check_abs_path(¶m.numberfile_name); err |= check_abs_path(¶m.numberfile_tmp_name); err |= check_abs_path(¶m.textbackupfile_name); err |= check_abs_path(¶m.backup_dir); err |= check_abs_path(¶m.statistic_name); err |= check_abs_path(¶m.pid_name); err |= check_abs_path(¶m.memuse_name); err |= check_abs_path(¶m.logfile_name); err |= check_abs_path(¶m.connection_status_file); err |= check_abs_path(¶m.connection_status_file_tmp); err |= check_abs_path(¶m.aux_def_file); err |= check_abs_path(¶m.status_file); err |= check_abs_path(¶m.core_dir); err |= check_abs_path(¶m.lyskomd_path); err |= check_abs_path(¶m.savecore_path); if (strcmp(param.sendmail_path, ":") != 0) err |= check_abs_path(¶m.sendmail_path); } if (param.saved_items_per_call < 1) { err = TRUE; kom_log("Parameter '%s' must be at least 1.\n", param_name(¶m.saved_items_per_call)); } /* We want max_texts and max_confs to hold the first forbidden number, but the documentation states that they hold the number of objects that are allowed to be created. Adjust. */ if (++param.max_text < 2) { err = TRUE; kom_log("Parameter '%s' must be at least 1.\n", param_name(¶m.max_text)); } if (++param.max_conf < 6) { err = TRUE; kom_log("Parameter '%s' must be at least 5.\n", param_name(¶m.max_conf)); } if (param.low_penalty >= param.max_penalty) { err = TRUE; require_less(¶m.low_penalty, ¶m.max_penalty); } if (param.default_weight < 1) { err = TRUE; kom_log("Parameter '%s' must be at least 1.\n", param_name(¶m.default_weight)); } if (param.default_weight > param.max_weight) { err = TRUE; require_less_eq(¶m.default_weight, ¶m.max_weight); } if (param.default_priority > param.max_priority) { err = TRUE; require_less_eq(¶m.default_priority, ¶m.max_priority); } if (param.max_priority > 0) { err = TRUE; kom_log("Parameter '%s' must be at most 0.\n", param_name(¶m.max_priority)); } /* This limit stops a potential overflow in adjust_penalty(). */ if (param.max_weight >= 0x10000) { err = TRUE; kom_log("Parameter '%s' must be at most %d.\n", param_name(¶m.max_weight), 0x10000); } /* This limit stops a potential overflow in adjust_penalty(). */ if (param.max_penalty >= 0x8000) { err = TRUE; kom_log("Parameter '%s' must be at most %d.\n", param_name(¶m.max_weight), 0x8000); } /* FIXME (bug 165): Check config parameters for sanity. One thing to check is: The following should always be true: 0 <= SYNCTIMEOUT <= GARBTIMEOUT <= TIMEOUT Times in milliseconds. There are probably many more things to check. */ if (err) restart_kom("Please fix the above configuration errors.\n"); } void free_configuration(void) { int i = 0; while (parameters[i].name != NULL) { if (parameters[i].freer != NULL) { (*parameters[i].freer)(¶meters[i]); } i += 1; } } #ifdef DEBUG_CALLS static void dump_timeval(const struct parameter *par) { struct timeval *tv = par->value; kom_log("Name: %s\n", par->name); kom_log(" Default suffix: %s\n", par->default_suffix); kom_log(" Seconds: %ld\n", tv->tv_sec); kom_log(" Microseconds: %ld\n", tv->tv_usec); } Success dump_cfg_timevals(void) { int ix; kom_log("Configuration timeval dump\n"); for (ix = 0; parameters[ix].name != NULL; ix++) if (parameters[ix].assigner == assign_timeval) dump_timeval(¶meters[ix]); kom_log("End of timeval dump\n"); return OK; } #endif lyskom-server-2.1.2/src/server/conf-file.c0000664000015100472110000002431007721716126014131 /* * $Id: conf-file.c,v 1.34 2003/08/23 16:38:18 ceder Exp $ * Copyright (C) 1994-1995, 1998-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * Read configuration files. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include "timewrap.h" #include #include #ifdef HAVE_STRING_H # include #else # ifdef HAVE_STRINGS_H # include # endif #endif #ifndef HAVE_STRCHR # define strchr index #endif #ifdef HAVE_STDLIB_H # include #endif #include "s-string.h" #include "server/smalloc.h" #include "log.h" #include "misc-types.h" #include "kom-types.h" #include "conf-file.h" #include "lyskomd.h" #include "eintr.h" #include "timeval-util.h" #define MAXLINE 1001 static int *assignment_count = NULL; static int npar = 0; static void init_init(const struct parameter *par) { int ix; for (npar = 0; par[npar].name != NULL; npar++) ; assert (assignment_count == NULL); assignment_count = smalloc(npar * sizeof (*assignment_count)); for (ix = 0; ix < npar; ix++) assignment_count[ix] = 0; } /* Check that each parameter is assigned at least as many times as the struct parameter says. Assign the default value if it is not assigned at all. */ static void assign_defaults(const struct parameter *par, int *err) { int ix; for (ix = 0; ix < npar; ix++) { if (assignment_count[ix] < par[ix].min_assignments) { kom_log ("Parameter %s only assigned %d times (%d times needed)\n", par[ix].name, assignment_count[ix], par[ix].min_assignments); (*err)++; } else if (assignment_count[ix] == 0) { if ((*par[ix].assigner)(par[ix].default_val, &par[ix]) != OK) { kom_log ("default assigner failed for %s\n", par[ix].name); (*err)++; } } } } /* Perform the assignments on one line. Returns EOF on end-of-file, 0 otherwise. A log message is printed, and (*err) is incremented, if errors are detected. */ static int configure_line(FILE *fp, const struct parameter *par, int *err) { char line[MAXLINE]; char *start; char *val; char *end; int found; int ix; if (fgets(line, MAXLINE, fp) == NULL) return EOF; /* Separate the line into its two parts. Set up ``start'' to point to the beginning of the variable name, ``val'' to point to the beginning of the value, and remove the trailing newline (using ``end''). */ for (start = line; *start == ' ' || *start == '\t'; start++) ; switch (*start) { case '#': /* Comment line */ return 0; case '\0': /* Too long */ kom_log ("line too long (max %d chars allowed): %s\n", MAXLINE-1, line); (*err)++; return 0; case '\n': /* Empty line */ return 0; } val = strchr(line, ':'); if (val == NULL) { /* Remove any trailing newline to avoid a blank line in the log. */ end = strchr(line, '\n'); if (end != NULL) *end = '\0'; kom_log("missing colon: %s\n", line); (*err)++; return 0; } *val = '\0'; /* NUL-terminate key */ for (val++; *val == ' ' || *val == '\t'; val++) ; switch (*val) { case '\0': kom_log ("line too long (max %d chars allowed): %s\n", MAXLINE-1, line); (*err)++; return 0; } end = strchr(val, '\n'); if (end == NULL) { kom_log ("line too long (max %d chars allowed): %s\n", MAXLINE-1, line); (*err)++; return 0; } *end = '\0'; /* Set the variable which match this line. */ found = 0; for (ix = 0; ix < npar; ix++) { if (!strcmp(start, par[ix].name)) { found++; if (assignment_count[ix] >= par[ix].max_assignments && par[ix].max_assignments != -1) { (*err)++; kom_log ("variable already assigned %d times: %s\n", assignment_count[ix], line); } else { assignment_count[ix]++; if ((*par[ix].assigner)(val, &par[ix]) != OK) { kom_log ("assigner for %s failed\n", par[ix].name); (*err)++; } } } } if (found != 1) { kom_log ("line matches %d times: %s\n", found, line); (*err)++; return 0; } return 0; } void read_config(const char *config_file, const struct parameter *par) { FILE *fp; int errs = 0; init_init(par); fp = i_fopen(config_file, "r"); if (fp == NULL) restart_kom("cannot open config file %s\n", config_file); while (configure_line(fp, par, &errs) != EOF) ; i_fclose(fp); assign_defaults(par, &errs); if (errs) restart_kom("Please fix the above errors in %s and restart lyskomd\n", config_file); sfree(assignment_count); assignment_count = 0; } Success assign_text_no(const char *val, const struct parameter *par) { int c; /* FIXME (bug 143): use strtol */ if (val != NULL) { c = (unsigned char)*val; if (!isascii(c) || !isdigit(c)) return FAILURE; *(Text_no*)par->value = atol(val); } return OK; } Success assign_conf_no(const char *val, const struct parameter *par) { int c; /* FIXME (bug 143): use strtol */ if (val != NULL) { c = (unsigned char)*val; if (!isascii(c) || !isdigit(c)) return FAILURE; *(Conf_no*)par->value = atol(val); } return OK; } Success assign_int(const char *val, const struct parameter *par) { int c; /* FIXME (bug 143): use strtol */ if (val != NULL) { c = (unsigned char)*val; if ((!isascii(c) || !isdigit(c)) && c != '-') return FAILURE; *(int*)par->value = atol(val); } return OK; } Success assign_ulong(const char *val, const struct parameter *par) { int c; if (val != NULL) { c = (unsigned char)*val; if ((!isascii(c) || !isdigit(c)) && c != '-') return FAILURE; *(unsigned long*)par->value = (unsigned long)atol(val); } return OK; } Success assign_uint(const char *val, const struct parameter *par) { int c; if (val != NULL) { c = (unsigned char)*val; if ((!isascii(c) || !isdigit(c)) && c != '-') return FAILURE; *(unsigned int*)par->value = (unsigned int)atol(val); } return OK; } Success assign_string(const char *val, const struct parameter *par) { if (val == NULL) *(char**)par->value = NULL; else { *(char**)par->value = smalloc(strlen(val) + 1); strcpy(*(char**)par->value, val); } return OK; } Success assign_bool(const char *val, const struct parameter *par) { if (val == NULL ||!strcmp(val, "false") || !strcmp(val, "off") || !strcmp(val, "no") || !strcmp(val, "0")) { *(Bool*)par->value = FALSE; } else if (!strcmp(val, "true") || !strcmp(val, "on") || !strcmp(val, "yes") || !strcmp(val, "1")) { *(Bool*)par->value = TRUE; } else { return FAILURE; } return OK; } Success assign_double(const char *val, const struct parameter *par) { char *tail = NULL; if (val != NULL) { errno = 0; *(double*)par->value = strtod(val, &tail); if (errno || tail == val || *tail != '\0') return FAILURE; } return OK; } struct suffix_conversion { const char *suffix; double factor; }; static const struct suffix_conversion suffix_table[] = { {"seconds", 1.0}, {"second", 1.0}, {"sec", 1.0}, {"s", 1.0}, {"minutes", 60.0}, {"minute", 60.0}, {"min", 60.0}, {"hours", 3600.0}, {"hour", 3600.0}, {"h", 3600.0}, {"days", 86400.0}, {"day", 86400.0}, {"d", 86400.0}, {"milliseconds", 0.001}, {"millisecond", 0.001}, {"milli", 0.001}, {"ms", 0.001}, {"microseconds", 0.000001}, {"microsecond", 0.000001}, {"micro", 0.000001}, {"us", 0.000001}, {"u", 0.000001}, {"kiloseconds", 1000.0}, {"megaseconds", 1000000.0}, {"microfortnights", 1.2096}, {"microfortnight", 1.2096}, {NULL, 0.0}, }; Success assign_timeval(const char *val, const struct parameter *par) { char *tail = NULL; double number; double err; const char *suffix; const struct suffix_conversion *s; struct timeval tv; assert(par->default_suffix != NULL); if (val != NULL) { errno = 0; number = strtod(val, &tail); if (errno || tail == val) return FAILURE; if (*tail != '\0') suffix = tail; else suffix = par->default_suffix; while (isspace((int)(unsigned char)*suffix)) ++suffix; for (s = suffix_table; s->suffix != NULL; ++s) if (!strcmp(s->suffix, suffix)) break; if (s->suffix == NULL) { kom_log("Bad suffix for parameter %s\n", par->name); return FAILURE; } number *= s->factor; if (number < 0) { kom_log("Negative values not supported for parameter %s\n", par->name); return FAILURE; } tv = timeval_ctor(number, ((number - (int)number) * 1000000) + 0.5); err = (tv.tv_sec + 1.0e-6 * tv.tv_usec) - number; if (err < 0) err = -err; if ((err > 1.0e-6 && err > 1.0e-6 * number) || tv.tv_sec < 0 || tv.tv_usec < 0 || tv.tv_usec >= 1000000) { kom_log("Overflow for parameter %s (%s)\n", par->name, val); return FAILURE; } *(struct timeval*)par->value = tv; } return OK; } void unassign_string(const struct parameter *par) { if (*(char**)par->value != NULL) { sfree(*(char**)par->value); *(char**)par->value = NULL; } } lyskom-server-2.1.2/src/server/lockdb.h0000664000015100472110000000232207721716127013532 /* * Lock and unlock the database. * Copyright (C) 1999, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* Attempt to lock the database. Returns 0 on success, or -1 if the database is already locked. If it is locked, an error message will be written using kom_log(). */ int lock_db(void); /* Unlock the database. */ void unlock_db(void); lyskom-server-2.1.2/src/server/lockdb.c0000664000015100472110000000701407721716127013530 /* * Lock and unlock the database. * Copyright (C) 1999, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ #include #include #include #include #include #include #ifdef HAVE_STRING_H # include #else # ifdef HAVE_STRINGS_H # include # endif #endif #ifndef HAVE_STRCHR # define strchr index #endif #include #include #include #include "timewrap.h" #include "lockdb.h" #include "log.h" #include "kom-types.h" #include "param.h" #include "lyskomd.h" int lock_db(void) { char new_lock[MAXHOSTNAMELEN + 3 + 3 * sizeof(pid_t)]; char current_lock[MAXHOSTNAMELEN + 4 + 3 * sizeof(pid_t)]; char *end; int retry; size_t sz; size_t ix; pid_t pid; if (gethostname(new_lock, MAXHOSTNAMELEN) == -1) restart_kom("gethostname failed (%d)\n", errno); new_lock[MAXHOSTNAMELEN+1] = '\0'; end = strchr(new_lock, '\0'); sprintf(end, ":%ld", (long)getpid()); for (retry = 0; retry < 2; ++retry) { if (symlink(new_lock, param.lockfile_name) == 0) { kom_log("Created lock %s\n", param.lockfile_name); return 0; } if (errno != EEXIST) restart_kom("Failed to create lock symlink %s " "pointing to %s: %d\n", param.lockfile_name, new_lock, errno); if (retry) { kom_log("Lock file recreated by some other party\n"); return -1; } sz = readlink(param.lockfile_name, current_lock, sizeof(current_lock)); if (sz >= sizeof(current_lock) - 1) restart_kom("Too much data in lock symlink %s\n", param.lockfile_name); current_lock[sz] = '\0'; for (ix = 0; ix < sizeof(new_lock); ++ix) { if (new_lock[ix] != current_lock[ix]) { kom_log("Database already locked by %s\n", current_lock); return -1; } if (new_lock[ix] == ':') break; } pid = strtol(¤t_lock[ix+1], &end, 10); if (end == ¤t_lock[ix+1]) restart_kom("Found a broken lock symlink %s: %s\n", param.lockfile_name, current_lock); if (kill(pid, 0) == 0 || errno != ESRCH) { kom_log("Database already locked by %s\n", current_lock); return -1; } /* The process is dead. Remove the stale lock file. If it was just removed by a dying process -- fine. */ if (remove(param.lockfile_name) < 0 && errno != ENOENT) restart_kom("Failed to remove stale lock symlink %s\n", param.lockfile_name); else kom_log("Removed stale lock file left by %s.\n", current_lock); } restart_kom("Unreachable code reached in lock_db.\n"); } void unlock_db(void) { if (remove(param.lockfile_name) < 0) restart_kom("Failed to remove lock file %s\n", param.lockfile_name); } lyskom-server-2.1.2/src/server/dbck-cache.h0000664000015100472110000000231707721716126014243 /* * $Id: dbck-cache.h,v 0.8 2003/08/23 16:38:17 ceder Exp $ * Copyright (C) 1991, 1998-1999, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: dbck-cache.h,v 0.8 2003/08/23 16:38:17 ceder Exp $ * */ extern void cached_flush_text(Text_no text_no, String message); extern void cache_open_new_text_file(void); extern long oformat; lyskom-server-2.1.2/src/server/getopt.h0000664000015100472110000001046506722217023013574 /* Declarations for getopt. Copyright (C) 1989-1993, 1996, 1999 Free Software Foundation, Inc. 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 2, 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, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _GETOPT_H #define _GETOPT_H 1 #ifdef __cplusplus extern "C" { #endif /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ extern char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ extern int optind; /* Callers store zero here to inhibit the error message `getopt' prints for unrecognized options. */ extern int opterr; /* Set to an option character which was unrecognized. */ extern int optopt; /* Describe the long-named options requested by the application. The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector of `struct option' terminated by an element containing a name which is zero. The field `has_arg' is: no_argument (or 0) if the option does not take an argument, required_argument (or 1) if the option requires an argument, optional_argument (or 2) if the option takes an optional argument. If the field `flag' is not NULL, it points to a variable that is set to the value given in the field `val' when the option is found, but left unchanged if the option is not found. To have a long-named option do something other than set an `int' to a compiled-in constant, such as set a value from `optarg', set the option's `flag' field to zero and its `val' field to a nonzero value (the equivalent single-letter option character, if there is one). For long options that have a zero `flag' field, `getopt' returns the contents of the `val' field. */ struct option { #if __STDC__ const char *name; #else char *name; #endif /* has_arg can't be an enum because some compilers complain about type mismatches in all the code that assumes it is an int. */ int has_arg; int *flag; int val; }; /* Names for the values of the `has_arg' field of `struct option'. */ #define no_argument 0 #define required_argument 1 #define optional_argument 2 #if __STDC__ #if defined(__GNU_LIBRARY__) /* Many other libraries have conflicting prototypes for getopt, with differences in the consts, in stdlib.h. To avoid compilation errors, only prototype getopt for the GNU C library. */ extern int getopt (int argc, char *const *argv, const char *shortopts); #else /* not __GNU_LIBRARY__ */ extern int getopt (); #endif /* not __GNU_LIBRARY__ */ extern int getopt_long (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); extern int getopt_long_only (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); /* Internal only. Users should not call this directly. */ extern int _getopt_internal (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind, int long_only); #else /* not __STDC__ */ extern int getopt (); extern int getopt_long (); extern int getopt_long_only (); extern int _getopt_internal (); #endif /* not __STDC__ */ #ifdef __cplusplus } #endif #endif /* _GETOPT_H */ lyskom-server-2.1.2/src/server/standalone.c0000664000015100472110000000340607721716130014415 /* * $Id: standalone.c,v 1.10 2003/08/23 16:38:13 ceder Exp $ * Copyright (C) 1999, 2002-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include "timewrap.h" #include "kom-types.h" #include "async.h" #include "com.h" #include "connections.h" #include "kom-errno.h" #include "manipulate.h" #include "unused.h" /* Dummy routines for standalone programs. */ void register_jubel(Pers_no UNUSED(pno), Text_no UNUSED(divis), Text_no UNUSED(tno), Bool UNUSED(public)) { } Info kom_info = { #include "version.incl" , /* version */ 1, /* conf_pres_conf */ 2, /* pers_pres_conf */ 3, /* motd_conf */ 4, /* kom_news_conf */ 0, /* motd_of_lyskom */ 0, /* highest_aux_no */ { 0, NULL } /* aux_item_list */ }; lyskom-server-2.1.2/src/server/komrunning.c0000664000015100472110000001254207721716127014463 /* * $Id: komrunning.c,v 1.11 2003/08/23 16:38:16 ceder Exp $ * Copyright (C) 1999, 2002-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include "timewrap.h" #include "kom-types.h" #include "s-string.h" #include "string-malloc.h" #include "server/smalloc.h" #include "kom-config.h" #include "server-config.h" #include "param.h" #include "pidfile.h" #include "linkansi.h" #include "eintr.h" static void usage(const char *arg0) { fprintf(stderr, "usage: %s [-c config-file] [ -v ] [ -V ] [start | stop]\n", arg0); exit(1); } static void create_status(const char *arg0) { FILE *fp; int saved_errno; struct passwd *pwent; const char *user; user = getenv("USER"); if (user == NULL) { pwent = getpwuid(getuid()); if (pwent != NULL) user = pwent->pw_name; } if (user == NULL) user = "root"; fp = i_fopen(param.status_file, "w"); if (fp == NULL) { saved_errno = errno; fputs(arg0, stderr); errno = saved_errno; perror(param.status_file); exit(1); } if (fputs(user, fp) == EOF || putc('\n', fp) == EOF) { saved_errno = errno; fprintf(stderr, "%s: writing to ", arg0); errno = saved_errno; perror(param.status_file); exit(1); } if (i_fclose(fp) != 0) { saved_errno = errno; fprintf(stderr, "%s: closing ", arg0); errno = saved_errno; perror(param.status_file); exit(1); } } static void shutdown_lyskom(pid_t pid, const char *arg0) { int saved_errno; if (pid < 2) { fprintf(stderr, "%s: insane pid %ld found in %s\n", arg0, (long)pid, param.pid_name); exit(1); } if (kill(pid, SIGTERM) != 0) { saved_errno = errno; fprintf(stderr, "%s: sending SIGTERM to pid %ld", arg0, (long)pid); errno = saved_errno; perror(""); exit(1); } while (kill(pid, 0) == 0) sleep(1); if (errno != ESRCH) { saved_errno = errno; fprintf(stderr, "%s: sending signal 0 to pid %ld", arg0, (long)pid); errno = saved_errno; perror(""); exit(1); } } int main (int argc, char **argv) { const char *config_file = NULL; int bring_up = 0; int bring_down = 0; int i; pid_t pid; int saved_errno; struct stat statbuf; link_ansi(); /* Initialize the string handling package. */ s_set_storage_management(string_malloc, string_realloc, string_free); /* Parse command line arguments. */ for (i = 1; i < argc && argv[i][0] == '-'; i++) { if (argv[i][1] == '\0' || argv[i][2] != '\0') usage(argv[0]); switch (argv[i][1]) { case 'c': if (config_file != NULL) { fprintf(stderr, "%s: -c may only be used once\n", argv[0]); exit(1); } if (++i >= argc) usage(argv[0]); config_file = argv[i]; break; case 'V': case 'v': fprintf(stderr, "komrunning from %s-%s\n", PACKAGE, VERSION); exit(0); default: usage(argv[0]); } } if (i < argc && !strcmp(argv[i], "start")) { i++; bring_up = 1; } if (i < argc && !strcmp(argv[i], "stop")) { i++; bring_down = 1; } if (i < argc || (bring_up && bring_down)) usage(argv[0]); /* Read in the configuration file. */ if (config_file == NULL) config_file = get_default_config_file_name(); read_configuration(config_file); if (bring_up) { if (remove(param.status_file) < 0 && errno != ENOENT) { saved_errno = errno; fprintf(stderr, "%s: ", argv[0]); errno = saved_errno; perror(param.status_file); exit(2); } } else { pid = read_pid_file(param.pid_name, argv[0]); if (bring_down) { create_status(argv[0]); shutdown_lyskom(pid, argv[0]); } else { if (stat(param.status_file, &statbuf) == 0) { if (pid < 1) printf("LysKOM is probably DOWN (pid file not found)\n"); else if (kill(pid, 0) == 0 || errno == EPERM) printf("LysKOM is going DOWN (pid %ld)\n", (long)pid); else if (errno == ESRCH) printf("LysKOM is DOWN\n"); else perror("kill"); } else { if (pid < 1) printf("LysKOM is probably going up " "(pid file not found)\n"); else if (kill(pid, 0) == 0 || errno == EPERM) printf("LysKOM is UP\n"); else if (errno == ESRCH) printf("LysKOM is going up\n"); else perror("kill"); } } } free_default_config_file_name(); return 0; } lyskom-server-2.1.2/src/server/pidfile.c0000664000015100472110000000340307721716127013704 /* * $Id: pidfile.c,v 1.5 2003/08/23 16:38:15 ceder Exp $ * Copyright (C) 1999, 2002-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include "pidfile.h" #include "eintr.h" pid_t read_pid_file(const char *pidfile, const char *arg0) { FILE *fp; int saved_errno; pid_t pid = 0; int c; fp = i_fopen(pidfile, "r"); if (fp == NULL) { saved_errno = errno; fprintf(stderr, "%s: warning: ", arg0); errno = saved_errno; perror(pidfile); } else { while ((c = getc(fp)) != EOF && c == ' ') ; ungetc(c, fp); while ((c = getc(fp)) != EOF && c >= '0' && c <= '9') pid = 10 * pid + c - '0'; i_fclose(fp); if (pid < 2) { fprintf(stderr, "%s: got pid %ld.\n", arg0, (long)pid); exit(1); } } return pid; } lyskom-server-2.1.2/src/server/pidfile.h0000664000015100472110000000206107721716127013710 /* * $Id: pidfile.h,v 1.3 2003/08/23 16:38:15 ceder Exp $ * Copyright (C) 1999, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ pid_t read_pid_file(const char *pidfile, const char *arg0); lyskom-server-2.1.2/src/server/string-malloc.c0000664000015100472110000000363607721716130015045 /* * $Id: string-malloc.c,v 0.21 2003/08/23 16:38:13 ceder Exp $ * Copyright (C) 1991, 1993-1995, 1998-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * Malloc wrappers for the string package. * * These functions call smalloc and also counts * how many allocated strings there are. */ #ifdef HAVE_CONFIG_H # include #endif #ifdef HAVE_STDDEF_H # include #endif #include #include #include "exp.h" #include "server/smalloc.h" #include "string-malloc.h" static int no_of_allocated_blocks = 0; EXPORT void * string_malloc(size_t size) { ++no_of_allocated_blocks; return smalloc (size); } EXPORT void string_free(void * ptr) { --no_of_allocated_blocks; sfree(ptr); } EXPORT void * string_realloc (void * ptr, size_t size) { if ( ptr == NULL ) return string_malloc (size); return srealloc (ptr, size); } EXPORT void dump_string_alloc_counts(FILE *stat_file) { fprintf(stat_file, "---%s:\n\tAllocated strings: %d\n", __FILE__, no_of_allocated_blocks); } lyskom-server-2.1.2/src/server/ramkomd.c0000664000015100472110000004433607721716130013726 /* * $Id: ramkomd.c,v 0.130 2003/08/23 16:38:14 ceder Exp $ * Copyright (C) 1991-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * The next comment block is a historic comment, written in Swedish * using ISO 646 since nobody in Lysator knew about ISO 8859-1 by * then. It translates, rougly, to "This is the main program of the * server. It will hopefully be bigger than it is at the moment. * Created by Willför 31-mar-1990." */ /* * Detta {r serverns huvudprogram. Det kommer f|rhoppningsvis bli st|rre * {n det {r just nu... * * Created by Willf|r 31/3-90 * * It has grown! /ceder */ #ifdef HAVE_CONFIG_H # include #endif #ifdef HAVE_LOCALE_H # include #endif #include #include #ifdef HAVE_STDLIB_H # include #endif #ifdef HAVE_STRING_H # include #endif #include #include "timewrap.h" #ifdef HAVE_SYS_RESOURCE_H # include #endif #include #include #if defined(HAVE_SYS_PARAM_H) && !defined(HAVE_GETCWD) # include #endif #include #include #include #include #include "oop.h" #include "exp.h" #include "s-string.h" #include "misc-types.h" #include "kom-types.h" #include "com.h" #include "async.h" #include "connections.h" #include "internal-connections.h" #include "kom-errno.h" #include "oop-malloc.h" #include "isc-malloc.h" #include "isc-interface.h" #include "kom-config.h" #include "cache.h" #include "string-malloc.h" #include "lyskomd.h" #include "log.h" #include "server/smalloc.h" #include "kom-memory.h" #include "conf-file.h" #include "param.h" #include "server-config.h" #include "manipulate.h" #include "version-info.h" #include "aux-items.h" #include "admin.h" #include "unused.h" #include "sigflags.h" #include "local-to-global.h" #include "server-time.h" #include "lockdb.h" #include "linkansi.h" #ifdef TRACED_ALLOCATIONS # include "trace-alloc.h" #endif #include "eintr.h" #include "stats.h" #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_OFILE) && !defined(RLIMIT_NOFILE) # define RLIMIT_NOFILE RLIMIT_OFILE #endif #if !HAVE_RLIM_T typedef int rlim_t; #endif struct timeval current_time = { 0, 0 }; #ifndef NDEBUG int buglevel = 0; #endif /* Don't place lyskomd in the background. Write the log to stdout. Prompt for input on stdin before exiting. This is primarily intended for debugging and the test suite. */ static int foreground = 0; static oop_adapter_signal *kom_signal_adapter; static void dump_exit_statistics(void); static void free_kom_info(void); static oop_call_signal sighandler_term; static oop_call_signal sighandler_quit; static oop_call_signal sighandler_usr1; static oop_call_signal sighandler_usr2; static oop_call_signal sighandler_winch; isc_accept_callback handle_accept_event; #ifdef HAVE_STRUCT_SIGACTION /* Assigning SIG_IGN to sa_handler results in ramkomd.c:310: warning: function declaration isn't a prototype on certain compilers. By performing the assignment in a function the number of warnings are reduced. */ static inline void set_handler_sig_ign(struct sigaction *ptr) { ptr->sa_handler = SIG_IGN; } #endif static isc_write_queue_change_cb write_queue_change_callback; static void write_queue_change_callback(int delta) { update_stat(STAT_SEND_QUEUE, delta); } static void server_init(const char *host, const char * client_port) { struct isc_scb *listen_client; oop_source *src; #ifdef HAVE_STRUCT_SIGACTION struct sigaction act; #endif oop_malloc = &oop_malloc_wrapper; oop_realloc = &oop_realloc_wrapper; oop_free = &oop_free_wrapper; kom_server_oop_src = oop_sys_new(); if (kom_server_oop_src == NULL) restart_kom("server_init: can't get system event source\n"); kom_signal_adapter = oop_signal_new(oop_sys_source(kom_server_oop_src)); if (kom_signal_adapter == NULL) restart_kom("server_init: can't create signal adapter\n"); /* Ignore the signals before we register them with liboop. That way, when liboop reinstalls the old signal handler during shutdown, we will ignore them rather than stop prematurely during the shutdown. This is especially important for the SIGTERM signal, which is sent periodically by updateLysKOM. */ #ifdef HAVE_STRUCT_SIGACTION sigemptyset(&act.sa_mask); act.sa_flags = 0; set_handler_sig_ign(&act); sigaction(SIGHUP, &act, NULL); sigaction(SIGTERM, &act, NULL); sigaction(SIGINT, &act, NULL); sigaction(SIGQUIT, &act, NULL); sigaction(SIGUSR1, &act, NULL); sigaction(SIGUSR2, &act, NULL); sigaction(SIGWINCH, &act, NULL); #else signal(SIGHUP, SIG_IGN); signal(SIGTERM, SIG_IGN); signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); signal(SIGUSR1, SIG_IGN); signal(SIGUSR2, SIG_IGN); signal(SIGWINCH, SIG_IGN); #endif src = oop_signal_source(kom_signal_adapter); oop_signal_use_sa_restart(); src->on_signal(src, SIGHUP, sighandler_term, NULL); src->on_signal(src, SIGTERM, sighandler_term, NULL); src->on_signal(src, SIGINT, sighandler_term, NULL); src->on_signal(src, SIGQUIT, sighandler_quit, NULL); src->on_signal(src, SIGUSR1, sighandler_usr1, NULL); src->on_signal(src, SIGUSR2, sighandler_usr2, NULL); src->on_signal(src, SIGWINCH, sighandler_winch, NULL); /* ** Setup some parameters here */ isc_setallocfn(&isc_malloc_wrapper, &isc_realloc_wrapper, &isc_free_wrapper); kom_server_mcb = isc_initialize(oop_sys_source(kom_server_oop_src), write_queue_change_callback); if ( kom_server_mcb == NULL ) restart_kom("server_init: can't isc_initialize()\n"); isc_cfg_fd_relocate(kom_server_mcb, PROTECTED_FDS); isc_cfg_stale_timeout(kom_server_mcb, param.stale_timeout, param.connect_timeout); isc_cfg_queue_size(kom_server_mcb, param.maxqueuedsize_bytes, param.maxmsgsize, param.maxqueuedsize, param.maxdequeuelen); listen_client = isc_listentcp(kom_server_mcb, host, client_port, handle_accept_event); if (listen_client == NULL) restart_kom("server_init: can't isc_listentcp(CLIENT)\n"); kom_log("Listening for clients on %d.\n", isc_getportnum(listen_client->laddr)); /* * Ignore SIGPIPE, which the server gets if it tries to write to a * socket and the client has died. The server will anyhow handle * this situation correct. */ #ifdef HAVE_STRUCT_SIGACTION sigemptyset(&act.sa_mask); act.sa_flags = 0; set_handler_sig_ign(&act); sigaction(SIGPIPE, &act, NULL); #else signal(SIGPIPE, SIG_IGN); #endif } static void init_data_base(void) { kom_log("Database = %s\n", param.datafile_name); kom_log("Backup = %s\n", param.backupfile_name); kom_log("2nd Backup = %s\n", param.backupfile_name_2); kom_log("Lock File = %s\n", param.lockfile_name); if ( init_cache() == FAILURE ) restart_kom ("Cannot find database.\n"); } static void * sighandler_term(oop_source *UNUSED(source), int sig, void *UNUSED(user)) { if (sig == SIGTERM) kom_log("Signal TERM received. Shutting down server.\n"); else if (sig == SIGHUP) kom_log("Signal HUP received. Shutting down server." " Please use SIGTERM instead.\n"); else if (sig == SIGINT) kom_log("Signal INT received. Shutting down server." " Please use SIGTERM instead.\n"); else kom_log("Some signal received. Shutting down server." " Please use SIGTERM instead.\n"); go_and_die = TRUE; return OOP_HALT; } static void * sighandler_quit(oop_source *UNUSED(source), int UNUSED(sig), void *UNUSED(user)) { kom_log ("Signal QUIT received - syncing...\n"); cache_sync_all(); kom_log ("Dumping core now.\n"); abort(); } static void * sighandler_usr1(oop_source *UNUSED(source), int UNUSED(sig), void *UNUSED(user)) { dump_statistics(); return OOP_CONTINUE; } static void * sighandler_usr2(oop_source *UNUSED(source), int UNUSED(sig), void *UNUSED(user)) { int child; kom_log ("Signal USR2 received - will dump core now. (Check that child dies.)\n"); if ((child = fork()) == 0) { abort(); kom_log ("Abort() failed!!!\n"); exit(1); } else if (child < 0) { kom_log ("Couldn't fork.\n"); } else { wait (NULL); } return OOP_CONTINUE; } static void * sighandler_winch(oop_source *UNUSED(source), int UNUSED(sig), void *UNUSED(user)) { free_aux_item_definitions(); initialize_aux_items(param.aux_def_file); kom_log("Signal WINCH received. aux definitions reloaded.\n"); return OOP_CONTINUE; } static void save_pid(void) { FILE *fp; if ((fp = i_fopen(param.pid_name, "w")) == NULL) return; fprintf(fp, "%ld\n", (long)getpid()); i_fclose(fp); } static void go_daemon(void) { pid_t child; int fd; #ifdef HAVE_STRUCT_SIGACTION struct sigaction act; #endif if (foreground != 0) { return; } if (getppid() != 1) { /* We were not invoked from /etc/inittab, so disassociate from controlling terminal. */ #ifdef HAVE_STRUCT_SIGACTION sigemptyset(&act.sa_mask); act.sa_flags = 0; set_handler_sig_ign(&act); # ifdef SIGTTOU sigaction(SIGTTOU, &act, NULL); # endif # ifdef SIGTTIN sigaction(SIGTTIN, &act, NULL); # endif # ifdef SIGTSTP sigaction(SIGTSTP, &act, NULL); # endif #else /* !HAVE_STRUCT_SIGACTION */ # ifdef SIGTTOU signal(SIGTTOU, SIG_IGN); # endif # ifdef SIGTTIN signal(SIGTTIN, SIG_IGN); # endif # ifdef SIGTSTP signal(SIGTSTP, SIG_IGN); # endif #endif child = fork(); if (child < 0) restart_kom("fork failed: %d\n", errno); else if (child > 0) exit (0); /* parent */ setsid(); } /* Close all file descriptors */ for (fd = 0; fd < fd_ceiling; fd++) close(fd); if (open("/dev/null", O_RDONLY) != 0 ||open("/dev/null", O_WRONLY) != 1 ||open(param.logfile_name, O_WRONLY|O_CREAT|O_APPEND, 0644) != 2) { /* Kinda stupid to try to log an error message now, but who knows? */ restart_kom("open of log file failed: %d\n", errno); } kom_log("*** Version %s (process %lu) coming up.\n", kom_version_info.server_version, (unsigned long)getpid()); } static void initialize(const char *config_file) { #ifdef USING_RLIMIT_NOFILE struct rlimit rlim; #endif read_configuration(config_file); initialize_aux_items(param.aux_def_file); #ifdef HAVE_LOCALE_H if (param.use_locale != NULL) if (setlocale(LC_CTYPE, param.use_locale) == NULL) { fprintf(stderr, "setlocale: "); perror(param.use_locale); exit(1); } #else if (param.use_locale != NULL) { fprintf(stderr, "locale not supported in your environment.\n"); exit(1); } #endif if (param.no_files != -1 && param.no_files > FD_SETSIZE) { fprintf(stderr, "The \"Open files: %ld\" is too large: FD_SETSIZE is %ld\n", (long)param.no_files, (long)FD_SETSIZE); exit(1); } #ifdef USING_RLIMIT_NOFILE if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) { perror("getrlimit(RLIMIT_NOFILE) failed"); exit(1); } if (param.no_files != -1) { if ((rlim_t)param.no_files > rlim.rlim_max) { fprintf(stderr, "attempt to raise open files from %ld to %ld, " "but only %ld is allowed\n", (long)rlim.rlim_cur, (long)param.no_files, (long)rlim.rlim_max); rlim.rlim_cur = rlim.rlim_max; } else rlim.rlim_cur = param.no_files; if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) { perror("setrlimit failed"); exit(1); } if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) { perror("getrlimit(RLIMIT_NOFILE) failed"); exit(1); } if (rlim.rlim_cur != (rlim_t)param.no_files) restart_kom("getrlimit after setrlimit returns %ld, not %ld.\n", (long)rlim.rlim_cur, (long)param.no_files); } fd_ceiling = rlim.rlim_cur; #elif HAVE_GETDTABLESIZE if (param.no_files == -1) fd_ceiling = getdtablesize(); else if (param.no_files >= getdtablesize()) { fprintf(stderr, "getdtablesize() indicates that at most %ld files" " can be used.\n", (long)getdtablesize()); exit(1); } else fd_ceiling = param.no_files; #elif defined(OPEN_MAX) if (param.no_files == -1) fd_ceiling = OPEN_MAX; else if (param.no_files >= OPEN_MAX) { fprintf(stderr, "OPEN_MAX indicates that at most %ld files" " can be used.\n", (long)OPEN_MAX); exit(1); } else fd_ceiling = param.no_files; #else # error Do not know how to find maximum number of open files. #endif if (fd_ceiling > FD_SETSIZE) fd_ceiling = FD_SETSIZE; go_daemon(); if (lock_db() < 0) { /* Don't actually die until something is entered on stdin in debug mode. This is mainly here for the benefit of the test suite, but is could also be useful to be able to attach a debugger and do pre-mortem debugging of the process at this point. */ kom_log("Cannot obtain database lock. Exiting.\n"); if (foreground) { kom_log("Press enter to terminate lyskomd\n"); getchar(); } exit(1); } server_init(param.ip_client_host, param.ip_client_port); init_data_base(); } /* Stop complaint from gcc 2.0 about "no previous prototype for `main'". */ int main(int argc, char **argv); int main (int argc, char **argv) { int i; const char *config_file; oop_source *src; link_ansi(); if (gettimeofday(¤t_time, NULL) < 0) restart_kom("gettimeofday failed: %s\n", strerror(errno)); #ifdef TRACED_ALLOCATIONS /* We must do this before we allocate any memory... */ { char buf[1024]; char *nl; fputs("Where does the trace want to go today? [stderr]\n", stdout); fflush(stdout); if (fgets(buf, sizeof(buf), stdin) != buf) restart_kom("main(): unable to read trace location\n"); if ((nl = strchr(buf, '\n')) != NULL) *nl = '\0'; trace_alloc_file(buf); } #endif kom_log("*** Version %s (process %lu) started.\n", kom_version_info.server_version, (unsigned long)getpid()); #ifdef DEBUG_CALLS kom_log("WARNING: This server was compiled with --with-debug-calls.\n"); kom_log("It isn't safe to use in a production environment.\n"); #endif #ifdef ENCRYPT_PASSWORDS /* Seed the random number generator. */ /* FIXME (bug 1068): This is not a good way to seed it... */ srand(time(NULL) + getpid()); #endif /* Initialize the string handling package. */ s_set_storage_management(string_malloc, string_realloc, string_free); /* Parse command line arguments. */ for (i = 1; i < argc && argv[i][0] == '-'; i++) switch (argv[i][1]) { case 'd': buglevel++; break; case 'f': foreground = 1; break; default: restart_kom("usage: %s [-f] [-d ...] [config-file]\n", argv[0]); } /* Read in the configuration file. */ if (i < argc) config_file = argv[i++]; else config_file = get_default_config_file_name(); if (i < argc) restart_kom("usage: %s [-d ...] [config-file]\n", argv[0]); init_stats(); initialize(config_file); /* Read config, listen, and start db */ chdir(param.core_dir); save_pid(); toploop(); /* There is no use sending logout messages to all sessions. */ param.send_async_messages = FALSE; logout_all_clients(); isc_shutdown(kom_server_mcb); cache_sync_all(); unlock_db(); src = oop_signal_source(kom_signal_adapter); src->cancel_signal(src, SIGWINCH, sighandler_winch, NULL); src->cancel_signal(src, SIGUSR2, sighandler_usr2, NULL); src->cancel_signal(src, SIGUSR1, sighandler_usr1, NULL); src->cancel_signal(src, SIGQUIT, sighandler_quit, NULL); src->cancel_signal(src, SIGHUP, sighandler_term, NULL); src->cancel_signal(src, SIGTERM, sighandler_term, NULL); src->cancel_signal(src, SIGINT, sighandler_term, NULL); oop_signal_delete(kom_signal_adapter); oop_sys_delete(kom_server_oop_src); /* Finish */ dump_exit_statistics(); kom_log("%s terminated normally.\n", argv[0]); /* Don't actually die until something is entered on stdin in debug mode. This is mainly here for the benefit of the test suite, but is could also be useful to be able to attach a debugger and do pre-mortem debugging of the process at this point. */ if (foreground) { kom_log("Press enter to terminate lyskomd\n"); getchar(); } exit(0); } static void dump_exit_statistics(void) { FILE *stat_file; time_t now; time(&now); stat_file = i_fopen(param.memuse_name, "a"); if ( stat_file == NULL ) restart_kom("Can't open file to save memory usage to.\n"); fprintf(stat_file, "\nLysKOM Server going down at %s\n", ctime(&now)); dump_cache_stats (stat_file); free_all_tmp(); free_all_cache(); free_all_jubel(); free_kom_info(); free_aux_item_definitions(); free_configuration(); free_default_config_file_name(); dump_smalloc_counts(stat_file); dump_alloc_counts(stat_file); dump_cache_mem_usage(stat_file); dump_string_alloc_counts(stat_file); dump_allocated_connections(stat_file); dump_isc_alloc_counts(stat_file); dump_oop_alloc_counts(stat_file); dump_l2g_stats(stat_file); i_fclose (stat_file); } static void free_kom_info(void) { unsigned long i; if (kom_info.aux_item_list.items != NULL) { for (i = 0; i < kom_info.aux_item_list.length; i++) { s_clear(&kom_info.aux_item_list.items[i].data); } sfree(kom_info.aux_item_list.items); } kom_info.aux_item_list.length = 0; kom_info.aux_item_list.items = 0; } lyskom-server-2.1.2/src/server/simple-cache.c0000664000015100472110000021027407721716130014622 /* * $Id: simple-cache.c,v 0.113 2003/08/23 16:38:13 ceder Exp $ * Copyright (C) 1991-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * This module contains some simple simulations of the routines in * cache.c. * * Extracted from ram-cache.c and rewritten by ceder. * * New database format with texts in their own file by Inge Wallin. * * New save algorithm by ceder. * Attempt at newer algorithm by byers (FASTSAVE) */ #ifdef HAVE_CONFIG_H # include #endif #include #include #ifdef HAVE_STDLIB_H # include #endif #include #ifdef HAVE_UNISTD_H # include #endif #ifdef HAVE_STRING_H # include #endif #ifndef SEEK_END # include #endif #ifndef SEEK_END # define SEEK_SET 0 # define SEEK_END 2 #endif #include "timewrap.h" #include #include "ldifftime.h" #include "exp.h" #include "misc-types.h" #include "s-string.h" #include "kom-types.h" #include "cache-node.h" #include "cache.h" #include "parser.h" #include "ram-parse.h" #include "ram-output.h" #include "server/smalloc.h" #include "kom-memory.h" #include "lyskomd.h" #include "debug.h" #include "kom-errno.h" #include "log.h" #include "com.h" #include "async.h" #include "connections.h" #include "send-async.h" #include "param.h" #include "kom-config.h" #include "admin.h" #include "unused.h" #include "local-to-global.h" #include "server-time.h" #include "eintr.h" #include "timeval-util.h" #include "stats.h" #include "services.h" #include "manipulate.h" /* * Possible improvements: * * FIXME (bug 167): When there are consecutive items in file A that * shall be copied to file B, copy them in one transfer (up to a * certain limit). */ /* * All functions that can fail sets kom_errno to a suitable value * if they fail. */ static Small_conf ** small_conf_arr; static Cache_node_mcb * pers_mcb; static Cache_node_mcb * conf_mcb; static Conf_no next_free_num = 1; static Cache_node_mcb * text_mcb; static Text_no next_text_num = 1; /* * The elements in the following lists with same index refers to the same * conference. */ static int no_of_match_info; EXPORT Matching_info *match_table = NULL; static FILE *text_file= NULL; static FILE *file_a = NULL; /* Current file. */ static FILE *file_b = NULL; /* File under construction. */ #ifdef FASTSAVE static FILE *file_b_r = NULL; /* Read from file under construction */ #endif /* * Four state variables for the background save. */ static enum { sync_idle, sync_save_conf, sync_save_pers, sync_save_text, sync_error, sync_wait, sync_ready } sync_state; /* The state machine sync_state works like this: * * Old state action new state * none sync_part called sync_idle * for the first time * sync_idle SYNC_INTERVAL sync_save_conf * sync_save_conf all confs saved sync_save_pers * sync_save_pers all persons saved sync_save_text * sync_save_text all texts saved sync_ready * sync_ready sync_part called sync_idle * any error occurs sync_error * sync_error sync_part called sync_wait * sync_wait SYNC_RETRY_INTERVAL sync_save_conf */ #ifndef FASTSAVE /* sync_next should be split in next_text_to_sync and next_conf_to_sync to avoid warnings about the different sizes of Conf_no and Text_no. Since that is indeed done if FASTSAVE is set, don't bother doing it in the old code that will anyhow soon be replaced. */ static unsigned long sync_next; #endif static Conf_no highest_conf_no = 0; static Text_no highest_text_no = 0; BUGDECL; #ifdef DEBUG_CALLS /* This is used by cache_sync_start() and cache_sync_finish(). */ static int block_after_pre_sync = 0; #endif /* Define LOGACCESSES if you want to be able to log all accesses to the data base. */ #ifdef LOGACCESSES enum log_type { lt_restart, lt_text_stat, lt_text_mass, lt_conf_stat, lt_pers_stat, lt_text_def, lt_conf_def, lt_pers_def, lt_create_text, lt_garb_text, lt_delete_text, lt_create_conf, lt_delete_conf, lt_create_pers, lt_delete_pers, lt_lock_conf, lt_unlock_conf, lt_lock_pers, lt_unlock_pers, lt_get_highest, /* Get highest Local_text_no for a conf. */ lt_get_conf_type /* Note: mark_*_as_changed is not logged. */ }; static FILE *logfile = NULL; static int syncing_or_saving = 0; static int garb_running = 0; static void log_access(enum log_type t, int id) { extern int putw(int, FILE *); if (garb_running + syncing_or_saving == 0) { putc(t, logfile); putw(id, logfile); } } #define LOGACC(a,b) {if (logfile) log_access(a, b);} #else #define LOGACC(a,b) #endif static Static_server_info boottime_info = { 0, 0, EMPTY_STRING_i, 0, 0, 0, 0, 0 }; /* Local functions */ static Success build_matching_info(void); static Success rebuild_matching_info_entry(Conf_no conf_no); static Matching_info *find_matching_info(Conf_no conf_no); /* Macros */ #define TRACE2(format, arg) if ( buglevel > 2 ) printf(format, arg) #define TRACE1(format) if ( buglevel > 2 ) printf(format) #define TRACESTR(str) if ( buglevel > 2 ) s_puts(str) static Person * read_person(FILE *fp, long pos, long UNUSED(size)) /* FIXME (bug 168): sanity-check the size */ { Person *p; long dummy; p = alloc_person(); fseek(fp, pos+1, SEEK_SET); /* Skip 'P' */ dummy = fparse_long(fp); if ( fparse_person(fp, p) != OK ) { free_person(p); return NULL; } else return p; } static Conference * read_conference(FILE *fp, long pos, long UNUSED(size)) /* FIXME (bug 169): sanity-check the size */ { Conference *c; long dummy; c = alloc_conference(); fseek(fp, pos+1, SEEK_SET); /* Skip 'C' */ dummy = fparse_long(fp); if ( fparse_conference(fp, c) != OK ) { free_conference(c); return NULL; } else return c; } static Text_stat * read_text_stat(FILE *fp, long pos, long UNUSED(size)) /* FIXME (bug 170): sanity-check the size */ { Text_stat *t; long dummy; t = alloc_text_stat(); fseek(fp, pos+1, SEEK_SET); /* Skip 'T' */ dummy = fparse_long(fp); if ( fparse_text_stat(fp, t) != OK ) { free_text_stat(t); return NULL; } else return t; } static void pers_set_mru(Pers_no pers_no) { set_mru(pers_mcb, pers_no); } static void text_set_mru(Text_no text_no) { set_mru(text_mcb, text_no); } static void conf_set_mru(Conf_no conf_no) { set_mru(conf_mcb, conf_no); } static Cache_node * get_pers_node(Pers_no pers_no) { if (pers_no >= next_free_num || pers_no < 1) return NULL; return get_cache_node(pers_mcb, pers_no); } static void unlink_text_lru (Cache_node *node) { unlink_lru (node, &text_mcb->lru, &text_mcb->mru); } static void unlink_conf_lru (Cache_node *node) { unlink_lru (node, &conf_mcb->lru, &conf_mcb->mru); } static void unlink_pers_lru (Cache_node *node) { unlink_lru (node, &pers_mcb->lru, &pers_mcb->mru); } static Cache_node * get_conf_node(Conf_no conf_no) { if (conf_no >= next_free_num || conf_no < 1) return NULL; return get_cache_node(conf_mcb, conf_no); } static Cache_node * get_text_node(Text_no text_no) { if (text_no >= next_text_num || text_no < 1) return NULL; return get_cache_node(text_mcb, text_no); } /* * Name caching routines */ /* * change_name changes the cached conference name. It is only called when * a conference name is changed or a conference is deleted. */ void cached_change_name( Conf_no name_num, String new_name ) { if ( name_num < 1 || name_num >= next_free_num ) restart_kom("cached_change_name(%d, ----): next_free_num==%d\n", name_num, next_free_num); s_clear( &small_conf_arr[name_num]->name ); s_strcpy( &small_conf_arr[name_num]->name, new_name); rebuild_matching_info_entry(name_num); } extern Conf_type cached_get_conf_type (Conf_no conf_no) { if ( conf_no < 1 || conf_no >= next_free_num ) restart_kom("cached_get_conf_type(%d): next_free_num==%d", conf_no, next_free_num); if ( small_conf_arr [ conf_no ] == NULL ) restart_kom("cached_get_conf_type(%d): conference does not exist.\n", conf_no); LOGACC(lt_get_conf_type, conf_no); return small_conf_arr [ conf_no ]->type; } extern Conf_no cached_get_conf_supervisor(Conf_no conf_no) { if (conf_no < 1 || conf_no >= next_free_num) restart_kom("cached_get_conf_supervisor(%d): next_free_num==%d\n", conf_no, next_free_num); if (small_conf_arr[conf_no] == NULL) restart_kom("cached_get_conf_supervisor(%d):" " conference does not exist.\n", conf_no); LOGACC(lt_get_conf_supervisor, conf_no); return small_conf_arr[conf_no]->supervisor; } /* * Return number of conferences present. (Actually, return a number * at least as large as the number of conferences present). */ extern Conf_no cached_no_of_existing_conferences(void) { return next_free_num; /* This is too large, but who cares? */ /* Actually, this is used in lookup_regexp (and maybe other places) to allocate an array this large, and that is pretty stupid if many conferences have been deleted. But it is no big deal. Not yet, anyhow... */ /* FIXME (bug 164): We should return a better estimate. */ } /* * Various function calls to tell the cache that something is changed. */ void mark_person_as_changed(Pers_no pers_no) { Cache_node *node; node = get_pers_node(pers_no); TRACE2("Person %d is changed\n", pers_no); if ( node == NULL || node->s.exists == 0) restart_kom("mark_person_as_changed(%d): nonexistent.\n", pers_no); node->s.dirty = 1; pers_set_mru( pers_no ); } /* * Mark the conference as dirty, so that it will be written to * the disk. * * Also update all fields in the Small_conf except then name, so that * they are always current. * * NOTE: You must call cached_change_name when the name changes. * It is not necessary to call cached_change_name after * cached_create_conf. */ void mark_conference_as_changed(Conf_no conf_no) { Cache_node *node; Conference *conf_c; node = get_conf_node (conf_no); TRACE2("Conf. %d is changed\n", conf_no); if ( node == NULL || node->s.exists == 0) restart_kom("mark_conference_as_changed(%d): nonexistent.\n", conf_no); node->s.dirty = 1; conf_set_mru( conf_no ); conf_c = (Conference *) node->ptr; small_conf_arr[conf_no]->highest_local_no = l2g_first_appendable_key(&conf_c->texts) - 1; small_conf_arr[conf_no]->nice = conf_c->nice; small_conf_arr[conf_no]->keep_commented = conf_c->keep_commented; small_conf_arr[conf_no]->type = conf_c->type; small_conf_arr[conf_no]->supervisor = conf_c->supervisor; } void mark_text_as_changed( Text_no text_no ) { Cache_node *node; node = get_text_node (text_no); TRACE2("Text %lu is changed.\n", text_no); if ( text_no < 1 || text_no >= next_text_num || node == NULL || node->s.exists == 0) { restart_kom("mark_text_as_changed(%lu): nonexistent.\n", text_no); } node->s.dirty = 1; text_set_mru (text_no); } /* * Store and retrieve the highest number used. */ static int write_number_file(void) { FILE *fp; if ((fp = i_fopen(param.numberfile_tmp_name, "w")) == NULL) { kom_log("opening %s: %s\n", param.numberfile_tmp_name, strerror(errno)); return -1; } fprintf(fp, "Text_no: %lu Conf_no: %lu End.\n", (unsigned long)next_text_num, (unsigned long)next_free_num); if (fflush(fp) != 0) { kom_log("fflush to %s failed\n", param.numberfile_tmp_name); i_fclose(fp); return -1; } if (ferror(fp) != 0) { kom_log("fprintf to %s failed\n", param.numberfile_tmp_name); i_fclose(fp); return -1; } if (i_fclose(fp) != 0) { kom_log("fclose %s failed\n", param.numberfile_tmp_name); return -1; } if (i_rename(param.numberfile_tmp_name, param.numberfile_name) != 0) { kom_log("failed to rename %s to %s: %s\n", param.numberfile_tmp_name, param.numberfile_name, strerror(errno)); return -1; } return 0; } static void read_number_file(void) { FILE *fp; unsigned long txt = 0; unsigned long cno = 0; Text_no text_no; Conf_no conf_no; if ((fp = i_fopen(param.numberfile_name, "r")) == NULL) { if (errno == ENOENT) kom_log("WARN: %s: No such file\n", param.numberfile_name); else restart_kom("opening %s: %s\n", param.numberfile_name, strerror(errno)); return; } if (fscanf(fp, "Text_no: %lu Conf_no: %lu", &txt, &cno) != 2 || getc(fp) != ' ' || getc(fp) != 'E' || getc(fp) != 'n' || getc(fp) != 'd' || getc(fp) != '.') { kom_log("WARN: %s: broken file (ignored)\n", param.numberfile_name); i_fclose(fp); return; } i_fclose(fp); text_no = txt; conf_no = cno; if (text_no > next_text_num) { kom_log("WARN: Texts %lu - %lu were lost.\n", (unsigned long)next_text_num, (unsigned long)text_no - 1); next_text_num = text_no; } if (conf_no > next_free_num) { kom_log("WARN: Confs %lu - %lu were lost.\n", (unsigned long)next_free_num, (unsigned long)conf_no - 1); next_free_num = conf_no; } } /* * Person-related calls */ extern Success cached_create_person( Pers_no person ) { Cache_node *node; TRACE2("Person %d is being created.\n", person); if ( person < 1 || person >= next_free_num ) { restart_kom("cached_create_person(%d): next_free_num == %d.\n", person, next_free_num); } if ( get_pers_node(person) != NULL ) { restart_kom("cached_create_person(%d): Person existed.\n", person); } create_cache_node (pers_mcb, person); node = get_pers_node (person); if ( node == NULL ) restart_kom("cached_create_person(): couldn't get cache_node.\n"); node->ptr = alloc_person(); node->s.dirty = 1; node->s.exists = 1; pers_set_mru( person ); LOGACC(lt_create_pers, person); return OK; } extern Person * cached_get_person_stat( Pers_no person ) { Cache_node *node; TRACE2("cached_get_person_stat %d\n", person); if ( person == 0 ) { err_stat = 0; kom_errno = KOM_CONF_ZERO; return NULL; } if ( person >= next_free_num ) { err_stat = person; kom_errno = KOM_UNDEF_PERS; return NULL; } node = get_pers_node (person); if ( node == NULL || node->s.exists == 0 ) { err_stat = person; kom_errno = KOM_UNDEF_PERS; return NULL; } LOGACC(lt_pers_stat, person); if ( node->ptr != NULL ) { pers_set_mru( person ); ++pers_mcb->hits; return node->ptr; } if ( node->snap_shot != NULL ) { node->ptr = copy_person (node->snap_shot); pers_set_mru (person); ++pers_mcb->hits; return node->ptr; } node->ptr = read_person(file_a, node->pos, node->size); ++pers_mcb->misses; pers_set_mru (person); return node->ptr; } /* * Conference-related calls */ static int no_of_allocated_small_confs = 0; static void free_small_conf (Small_conf *sc) { if ( sc != NULL ) { --no_of_allocated_small_confs; s_clear ( &sc->name ); sfree (sc); } } static void init_small_conf(Small_conf *sc) { sc->name = EMPTY_STRING; init_conf_type(&sc->type); sc->supervisor = 0; sc->highest_local_no = 0; sc->nice = param.default_nice; sc->keep_commented = param.default_keep_commented; } static Small_conf * alloc_small_conf(void) { Small_conf *s; s = smalloc(sizeof(Small_conf)); init_small_conf(s); ++no_of_allocated_small_confs; return s; } /* * Create a conference. * * Set up a Conference and cache the name in the small_conf_array. */ extern Conf_no cached_create_conf (String name) { Conference * conf_c; Conf_no conf_no; Cache_node *node; TRACE1("cached_create_conf( "); TRACESTR(name); TRACE1(" )\n"); if ( next_free_num >= param.max_conf ) { err_stat = next_free_num; kom_errno = KOM_INDEX_OUT_OF_RANGE; return 0; } conf_no = next_free_num++; if (write_number_file() < 0) { next_free_num--; err_stat = 0; kom_errno = KOM_TEMPFAIL; return 0; } create_cache_node (conf_mcb, conf_no); node = get_conf_node (conf_no); if ( node == NULL ) restart_kom("cached_create_conf(): failed to allocate cache_node.\n"); node->s.exists = 1; node->s.dirty = 1; node->ptr = conf_c = alloc_conference(); conf_set_mru(conf_no); zero_init_cache_node (pers_mcb, conf_no); small_conf_arr[ conf_no ] = alloc_small_conf(); conf_c->name = EMPTY_STRING; s_strcpy(&conf_c->name, name); cached_change_name( conf_no, name); TRACE2("Created conference number %d\n", conf_no); LOGACC(lt_create_conf, conf_no); return conf_no; } extern Success cached_delete_conf( Conf_no conf ) { Cache_node *node; if ( conf == 0 ) { err_stat = conf; kom_errno = KOM_CONF_ZERO; return FAILURE; } if ( conf >= next_free_num ) { err_stat = conf; kom_errno = KOM_UNDEF_CONF; return FAILURE; } node = get_conf_node (conf); if ( node == NULL || node->s.exists == 0 ) { err_stat = conf; kom_errno = KOM_UNDEF_CONF; return FAILURE; } if ( node->lock_cnt > 0 ) kom_log("WNG: cached_delete_conf(%d): lock_cnt === %d\n", conf, node->lock_cnt); free_small_conf(small_conf_arr[conf]); small_conf_arr[conf] = NULL; free_conference(node->ptr); node->ptr = NULL; node->s.exists = 0; LOGACC(lt_delete_conf, conf); rebuild_matching_info_entry(conf); return OK; } Success cached_delete_person(Pers_no pers) { Cache_node *node; if ( pers == 0 ) { err_stat = pers; kom_errno = KOM_CONF_ZERO; return FAILURE; } if ( pers >= next_free_num ) { kom_log("cached_delete_person(%lu): next_free_num == %lu\n", (unsigned long)pers, (unsigned long)next_free_num); err_stat = pers; kom_errno = KOM_UNDEF_PERS; return FAILURE; } node = get_pers_node (pers); if ( pers >= next_free_num || node == NULL || node->s.exists == 0 ) { kom_log("cached_delete_person(): attempt to delete void person.\n"); err_stat = pers; kom_errno = KOM_UNDEF_PERS; return FAILURE; } if ( node->lock_cnt > 0 ) kom_log("cached_delete_pers(%lu): lock_cnt === %lu\n", (unsigned long)pers, (unsigned long)node->lock_cnt); LOGACC(lt_delete_pers, pers); free_person (node->ptr); node->ptr = NULL; node->s.exists = 0; return OK; } Success cached_delete_text(Text_no text) { Cache_node *node; if ( text == 0 ) { err_stat = text; kom_errno = KOM_TEXT_ZERO; return FAILURE; } node = get_text_node (text); if ( text >= next_text_num || node == NULL || node->s.exists == 0 ) { kom_log("cached_delete_text(): attempt to delete void text %lu.\n", text); err_stat = text; kom_errno = KOM_NO_SUCH_TEXT; return FAILURE; } if ( node->lock_cnt > 0 ) kom_log("cached_delete_text(%lu): lock_cnt === %d\n", text, node->lock_cnt); free_text_stat(node->ptr); node->ptr = NULL; node->s.exists = 0; #ifdef LOGACCESSES if (garb_running) { LOGACC(lt_garb_text, text); } else LOGACC(lt_delete_text, text); #endif return OK; } extern Conference * cached_get_conf_stat (Conf_no conf_no) { Cache_node *node; TRACE2("cached_get_conf_stat %d\n", conf_no); if ( conf_no == 0 ) { err_stat = conf_no; kom_errno = KOM_CONF_ZERO; return NULL; } node = get_conf_node (conf_no); if ( conf_no >= next_free_num || node == NULL || node->s.exists == 0 ) { err_stat = conf_no; kom_errno = KOM_UNDEF_CONF; return NULL; } LOGACC(lt_conf_stat, conf_no); if ( node->ptr != NULL ) { conf_set_mru (conf_no); ++conf_mcb->hits; return node->ptr; } if ( node->snap_shot != NULL ) { node->ptr = copy_conference (node->snap_shot); conf_set_mru (conf_no); ++conf_mcb->hits; return node->ptr; } node->ptr = read_conference(file_a, node->pos, node->size); ++conf_mcb->misses; conf_set_mru (conf_no); return node->ptr; } /* * Return TRUE if conf_no exists. */ Bool cached_conf_exists(Conf_no conf_no) { if (conf_no == 0 || conf_no >= next_free_num ) return FALSE; return small_conf_arr[conf_no] != NULL ? TRUE : FALSE; } /* * Calls to handle texts */ /* * FIXME (bug 171): cached_get_text() should return Success. */ extern String cached_get_text( Text_no text ) { String the_string; Text_stat *t_stat; TRACE2("cached_get_text %lu\n", text); if ( (t_stat = cached_get_text_stat (text)) == NULL ) return EMPTY_STRING; else { LOGACC(lt_text_mass, text); the_string.string = tmp_alloc( t_stat->no_of_chars ); the_string.len = t_stat->no_of_chars; fseek(text_file, t_stat->file_pos, SEEK_SET); if ( fread(the_string.string, sizeof(char), the_string.len, text_file) != (size_t)the_string.len ) { kom_log("WARNING: cached_get_text: premature end on text %lu\n", text); return EMPTY_STRING; } return the_string; } } extern Text_stat * /* NULL on error */ cached_get_text_stat( Text_no text ) { Cache_node *node; TRACE2("cached_get_text_stat(%lu); next_text_num == ", text); TRACE2("%lu\n", (unsigned long)next_text_num); if ( text == 0 ) { err_stat = text; kom_errno = KOM_TEXT_ZERO; return NULL; } node = get_text_node (text); if ( text >= next_text_num || node == NULL || node->s.exists == 0 ) { TRACE1("cached_get_text_stat: no such text.\n"); err_stat = text; kom_errno = KOM_NO_SUCH_TEXT; return NULL; } LOGACC(lt_text_stat, text); if ( node->ptr != NULL ) { TRACE1("Found in ptr.\n"); text_set_mru( text ); ++text_mcb->hits; return node->ptr; } if ( node->snap_shot != NULL ) { TRACE1("Found in snap_shot\n"); node->ptr = copy_text_stat(node->snap_shot); text_set_mru (text); ++text_mcb->hits; return node->ptr; } TRACE1("Found in file A.\n"); node->ptr = read_text_stat(file_a, node->pos, node->size); text_set_mru (text); ++text_mcb->misses; return node->ptr; } /* * The text is set up with an empty misc-field. The misc field is * then initialized by create_text. */ extern Text_no cached_create_text(const String message) { Text_no tno; Cache_node *node; long file_pos; tno = next_text_num++; TRACE2("cached_create_text (len=%lu)\n", message.len); if ( tno >= param.max_text ) { err_stat = tno; kom_errno = KOM_INDEX_OUT_OF_RANGE; next_text_num = param.max_text; return 0; } if (write_number_file() < 0) { next_text_num--; err_stat = 0; kom_errno = KOM_TEMPFAIL; return 0; } if (fseek(text_file, 0, SEEK_END) != 0) { kom_log("ERROR: cannot seek to end of text_file: %s\n", strerror(errno)); clearerr(text_file); return 0; } file_pos = ftell(text_file); if (fwrite(message.string, 1, message.len, text_file) != (size_t)message.len) { if (errno != ENOSPC) kom_log("WARNING: cached_create_text: Couldn't write text %lu: %s\n", tno, strerror(errno)); err_stat = 0; kom_errno = KOM_TEMPFAIL; clearerr(text_file); return 0; } if (fflush(text_file) != 0) { if (errno != ENOSPC) kom_log("WARNING: cached_create_text: Couldn't fflush text %lu: %s\n", tno, strerror(errno)); err_stat = 0; kom_errno = KOM_TEMPFAIL; clearerr(text_file); return 0; } if (fsync(fileno(text_file)) != 0) { if (errno != ENOSPC) kom_log("WARNING: cached_create_text: Couldn't fsync text %lu: %s\n", tno, strerror(errno)); err_stat = 0; kom_errno = KOM_TEMPFAIL; clearerr(text_file); return 0; } create_cache_node(text_mcb, tno); node = get_text_node (tno); if ( node == NULL ) restart_kom("cached_create_text(): couldn't create cache-node.\n"); node->s.exists = 1; node->s.dirty = 1; node->ptr = alloc_text_stat(); ((Text_stat *)node->ptr)->no_of_misc = 0; ((Text_stat *)node->ptr)->misc_items = NULL; ((Text_stat *)node->ptr)->no_of_marks = 0; ((Text_stat *)node->ptr)->no_of_lines = 0; ((Text_stat *)node->ptr)->no_of_chars = 0; ((Text_stat *)node->ptr)->file_pos = file_pos; text_set_mru( tno ); LOGACC(lt_create_text, tno); TRACE2("cached_create_text -> %lu\n", tno); return tno; } EXPORT Text_no traverse_text(Text_no seed) { Cache_node *node; seed++; while ( seed < next_text_num ) { node = get_text_node (seed); if ( node != NULL && node->s.exists != 0 ) break; seed++; } return (seed >= next_text_num) ? 0 : seed ; } #if 0 /* This is not used, but should work OK. */ Pers_no traverse_person(Pers_no seed) { Cache_node *node; seed++; while ( seed < next_free_num ) { node = get_pers_node (seed); if (node != NULL && node->s.exists != 0 ) break; seed++; } return (seed >= next_free_num) ? 0 : seed ; } #endif Conf_no traverse_conference(Conf_no seed) { Cache_node *node; seed++; while ( seed < next_free_num ) { node = get_conf_node (seed); if (node != NULL && node->s.exists != 0 ) break; seed++; } return (seed >= next_free_num) ? 0 : seed ; } extern Garb_nice cached_get_garb_nice (Conf_no conf_no) { return small_conf_arr [ conf_no ]->nice; } extern Garb_nice cached_get_keep_commented(Conf_no conf_no) { return small_conf_arr[conf_no]->keep_commented; } extern String cached_get_name (Conf_no conf_no) { return small_conf_arr [ conf_no ]->name; } extern Local_text_no cached_get_highest_local_no (Conf_no conf_no) { LOGACC(lt_get_highest, conf_no); return small_conf_arr[ conf_no ]->highest_local_no; } extern Small_conf * cached_get_small_conf_stat (Conf_no conf_no) { TRACE2("cached_get_small_conf_stat %d\n", conf_no); if (conf_no == 0) { err_stat = conf_no; kom_errno = KOM_CONF_ZERO; return NULL; } if (conf_no >= next_free_num || small_conf_arr[conf_no] == NULL) { err_stat = conf_no; kom_errno = KOM_UNDEF_CONF; return NULL; } return small_conf_arr[conf_no]; } /* Lock a person struct in memory. Increase a referenc count. */ void cached_lock_person(Pers_no pers_no) { Cache_node *node; LOGACC(lt_lock_pers, pers_no); node = get_pers_node(pers_no); if ( node == NULL || node->s.exists == 0 ) restart_kom("cached_lock_person(%d): nonexistent.\n", pers_no); if ( node->ptr == NULL ) { Person *pers_stat_ptr; pers_stat_ptr = cached_get_person_stat( pers_no ); if ( pers_stat_ptr == NULL ) restart_kom("cached_lock_person(%d): couldn't read in person.\n", pers_no); if ( pers_stat_ptr != node->ptr ) restart_kom("%s(%d): pers_stat_ptr == %lu, node->ptr == %lu.\n", "cached_lock_person", pers_no, (unsigned long)pers_stat_ptr, (unsigned long)node->ptr); } node->lock_cnt++; } /* Decrease reference count. If zero, unlock person. */ void cached_unlock_person(Pers_no pers_no) { Cache_node *node; LOGACC(lt_unlock_pers, pers_no); node = get_pers_node (pers_no); if ( node == NULL ) restart_kom("cached_unlock_person(): couldn't get cache-node.\n"); if ( node->lock_cnt <= 0 ) { kom_log("cached_unlock_person(%d): lock_cnt == %d.\n", pers_no, node->lock_cnt); node->lock_cnt = 0; } else node->lock_cnt--; } /* Lock a conf struct in memory. Increase a reference count. */ void cached_lock_conf(Conf_no conf_no) { Cache_node *node; node = get_conf_node(conf_no); if ( node == NULL) restart_kom("cached_lock_conf(): can't get cache-node.\n"); if ( node->s.exists == 0 ) restart_kom("cached_lock_conf(%d): nonexistent.\n", conf_no); LOGACC(lt_lock_conf, conf_no); if ( node->ptr == NULL ) { Conference *conference_ptr; conference_ptr = cached_get_conf_stat( conf_no ); if ( conference_ptr == NULL ) restart_kom("cached_lock_conf(%d): couldn't read in conf.\n", conf_no); if ( conference_ptr != node->ptr ) restart_kom("%s(%d): conference_ptr == %lu, node->ptr == %lu.\n", "cached_lock_conf", conf_no, (unsigned long)conference_ptr, (unsigned long)node->ptr); } node->lock_cnt++; } /* Decrease reference count. If zero, unlock conf. */ void cached_unlock_conf(Conf_no conf_no) { Cache_node *node; LOGACC(lt_unlock_conf, conf_no); node = get_conf_node(conf_no); if ( node == NULL ) restart_kom("cached_unlock_conf(): can't get node.\n"); if ( node->lock_cnt <= 0 ) { kom_log("cached_unlock_conf(%d): lock_cnt == %d.\n", conf_no, node->lock_cnt); node->lock_cnt = 0; } else node->lock_cnt--; } /* * And here comes some functions to deal with lookup_names. */ /* Free the _contents_ of a match_table. The table itself i _not_ freed. */ static void free_match_table(Matching_info *mtch) { if ( mtch == NULL ) return; while ( mtch->conf_no != 0 ) { free_tokens( mtch->tokens ); /* mtch->name is not freed since it points into conf_arr[]. */ ++mtch; } } /* Find the entry for CONF_NO in match_table. Return something if there is a nonempty name or a list of tokens in the entry. The caller is responsible to checking that the name of the returned entry is nonempty. The reason for this is that cached_delete_conf clears the name before rebuilding the matching_info, and rebuild_matching_info_entry needs to get the entry to free the token list when it is called from cached_delete_conf */ static int find_matching_info_compare(const void *a, const void *b) { Matching_info *info_a = (Matching_info *)a; Matching_info *info_b = (Matching_info *)b; return info_a->conf_no - info_b->conf_no; } static Matching_info * find_matching_info(Conf_no conf_no) { Matching_info *info, key; /* FIXME (bug 172): The comment below, the fact that bsearch() is used, and the comment above find_matching_info_compare() seems to indicate that cleanup is required here. */ /* FIXME: Do a binary search here! The search must be able to FIXME: deal with NULL entries. We could do this with a regular FIXME: bearch and a final check that the entry has a non-NULL FIXME: tokens field. */ key.conf_no = conf_no; info = bsearch(&key, match_table, no_of_match_info, sizeof(Matching_info), find_matching_info_compare); if (info == NULL) return NULL; else if (s_empty(info->name) && info->tokens == NULL) return NULL; else return info; } /* Rebuild the matching info entry for a conference. If the conference does not exist in the table, it will be added. If it is not a new conference (conf_no higher than the highest in the table) the entire table will be rebuilt. */ static Success rebuild_matching_info_entry(Conf_no conf_no) { Matching_info *mtch; Cache_node *node; mtch = find_matching_info(conf_no); if (mtch != NULL) { /* The entry was found. Free the old data */ free_tokens(mtch->tokens); /* Add or remove the new entry, depending on if the conf exists */ if (small_conf_arr[conf_no] != NULL) { /* Renamed a conference */ mtch->name = small_conf_arr[conf_no]->name; mtch->tokens = tokenize(small_conf_arr[conf_no]->name, s_fcrea_str(WHITESPACE)); } else { /* Deleted a conference. Clear everything but the conf_no */ /* FIXME (bug 173): We should compress the table by moving the entries above the deleted one down one step. This will save a little time in lookup, and make realloc the next time someone creates a conference not have to move memory. Warning: doing this might interfere with the comments refered to by bug 172. */ mtch->name = EMPTY_STRING; mtch->tokens = NULL; mtch->priority = 0; } } else { /* The entry was not found in match_table. This can mean one of two things... (1) The name was deleted earlier. This happens when a name is deleted, build_match_info is called, and then this function is called on the same conference. This is an error, of sorts, but can be safely ignored. (2) We are being called on a new conference. When this happens, make sure the new conference has a conf_no higher than the highest in the array, then add it to the end (if it has a conf_no not higher than the last entry, rebuild the entire thing.) */ /* Check that the conference actually exists. The cache node must exist, the node must have the exists flag set and the name must be in small_conf_arr (the last bit is really just a precaution to avoid a crash later on.) */ node = get_conf_node(conf_no); if (node == NULL || node->s.exists == 0 || s_empty(small_conf_arr[conf_no]->name)) { return OK; } /* The conference exists. Check if it's conf_no is higher than the last current entry in the list */ if (conf_no <= match_table[no_of_match_info - 1].conf_no) { kom_log("Rebuilding entire match_table. It doesn't look right.\n"); return build_matching_info(); } /* Add an entry to the match table */ match_table = srealloc(match_table, (no_of_match_info + 2) * sizeof(Matching_info)); match_table[no_of_match_info].name = small_conf_arr[conf_no]->name; match_table[no_of_match_info].tokens = tokenize(small_conf_arr[conf_no]->name, s_fcrea_str(WHITESPACE)); match_table[no_of_match_info].priority = 7; match_table[no_of_match_info].conf_no = conf_no; /* Bump the number of match infos and enter the ending dummy */ no_of_match_info += 1; match_table[no_of_match_info].name = EMPTY_STRING; match_table[no_of_match_info].tokens = NULL; match_table[no_of_match_info].priority = 0; match_table[no_of_match_info].conf_no = 0; } return OK; } static Success build_matching_info(void) { Conf_no i; Matching_info *mtch; Conf_no *conf; free_match_table(match_table); match_table = srealloc(match_table, next_free_num * sizeof(Matching_info)); no_of_match_info = 0; mtch = match_table; for ( i = 1; i < next_free_num; i++ ) { if ( small_conf_arr[ i ] != NULL && ! s_empty ( small_conf_arr[ i ]->name ) ) { mtch->name = small_conf_arr[ i ]->name; mtch->tokens = tokenize(mtch->name, s_fcrea_str(WHITESPACE)); mtch->priority = 7; mtch->conf_no = i; ++mtch; ++conf; ++no_of_match_info; } } mtch->name = EMPTY_STRING; mtch->tokens = NULL; mtch->priority = 0; mtch->conf_no = 0; return OK; } /* Map conference name to number */ extern Success cached_lookup_name(const String name, Conf_list_old *result) { Parse_info tmp; int i; /* FIXME (bug 174): It is a waste of resources to include persons here if this lookup is performed due to a lookup-z-name that only requests conferences, and vice versa. */ tmp = parse(name, match_table, FALSE, FALSE, s_fcrea_str(WHITESPACE), DEFAULT_COLLAT_TAB); if ( tmp.no_of_matches == -1 ) { kom_errno = KOM_INTERNAL_ERROR; err_stat = 0; return FAILURE; } if ( tmp.no_of_matches == 1 && tmp.indexes[ 0 ] == -1 ) { /* Return the entire list. */ /* FIXME (bug 175): This allocates too much data if some conferences have been deleted. */ result->no_of_conf_nos = 0; result->conf_nos = tmp_alloc(no_of_match_info * sizeof(Conf_no)); result->type_of_conf = tmp_alloc(no_of_match_info * sizeof(Conf_type)); for ( i = 0; i < no_of_match_info; i++ ) { if (s_empty(match_table[i].name)) continue; result->conf_nos[result->no_of_conf_nos] = match_table[i].conf_no; result->type_of_conf[result->no_of_conf_nos] = small_conf_arr[match_table[i].conf_no]->type; result->no_of_conf_nos++; } } else { /* Return the conferences whose conf_nos are in indexes[]. */ result->no_of_conf_nos = tmp.no_of_matches; result->conf_nos = tmp_alloc(tmp.no_of_matches * sizeof(Conf_no)); result->type_of_conf = tmp_alloc(tmp.no_of_matches * sizeof(Conf_type)); for ( i = 0; i < tmp.no_of_matches; i++ ) { result->conf_nos[ i ] = match_table[ tmp.indexes[ i ] ].conf_no; result->type_of_conf[ i ] = small_conf_arr[ match_table[ tmp.indexes[ i ] ].conf_no ]->type; } } sfree(tmp.indexes); return OK; } static Bool is_clean(const char *fn) { FILE *fp; if ( (fp = i_fopen(fn, "rb")) == NULL ) return FALSE; if ( getc(fp) == 'C' && getc(fp) == 'L' && getc(fp) == 'E' && getc(fp) == 'A' && getc(fp) == 'N' ) { i_fclose(fp); return TRUE; } else { i_fclose(fp); return FALSE; } } static long get_version(const char *fn) { FILE *fp; long version; if ((fp = i_fopen(fn, "rb")) == NULL) return -1; fseek(fp, 5, SEEK_SET); if (getc(fp) == '\n') { i_fclose(fp); return 0; } version = fparse_long(fp); i_fclose(fp); return version; } static void sync_output_header(FILE* fp, const char *state) { fprintf(fp, "%s:%05ld\n", state, 2L); /* DIRTY-FLAG and VERSION*/ fprintf(fp, "%020lu\n", (unsigned long)current_time.tv_sec); } static void pre_sync(void) { Text_no tno_iter; Conf_no cno_iter; Cache_node *node; async_sync_db(); /* Mark up what to save.*/ BUG(("Sync starting\n")); highest_text_no = next_text_num; highest_conf_no = next_free_num; #ifndef FASTSAVE for ( cno_iter = 1; cno_iter < highest_conf_no; cno_iter++ ) { node = get_conf_node(cno_iter); if ( node == NULL ) continue; if (node->s.exists == 0) { unlink_conf_lru(node); destruct_cache_node(conf_mcb, cno_iter); } else { if (node->s.dirty != 0) { free_conference(node->snap_shot); if ( node->lock_cnt == 0 ) { unlink_conf_lru(node); node->snap_shot = node->ptr; node->ptr = NULL; } else node->snap_shot = copy_conference(node->ptr); node->s.dirty = 0; } } } for ( cno_iter = 1; cno_iter < highest_conf_no; cno_iter++ ) { node = get_pers_node(cno_iter); if ( node == NULL ) continue; if (node->s.exists == 0) { unlink_pers_lru(node); destruct_cache_node(pers_mcb, cno_iter); } else { if (node->s.dirty != 0) { free_person(node->snap_shot); if ( node->lock_cnt == 0 ) { unlink_pers_lru(node); node->snap_shot = node->ptr; node->ptr = NULL; } else node->snap_shot = copy_person(node->ptr); node->s.dirty = 0; } } } for ( tno_iter = 1; tno_iter < highest_text_no; tno_iter++ ) { node = get_text_node(tno_iter); if ( node == NULL ) continue; if (node->s.exists == 0) { unlink_text_lru(node); destruct_cache_node(text_mcb, tno_iter); } else { if (node->s.dirty != 0) { free_text_stat(node->snap_shot); if ( node->lock_cnt == 0 ) { unlink_text_lru(node); node->snap_shot = node->ptr; node->ptr = NULL; } else node->snap_shot = copy_text_stat(node->ptr); node->s.dirty = 0; } } } #endif /* All marking is done. Now open file B. */ if (is_clean(param.datafile_name)) { if (is_clean(param.backupfile_name)) { if (i_rename(param.backupfile_name, param.backupfile_name_2) != 0) { kom_log("pre_sync: can't do extra backup.\n"); } } if (i_rename(param.datafile_name, param.backupfile_name) != 0) restart_kom("pre_sync: can't backup.\n"); } else kom_log("pre_sync: datafile not clean. No backup taken.\n"); if ( file_b != NULL ) { kom_log("pre_sync: Save in progress aborted.\n"); i_fclose(file_b); #ifdef FASTSAVE file_b = NULL; #endif } if ((file_b = i_fopen(param.datafile_name, "wb")) == NULL) { kom_log("WARNING: pre_sync: can't open file to save in.\n"); sync_state = sync_wait; return; } #ifdef FASTSAVE if ((file_b_r = i_fopen(param.datafile_name, "rb")) == NULL) { i_fclose(file_b); file_b = NULL; kom_log("WARNING: pre_sync: can't open file to save in for reading.\n"); sync_state = sync_wait; return; } #endif sync_output_header(file_b, "DIRTY"); fprintf(file_b, "#C %d\n", highest_conf_no); fprintf(file_b, "#T %ld\n", highest_text_no); fprintf(file_b, "I"); foutput_info(file_b, &kom_info); fprintf(file_b, "\n"); sync_state = sync_save_conf; #ifdef FASTSAVE next_text_to_sync = 1; next_conf_to_sync = 1; #else sync_next = 1; #endif } static void copy_file(FILE *from, FILE *to, long from_pos, long len, long no) { static char buf[BUFSIZ]; long result; long num; long new_num; long num_ix; long chunk_len; long orig_len = len; int first_chunk = 1; if (len < 3) { restart_kom("copy_file: insane len %ld\n", len); } /* Include the terminating newline in the length. */ ++len; if ( fseek(from, from_pos, SEEK_SET) == -1 ) { sync_state = sync_error; restart_kom("sync: copy_file(): src fseek failed.\n"); return; } if ( fseek(to, 0, SEEK_END) == -1 ) { sync_state = sync_error; kom_log("sync: copy_file(): dst fseek failed.\n"); return; } first_chunk = 1; while (len > 0) { chunk_len = len; if (chunk_len > BUFSIZ) chunk_len = BUFSIZ; if ((result = fread(buf, 1, chunk_len, from)) != chunk_len) { restart_kom("%s.\nfrom_pos = %ld, len = %ld, result = %ld\n", "sync: copy_file(): fread failed", from_pos, len, result); sync_state = sync_error; return; } if (first_chunk) { /* Check the start of the first chunk. */ if (buf[0] != 'T' && buf[0] != 'C' && buf[0] != 'P') { restart_kom("Found char %d at pos %ld; expected T, C or P\n", buf[0], from_pos); } if (buf[1] != ' ') { restart_kom("Expected space after T, C or P but got " "%d at %ld\n", buf[1], from_pos); } num = 0; for (num_ix = 2; num_ix < chunk_len && buf[num_ix] >= '0' && buf[num_ix] <= '9'; ++num_ix) { new_num = 10 * num + buf[num_ix] - '0'; if (new_num / 10 != num) { restart_kom("copy_file: number overflow at %ld\n", from_pos); } num = new_num; } if (num != no) { restart_kom("copy_file: expected %ld, got %ld; " "no sanity at %ld\n", no, num, from_pos); } if (num_ix >= chunk_len) { restart_kom("copy_file: to little data at %ld\n", from_pos); } if (buf[num_ix] != ' ') { restart_kom("copy_file: expected space after number " "%ld at %ld; got %d\n", num, from_pos, buf[num_ix]); } first_chunk = 0; } /* The last chunk should end with a newline. */ if (len == result) { if (buf[len-1] != '\n') { restart_kom("Failed to find a newline at %ld + %ld - 1\n", from_pos, orig_len); } /* Don't emit the newline here. */ --len; --chunk_len; if (len == 0) return; } /* Write this chunk. */ if (fwrite(buf, 1, chunk_len, to) != (size_t)chunk_len) { sync_state = sync_error; kom_log("sync: copy_file(): fwrite failed.\n"); return; } len -= chunk_len; } } static void save_one_conf(void) { Cache_node *cn; #ifdef DEBUG_CALLS if (block_after_pre_sync) return; #endif #ifdef FASTSAVE if (next_conf_to_sync < highest_conf_no) #else if (sync_next < highest_conf_no) #endif { cn = get_conf_node (sync_next); if ( cn == NULL ) { } else { #ifdef FASTSAVE cn->saved_pos = cn->pos; cn->pos = ftell(file_b); cn->s.saved_dirty = cn->s.dirty; #else cn->pos_b = ftell(file_b); #endif if ( cn->snap_shot != NULL ) { fprintf(file_b, "C %lu ", sync_next); foutput_conference(file_b, cn->snap_shot); #ifdef FASTSAVE free_conference( cn->snap_shot ); #endif } else if ( cn->s.dirty == 0 && cn->ptr != NULL ) { fprintf(file_b, "C %lu", sync_next); foutput_conference(file_b, cn->ptr); } else { copy_file(file_a, file_b, cn->pos, cn->size - 1, sync_next); } putc('\n', file_b); #ifdef FASTSAVE cn->saved_size = cn->size; cn->size = ftell(file_b) - cn->pos; cn->s.dirty = 0; #else cn->size_b = ftell(file_b) - cn->pos_b; #endif } #ifdef FASTSAVE next_conf_to_sync += 1; #else sync_next++; #endif } else /* All conferences are written. */ { #ifdef FASTSAVE sync_stat = sync_save_conf; #else sync_next = 1; sync_state = sync_save_pers; #endif } } static void write_pers(FILE *fp, Person *p, int pers_no) { fprintf(fp, "P %d %dH", pers_no, PASSWD_LEN); fwrite(p->pwd, PASSWD_LEN, 1, fp); foutput_person(fp, p); } static void save_one_pers(void) { Cache_node *cn; #ifdef FASTSAVE restart_kom("Attempt to save one person in FASTSAVE mode (can't happen.)"); #endif if (sync_next < highest_conf_no) { cn = get_pers_node (sync_next); if ( cn == NULL ) { } else { cn->pos_b = ftell(file_b); if ( cn->snap_shot != NULL ) { write_pers(file_b, cn->snap_shot, sync_next); } else if ( cn->s.dirty == 0 && cn->ptr != NULL ) { write_pers(file_b, cn->ptr, sync_next); } else { copy_file(file_a, file_b, cn->pos, cn->size - 1, sync_next); } putc('\n', file_b); cn->size_b = ftell(file_b) - cn->pos_b; } sync_next++; } else /* All persons are written. */ { sync_next = 1; sync_state = sync_save_text; } } static void post_sync(void) { Text_no tno_iter; Conf_no cno_iter; Cache_node *node; async_sync_db(); if ( file_a == NULL ) kom_log("WARNING: post_sync(): file_a == NULL. This is only normal %s", "if this is the first sync ever on this data file.\n"); else i_fclose(file_a); if ((file_a = i_fopen(param.datafile_name, "rb")) == NULL) { kom_log("post_sync: can't open the file I just saved.\n"); sync_state = sync_wait; return; } for ( cno_iter = 1; cno_iter < highest_conf_no; cno_iter++ ) { node = get_conf_node(cno_iter); if ( node != NULL ) { node->pos = node->pos_b; node->size = node->size_b; free_conference(node->snap_shot); node->snap_shot = NULL; } } for ( cno_iter = 1; cno_iter < highest_conf_no; cno_iter++ ) { node = get_pers_node(cno_iter); if ( node != NULL ) { node->pos = node->pos_b; node->size = node->size_b; free_person(node->snap_shot); node->snap_shot = NULL; } } for ( tno_iter = 1; tno_iter < highest_text_no; tno_iter++ ) { node = get_text_node(tno_iter); if ( node != NULL ) { node->pos = node->pos_b; node->size = node->size_b; free_text_stat(node->snap_shot); node->snap_shot = NULL; } } } static void save_one_text(void) { Cache_node *cn; long offset; long offset2; #ifdef FASTSAVE while (next_text_to_sync < highest_text_no) #else while (sync_next < highest_text_no) #endif { cn = get_text_node(sync_next); if ( cn == NULL ) { #ifdef FASTSAVE next_text_to_sync += 1; #else sync_next++; #endif continue; } else { #ifdef FASTSAVE cn->saved_pos = cn->pos; cn->pos = ftell(file_b); cn->s.saved_dirty = cn->s.dirty; #else cn->pos_b = ftell(file_b); #endif if ( cn->snap_shot != NULL ) { fprintf(file_b, "T %lu", sync_next); foutput_text_stat(file_b, cn->snap_shot); #ifdef FASTSAVE free_text_stat( cn->snap_shot ); #endif } else if ( cn->s.dirty == 0 && cn->ptr != NULL ) { fprintf(file_b, "T %lu", sync_next); foutput_text_stat(file_b, cn->ptr); } else { copy_file(file_a, file_b, cn->pos, cn->size - 1, sync_next); } putc('\n', file_b); #ifdef FASTSAVE cn->size = ftell(file_b) - cn->pos; next_text_to_sync += 1; cn->s.dirty = 0; #else cn->size_b = ftell(file_b) - cn->pos_b; sync_next++; #endif break; } /*NOTREACHED*/ restart_kom("Unreachable statement reached."); } /* If all texts are written, do some clean-up. */ #ifdef FASTSAVE if (next_text_to_sync == highest_text_no) #else if (sync_next == highest_text_no) #endif { if ( ferror(file_b) != 0 ) { kom_log ("save_one_text(): ferror() detected.\n"); sync_state = sync_error; return; } offset = ftell(file_b); /* Make sure that the entire file resides on disk. This test seems to be necessary. The data file has been corrupted at least once. */ if (offset == -1) { kom_log ("save_one_text(): ftell returned -1.\n"); sync_state = sync_error; return; } rewind(file_b); if ( ferror(file_b) != 0 ) { kom_log ("save_one_text(): rewind failed.\n"); sync_state = sync_error; return; } sync_output_header(file_b, "CLEAN"); if ( ferror(file_b) != 0 ) { kom_log ("save_one_text(): Set state to CLEAN failed.\n"); sync_state = sync_error; return; } if (fflush(file_b) != 0) { kom_log ("save_one_text(): fflush failed.\n"); sync_state = sync_error; return; } if ( ferror(file_b) != 0 ) { kom_log ("save_one_text(): ferror after fflush failed.\n"); sync_state = sync_error; return; } if (i_fclose(file_b) != 0) { file_b = NULL; kom_log("Sync: fclose() failed in save_one_text. Retrying.\n"); remove(param.datafile_name); sync_state = sync_wait; return; } #ifdef FASTSAVE if (i_fclose(file_b_r) != 0) { file_b_r = NULL; kom_log("Sync: fclose() of reader failed in save_one_text. Retrying.\n"); remove(param.datafile_name); sync_state = sync_wait; return; } file_b_r = NULL; #endif file_b = i_fopen(param.datafile_name, "rb"); if (file_b == NULL) { kom_log("save_one_text(): failed to reopen file.\n"); remove (param.datafile_name); sync_state = sync_wait; return; } if (fseek(file_b, 0, SEEK_END) != 0) { kom_log("save_one_text(): fseek failed.\n"); sync_state = sync_error; return; } offset2 = ftell (file_b); if ( offset2 != offset ) { kom_log ("save_one_text(): ftell confused (%ld and %ld).\n", offset, offset2); sync_state = sync_error; return; } i_fclose (file_b); file_b = NULL; sync_state = sync_ready; BUG(("Sync ready\n")); post_sync(); } } /* * Sync_part() should be called often as long as it returns 0. If it * returns anything else, there is no need to call it again for that * many seconds, but it is harmless to call it more often than that. */ struct timeval sync_part(void) { static struct timeval last_sync_start = {0, 0}; struct timeval timeleft; if (timeval_zero(last_sync_start)) { last_sync_start = current_time; sync_state = sync_idle; } #ifdef LOGACCESSES syncing_or_saving = 1; #endif switch(sync_state) { case sync_save_conf: save_one_conf(); break; #ifndef FASTSAVE case sync_save_pers: save_one_pers(); break; #endif case sync_save_text: save_one_text(); break; case sync_ready: sync_state = sync_idle; return timeval_ctor(1, 0); case sync_idle: if (param.never_save) return timeval_ctor(60, 0); if (timeval_remaining(&timeleft, param.sync_interval, last_sync_start, current_time)) { #ifdef LOGACCESSES syncing_or_saving = 0; #endif return timeleft; } last_sync_start = current_time; pre_sync(); break; case sync_wait: if (timeval_remaining(&timeleft, param.sync_retry_interval, last_sync_start, current_time)) { #ifdef LOGACCESSES syncing_or_saving = 0; #endif return timeleft; } last_sync_start = current_time; pre_sync(); break; case sync_error: kom_log("sync: Error saving new file. Retrying.\n"); i_fclose(file_b); file_b = NULL; #ifdef FASTSAVE if (file_b_r != NULL) { i_fclose(file_b_r); file_b_r = NULL; } #endif remove(param.datafile_name); /* Send a message to all clients if we fail to save the database. */ async_send_message( 0, 0, s_fcrea_str( "A serious error occurred while saving the database. Tell\n" "the administrator to check the server. This could be caused\n" "by insufficient disc space."), FALSE); sync_state = sync_wait; break; default: restart_kom("sync(): sync_state==%d", sync_state); } if ( file_b != NULL && ferror(file_b) != 0) sync_state = sync_error; #ifdef LOGACCESSES syncing_or_saving = 0; #endif return timeval_ctor(0, 0); } static void setup_small_conf(Conf_no conf_no, Conference *conf_c) { small_conf_arr[conf_no] = alloc_small_conf(); s_strcpy(&small_conf_arr[conf_no]->name, conf_c->name); small_conf_arr[conf_no]->type = conf_c->type; small_conf_arr[conf_no]->supervisor = conf_c->supervisor; small_conf_arr[conf_no]->highest_local_no = l2g_first_appendable_key(&conf_c->texts) - 1; small_conf_arr[conf_no]->nice = conf_c->nice; small_conf_arr[conf_no]->keep_commented = conf_c->keep_commented; } extern Success init_cache(void) { Conf_no ic; Text_no it; Cache_node *node; Conference tmp_conf; Person tmp_pers; Text_stat tmp_text; long datafile_version; long pos, num; Bool done = FALSE; Bool read_text_no = FALSE; Bool read_conf_no = FALSE; int c = 0; struct timeval saved_time; long record; boottime_info.boot_time = current_time.tv_sec; small_conf_arr = smalloc(sizeof(*small_conf_arr) * param.max_conf); pers_mcb = create_cache_node_mcb(100, param.max_conf); conf_mcb = create_cache_node_mcb(100, param.max_conf); text_mcb = create_cache_node_mcb(100, param.max_text); init_conference(&tmp_conf); init_person(&tmp_pers); init_text_stat(&tmp_text); #ifdef LOGACCESSES if (param.logaccess_file) { logfile = i_fopen(param.logaccess_file, "a"); if (logfile) kom_log("Logging db accesses to %s.\n", param.logaccess_file); else kom_log("Failed to open db log file %s. Not logging.\n", param.logaccess_file); } #endif LOGACC(lt_restart, current_time); for (ic = 0; ic < param.max_conf; ic++) small_conf_arr[ic] = NULL; for (ic = 1; ic < param.max_conf; ic++) zero_init_cache_node(pers_mcb, ic); for (ic = 1; ic < param.max_conf; ic++) zero_init_cache_node(conf_mcb, ic); for (it = 1; it < param.max_text; it++) zero_init_cache_node(text_mcb, it); datafile_version = -1; if ((text_file = i_fopen(param.textfile_name, "a+b")) == NULL) { restart_kom("%s \"%s\". errno = %d\n", "ERROR: init_cache: can't open text file", param.textfile_name, errno); } if (is_clean(param.datafile_name)) { if ((file_a = i_fopen(param.datafile_name, "rb")) == NULL) { kom_log("WARNING: init_cache: can't open datafile.\n"); kom_errno = KOM_INTERNAL_ERROR; err_stat = 0; return FAILURE; } kom_log("MSG: init_cache: using datafile.\n"); datafile_version = get_version(param.datafile_name); boottime_info.db_status = s_fcrea_str("clean"); } else if (is_clean(param.backupfile_name)) { if ((file_a = i_fopen(param.backupfile_name, "rb")) == NULL) { kom_log("WARNING: init_cache: can't open backupfile.\n"); kom_errno = KOM_INTERNAL_ERROR; err_stat = 0; return FAILURE; } kom_log("MSG: init_cache: using backup file.\n"); datafile_version = get_version(param.backupfile_name); boottime_info.db_status = s_fcrea_str("backup"); } else { /* Don't attempt to use backupfile_name_2 automatically. If that file is ever needed something is really broken; manual intervention is needed to assess the damage. */ kom_log("WARNING: init_cache: can't find old data base.\n"); kom_errno = KOM_INTERNAL_ERROR; err_stat = 0; return FAILURE; } switch (datafile_version) { case 0: restart_kom("Database is version 0. Please convert it with dbck.\n"); break; case 1: fseek(file_a, 12, SEEK_SET); restart_kom("You need to run dbck to convert your datafile to version 2.\n"); break; case 2: /* * Read timestamp */ fseek(file_a, 12, SEEK_SET); saved_time.tv_sec = fparse_long(file_a); saved_time.tv_usec = 0; if (timeval_greater(saved_time, current_time)) { restart_kom("Saved time is later than current time. Exiting.\n"); } kom_log("Database saved on %s", /* ctime returns a trailing newline. */ ctime(&saved_time.tv_sec)); boottime_info.save_time = saved_time.tv_sec; break; default: restart_kom("Can't read database version %ld. Giving up.\n", datafile_version); } set_input_format(datafile_version); for (record = 1; !done ; record++) { fskipwhite(file_a); switch(c = getc(file_a)) { case EOF: done = TRUE; break; case '@': case '+': restart_kom("init_cache(): old type record in new type file\n"); break; case '#': fskipwhite(file_a); switch(getc(file_a)) { case 'C': next_free_num = fparse_long(file_a); read_conf_no = TRUE; break; case 'T': next_text_num = fparse_long(file_a); read_text_no = TRUE; break; default: restart_kom("init_cache(): Bad number in database\n"); } break; case '-': fskipwhite(file_a); switch(getc(file_a)) { case 'C': num = fparse_long(file_a); node = get_conf_node(num); if (node) { if (node->s.exists) { update_stat(STAT_CONFS, -1); node->s.exists = 0; node->pos = -1; } } break; case 'P': num = fparse_long(file_a); node = get_pers_node(num); if (node) { if (node->s.exists) { update_stat(STAT_PERSONS, -1); node->s.exists = 0; node->pos = -1; } } break; case 'T': num = fparse_long(file_a); node = get_text_node(num); if (node) { if (node->s.exists) { update_stat(STAT_TEXTS, -1); node->s.exists = 0; node->pos = -1; } } break; default: restart_kom("init_cache(): bad remove block in data file\n"); } case 'I': if (fparse_info(file_a, &kom_info) != OK) restart_kom("init_cache(): fparse_info() failed.\n"); break; case 'C': pos = ftell(file_a) - 1; /* Don't forget the '+' */ num = fparse_long(file_a); LOGACC(lt_conf_def, num); if (num < 1) { restart_kom("ERROR: init_cache(), bad conf_no %ld" " at record %ld\n", num, record); } node = get_conf_node(num); if (!node) { create_cache_node(conf_mcb, num); node = get_conf_node(num); update_stat(STAT_CONFS, 1); } node->s.exists = 1; node->pos = pos; if ( fparse_conference(file_a, &tmp_conf) != OK ) restart_kom("init_cache(): fparse_conference() failed" " at record %ld.\n", record); node->size = ftell(file_a) - node->pos; setup_small_conf(num, &tmp_conf); clear_conference(&tmp_conf); break; case 'P': pos = ftell(file_a) - 1; /* Don't forget the '+' */ num = fparse_long(file_a); LOGACC(lt_pers_def, num); node = get_pers_node(num); if (!node) { create_cache_node(pers_mcb, num); node = get_pers_node(num); update_stat(STAT_PERSONS, 1); } node->s.exists = 1; node->pos = pos; if ( fparse_person(file_a, &tmp_pers) != OK ) restart_kom("init_cache: fparse_person failed at" " record %ld.\n", record); node->size = ftell(file_a) - node->pos; clear_person(&tmp_pers); break; case 'T': pos = ftell(file_a) - 1; /* Don't forget the '+' */ num = fparse_long(file_a); LOGACC(lt_text_def, num); node = get_text_node(num); if (!node) { create_cache_node(text_mcb, num); node = get_text_node(num); update_stat(STAT_TEXTS, 1); } node->s.exists = 1; node->pos = pos; if ( fparse_text_stat(file_a, &tmp_text) != OK ) restart_kom("init_cache(): fparse_text_stat failed at" " record %ld.\n", record); node->size = ftell(file_a) - node->pos; clear_text_stat(&tmp_text); break; default: restart_kom("init_cache(): Unknown key %c (%d) " "in data file at %lu\n", c, c, (unsigned long)ftell(file_a)); break; } } if (read_conf_no == FALSE || read_text_no == FALSE) { restart_kom("init_cache(): highest text or conf no not read!\n"); } build_matching_info(); kom_log("Read %d confs/persons and %ld texts\n", next_free_num, next_text_num); read_number_file(); boottime_info.highest_text_no = next_text_num - 1; boottime_info.highest_conf_no = next_free_num - 1; boottime_info.existing_texts = read_stat_value(STAT_TEXTS); boottime_info.existing_confs = read_stat_value(STAT_CONFS); boottime_info.existing_persons = read_stat_value(STAT_PERSONS); return OK; } extern void cache_sync_all(void) { if (param.never_save) return; #ifdef DEBUG_CALLS if (block_after_pre_sync) restart_kom("cache_sync_all: block_after_pre_sync is set!\n"); #endif pre_sync(); while (timeval_zero(sync_part())) ; } #ifdef DEBUG_CALLS /* Do pre_sync(), but stop after that. Nothing will actually be saved until cache_sync_finish() is called. You must call cache_sync_finish() before shutting down the server or attempting to use sync_kom(). */ extern Success cache_sync_start(void) { CHK_CONNECTION(FAILURE); block_after_pre_sync = 1; pre_sync(); return OK; } /* This should only be called afrer a call to cache_sync_start(). Stop being blocked and save everything. */ extern Success cache_sync_finish(void) { CHK_CONNECTION(FAILURE); block_after_pre_sync = 0; while (timeval_zero(sync_part())) ; return OK; } #endif void free_all_cache (void) { unsigned int i; Cache_node *node; #ifdef LOGACCESSES if (logfile) i_fclose(logfile); #endif for ( i = 1; i < next_free_num; i++ ) { node = get_conf_node(i); if ( node != NULL ) { if ( node->snap_shot != NULL ) { free_conference (node->snap_shot); node->snap_shot = NULL; } if ( node->ptr != NULL ) { free_conference (node->ptr); node->ptr = NULL; } } destruct_cache_node (conf_mcb, i); node = get_pers_node(i); if ( node != NULL ) { if ( node->snap_shot != NULL ) { free_person (node->snap_shot); node->snap_shot = NULL; } if ( node->ptr != NULL ) { free_person (node->ptr); node->ptr = NULL; } } destruct_cache_node (pers_mcb, i); if ( small_conf_arr[i] != NULL ) { free_small_conf (small_conf_arr[i]); small_conf_arr[i] = NULL; } } for ( i = 1; i < next_text_num; i++ ) { node = get_text_node(i); if ( node != NULL ) { if ( node->snap_shot != NULL ) { free_text_stat (node->snap_shot); node->snap_shot = NULL; } if ( node->ptr != NULL ) { free_text_stat (node->ptr); node->ptr = NULL; } } destruct_cache_node (text_mcb, i); } free_match_table(match_table); free_cache_node_mcb(conf_mcb); free_cache_node_mcb(text_mcb); free_cache_node_mcb(pers_mcb); sfree(small_conf_arr); sfree (match_table); } /* Is it allowed to delete this node from the cache? It is, unless the node is locked, dirty, or contains a snap-shot. */ static Bool throwable_p(Cache_node *node) { return ((node->s.dirty == 0 || node->s.exists == 0) && node->snap_shot == NULL && node->lock_cnt == 0) ? TRUE : FALSE; } static void limit_pers(void) { Cache_node *node; Cache_node *next_node; int i; node = pers_mcb->mru; /* Skip first CACHE_PERSONS clean persons. */ for ( i = 0; node != NULL && i < param.cache_persons; i++ ) { while (node != NULL && !throwable_p(node)) node = node->next; if ( node != NULL ) node = node->next; } /* Delete any remaining clean persons */ while ( node != NULL ) { next_node = node->next; if (throwable_p(node)) { unlink_pers_lru(node); free_person (node->ptr); node->ptr = NULL; /* FIXME (bug 95): delete cache-node if non-existent. */ } node = next_node; } } static void limit_conf(void) { Cache_node *node; Cache_node *next_node; int i; node = conf_mcb->mru; /* Skip first CACHE_CONFERENCES clean confs. */ for ( i = 0; node != NULL && i < param.cache_conferences; i++ ) { while (node != NULL && !throwable_p(node)) node = node->next; if ( node != NULL ) node = node->next; } /* Delete any remaining clean confs. */ while ( node != NULL ) { next_node = node->next; if (throwable_p(node)) { unlink_conf_lru(node); free_conference (node->ptr); node->ptr = NULL; /* FIXME (bug 95): delete if non-existent. */ } node = next_node; } } static void limit_text_stat(void) { Cache_node *node; Cache_node *next_node; int i; node = text_mcb->mru; /* Skip first CACHE_TEXT_STATS clean text_stats. */ for ( i = 0; node != NULL && i < param.cache_text_stats; i++ ) { while (node != NULL && !throwable_p(node)) node = node->next; if (node != NULL) node = node->next; } /* Delete any remaining clean text_stats. */ while ( node != NULL ) { next_node = node->next; if (throwable_p(node)) { unlink_text_lru(node); free_text_stat (node->ptr); node->ptr = NULL; /* FIXME (bug 95): delete if non-existent. */ } node = next_node; } } /* * Limit the number of 'clean' cache entries. */ EXPORT void cache_limit_size(void) { limit_pers(); limit_conf(); limit_text_stat(); } EXPORT void dump_cache_mem_usage(FILE *fp) { fprintf(fp, "---simple-cache.c:\n"); fprintf(fp, "\tSmall_confs: %d\n", no_of_allocated_small_confs); } EXPORT void dump_cache_stats(FILE *fp) { fprintf(fp, "---simple-cache.c:\n"); fprintf(fp, "\tPersons (cache size: %d):\n", param.cache_persons); fprintf(fp, "\t hits: %lu\n\t miss: %lu\n", pers_mcb->hits, pers_mcb->misses); fprintf(fp, "\tConferences (cache size: %d):\n", param.cache_conferences); fprintf(fp, "\t hits: %lu\n\t miss: %lu\n", conf_mcb->hits, conf_mcb->misses); fprintf(fp, "\tText_stats (cache size: %d):\n", param.cache_text_stats); fprintf(fp, "\t hits: %lu\n\t miss: %lu\n", text_mcb->hits, text_mcb->misses); } EXPORT Text_no query_next_text_num(void) { return next_text_num; } EXPORT Conf_no query_next_conf_no(void) { return next_free_num; } EXPORT void tell_cache_garb_text(int running) { #ifdef LOGACCESSES garb_running = running; #else /* Kluge to remove compiler warning The compiler should be able to optimize this away */ running = running; #endif } Success get_boottime_info(Static_server_info *result) { CHK_CONNECTION(FAILURE); *result = boottime_info; return OK; } lyskom-server-2.1.2/src/server/disk-end-of-atomic.c0000664000015100472110000000434607721716126015650 /* * $Id: disk-end-of-atomic.c,v 0.29 2003/08/23 16:38:17 ceder Exp $ * Copyright (C) 1991-1994, 1998-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * end-of-atomic.c * * This is the magic function which is called at the end of every atomic * call to the server. It is responisble for * Free:ing all tmp_alloc:ated memory * Throw out some cached data if necessary * Forget some old texts if necessary * Save some items to disk if saving * * idle is TRUE if the server has no pending calls. That might be a good time * to forget old texts. */ #ifdef HAVE_CONFIG_H # include #endif #ifdef HAVE_STDDEF_H # include #endif #include #include "timewrap.h" #include "misc-types.h" #include "s-string.h" #include "kom-types.h" #include "end-of-atomic.h" #include "cache.h" #include "server/smalloc.h" #include "kom-config.h" #include "param.h" #include "timeval-util.h" struct timeval end_of_atomic(void) { struct timeval timeout; static int limit = 0; int parts_left; free_tmp(); /* FIXME (bug 148): make limit_text_stat smarter instead. */ if (limit++ > 100) { cache_limit_size(); limit = 0; } for (parts_left = param.saved_items_per_call; parts_left > 0; --parts_left) { timeout = sync_part(); if (timeval_nonzero(timeout)) return timeout; } return param.synctimeout; } lyskom-server-2.1.2/src/server/cache-node.c0000664000015100472110000001240107721716126014253 /* * $Id: cache-node.c,v 0.26 2003/08/23 16:38:18 ceder Exp $ * Copyright (C) 1991, 1993-1994, 1996, 1998-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * cache-node.c * * Used in diskomd. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #ifdef HAVE_STDDEF_H # include #endif #include "cache-node.h" #include "exp.h" #include "server/smalloc.h" #include "lyskomd.h" EXPORT const Cache_node EMPTY_CACHE_NODE = {{ 0, 0 }, NULL, NULL, 0, 0, 0, 0, NULL, NULL, 0}; EXPORT const Cache_node_block EMPTY_CACHE_NODE_BLOCK = { 0, NULL, NULL}; EXPORT const Cache_node_mcb EMPTY_CACHE_NODE_MCB = { 0, NULL, 0, 0, NULL, NULL, 0, NULL }; EXPORT void unlink_lru(Cache_node *node, Cache_node **lru, Cache_node **mru) { Cache_node *link; link = node->next; if ( node->next != NULL ) node->next->prev = node->prev; else if (*lru == node) *lru = node->prev; if ( node->prev != NULL ) node->prev->next = link; else if (*mru == node) *mru = link; node->next = NULL; node->prev = NULL; } static void insert_mru(Cache_node *node, Cache_node **lru, Cache_node **mru) { node->prev = NULL; node->next = *mru; *mru = node; if ( *lru == NULL ) *lru = node; if ( node->next != NULL ) node->next->prev = node; } static Cache_node_mcb * alloc_cache_node_mcb(void) { Cache_node_mcb *t; t = smalloc(sizeof(Cache_node_mcb)); *t = EMPTY_CACHE_NODE_MCB; return t; } static Cache_node_block * alloc_cache_node_block(int table_size) { Cache_node_block *t; t = smalloc(sizeof(Cache_node_block)); *t = EMPTY_CACHE_NODE_BLOCK; t->nodes = smalloc (table_size * sizeof (Cache_node)); t->next_free = 0; t->link = NULL; return t; } EXPORT Cache_node_mcb * create_cache_node_mcb(int mcb_size, int table_size) { Cache_node_mcb *tmp; tmp = alloc_cache_node_mcb(); *tmp = EMPTY_CACHE_NODE_MCB; tmp->lookup_table = smalloc(sizeof(Cache_node *) * table_size); tmp->lookup_table_size = table_size; tmp->mcb_size = mcb_size; tmp->last_block = NULL; return tmp; } /* Note: No check is done that it is initialized. */ EXPORT Cache_node * get_cache_node (Cache_node_mcb *control, unsigned long key) { if ( key >= control->lookup_table_size ) return NULL; return control->lookup_table[ key ]; } static Cache_node * alloc_cache_node (Cache_node_mcb *control) { Cache_node *c; Cache_node_block *new_block; if ( control->last_block == NULL || control->last_block->next_free >= control->mcb_size ) { new_block = alloc_cache_node_block (control->mcb_size); new_block->link = control->last_block; control->last_block = new_block; } c = &control->last_block->nodes[ control->last_block->next_free++ ]; *c = EMPTY_CACHE_NODE; return c; } EXPORT void destruct_cache_node(Cache_node_mcb *control, unsigned long key) { if ( key >= control->lookup_table_size ) return; control->lookup_table[ key ] = NULL; } EXPORT void create_cache_node (Cache_node_mcb *control, unsigned long key) { if ( key >= control->lookup_table_size ) restart_kom("%s(%lu, %lu): lookup_table_size = %lu\n", "ERROR: create_cache_node", (unsigned long) control, key, control->lookup_table_size); control->lookup_table[ key ] = alloc_cache_node(control); } EXPORT void zero_init_cache_node (Cache_node_mcb *control, unsigned long key) { if ( key >= control->lookup_table_size ) restart_kom("%s(%lu, %lu): lookup_table_size = %lu\n", "ERROR: zero_init_cache_node", (unsigned long)control, key, control->lookup_table_size); control->lookup_table[ key ] = NULL; } EXPORT void set_mru(Cache_node_mcb *mcb, unsigned long key) { Cache_node *node; node = get_cache_node(mcb, key); if (node == NULL) restart_kom("set_mru(%lu): nonexistent.\n", key); unlink_lru(node, &mcb->lru, &mcb->mru); insert_mru(node, &mcb->lru, &mcb->mru); } static void free_cache_node_block (Cache_node_block *block) { sfree(block->nodes); sfree(block); } extern void free_cache_node_mcb(Cache_node_mcb *control) { Cache_node_block *block; while ( control->last_block != NULL ) { block = control->last_block; control->last_block = block->link; free_cache_node_block (block); } sfree(control->lookup_table); sfree(control); } lyskom-server-2.1.2/src/server/connections.c0000664000015100472110000007337507723473431014631 /* * Copyright (C) 1991-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * connections.c * * Denna fil inneh}ller niv}n ovanf|r isc. * * Created by Willf|r 31/3-90. Mostly written by ceder. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #ifdef HAVE_STRING_H # include #endif #include #include #include "timewrap.h" #include #include #include #include #include #include "adns.h" #include "oop.h" #include "unused.h" #include "ldifftime.h" #include "misc-types.h" #include "s-string.h" #include "kom-types.h" #include "kom-memory.h" #include "debug.h" #include "isc-interface.h" #include "com.h" #include "async.h" #include "connections.h" #include "internal-connections.h" #include "prot-a-parse-arg.h" #include "log.h" #include "lyskomd.h" #include "services.h" #include "isc-parse.h" #include "prot-a.h" #include "prot-a-parse.h" #include "server/smalloc.h" #include "end-of-atomic.h" #include "send-async.h" #include "cache.h" #include "rfc931.h" #include "param.h" #include "kom-config.h" #include "kom-errno.h" #include "sigflags.h" #include "server-time.h" #include "aux-items.h" #include "eintr.h" #include "text-garb.h" #include "timeval-util.h" #include "stats.h" #include "string-malloc.h" #include "manipulate.h" oop_source_sys * kom_server_oop_src = NULL; struct isc_mcb * kom_server_mcb = NULL; Connection * active_connection = NULL; /* * This is set TRUE when the server should be closed. It is checked * each time around the main loop. It is set if someone with enough * privileges issues a `shutdown', or of lyskomd receives a SIGTERM. * This not an abort: all data is saved before we exit. */ Bool go_and_die = FALSE; /* * The number of times that the session penalties has been averaged. * Beware: this number will wrap around. */ static unsigned int penalty_generation = 0; /* * These state variables are used to find out if we are busy or not. * When a packet arrives, data_available_callback() will set work_done * to TRUE and is_idle to FALSE. */ static Bool work_done = FALSE; static Bool is_idle = FALSE; jmp_buf parse_env; const Fnc_descriptor fnc_defs[]={ #include "fnc-def-init.incl" }; const int num_fnc_defs = sizeof (fnc_defs) / sizeof (Fnc_descriptor); unsigned long service_statistics[sizeof (fnc_defs) / sizeof (Fnc_descriptor)]; BUGDECL; static oop_call_fd data_available_callback; static oop_call_time check_kill_flg; static oop_call_time check_idle_callback; static isc_write_error_cb write_err_cb; static isc_stale_output_cb stale_cb; static isc_stale_output_cb idle_cb; static Connection *queue_first = NULL; static Connection *queue_last = NULL; static void busy(void); static void queue_add(Connection *c) { assert(c->on_queue == FALSE); c->on_queue = TRUE; c->queue_prev = queue_last; c->queue_next = NULL; if (queue_first == NULL) queue_first = c; else queue_last->queue_next = c; queue_last = c; update_stat(STAT_RUN_QUEUE, 1); } static void queue_remove(Connection *c) { assert(c->on_queue == TRUE); c->on_queue = FALSE; if (c->queue_next != NULL) c->queue_next->queue_prev = c->queue_prev; else queue_last = c->queue_prev; if (c->queue_prev != NULL) c->queue_prev->queue_next = c->queue_next; else queue_first = c->queue_next; c->queue_prev = NULL; c->queue_next = NULL; update_stat(STAT_RUN_QUEUE, -1); } void set_time(void) { struct timeval last_time; static int limiter = 0; last_time = current_time; if (gettimeofday(¤t_time, NULL) < 0) { if (limiter < 50) { kom_log("WARNING: gettimeofday failed: %s\n", strerror(errno)); if (++limiter == 50) kom_log("WARNING: will not log the above message again.\n"); } } if (timeval_less(current_time, last_time)) { kom_log("WARNING: Time moved backward at least %g seconds.", timeval_diff_d(last_time, current_time)); /* FIXME (bug 62): Should we take more decisive action here? */ } } static void logout_client(Connection *cp) { Connection *real_active_connection; int ret; if ( active_connection != NULL ) { kom_log("BUGCHK: logout_client(%ld): connection %ld is active.\n", cp->session_no, active_connection->session_no); } if ( cp->pers_no != 0 ) { int ctr = 0; if (active_connection != NULL) { kom_log("WNG: logout_client(): active_connection != NULL\n"); if (ctr < 100) ctr++; else kom_log("WNG: won't log the above message more\n"); } real_active_connection = active_connection; active_connection = cp; logout(); active_connection = real_active_connection; } else { #if 0 /* FIXME (bug 908): send a new async here instead. This causes the elisp client to say that a secret (or unknown) person has left the system. */ async_logout( 0, cp->session_no ); #endif } switch(cp->protocol) { case 0: /* Hasn't yet allocated any protocol. */ break; case 'A': prot_a_destruct(cp); break; default: restart_kom("logout_client(): Bad protocol.\n"); } ret = isc_destroy(kom_server_mcb, cp->isc_session); if (ret < 0) kom_log("logout_client(): isc_destroyed returned %d\n", ret); cp->isc_session = NULL; if (cp->on_queue) queue_remove(cp); kill_client(cp); /* Free the Connection */ update_stat(STAT_CLIENTS, -1); } /* * This function is part of the shutdown tidy-up sequence. */ void logout_all_clients(void) { Session_no sess = 0; Connection *conn; while ( (sess = traverse_connections (sess)) != 0) { conn = get_conn_by_number (sess); if ( conn == NULL ) restart_kom("logout_all_clients(): cant get session %ld.\n", sess); else logout_client (conn); } if ( traverse_connections (0) != 0) restart_kom("logout_all_clients(): traverse_connections(0) == %ld.\n", traverse_connections(0)); } /* * Call a function in services.c. A pointer to the result is returned. * The pointer points to static data which is overwritten on each call. */ static Success call_function(Connection *client, union result_holder *res) { Success status=FAILURE; /* OK if the call was successful. */ if ( active_connection != NULL ) { kom_log("call_function(%ld): active_connection = %ld\n", client->session_no, active_connection->session_no); } if (client->function == illegal_fnc) { err_stat = 0; kom_errno = KOM_NOT_IMPL; return FAILURE; } active_connection = client; service_statistics[client->function_index]++; #include "call-switch.incl" active_connection = NULL; return status; } static void parse_packet(Connection *client) { if ( client->protocol == '\0' ) /* Not known yet. */ { client->protocol = parse_char(client); switch(client->protocol) { case 'A': prot_a_init(client); break; default: client->protocol = '\0'; isc_puts("%%LysKOM unsupported protocol.\n", client->isc_session); isc_flush(client->isc_session); BUG(("%%%%Unsupported protocol.\n")); longjmp(parse_env, KOM_LOGOUT); } } switch(client->protocol) { case 'A': prot_a_parse_packet(client); break; default: restart_kom("parse_packet(): Bad protocol.\n"); break; } } /* * Free all parsed areas which are no longer needed. Re-initialize all * parse_pos fields so that the parse will expect a new function. * * This function is called * when a parse error occurs * when a parse is complete and the function has executed. */ static void free_parsed(Connection *client) { s_clear(&client->c_string0); s_clear(&client->c_string1); client->string0 = EMPTY_STRING; /* So that no one frees it. */ sfree(client->misc_info_list.misc); client->misc_info_list.misc = 0; client->misc_info_list.no_of_misc = 0; s_clear(&client->aux_item.data); s_clear(&client->dummy_aux_item.data); sfree(client->read_range_list.ranges); client->read_range_list.ranges = NULL; client->read_range_list.length = 0; client->parse_pos = 0; client->fnc_parse_pos = 0; client->array_parse_index = 0; client->array_parse_parsed_length = 0; client->array_parse_pos = 0; client->struct_parse_pos = 0; client->string_parse_pos = 0; client->hunt_parse_pos = 0; client->array_hunt_num = 0; client->array_hunt_depth = 0; sfree(client->num_list.data); client->num_list.data = NULL; client->num_list.length = 0; free_aux_item_list(&client->aux_item_list); client->info.highest_aux_no = 0; } /* * Send a reply to a call. */ static void reply(Connection *client, Success status, union result_holder *result) { switch(client->protocol) { case 'A': prot_a_reply(client, status, result); break; default: restart_kom("reply(): Bad protocol.\n"); break; } } /* * Try to parse enough data from client->unparsed to call a function. * If more data is needed set client->more_to_parse to FALSE. Returns * TRUE if anything was (or might have been) written to the client. */ static Bool parse_unparsed(Connection *client) { Success status; union result_holder result; switch ( setjmp(parse_env) ) { case 0 : /* Parse message. If message is complete call function and reply. */ parse_packet(client); if (client->blocked_by_dns) return TRUE; update_stat(STAT_REQUESTS, 1); status = call_function(client, &result); update_stat(STAT_REQUESTS, -1); reply(client, status, &result); client->penalty += param.penalty_per_call; free_parsed(client); end_of_atomic(); return TRUE; case KOM_PROTOCOL_ERR: s_clear(&client->string0); free_parsed(client); isc_puts("%% LysKOM protocol error.\n", client->isc_session); BUG(("%%%% Protocol error.\n")); client->penalty += param.max_penalty; s_clear(&client->unparsed); client->first_to_parse = 0; client->more_to_parse = FALSE; end_of_atomic(); return TRUE; case KOM_MSG_INCOMPLETE: client->more_to_parse = FALSE; return FALSE; case KOM_LOGOUT: add_to_kill_list(client); client->more_to_parse = FALSE; return TRUE; default: restart_kom("Bad longjmp return value.\n"); } /*NOTREACHED*/ } /* Return 1 if the named file exists, 0 otherwise */ static int fexists(const char *filename) { struct stat buf; int code; code = !stat(filename, &buf); errno = 0; return code; } void dump_statistics(void) { static struct timeval last_dump = {0, 0}; int i; FILE *fp; if ((fp = i_fopen(param.statistic_name, "a")) == NULL) { kom_log("dump_statistics(): can't open file %s\n", param.statistic_name); return; } if (timeval_zero(last_dump)) { fprintf(fp, "RESTART\n"); last_dump = current_time; } fprintf(fp, "TIME: %s", ctime(¤t_time.tv_sec)); fprintf(fp, "SECONDS: %ld\n", timeval_diff_sec(current_time, last_dump)); fprintf(fp, "STATISTICS:"); /* The last entry corresponds to the dummy entry that is used to skip arguments to unimplemented requests. Skip that, since it contains no useful statistics. */ for (i = 0; i < num_fnc_defs - 1; i++) { fprintf(fp, " %d:%lu", fnc_defs[i].function, service_statistics[i]); service_statistics[i]=0; } fprintf(fp, "\n"); i_fclose(fp); last_dump = current_time; } /* List of connections to kill. */ static Session_no *kill_list = NULL; static int kill_list_size = 0; static int kill_pending = 0; /* Schedule this client for termination. */ void add_to_kill_list(Connection *conn) { oop_source *source; int i; switch (conn->kill_status) { case ks_pending: /* A kill is already pending. Do nothing--but check that the the client really is present on the kill_list. */ for (i = 0; i < kill_list_size; i++) if (kill_list[i] == conn->session_no) return; restart_kom("add_to_kill_list(): kill_pending set but not on list.\n"); return; case ks_dying: /* Don't add this client to the kill list while it is being killed. */ return; case ks_none: /* The normal case. Do all the work below. */ break; } /* Check that the client isn't already present on the kill_list. */ for (i = 0; i < kill_list_size; i++) if (kill_list[i] == conn->session_no) restart_kom("add_to_kill_list(): on list but not kill_pending.\n"); if (kill_list == NULL) { if (kill_list_size != 0) restart_kom("add_to_kill_list(): size = %d\n", kill_list_size); kill_list_size = 1; kill_list = smalloc(sizeof(Session_no)); } else { kill_list_size++; kill_list = srealloc(kill_list, kill_list_size * sizeof(Session_no)); } kill_list[kill_list_size-1] = conn->session_no; conn->kill_status = ks_pending; if (!kill_pending) { source = isc_getoopsource(conn->isc_session); source->on_time(source, OOP_TIME_NOW, check_kill_flg, NULL); kill_pending = 1; } } static void dump_connections(void) { Session_no s; Connection *conn; FILE *fp; if ((fp = i_fopen(param.connection_status_file_tmp, "w")) == NULL) { kom_log("dump_connections(): can't open file %s: %s\n", param.connection_status_file_tmp, strerror(errno)); return; } for (s = 0; (s = traverse_connections(s)) != 0;) { conn = get_conn_by_number(s); fprintf(fp, "%d %lu %d %s\n", conn->isc_session->fd, conn->session_no, handshake_ok(conn, 0), conn->peer); } if (fflush(fp) != 0) kom_log("dump_connections(): fflush() says an error has occured.\n"); if (ferror(fp)) kom_log("dump_connections(): ferror() says an error has occured.\n"); if (i_fclose(fp) < 0) { kom_log("dump_connections(): fclose failed: %s (ignored)\n", strerror(errno)); } errno = 0; if (i_rename(param.connection_status_file_tmp, param.connection_status_file) < 0) { kom_log("dump_connections(): can't rename %s to %s: %s\n", param.connection_status_file_tmp, param.connection_status_file, strerror(errno)); } } /* * check_kill_flg must NEVER be called inside an atomic call! */ static void * check_kill_flg(oop_source *UNUSED(source), struct timeval UNUSED(tv), void *UNUSED(user)) { Connection *conn; Bool changed = FALSE; kill_pending = 0; if ( active_connection != NULL ) { restart_kom("check_kill_flg: active_connection == %ld", active_connection->session_no); } while (kill_list_size > 0) { --kill_list_size; conn = get_conn_by_number (kill_list[kill_list_size]); if (conn == NULL) { kom_log("check_kill_flg(): Connection %ld doesn't exist.\n", kill_list[kill_list_size]); } else { assert(conn->kill_status == ks_pending); conn->kill_status = ks_dying; logout_client(conn); end_of_atomic(); changed = TRUE; } } if (kill_list != NULL) { sfree (kill_list); kill_list = NULL; } if (changed == TRUE) dump_connections(); return OOP_CONTINUE; } static void * dns_resolution(struct isc_scb *scb, enum isc_resolve_status res, long errcode) { struct timeval after; double diff = -1.0; Connection *conn; char *hostname = NULL; update_stat(STAT_DNS_QUEUE, -1); conn = scb->udg; conn->dns_done = TRUE; if (conn->blocked_by_dns) { conn->blocked_by_dns = FALSE; if (!conn->on_queue) queue_add(conn); } if (res == isc_resolve_aborted) return OOP_CONTINUE; if (gettimeofday(&after, NULL) < 0) kom_log("gettimeofday failed: %s\n", strerror(errno)); diff = timeval_diff_d(after, conn->connect_time); busy(); switch (res) { case isc_resolve_h_errno: if (hostname == NULL) hostname = s_crea_c_str(scb->remote); if (errcode == HOST_NOT_FOUND) kom_log("No hostname found for %s.\n", hostname); else if (errcode == TRY_AGAIN) kom_log("Lookup of %s timed out.\n", hostname); else if (errcode == NO_RECOVERY) kom_log("Non-recoverable error looking up %s.\n", hostname); else if (errcode == NO_ADDRESS) kom_log("Got NO_ADDRESS error looking up %s.\n", hostname); else kom_log("Unknown resolver error %ld looking up %s.\n", errcode, hostname); break; case isc_resolve_adns_error: if (hostname == NULL) hostname = s_crea_c_str(scb->remote); /* Misconfigurations of localhost are common and harmless. Don't bother logging them, since that makes the test cases fail. */ if ((errcode != adns_s_inconsistent && errcode != adns_s_nxdomain) || strcmp(hostname, "127.0.0.1") != 0) kom_log("Error looking up %s: %s\n", hostname, adns_strerror(errcode)); break; case isc_resolve_aborted: abort(); case isc_resolve_ok: break; } if (diff > param.dns_log_threshold) { if (hostname == NULL) hostname = s_crea_c_str(scb->remote); if (res == isc_resolve_ok) kom_log("Slow DNS: got %s after %f seconds\n", hostname, diff); else kom_log("Slow bad DNS: %s failed after %f seconds\n", hostname, diff); } if (hostname != NULL) string_free(hostname); if (handshake_ok(conn, 0)) dump_connections(); return OOP_CONTINUE; } static void write_err_cb(struct isc_scb *cb_session, int saved_errno) { Connection * cp = cb_session->udg; if (saved_errno != ECONNRESET && saved_errno != EPIPE) kom_log("Failed to write to client %lu from %s: %s\n", cp->session_no, cp->peer, strerror(saved_errno)); cp->penalty += param.max_penalty; add_to_kill_list(cp); } static void stale_cb(struct isc_scb *cb_session) { Connection *cp = cb_session->udg; kom_log("Client %lu from %s has stalled. Killing it.\n", cp->session_no, cp->peer); cp->penalty += param.max_penalty; add_to_kill_list(cp); } static void idle_cb(struct isc_scb *cb_session) { Connection *cp = cb_session->udg; kom_log("Client %lu from %s has been idle too long. Killing it.\n", cp->session_no, cp->peer); cp->penalty += param.max_penalty; add_to_kill_list(cp); } static void login_request(struct isc_scb *session) { Connection * cp; const char *realuser; char portbuf[1+2+3*sizeof(long)]; size_t portlen; char *remote_ip = NULL; /* Supress logins if /etc/nologin exists */ if (fexists(param.nologin_file)) { isc_puts("%% No logins allowed.\n", session); isc_flush(session); isc_destroy(kom_server_mcb, session); return; } /* Create a Connection, and link the Connection and the isc_session together. */ cp = new_client(); cp->isc_session = session; session->udg = cp; update_stat(STAT_CLIENTS, 1); /* Store the IP address in readable form. */ s_crea_str(&cp->remote_ip, isc_getipnum(session->raddr, NULL, 0)); remote_ip = s_crea_c_str(cp->remote_ip); /* Initiate DNS lookup. */ if (param.use_dns && isc_resolve_remote(session, dns_resolution) == 0) update_stat(STAT_DNS_QUEUE, 1); else s_strcpy(&session->remote, cp->remote_ip); /* Update the status file that contains all connection. */ sprintf(portbuf, " %d", isc_getportnum(session->raddr)); portlen = strlen(portbuf); cp->peer = smalloc(s_strlen(cp->remote_ip) + portlen + 1); strcpy(cp->peer, remote_ip); strcpy(cp->peer + s_strlen(cp->remote_ip), portbuf); dump_connections(); /* Start with max penalty, so that it doesn't pay to make a lot of new connections. */ cp->penalty = param.max_penalty; cp->penalty_generation = penalty_generation; cp->schedule.priority = param.default_priority; cp->schedule.weight = param.default_weight; /* Get the real user name, as returned by the Ident protocol (rfc 931). */ realuser = get_real_username(session, remote_ip); if (realuser == NULL && param.authentication_level == 2) { kom_log("Connection from %s rejected - no IDENT available.\n", remote_ip); isc_puts("%% No IDENT server reachable at your site.\n", session); isc_flush(session); logout_client(cp); string_free(remote_ip); return; } if (realuser != NULL) s_crea_str(&cp->ident_user, realuser); BUG(("\n[Client %lu from %s is connecting]\n", cp->session_no, remote_ip)); isc_set_read_callback(session, data_available_callback, write_err_cb, stale_cb, idle_cb); string_free(remote_ip); } static void adjust_penalty(Connection *conn) { unsigned int gens = penalty_generation - conn->penalty_generation; if (gens > 0) { /* The weight is in the range 1-0xffff (inclusive). The penalty is in the range 0-0x10000 (inclusive). This means that the multiplication can never overflow. */ if (conn->penalty <= gens) conn->penalty = 0; else { unsigned int tmp = conn->penalty - gens * conn->schedule.weight; if (tmp < conn->penalty) conn->penalty = tmp; else conn->penalty = 0; } conn->penalty_generation = penalty_generation; } } static void read_from_connection(Connection *conn) { Bool would_block = FALSE; Bool need_flush = FALSE; String_size pre; adjust_penalty(conn); while (!would_block && !go_and_die && conn->penalty < param.max_penalty && conn->kill_status == ks_none && !conn->blocked_by_dns) { pre = s_strlen(conn->unparsed) - conn->first_to_parse; while (conn->more_to_parse && !go_and_die && conn->penalty < param.max_penalty && conn->kill_status == ks_none && !conn->blocked_by_dns) need_flush |= parse_unparsed(conn); update_stat(STAT_RECV_QUEUE, s_strlen(conn->unparsed) - conn->first_to_parse - pre); if (go_and_die || conn->penalty >= param.max_penalty || conn->kill_status != ks_none || conn->blocked_by_dns) break; if (!conn->more_to_parse) { pre = s_strlen(conn->unparsed) - conn->first_to_parse; switch (isc_read_data(conn->isc_session, &conn->unparsed, &conn->first_to_parse)) { case ISC_READ_DATA: update_stat(STAT_RECV_QUEUE, s_strlen(conn->unparsed) - conn->first_to_parse - pre); conn->penalty += param.penalty_per_read; conn->more_to_parse = TRUE; break; case ISC_READ_ERROR: if (errno != ECONNRESET && errno != ETIMEDOUT) kom_log("Error reading from client: %s\n", strerror(errno)); /*FALLTHROUGH*/ case ISC_READ_LOGOUT: add_to_kill_list(conn); break; case ISC_READ_WOULDBLOCK: would_block = TRUE; break; case ISC_READ_NOMEM: restart_kom("isc_read_data() reports no memory\n"); } if (!conn->more_to_parse) break; } } if (need_flush) isc_flush(conn->isc_session); /* Delete the parsed part of 'unparsed' */ if (s_trim_left(&conn->unparsed, conn->first_to_parse) != OK) restart_kom("parse_unparsed: s_trim_left\n"); conn->first_to_parse = 0; if (conn->penalty >= param.max_penalty && !conn->blocked_by_dns) { /* isc_disable() will fail if we have received EPIPE on this socket. In that case will soon close it, since write_err_cb() has added it to the kill list. */ if (isc_disable(conn->isc_session) == 0) queue_add(conn); } } static void enable_idle_check(void) { oop_source *source = oop_sys_source(kom_server_oop_src); source->on_time(source, OOP_TIME_NOW, check_idle_callback, NULL); } static void * check_idle_callback(oop_source *UNUSED(source), struct timeval UNUSED(tv), void *UNUSED(user)) { Connection *c; Connection *next; Connection *head = NULL; Connection *tail = NULL; set_time(); is_idle = !work_done; work_done = FALSE; if (is_idle && queue_first != NULL) { is_idle = FALSE; ++penalty_generation; for (next = queue_first; next != NULL; ) { c = next; next = next->queue_next; adjust_penalty(c); if (c->penalty < param.low_penalty) { queue_remove(c); if (head == NULL) head = c; else tail->queue_next = c; tail = c; } } } for (next = head; next != NULL; ) { c = next; next = next->queue_next; c->queue_next = NULL; if (isc_enable(c->isc_session) < 0) restart_kom("failed to re-enable session\n"); /* The call to read_from_connection() might add the connection to the queue. That's why we remove all entries first, and use a private queue within this function. */ if (!go_and_die) read_from_connection(c); } if (!is_idle) enable_idle_check(); /* Check if a client issued a shutdown command. */ return go_and_die ? OOP_HALT : OOP_CONTINUE; } static void * saver_callback(oop_source *source, struct timeval UNUSED(tv), void *user) { struct timeval timeout; struct timeval *next_timer = user; timeout = end_of_atomic(); if (setup_timer(next_timer, timeout) < 0) kom_log("gettimeofday failed: %s\n", strerror(errno)); source->on_time(source, *next_timer, saver_callback, user); return OOP_CONTINUE; } static void busy(void) { /* Something arrived, so we are busy. */ if (is_idle) { is_idle = FALSE; enable_idle_check(); } work_done = TRUE; } static void * data_available_callback(oop_source *source, int fd, oop_event event, void *user) { Connection *conn = ((struct isc_scb*)user)->udg; assert(event == OOP_READ); assert(conn->isc_session->fd == fd); assert(isc_getoopsource(conn->isc_session) == source); assert(conn->on_queue == FALSE); busy(); set_time(); read_from_connection(conn); /* Check if the client issued a shutdown command. */ return go_and_die ? OOP_HALT : OOP_CONTINUE; } void * handle_accept_event(struct isc_scb *UNUSED(accepting_session), struct isc_scb *new_session) { new_session->udg = NULL; set_time(); if (new_session->fd <= PROTECTED_FDS || new_session->fd >= fd_ceiling) { BUG(("Connection attempt rejected.\n")); isc_puts("%% No connections left.\n", new_session); isc_flush(new_session); isc_destroy(new_session->master, new_session); async_rejected_connection(); } else login_request(new_session); return OOP_CONTINUE; } void toploop(void) { struct timeval saver_timer; void *exit_reason; oop_source *source = oop_sys_source(kom_server_oop_src); /* Start the garb right away. */ start_garb_thread(source); /* Hack to find out when we are idle. */ enable_idle_check(); /* Save the database even if we happen to be idle. */ saver_timer = OOP_TIME_NOW; source->on_time(source, saver_timer, saver_callback, &saver_timer); exit_reason = oop_sys_run(kom_server_oop_src); if (exit_reason == OOP_ERROR) kom_log("ERROR: unexpected error from oop_sys_run: %s\n", strerror(errno)); else if (exit_reason == OOP_CONTINUE) kom_log("ERROR: all oop sinks disappeared\n"); else if (exit_reason != OOP_HALT) kom_log("ERROR: unexpected error from oop_sys_run: %s\n", strerror(errno)); if (kill_pending) { source->cancel_time(source, OOP_TIME_NOW, check_kill_flg, NULL); check_kill_flg(NULL, OOP_TIME_NOW, NULL); } if (is_idle == FALSE) source->cancel_time(source, OOP_TIME_NOW, check_idle_callback, NULL); stop_garb_thread(source); source->cancel_time(source, saver_timer, saver_callback, &saver_timer); } Bool server_idle(void) { return is_idle; } Success get_scheduling(Session_no session_no, Scheduling_info *result) { Connection *cptr; CHK_CONNECTION(FAILURE); if (session_no != 0 && session_no != active_connection->session_no) CHK_LOGIN(FAILURE); if ((cptr = get_conn_by_number(session_no)) == NULL || !handshake_ok(cptr, 0)) { kom_errno = KOM_UNDEF_SESSION; err_stat = session_no; return FAILURE; } *result = cptr->schedule; return OK; } static Bool may_change_scheduling(Session_no session_no, Connection *cptr) { if (session_no == 0) return TRUE; if (session_no == active_connection->session_no) return TRUE; if (cptr->pers_no == 0 && (ENA_C(active_connection, admin, 2) || ENA_C(active_connection, wheel, 8))) return TRUE; if (has_access(cptr->pers_no, active_connection, unlimited)) return TRUE; return FALSE; } Success set_scheduling(Session_no session_no, unsigned short priority, unsigned short weight) { Connection *cptr; CHK_CONNECTION(FAILURE); if (weight == 0) { kom_errno = KOM_WEIGHT_ZERO; err_stat = 0; return FAILURE; } if (session_no != 0 && session_no != active_connection->session_no) CHK_LOGIN(FAILURE); if ((cptr = get_conn_by_number(session_no)) == NULL || !handshake_ok(cptr, 0)) { kom_errno = KOM_UNDEF_SESSION; err_stat = session_no; return FAILURE; } if (!may_change_scheduling(session_no, cptr)) { kom_errno = KOM_ACCESS; err_stat = session_no; return FAILURE; } if (priority > param.max_priority) { kom_errno = KOM_INDEX_OUT_OF_RANGE; err_stat = param.max_priority; return FAILURE; } #if 0 /* Since priority is unsigned this can never happen. */ if (priority < 0) { kom_errno = KOM_PRIORITY_DENIED; err_stat = 0; return FAILURE; } #endif if (weight > param.max_weight) { kom_errno = KOM_WEIGHT_DENIED; err_stat = param.max_weight; return FAILURE; } cptr->schedule.priority = priority; cptr->schedule.weight = weight; return OK; } lyskom-server-2.1.2/src/server/text.c0000664000015100472110000021454607722446226013271 /* * $Id: text.c,v 0.118 2003/08/25 17:24:23 ceder Exp $ * Copyright (C) 1991-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * text.c * * All atomic calls that deals with texts. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include "timewrap.h" #include #include #include #include "aux-no.h" #include "server/smalloc.h" #include "s-string.h" #include "misc-types.h" #include "kom-types.h" #include "services.h" #include "com.h" #include "async.h" #include "connections.h" #include "kom-errno.h" #include "manipulate.h" #include "lyskomd.h" #include "kom-config.h" #include "internal-connections.h" #include "cache.h" #include "log.h" #include "minmax.h" #include "admin.h" #include "send-async.h" #include "param.h" #include "kom-memory.h" #include "aux-items.h" #include "local-to-global.h" #include "server-time.h" #include "text.h" #include "string-malloc.h" #include "stats.h" /* * Forward declarations */ static Text_no do_create_text(const String message, u_short no_of_misc, Misc_info *misc, Aux_item_list *aux, Bool anonymous, Text_stat **ret_stat); static void filter_secret_info(Text_stat *result, const Text_stat *original, const Connection *viewer_conn, Bool output_bcc); static Bool interested_party(const Connection *cptr, Text_no tno, const Text_stat *text_s); /* * Static functions */ /* * Add text_no to the list of texts in a conference. Return the local number * the text gets in this conference. */ static Local_text_no add_text_in_conf(Conference * conf_c, Text_no text_no) { Local_text_no res; conf_c->last_written = current_time.tv_sec; /* Add number last on the text_list */ res = l2g_first_appendable_key(&conf_c->texts); l2g_append(&conf_c->texts, res, text_no); return res; } /* * Count how many recipients and cc_recipients a text has. */ static int count_recipients(const Text_stat *t_stat) { int n = 0; Misc_info * end = t_stat->misc_items + t_stat->no_of_misc; Misc_info * misc; for (misc = t_stat->misc_items; misc < end; misc++) if (misc->type == recpt || misc->type == cc_recpt || misc->type == bcc_recpt) { n++; } return n; } /* * Count how many footnotes a text has. */ static int count_footn(const Text_stat *t_stat) { int n = 0; Misc_info * end = t_stat->misc_items + t_stat->no_of_misc; Misc_info * misc; for (misc = t_stat->misc_items; misc < end; misc++) if ( misc->type == footn_in ) n++; return n; } /* * Count how many commments a text has. */ static int count_comment(const Text_stat *t_stat) { int n = 0; Misc_info * end = t_stat->misc_items + t_stat->no_of_misc; Misc_info * misc; for (misc = t_stat->misc_items; misc < end; misc++) if ( misc->type == comm_in ) n++; return n; } /* * Check if CONF_NO is a recipient of the text whose text_stat is given. */ static int find_recipient(Conf_no conf_no, const Text_stat *t_stat) { int i; for (i = 0; i < t_stat->no_of_misc; i++) { switch (t_stat->misc_items[i].type) { case recpt: case cc_recpt: case bcc_recpt: if (t_stat->misc_items[i].datum.recipient == conf_no) return i; break; case rec_time: case comm_to: case comm_in: case footn_to: case footn_in: case sent_by: case sent_at: case loc_no: break; #ifndef COMPILE_CHECKS default: #endif case unknown_info: restart_kom("find_recipient(): illegal misc_item\n"); } } return -1; } /* * Find the misc-index of the comment or footnote link between CHILD * and PARENT, or return -1 if no such comment or footnote link * exists. * * Note: the caller must check if the link is a comment or footnote * link. */ static int find_textlink(const Text_stat *child, Text_no parent) { int i; for (i = 0; i < child->no_of_misc; i++) { switch (child->misc_items[i].type) { case comm_to: case footn_to: if (child->misc_items[i].datum.text_link == parent) return i; break; default: break; } } return -1; } /* * Return the conference which the text goes to. This is normally conf_no, but * it may be a super_conf. If ACTPERS is not allowed to submit a text to * conf_no or a super_conf, return 0. */ static Conf_no submit_to(Conf_no conf_no, /* The conference the user is trying to */ /* submit a text to. */ const Conference *conf_c) /* May be NULL */ { int i; enum access acc; CHK_CONNECTION(0); CHK_LOGIN(0); if (conf_c == NULL) GET_C_STAT(conf_c, conf_no, 0); for (i=0; i < param.max_super_conf_loop; i++) { acc = access_perm(conf_no, active_connection, unlimited); if (acc <= none) { err_stat = conf_no; kom_errno = KOM_UNDEF_CONF; return 0; } if (conf_c->permitted_submitters == 0 || acc == unlimited || locate_membership(conf_c->permitted_submitters, ACT_P) != NULL) { return conf_no; } if (conf_c->super_conf == 0) { err_stat = conf_no; kom_errno = KOM_ACCESS; return 0; } conf_no = conf_c->super_conf; GET_C_STAT(conf_c, conf_no, 0); } err_stat = conf_no; kom_errno = KOM_ACCESS; return 0; } /* * Say that CHILD is a footnote to PARENT. */ static Success do_add_footnote(Text_no child, Text_stat *child_s, Text_no parent, Text_stat *parent_s) /* May be NULL. */ { assert(child_s != NULL); if (parent_s == NULL) GET_T_STAT(parent_s, parent, FAILURE); ADD_MISC(child_s, footn_to, text_link, parent); ADD_MISC(parent_s, footn_in, text_link, child); mark_text_as_changed(child); mark_text_as_changed(parent); return OK; } /* * Say that CHILD is a comment to PARENT. */ static Success do_add_comment(Text_no child, Text_stat *child_s, Text_no parent, Text_stat *parent_s) /* May be NULL. */ { assert(child_s != NULL); if (parent_s == NULL) GET_T_STAT(parent_s, parent, FAILURE); ADD_MISC(child_s, comm_to, text_link, parent); ADD_MISC(parent_s, comm_in, text_link, child); mark_text_as_changed(child); mark_text_as_changed(parent); return OK; } /* * Say that RECEIVER is a recipient of TEXT. */ static Success do_add_recipient(Text_no text, Text_stat * text_s, Conf_no receiver, enum info_type recv_type) { Conference *rece_c; assert(recv_type == recpt || recv_type == cc_recpt || recv_type == bcc_recpt); assert(text_s != NULL); GET_C_STAT(rece_c, receiver, FAILURE); ADD_MISC(text_s, recv_type, recipient, receiver); ADD_MISC(text_s, loc_no, local_no, add_text_in_conf(rece_c, text)); mark_text_as_changed(text); mark_conference_as_changed(receiver); return OK; } static Bool is_member_in(const Person *person, Conf_no conf_no, Bool skip_passive) { Membership *mship; if ((mship = locate_membership(conf_no, person)) != NULL) { if (!(mship->type.passive && skip_passive)) return TRUE; } return FALSE; } /* * Check if person is a member in any of the recipients, * cc_recipients or bcc_recipients of text_s. If skip_passive is * true, ignore passive memberships. */ static Bool is_member_in_recpt(const Person *person, const Text_stat *text_s, Bool skip_passive) { int i; for (i = 0; i < text_s->no_of_misc; i++) { switch(text_s->misc_items[i].type) { case recpt: case cc_recpt: case bcc_recpt: if (is_member_in(person, text_s->misc_items[i].datum.recipient, skip_passive) == TRUE) return TRUE; break; case comm_to: case comm_in: case footn_to: case footn_in: case loc_no: case rec_time: case sent_by: case sent_at: break; #ifndef COMPILE_CHECKS default: #endif case unknown_info: kom_log("is_member_in_recpt(): bad misc_item.\n"); break; } } return FALSE; } static Bool is_member_in_recpt_of(const Person *person, const Text_no text_no, Bool skip_passive) { Text_stat *text_s; GET_T_STAT(text_s, text_no, FALSE); return is_member_in_recpt(person, text_s, skip_passive); } static void report_bad_aux(Text_no tno, String *data, int tag, const char *reason) { static Text_no last = 0; char *d; if (tno == last) return; last = tno; d= s_crea_c_str(*data); kom_log("Bad aux-item %d found in text %ld: \"%s\": %s.\n", tag, (unsigned long)tno, d, reason); string_free(d); } /* * Check if person is a member in any of the recipients of a text that * is linked to this text. If skip_passive is true, ignore passive * memberships. */ static Bool is_member_in_linked_recpt(const Person *person, Text_no tno, const Text_stat *text_s, Bool skip_passive) { int i; Text_no linked_nr; String *data; #if 0 String copy; #endif String_size end; for (i = 0; i < text_s->no_of_misc; i++) { switch(text_s->misc_items[i].type) { case comm_to: case comm_in: case footn_to: case footn_in: linked_nr = text_s->misc_items[i].datum.text_link; if (is_member_in_recpt_of(person, linked_nr, skip_passive) == TRUE) return TRUE; break; case recpt: case cc_recpt: case bcc_recpt: case loc_no: case rec_time: case sent_by: case sent_at: break; #ifndef COMPILE_CHECKS default: #endif case unknown_info: kom_log("is_member_in_linked_recpt(): bad misc_item.\n"); break; } } for (i = 0; i < text_s->aux_item_list.length; i++) { data = &text_s->aux_item_list.items[i].data; switch (text_s->aux_item_list.items[i].tag) { case aux_cross_reference: /* FIXME (bug 23): Until there is a mirroring aux-item, there is no point doing this. */ #if 0 /* Data is "T", optional space, a text number, a space, and some junk we don't care about. */ if (s_strlen(*data) < 2) { report_bad_aux(tno, data, "cross-reference", "too short"); continue; } if (data->string[0] != 'T') continue; copy = s_fsubstr(*data, 1, END_OF_STRING); linked_nr = s_strtol(copy, &end); if (end == -1) { report_bad_aux(tno, data, "cross-reference", "no number found"); continue; } if (end < s_strlen(copy) && copy.string[end] != ' ') { report_bad_aux(tno, data, "cross-reference", "trailing garbage"); continue; } if (is_member_in_recpt_of(person, linked_nr, skip_passive) == TRUE) return TRUE; #endif break; case aux_mx_mime_belongs_to: case aux_mx_mime_part_in: /* Data is a single text number. */ linked_nr = s_strtol(*data, &end); if (end == -1) { report_bad_aux(tno, data, text_s->aux_item_list.items[i].tag, "bad number"); continue; } if (end != s_strlen(*data)) { report_bad_aux(tno, data, text_s->aux_item_list.items[i].tag, "trailing garbage"); continue; } if (is_member_in_recpt_of(person, linked_nr, skip_passive) == TRUE) return TRUE; break; case aux_faq_for_conf: /* Data is a conference number. 0 means the entire system. */ linked_nr = s_strtol(*data, &end); if (end == -1) continue; if (end != s_strlen(*data)) continue; if (linked_nr == 0 || is_member_in(person, linked_nr, skip_passive) == TRUE) return TRUE; break; default: break; } } return FALSE; } /* * Return number of lines in a text */ static u_short count_lines(String str) { u_short l = 0; while (str.len-- > 0) if(*str.string++ == '\n') l++; return l; } /* * Delete misc_info at location loc. * If it is a recpt, cc_recpt, comm_to or footn_to delete any * loc_no, rec_time, sent_by or sent_at that might follow it. * * Note that the Misc_info is not reallocated. */ static void do_delete_misc(u_short * no_of_misc, Misc_info * misc, int loc) { int del = 1; /* Number of items to delete. */ /* Always delete at least one item. */ Bool ready = FALSE; /* Check range of loc */ if (loc < 0 || loc >= *no_of_misc) restart_kom("do_delete_misc() - loc out of range"); while (ready == FALSE && loc + del < *no_of_misc) { switch (misc[loc+del].type) { case loc_no: case rec_time: case sent_by: case sent_at: del++; break; case recpt: case cc_recpt: case bcc_recpt: case footn_to: case footn_in: case comm_to: case comm_in: ready = TRUE; break; #ifndef COMPILE_CHECKS default: #endif case unknown_info: restart_kom("do_delete_misc() - illegal misc"); } } *no_of_misc -= del; /* Move items beyond the deleted ones. */ while (loc < *no_of_misc) { misc[loc] = misc[loc+del]; loc++; } } static void send_async_sub_recipient(Text_no text_no, const Text_stat *text_s, Conf_no conf_no, enum info_type type) { Connection *cptr; Session_no i = 0; while ((i = traverse_connections(i)) != 0) { cptr = get_conn_by_number(i); if (interested_party(cptr, text_no, text_s) && text_read_access(cptr, text_no, text_s)) { Text_stat copy; filter_secret_info(©, text_s, cptr, TRUE); if (find_recipient(conf_no, ©) != -1) async_sub_recipient(cptr, text_no, conf_no, type); } } } /* * Delete the recipient ``conf_no'' from text ``text_no''. * The misc-item is locate at position ``loc'' in the miscinfolist. * ``text_s'' and ``conf_s'' must be supplied. An async-sub-recipient * message will be sent if ``want_async'' is true. */ static Success perform_subtraction(Text_no text_no, Text_stat *text_s, Conf_no conf_no, Conference *conf_s, /* NULL if the conf_no doesn't exist */ int loc, Bool want_async) { if (conf_s != NULL) { /* Only if the conference exists: */ if (text_s->misc_items[loc+1].type == loc_no) { l2g_delete(&conf_s->texts, text_s->misc_items[loc+1].datum.local_no); mark_conference_as_changed(conf_no); } else { kom_log("Bad misc-info-list detected in perform_subtraction()" " for text number %lu.\n", (unsigned long)text_no); } } if (want_async) send_async_sub_recipient(text_no, text_s, conf_no, text_s->misc_items[loc].type); do_delete_misc(&text_s->no_of_misc, text_s->misc_items, loc); mark_text_as_changed(text_no); return OK; } /* * Delete a recipient from a text. Does not fail if the recipient doesn't * exist - that is not an error. (The recipients of a text are not * removed when a conference is deleted.) */ static Success do_sub_recpt(Text_no text_no, Text_stat * text_s, /* May be NULL */ Conf_no conf_no, Conference * conf_s, /* May be NULL */ Bool want_async) { int i; if (text_s == NULL) GET_T_STAT(text_s, text_no, FAILURE); if (conf_s == NULL) conf_s = cached_get_conf_stat(conf_no); /* Might still be NULL. */ for (i = 0; i < text_s->no_of_misc; i++) { switch (text_s->misc_items[i].type) { case recpt: case cc_recpt: case bcc_recpt: if (text_s->misc_items[i].datum.recipient == conf_no) return perform_subtraction(text_no, text_s, conf_no, conf_s, i, want_async); break; case comm_to: case comm_in: case footn_to: case footn_in: case loc_no: case rec_time: case sent_by: case sent_at: break; #ifndef COMPILE_CHECKS default: #endif case unknown_info: kom_log("do_sub_recpt(): bad misc_item.\n"); break; } } err_stat = conf_no; kom_errno = KOM_NOT_RECIPIENT; return FAILURE; } /* OTHER is a INFO_TYPE to text number TEXT (whose text status is TEXT_S). This function removes that misc-info from TEXT_S. */ static void remove_misc_item(Text_no text, Text_stat *text_s, enum info_type info_type, Text_no other) { int i; assert(info_type == comm_to || info_type == comm_in || info_type == footn_to || info_type == footn_in); for (i = 0; i < text_s->no_of_misc; i++) { if (text_s->misc_items[i].type == info_type && text_s->misc_items[i].datum.text_link == other) { do_delete_misc(&text_s->no_of_misc, text_s->misc_items, i); mark_text_as_changed(text); return; } } restart_kom("remove_misc_item() failed.\n"); } /* * Delete the link between comment and comment_to. */ static void do_sub_comment(Text_no comment, /* The comment. */ Text_stat * text_s, Text_no comment_to, /* The commented. */ Text_stat * parent_s ) { if (text_s == NULL) VOID_GET_T_STAT(text_s, comment); if (parent_s == NULL) VOID_GET_T_STAT(parent_s, comment_to); remove_misc_item(comment, text_s, comm_to, comment_to); remove_misc_item(comment_to, parent_s, comm_in, comment); } /* * Delete the link between footnote and footnote_to. */ static void do_sub_footnote(Text_no footnote, Text_stat * text_s, Text_no footnote_to, Text_stat * parent_s) { if (text_s == NULL) VOID_GET_T_STAT(text_s, footnote); if (parent_s == NULL) VOID_GET_T_STAT(parent_s, footnote_to); remove_misc_item(footnote, text_s, footn_to, footnote_to); remove_misc_item(footnote_to, parent_s, footn_in, footnote); } /* * Return true if the sender of T_STAT misc-item number I is a person * that the one logged in on CONN is a supervisor of. */ static Bool is_supervisor_of_sender(const Text_stat *t_stat, int i, const Connection *conn) { for (i++ ; i < t_stat->no_of_misc; i++) { switch (t_stat->misc_items[i].type) { case sent_by: return is_supervisor(t_stat->misc_items[i].datum.sender, conn); case recpt: case cc_recpt: case bcc_recpt: case comm_to: case comm_in: case footn_to: case footn_in: case sent_at: return FALSE; /* No sender. */ case loc_no: case rec_time: break; /* These may come before a sent_by. */ #ifndef COMPILE_CHECKS default: #endif case unknown_info: restart_kom("ERROR: is_supervisor_of_sender(): " "Illegal misc_item found.\n"); } } return FALSE; /* No sender. */ } /* * Check if ACTPERS is allowed to add a footnote to a text. Sets errno if * there is an error. * * Note: Caller must set err_stat */ static Success check_footn(const Text_stat * t_stat) { if (active_connection == NULL || t_stat->author != ACTPERS) { kom_errno = KOM_NOT_AUTHOR; return FAILURE; } if (count_footn(t_stat) >= param.max_foot) { err_stat = 0; kom_errno = KOM_FOOT_LIMIT; return FAILURE; } return OK; } /* * Check if ACTPERS is allowed to add a comment to a text. Sets errno if * there is an error. Note that it is allowed to comment a text even if * you are not allowed to read it. */ static Success check_comm(const Text_stat * t_stat) { if (count_comment(t_stat) >= param.max_comm) { kom_errno = KOM_COMM_LIMIT; return FAILURE; } return OK; } /* * Return a pointer to a Mark if pers_no has marked the text text_no. * Otherwise, return NULL. */ static Mark * locate_mark(Pers_no pers_no, const Person *pers_p, /* May be NULL. */ Text_no text_no) { Mark *mp; Mark *result = NULL; int i; Mark_list mlist; if (pers_p == NULL) GET_P_STAT(pers_p, pers_no, NULL); mlist = pers_p->marks; for (i = mlist.no_of_marks, mp = mlist.marks; i > 0 && result == NULL; i--, mp++) { if (mp->text_no == text_no) result = mp; } return result; } /* * Skip one misc-item with all additional data. * * This is only used from get_text_stat. */ static unsigned short skip_recp(unsigned short misc_index, const Text_stat *text_stat) { ++misc_index; while (misc_index < text_stat->no_of_misc) { switch (text_stat->misc_items[misc_index].type) { case loc_no: case rec_time: case sent_by: case sent_at: ++misc_index; break; case recpt: case cc_recpt: case bcc_recpt: case comm_to: case comm_in: case footn_to: case footn_in: return misc_index; break; #ifndef COMPILE_CHECKS default: #endif case unknown_info: restart_kom("skip_recp() - illegal misc\n"); } } return misc_index; } /* * Copy the text_stat original into result, but only those part * that viewer is allowed to see. (Censor away information about * conferences that viewer is not allowed to know about). * * All memory is allocated via tmp_alloc(). */ static void filter_secret_info(Text_stat *result, const Text_stat *original, const Connection *viewer_conn, Bool output_bcc) { unsigned short orig; unsigned short copy; Pers_no bcc; /* FIXME (bug 177): Possible optimisation: No need to copy unless there is a secret conf among the recipients. */ *result = *original; filter_aux_item_list(&original->aux_item_list, &result->aux_item_list, viewer_conn); result->misc_items = tmp_alloc(result->no_of_misc * sizeof(Misc_info)); result->no_of_misc = 0; copy = 0; for (orig = 0; orig < original->no_of_misc; ) { switch (original->misc_items[orig].type) { case recpt: case cc_recpt: if (!has_access(original->misc_items[orig].datum.recipient, viewer_conn, read_protected) && !ENA_C(viewer_conn, admin, 4)) { orig = skip_recp(orig, original); } else { result->misc_items[copy++] = original->misc_items[orig++]; ++result->no_of_misc; } break; case bcc_recpt: /* * We will send this if any of the following is true: * - The viewer is the recipient. * - The recipient is an open conference. * - The viewer sent the BCC. * - The viewer is supervisor of the author, and allowed * to know that the recipient exists. */ bcc = original->misc_items[orig].datum.recipient; if (viewer_conn->person != NULL && (has_access(bcc, viewer_conn, limited) || locate_membership(bcc, viewer_conn->person) || ENA_C(viewer_conn, admin, 4) || is_supervisor_of_sender(original, orig, viewer_conn) || (is_supervisor(original->author, viewer_conn) && (has_access(bcc, viewer_conn, read_protected))))) { result->misc_items[copy++] = original->misc_items[orig++]; ++result->no_of_misc; if (!output_bcc) result->misc_items[copy-1].type = cc_recpt; } else { orig = skip_recp(orig, original); } break; case loc_no: case rec_time: case comm_to: case comm_in: case footn_to: case footn_in: case sent_by: case sent_at: result->misc_items[copy++] = original->misc_items[orig++]; ++result->no_of_misc; break; #ifndef COMPILE_CHECKS default: #endif case unknown_info: restart_kom("filter_secret_info() - illegal misc_item!\n"); } } } static Bool interested_party(const Connection *cptr, Text_no tno, const Text_stat *text_s) { if (cptr->person == NULL) return FALSE; if (is_member_in_recpt(cptr->person, text_s, TRUE) == TRUE) return TRUE; if (is_member_in_linked_recpt(cptr->person, tno, text_s, TRUE) == TRUE) return TRUE; return FALSE; } /* * Send message to all interested parties that a text has been deleted. */ static void send_async_deleted_text(Text_no text_no, const Text_stat *text_s) { Connection *cptr; Text_stat filtered; Session_no i = 0; init_text_stat(&filtered); while ((i = traverse_connections(i)) != 0) { cptr = get_conn_by_number(i); if (interested_party(cptr, text_no, text_s) && text_read_access(cptr, text_no, text_s)) { filter_secret_info(&filtered, text_s, cptr, TRUE); async_deleted_text(cptr, text_no, &filtered); } } #if 0 /* * This is not strictly necessary since the text-stat is sent * in the previous message, and the clients should be able to * update their caches from that information. */ for (misc = text_s->misc_items; misc < text_stat->misc_items + text_stat->no_of_misc; misc++) { if (misc->type == footn_in || misc->type == comm_in || misc->type == comm_to || misc->type == footn_to) { i = 0; c_text_no = 0; if (misc->type == comm_to) c_text_no = misc->datum.comment_to; else if (misc->type == comm_in) c_text_no = misc->datum.comment_in; else if (misc->type == footn_in) c_text_no = misc->datum.footnote_in; else if (misc->type == footn_to) c_text_no = misc->datum.footnote_to; c_text = get_text_stat(c_text_no); if (c_text) { while ((i = traverse_connections(i)) != 0) { cptr = get_conn_by_number(i); if (cptr->person != NULL && is_member_in_recpt(cptr->person, c_text) == TRUE) { async_invalidate_text(cptr, c_text_no); } } } } } #endif } /* * End of static functions. */ /* * Functions that are exported to the rest of the server. */ Bool text_read_access(const Connection *conn, Text_no text_no, const Text_stat *text_stat) { int i = 0; Misc_info *misc = NULL; Conference *recipient = NULL; if (conn == NULL) { kom_log("ERROR: text_read_access() called with conn==NULL for t=%ld\n", (unsigned long)text_no); return FALSE; } /* Everyone may read the MOTD of KOM */ if (text_no == kom_info.motd_of_lyskom) return TRUE; if (text_stat == NULL && (text_stat = cached_get_text_stat(text_no)) == NULL) { if (!conn->pers_no) { /* If you are not logged in, you are not allowed to know if the text exists or not. */ err_stat = 0; kom_errno = KOM_LOGIN; } return FALSE; } /* Check for world-readable aux item. */ for (i = 0; i < text_stat->aux_item_list.length; i++) if (text_stat->aux_item_list.items[i].tag == aux_world_readable) return TRUE; /* Users who are not logged in may not read anything else. */ if (!conn->pers_no) { err_stat = 0; kom_errno = KOM_LOGIN; return FALSE; } /* Some bits let you read everything. */ if (ENA_C(conn, wheel, 10)) return TRUE; if (text_stat->author == conn->pers_no) return TRUE; /* Check if conn->pers_no or current working conference is a recipient */ for (i = text_stat->no_of_misc, misc = text_stat->misc_items; i; i--, misc++) { if ((misc->type == recpt || misc->type == cc_recpt || misc->type == bcc_recpt) && (misc->datum.recipient == conn->cwc || misc->datum.recipient == conn->pers_no)) { return TRUE; } } /* Check if conn->pers_no is member in any of the recipients */ for (i = text_stat->no_of_misc, misc = text_stat->misc_items; i > 0; i--, misc++) { if ((misc->type == recpt || misc->type == cc_recpt || misc->type == bcc_recpt) && locate_membership(misc->datum.recipient, conn->person) != NULL) { return TRUE; } } if (locate_mark(conn->pers_no, conn->person, text_no) != NULL) return TRUE; /* Check if any of the recipients is an open conference, or if the user of conn is a supervisor. (Note: He is not supervisor of anything if he isn't logged in.) */ for (i = text_stat->no_of_misc, misc = text_stat->misc_items; i > 0; i--, misc++) { if ((misc->type == recpt || misc->type == cc_recpt || misc->type == bcc_recpt) && (recipient=cached_get_conf_stat(misc->datum.recipient)) != NULL) { if (!recipient->type.rd_prot || (ENA_C(conn, wheel, 8)) || is_supervisor(misc->datum.recipient, conn) == TRUE) { return TRUE; } } } return FALSE; } Success do_delete_text(Text_no text_no, Text_stat *text_s) { Person *author; if (text_s == NULL) GET_T_STAT(text_s, text_no, FAILURE); send_async_deleted_text(text_no, text_s); if ((author = cached_get_person_stat(text_s->author)) != NULL) { l2g_delete_global_in_sorted(&author->created_texts, text_no); mark_person_as_changed(text_s->author); } while (text_s->no_of_misc > 0) { switch (text_s->misc_items[0].type) { case recpt: case cc_recpt: case bcc_recpt: if (do_sub_recpt(text_no, text_s, text_s->misc_items[0].datum.recipient, NULL, FALSE) != OK) restart_kom("do_delete_text(): error pos 1.\n"); break; case comm_to: do_sub_comment(text_no, text_s, text_s->misc_items[0].datum.text_link, NULL); break; case comm_in: do_sub_comment(text_s->misc_items[0].datum.text_link, NULL, text_no, text_s); break; case footn_to: do_sub_footnote(text_no, text_s, text_s->misc_items[0].datum.text_link, NULL); break; case footn_in: do_sub_footnote(text_s->misc_items[0].datum.text_link, NULL, text_no, text_s); break; case loc_no: case rec_time: case sent_by: case sent_at: restart_kom("do_delete_text(): Illegal misc-item syntax.\n"); #ifndef COMPILE_CHECKS default: #endif case unknown_info: restart_kom("do_delete_text(): Illegal misc-item.\n"); } } cached_delete_text(text_no); update_stat(STAT_TEXTS, -1); return OK; } /* * Atomic calls. */ /* * Calls to handle marks. * * Marks are secret. No else can know what you have marked. */ /* * Get text_nos of all marked texts. */ extern Success get_marks(Mark_list *result) { CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); *result = ACT_P->marks; return OK; } /* * Get the text. The text will not be marked as read until you * explicitly mark_as_read() it. start_char = 0 && end_char = END_OF_STRING * gives the entire text. */ extern Success get_text(Text_no text_no, String_size start_char, String_size end_char, String * result) { Text_stat * text_s; CHK_CONNECTION(FAILURE); GET_T_STAT(text_s, text_no, FAILURE); /* Check if ACTPERS has read acess to the text */ if (text_read_access(active_connection, text_no, text_s) != TRUE) { kom_errno = KOM_NO_SUCH_TEXT; err_stat = text_no; return FAILURE; } *result = cached_get_text(text_no); if (start_char > result->len) { err_stat = start_char; kom_errno = KOM_INDEX_OUT_OF_RANGE; return FAILURE; } /* FIXME (bug 179): Should use something in s-string.c to do this. */ result->string += start_char; result->len = min(result->len - 1, end_char) + 1 - start_char; if (ACTPERS) { ++ACT_P->no_of_text_fetches; mark_person_as_changed(ACTPERS); } return OK; } /* * Get text status. * * If there are recipients of the text that are secret confs * those misc-items will be censored. */ extern Success get_text_stat_old(Text_no text_no, Text_stat *result) { Text_stat * text_stat; CHK_CONNECTION(FAILURE); GET_T_STAT(text_stat, text_no, FAILURE); if (!text_read_access(active_connection, text_no, text_stat) && !ENA(admin, 2)) /* OK -- In an RPC call */ { kom_errno = KOM_NO_SUCH_TEXT; err_stat = text_no; return FAILURE; } filter_secret_info(result, text_stat, active_connection, FALSE); return OK; } extern Success get_text_stat(Text_no text_no, Text_stat *result) { Text_stat * text_stat; CHK_CONNECTION(FAILURE); GET_T_STAT(text_stat, text_no, FAILURE); if (!text_read_access(active_connection, text_no, text_stat) && !ENA(admin, 2)) /* OK -- In an RPC call */ { kom_errno = KOM_NO_SUCH_TEXT; err_stat = text_no; return FAILURE; } filter_secret_info(result, text_stat, active_connection, TRUE); return OK; } /* * Functions local to create_text: */ /* * Check that the text can be submitted anonymously */ static Success check_anonymous_subm(Conf_no addressee) { Conf_type conf_type; conf_type = cached_get_conf_type(addressee); if (conf_type.allow_anon) return OK; else return FAILURE; } /* * Check that the recipient or cc_recipient at LOC is not already a * recipient or cc_recipient of this text. */ static Success check_double_subm(const Misc_info *misc, int loc, Conf_no addressee) { int j; for (j = 0; j < loc; j++) { switch (misc[j].type) { case recpt: case cc_recpt: case bcc_recpt: if (misc[j].datum.recipient == addressee) return FAILURE; break; case comm_to: case comm_in: case footn_to: case footn_in: case loc_no: case rec_time: case sent_by: case sent_at: break; #ifndef COMPILE_CHECKS default: #endif case unknown_info: kom_log("check_double_subm(): bad misc_item.\n"); break; } } return OK; } /* * Check that none of the first 'pos' misc_items pointed to by misc * is a comment or footnote to text forbidden. */ static Success check_double_comm(const Misc_info *misc, int pos, Text_no forbidden) { for (;pos > 0; pos--, misc++) { switch (misc->type) { case comm_to: case footn_to: if (misc->datum.text_link == forbidden) return FAILURE; break; case recpt: case cc_recpt: case bcc_recpt: case comm_in: case footn_in: case loc_no: case rec_time: case sent_by: case sent_at: break; #ifndef COMPILE_CHECKS default: #endif case unknown_info: kom_log("check_double_comm(): bad misc_item.\n"); break; } } return OK; } /* * Check that all misc_items are legal. Return OK / FAILURE. * Update recpt & cc_recpt fields if the text goes to a super_conf. * Signal an error if a conference is recipient more than once, or if * a text is a comment to the same text more than once. */ static Success create_text_check_misc(u_short *no_of_misc, Misc_info *misc, Bool anonymous, Bool need_public_jubel) { int i; Text_stat *parent; Conf_no addressee; for (i = 0; i < *no_of_misc; i++) { err_stat = i; /* In case of an error, err_stat indicates which misc_item caused the error. */ switch (misc[i].type) { case footn_to: case comm_to: GET_T_STAT(parent, misc[i].datum.text_link, FAILURE); if (!text_read_access(active_connection, misc[i].datum.text_link, parent)) { err_stat = misc[i].datum.text_link; kom_errno = KOM_NO_SUCH_TEXT; return FAILURE; } if ((misc[i].type == footn_to ? check_footn : check_comm)(parent) == FAILURE) { err_stat = misc[i].datum.text_link; return FAILURE; } if (check_double_comm(misc, i, misc[i].datum.text_link) != OK) { err_stat = i; kom_errno = KOM_ILL_MISC; return FAILURE; } break; case recpt: case cc_recpt: case bcc_recpt: /* Check that ACTPERS has write access to the conference or a superconference. */ /* Superconfs are recursive */ addressee = submit_to(misc[i].datum.recipient, NULL); /* Update in case of super_conf */ misc[i].datum.recipient = addressee; if (addressee == 0) { /* Error data set in submit_to */ return FAILURE; } /* Check that this recipient is not already a recipient. */ if (check_double_subm(misc, i, addressee) != OK) { err_stat = i; kom_errno = KOM_ILL_MISC; return FAILURE; } /* Check that an anonymous text can be created */ if (anonymous && check_anonymous_subm(addressee) != OK) { err_stat = addressee; kom_errno = KOM_ANON_REJECTED; return FAILURE; } /* Check if this is a public conference. */ if (need_public_jubel) { Conf_type conf_type; conf_type = cached_get_conf_type(addressee); if (!conf_type.rd_prot) need_public_jubel = FALSE; } break; case loc_no: /* Ignore loc_no */ break; case unknown_info: /* Unrecognized info type */ err_stat = misc[i].datum.unknown_type; kom_errno = KOM_ILLEGAL_INFO_TYPE; return FAILURE; case comm_in: case footn_in: case rec_time: case sent_by: case sent_at: /* Fall through */ #ifndef COMPILE_CHECKS default: #endif err_stat = i; kom_errno = KOM_ILL_MISC; return FAILURE; } } if (need_public_jubel) { /* We still have not found an open conference among the recipients. */ err_stat = 0; kom_errno = KOM_TEMPFAIL; kom_log("Jubel stopped because no public recipient was found.\n"); return FAILURE; } return OK; } /* * Add the aux_infos to the new text stat */ static Success create_text_add_aux(Text_stat *t_stat, Text_no text_no, Aux_item_list *aux, Pers_no creator) { u_short i; Text_stat *parent; text_stat_add_aux_item_list(t_stat, text_no, aux, creator); for (i = 0; i < t_stat->no_of_misc; i++) { switch (t_stat->misc_items[i].type) { case footn_to: case comm_to: parent = cached_get_text_stat(t_stat->misc_items[i].datum.text_link); if (parent != NULL && text_read_access(active_connection, t_stat->misc_items[i].datum.text_link, parent)) { aux_inherit_items(&t_stat->aux_item_list, &parent->aux_item_list, &t_stat->highest_aux, t_stat->author, text_no, t_stat); } break; default: break; } } return OK; } /* * Fix all double references. Eg if misc contains comm_to, add a comm_in field. * No access-permission checking is done. */ static Success create_text_add_miscs(Text_no new_text, Text_stat *new_stat, int no_of_misc, Misc_info * misc) { int i; Conference *conf_c; for (i = 0; i < no_of_misc; i++) { err_stat = i; /* In case of an error, err_stat indicates which misc_item caused the error. */ switch (misc[i].type) { case footn_to: if (do_add_footnote(new_text, new_stat, misc[i].datum.text_link, NULL) != OK) return FAILURE; break; case comm_to: if (do_add_comment(new_text, new_stat, misc[i].datum.text_link, NULL) != OK) return FAILURE; break; case recpt: case cc_recpt: case bcc_recpt: if (do_add_recipient(new_text, new_stat, misc[i].datum.recipient, misc[i].type) != OK) return FAILURE; GET_C_STAT(conf_c, misc[i].datum.recipient, FAILURE); conf_c->last_written = current_time.tv_sec; break; case loc_no: /* Ignore loc_no. */ break; case comm_in: case footn_in: case rec_time: case sent_by: case sent_at: /* Fall through */ #ifndef COMPILE_CHECKS default: #endif case unknown_info: restart_kom("create_text_add_misc() - illegal enum info_type"); } } return OK; } /* * Send an asynchronous message, but filter any secret information. */ static void send_async_new_text_old(Text_no text_no, const Text_stat *text_s) { Connection *cptr; Session_no i = 0; Text_stat filtered; init_text_stat(&filtered); while ((i = traverse_connections(i)) != 0) { cptr = get_conn_by_number(i); /* * filter_secret_info copies the text-stat to filtered, but * since it is allocated with tmp_alloc we do not need to free * the memory now. */ if (interested_party(cptr, text_no, text_s) && text_read_access(cptr, text_no, text_s)) { filter_secret_info(&filtered, text_s, cptr, FALSE); async_new_text_old(cptr, text_no, &filtered); } } } static void send_async_new_text(Text_no text_no, const Text_stat *text_s) { Connection *cptr; Session_no i = 0; Text_stat filtered; init_text_stat(&filtered); while ((i = traverse_connections(i)) != 0) { cptr = get_conn_by_number(i); /* * filter_secret_info copies the text-stat to filtered, but * since it is allocated with tmp_alloc we do not need to free * the memory now. */ if (interested_party(cptr, text_no, text_s) && text_read_access(cptr, text_no, text_s)) { filter_secret_info(&filtered, text_s, cptr, TRUE); async_new_text(cptr, text_no, &filtered); } } } /* * Special case handling of special text numbers. * * In the KOMmunity, there has arisen an odd phenomenon known as * "jubel" to the local citizens of LysKOM. There are several kinds * of "jubel"; a text number divisible by 1000 is one famous such. * * There is a feeling that jubels, at least the more prominent jubels, * should not be created by automatic postings. This code is * primarily aimed at stopping such things, but it can have other, eh, * interesting uses as well... */ struct jubel { struct jubel *next; Pers_no bad_guy; Text_no divisor; /* 0 is used to represent infinity */ Text_no remainder; Bool public; /* Text must be sent to a public conference */ }; static struct jubel *jubel_root = NULL; /* * register_jubel(char*) - tell lyskomd about a jubel, and a * person which is not allowed to create that jubel. The argument is * a string consisting of two or three numbers: * persno textno * persno divisor remainder * meaning that PERSNO is not allowed to create text TEXTNO, or any * text number which fulfills the relation textno%DIVISOR==REMAINDER. */ void register_jubel(Pers_no pno, Text_no divis, /* 0 if no division should be made. */ Text_no tno, Bool public) { struct jubel *j = smalloc(sizeof(struct jubel)); j->next = jubel_root; j->bad_guy = pno; j->divisor = divis; j->remainder = tno; j->public = public; jubel_root = j; } /* Free the jubel list */ void free_all_jubel(void) { struct jubel *a; struct jubel *b; a = jubel_root; while (a != NULL) { b = a; a = a->next; sfree(b); } jubel_root = NULL; } /* Check if it is ok for ACTPERS to create the next text. */ static Bool ok_to_create_next_text(const Connection *conn, Bool *must_be_public) /* [out] */ { struct jubel *j; Text_no next_tno; Bool is_jubel = FALSE; *must_be_public = FALSE; if (conn == NULL) return FALSE; next_tno = query_next_text_num(); for (j = jubel_root; j != NULL; j = j->next) { if ((j->divisor == 0 && next_tno == j->remainder) ||(j->divisor != 0 && next_tno%j->divisor == j->remainder)) { if (conn->pers_no == j->bad_guy) { kom_log("Stopped person %d from creating jubel %lu.\n", conn->pers_no, next_tno); return FALSE; } else is_jubel = TRUE; if (j->public) *must_be_public = TRUE; } } if (is_jubel) { if (*must_be_public) kom_log("Granted jubel %lu to person %d, pending public check.\n", next_tno, conn->pers_no); else kom_log("Granted jubel %lu to person %d.\n", next_tno, conn->pers_no); } return TRUE; } /* * Create a text. * * The recipients may change. See doc for set_permitted_submitters. * * The only allowed Misc_items are recpt, cc_recpt, comm_to and footn_to. * loc_no are allowed, but ignored. * * Returns text_no of the created text, or 0 if there was an error. */ extern Text_no create_text_old(const String message, Misc_info_list * misc_l) { Text_stat *t_stat; Text_no text; /* CHK_CONNECTION in do_create_text */ text = do_create_text(message, misc_l->no_of_misc, misc_l->misc, NULL, FALSE, &t_stat); if (text != 0) { send_async_new_text_old(text, t_stat); send_async_new_text(text, t_stat); } return text; } extern Text_no create_text(const String message, Misc_info_list *misc_l, Aux_item_list *aux) { Text_stat *t_stat; Text_no text; /* CHK_CONNECTION in do_create_text */ text = do_create_text(message, misc_l->no_of_misc, misc_l->misc, aux, FALSE, &t_stat); if (text != 0) { send_async_new_text_old(text, t_stat); send_async_new_text(text, t_stat); } return text; } /* * Create an anonymous text. * * This is just like create_text, but the author of the text is set to * Pers_no 0, to guarantee that the author is anonymous. * * Returns text_no of the created text, or 0 if there was an error. */ extern Text_no create_anonymous_text(const String message, Misc_info_list *misc_l, Aux_item_list *aux) { Text_no text; Text_stat * t_stat; /* CHK_CONNECTION in do_create_text */ text = do_create_text(message, misc_l->no_of_misc, misc_l->misc, aux, TRUE, &t_stat); if (text != 0) { send_async_new_text_old(text, t_stat); send_async_new_text(text, t_stat); } return text; } extern Text_no create_anonymous_text_old(const String message, Misc_info_list *misc_l) { Text_no text; Text_stat * t_stat; /* CHK_CONNECTION in do_create_text */ text = do_create_text(message, misc_l->no_of_misc, misc_l->misc, NULL, TRUE, &t_stat); if (text != 0) { send_async_new_text_old(text, t_stat); send_async_new_text(text, t_stat); } return text; } /* * Generic create_text call. This is used by all the other create_text * calls, old and new, anonymous and not */ static Text_no do_create_text(const String message, u_short no_of_misc, Misc_info *misc, Aux_item_list *aux, Bool anonymous, Text_stat **ret_stat) { Text_no text; Text_stat *t_stat; Bool need_public_jubel = FALSE; CHK_CONNECTION(0); CHK_LOGIN(0); if (no_of_misc > param.max_crea_misc) { err_stat = param.max_crea_misc; kom_errno = KOM_LONG_ARRAY; return 0; } /* Check the length of the text. */ if (s_strlen(message) > param.text_len) { err_stat = param.text_len; kom_errno = KOM_LONG_STR; return 0; } /* Check that the author is allowed to write this text number */ if (ok_to_create_next_text(active_connection, &need_public_jubel) == FALSE) { err_stat = 0; kom_errno = KOM_TEMPFAIL; return 0; } /* Check all misc-items and aux-items */ prepare_aux_item_list(aux, anonymous?0:ACTPERS); if (create_text_check_misc(&no_of_misc, misc, anonymous, need_public_jubel) != OK || text_stat_check_add_aux_item_list(NULL, aux, active_connection) != OK || (text = cached_create_text(message)) == 0) { return 0; } if ((t_stat = cached_get_text_stat(text)) == NULL) { restart_kom("%s.\nText == %lu, kom_errno == %lu, errno == %lu\n", "create_text: can't get text-stat of newly created text", (unsigned long)text, (unsigned long)kom_errno, (unsigned long)errno); } *ret_stat = t_stat; t_stat->author = anonymous?0:ACTPERS; t_stat->creation_time = current_time.tv_sec; t_stat->no_of_lines = count_lines(message); t_stat->no_of_chars = s_strlen(message); if (create_text_add_miscs(text, t_stat, no_of_misc, misc) != OK) { kom_log("ERROR: create_text(): can't add miscs.\n"); return 0; } if (create_text_add_aux(t_stat, text, aux, anonymous?0:ACTPERS) != OK) { kom_log("ERROR: create_text(): can't add aux.\n"); return 0; } if (!anonymous) { l2g_append(&ACT_P->created_texts, l2g_first_appendable_key(&ACT_P->created_texts), text); ACT_P->created_lines += t_stat->no_of_lines; ACT_P->created_bytes += t_stat->no_of_chars; mark_person_as_changed(ACTPERS); } mark_text_as_changed(text); update_stat(STAT_TEXTS, 1); return text; } /* * Delete a text. * * Only a supervisor of the author may delete a text. */ extern Success delete_text(Text_no text_no) { Text_stat *text_s; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_T_STAT(text_s, text_no, FAILURE); if (!is_supervisor(text_s->author, active_connection) && !ENA(wheel, 8) /* OK -- In an RPC call */ && !ENA(admin, 5)) /* OK -- In an RPC call */ { err_stat = text_no; if (text_read_access(active_connection, text_no, text_s)) kom_errno = KOM_NOT_AUTHOR; else kom_errno = KOM_NO_SUCH_TEXT; return FAILURE; } return do_delete_text(text_no, text_s); } /* Return TRUE if ``a'' is greater than ``b'. */ static Bool greater(const struct tm *a, const struct tm *b) { if (a->tm_year < b->tm_year) return FALSE; if (a->tm_year > b->tm_year) return TRUE; if (a->tm_mon < b->tm_mon) return FALSE; if (a->tm_mon > b->tm_mon) return TRUE; if (a->tm_mday < b->tm_mday) return FALSE; if (a->tm_mday > b->tm_mday) return TRUE; if (a->tm_hour < b->tm_hour) return FALSE; if (a->tm_hour > b->tm_hour) return TRUE; if (a->tm_min < b->tm_min) return FALSE; if (a->tm_min > b->tm_min) return TRUE; if (a->tm_sec < b->tm_sec) return FALSE; if (a->tm_sec > b->tm_sec) return TRUE; /* ``a'' is not greater if it is equal to ``b''. */ return FALSE; } /* * Lookup a text according to creation-time. * The text-no of the text created closest before WANTED_TIME is returned. * The returned text is not necessarily readable. */ extern Success get_last_text(struct tm *wanted_time, Text_no *result) { struct tm *texttime; Text_no lower = 0; Text_no higher = query_next_text_num() - 1; Text_stat *text_stat = NULL; Text_no try; Text_no middle; /* * We search for the text in the interval [lower, higher] *(inclusive). Middle is set to the middle(rounded towards * infinity), and we search from there and upward until we find a * text. */ CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); while (lower < higher) { middle = (lower + higher)/2 + 1; /* Binary search */ try = middle; text_stat = NULL; /* FIXME (bug 180): Once there is a more efficient structure that maps Text_nos to the internal cache_node this loop could probably be rewritten in a more efficient way. */ while (text_stat == NULL && try <= higher) text_stat = cached_get_text_stat(try++); if (text_stat == NULL) higher = middle - 1; else { if (active_connection->use_utc) texttime = gmtime(&text_stat->creation_time); else texttime = localtime(&text_stat->creation_time); if (greater(wanted_time, texttime)) lower = try - 1; else higher = middle - 1; } } *result = lower; return OK; } /* * Return next existing text-no, which ACTPERS is allowed to read. */ extern Success find_next_text_no(Text_no start, Text_no *result) { Text_no highest = query_next_text_num(); Text_stat *text_s; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); err_stat = start; while (++start < highest) { text_s = cached_get_text_stat(start); if (text_s != NULL && text_read_access(active_connection, start, text_s) == TRUE) { *result = start; return OK; } } kom_errno = KOM_NO_SUCH_TEXT; return FAILURE; } /* * Return previous existing text-no, which ACTPERS is allowed to read. */ extern Success find_previous_text_no(Text_no start, Text_no *result) { Text_stat *text_s; Text_no next_tno; const Text_no saved_start = start; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); if (start >(next_tno = query_next_text_num())) start = next_tno; while (start-- > 0) { text_s = cached_get_text_stat(start); if (text_s != NULL && text_read_access(active_connection, start, text_s) == TRUE) { *result = start; return OK; } } kom_errno = KOM_NO_SUCH_TEXT; err_stat = saved_start; return FAILURE; } static void send_async_add_recipient(Text_no text_no, const Text_stat *text_s, Conf_no conf_no, enum info_type type) { Connection *cptr; Session_no i = 0; while ((i = traverse_connections(i)) != 0) { cptr = get_conn_by_number(i); if (interested_party(cptr, text_no, text_s) && text_read_access(cptr, text_no, text_s)) { Text_stat copy; filter_secret_info(©, text_s, cptr, TRUE); if (find_recipient(conf_no, ©) != -1) async_new_recipient(cptr, text_no, conf_no, type); } } } /* * Add a recipient to a text. */ extern Success add_recipient(Text_no text_no, Conf_no conf_no, enum info_type type) /* recpt, cc_recpt or bcc_recpt */ { Text_stat *t_stat; Conference *conf_c; int rcpt_index; Conf_no submit_conf; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); /* Get the conference */ GET_C_STAT(conf_c, conf_no, FAILURE); if (!has_access(conf_no, active_connection, read_protected)) { err_stat = conf_no; kom_errno = KOM_UNDEF_CONF; return FAILURE; } /* Get the text */ GET_T_STAT(t_stat, text_no, FAILURE); if (!text_read_access(active_connection, text_no, t_stat) && !ENA(admin, 4)) /* OK -- In an RPC call */ { err_stat = text_no; kom_errno = KOM_NO_SUCH_TEXT; return FAILURE; } rcpt_index = find_recipient(conf_no, t_stat); if (rcpt_index != -1) { /* You cannot add the same conference twice. */ if (t_stat->misc_items[rcpt_index].type == type) { err_stat = conf_no; kom_errno = KOM_ALREADY_RECIPIENT; return FAILURE; } if (type != recpt && type != cc_recpt && type != bcc_recpt) { err_stat = type; kom_errno = KOM_ILLEGAL_INFO_TYPE; return FAILURE; } if (!is_supervisor(t_stat->author, active_connection) && !is_supervisor(conf_no, active_connection) && !is_supervisor_of_sender(t_stat, rcpt_index, active_connection) && !ENA(wheel, 8)) /* OK -- In an RPC call */ { err_stat = conf_no; kom_errno = KOM_PERM; return FAILURE; } /* Change a recpt to a cc_recpt or a cc_recpt to a recpt. The ability to do this was introduced after a request from Lisa Hallingstrom, who wanted to do this repeatedly when managing the conference "Fragor och svar". */ t_stat->misc_items[rcpt_index].type = type; #if 0 /* FIXME (bug 182): This should possibly be done, but differently. ADD_MISC adds things lasts in the misc-info, and that is not the correct thing to do. The change is now performed silently instead. Also note that these fields may already be present... */ if (t_stat->author != ACTPERS) ADD_MISC(t_stat, sent_by, sender, ACTPERS); ADD_MISC(t_stat, sent_at, sent_at, current_time); #endif mark_text_as_changed(text_no); send_async_add_recipient(text_no, t_stat, conf_no, type); return OK; } if (count_recipients(t_stat) >= param.max_recipients) { err_stat = text_no; kom_errno = KOM_RECIPIENT_LIMIT; return FAILURE; } submit_conf = submit_to(conf_no, conf_c); if (submit_conf == 0) { /* Error data set in submit_to */ return FAILURE; } else if (submit_conf != conf_no) { /* Error data not set in submit_to */ err_stat = conf_no; kom_errno = KOM_ACCESS; return FAILURE; } if (!conf_c->type.allow_anon && t_stat->author == 0) { kom_errno = KOM_ANON_REJECTED; err_stat = 0; return FAILURE; } switch (type) { case recpt: case cc_recpt: case bcc_recpt: if (do_add_recipient(text_no, t_stat, conf_no, type) != OK) return FAILURE; break; case comm_to: case comm_in: case footn_to: case footn_in: case loc_no: case rec_time: case sent_by: case sent_at: case unknown_info: /* Fall through */ #ifndef COMPILE_CHECKS default: #endif err_stat = type; kom_errno = KOM_ILLEGAL_INFO_TYPE; return FAILURE; } if (t_stat->author != ACTPERS) ADD_MISC(t_stat, sent_by, sender, ACTPERS); ADD_MISC(t_stat, sent_at, sent_at, current_time.tv_sec); mark_text_as_changed(text_no); send_async_add_recipient(text_no, t_stat, conf_no, type); return OK; } /* * Subtract a recipient from a text. * * This may be done by * a) a supervisor of the author. * b) a supervisor of the recipient. * c) the sender of the text to the recipient */ extern Success sub_recipient(Text_no text_no, Conf_no conf_no) { Text_stat *text_s; Conference *conf_c; int misc_index; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_T_STAT(text_s, text_no, FAILURE); if (!text_read_access(active_connection, text_no, text_s) && !ENA(admin, 4)) /* OK -- In an RPC call */ { err_stat = text_no; kom_errno = KOM_NO_SUCH_TEXT; return FAILURE; } if (!has_access(conf_no, active_connection, read_protected)) { err_stat = conf_no; kom_errno = KOM_UNDEF_CONF; return FAILURE; } GET_C_STAT(conf_c, conf_no, FAILURE); if ((misc_index = find_recipient(conf_no, text_s)) == -1) { err_stat = conf_no; kom_errno = KOM_NOT_RECIPIENT; return FAILURE; } if (!is_supervisor(text_s->author, active_connection) && !is_supervisor(conf_no, active_connection) && !ENA(wheel, 8) /* OK -- In an RPC call */ && !is_supervisor_of_sender(text_s, misc_index, active_connection)) { err_stat = text_no; kom_errno = KOM_PERM; return FAILURE; } return do_sub_recpt(text_no, text_s, conf_no, conf_c, TRUE); } /* Make all checks that are common to add-comment and add-footnote. child is the text that will be a comment or footnote of the parent if the operation is allowed. parent_checker should be either check_comm() or check_footn(). */ static Success check_add_textlink(Text_no child, Text_no parent, Success (*parent_checker)(const Text_stat *), Text_stat **child_p, Text_stat **parent_p) { Text_stat *child_s; Text_stat *parent_s; int misc_index; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); /* FIXME (bug 183, bug 184): The following code can not cope with a text that is a comment/footnote to itself. That is considered to be a bug. Work around it for now, until a proper misc-info-list handling package is written. */ if (child == parent) { kom_errno = KOM_INDEX_OUT_OF_RANGE; err_stat = child; return FAILURE; } GET_T_STAT(child_s, child, FAILURE); if (!text_read_access(active_connection, child, child_s)) { kom_errno = KOM_NO_SUCH_TEXT; err_stat = child; return FAILURE; } GET_T_STAT(parent_s, parent, FAILURE); if (!text_read_access(active_connection, parent, parent_s)) { kom_errno = KOM_NO_SUCH_TEXT; err_stat = parent; return FAILURE; } err_stat = parent; if (parent_checker(parent_s) != OK) return FAILURE; /* Check if already comment/footnote. */ if ((misc_index = find_textlink(child_s, parent)) != -1) { err_stat = child; if (child_s->misc_items[misc_index].type == comm_to) kom_errno = KOM_ALREADY_COMMENT; else kom_errno = KOM_ALREADY_FOOTNOTE; return FAILURE; } *child_p = child_s; *parent_p = parent_s; return OK; } /* * Add a comment-link between two existing texts. */ extern Success add_comment(Text_no child, Text_no parent) { Text_stat *child_s; Text_stat *parent_s; if (check_add_textlink(child, parent, check_comm, &child_s, &parent_s) != OK) return FAILURE; if (do_add_comment(child, child_s, parent, parent_s) != OK) return FAILURE; if (child_s->author != ACTPERS) ADD_MISC(child_s, sent_by, sender, ACTPERS); ADD_MISC(child_s, sent_at, sent_at, current_time.tv_sec); mark_text_as_changed(child); return OK; } /* * Delete a comment-link between two texts. * * This can be done by: * a) a supervisor of the author of the comment. * b) a supervisor of the creator of the comment link. */ extern Success sub_comment(Text_no child, /* 'child' is no longer a comment */ Text_no parent) /* to 'parent' */ { Text_stat *child_s; Text_stat *parent_s; int misc_index; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_T_STAT(child_s, child, FAILURE); GET_T_STAT(parent_s, parent, FAILURE); if ((misc_index = find_textlink(child_s, parent)) == -1 || child_s->misc_items[misc_index].type != comm_to) { err_stat = child; kom_errno = KOM_NOT_COMMENT; return FAILURE; } if (!is_supervisor(child_s->author, active_connection) && !ENA(wheel, 8) /* OK -- In an RPC call */ && !is_supervisor_of_sender(child_s, misc_index, active_connection)) { err_stat = child; kom_errno = KOM_PERM; return FAILURE; } do_sub_comment(child, child_s, parent, parent_s); return OK; } /* * Add a footnote-link between two existing texts. Only the author * may do this. The texts must have the same author. */ extern Success add_footnote(Text_no child, Text_no parent) { Text_stat *child_s; Text_stat *parent_s; if (check_add_textlink(child, parent, check_footn, &child_s, &parent_s) != OK) return FAILURE; if (child_s->author != parent_s->author) { kom_errno = KOM_NOT_AUTHOR; /* check_footn() has already checked that the active person is author of the parent, so it must be the child that is in error. */ err_stat = child; return FAILURE; } if (do_add_footnote(child, child_s, parent, parent_s) != OK) return FAILURE; ADD_MISC(child_s, sent_at, sent_at, current_time.tv_sec); mark_text_as_changed(child); return OK; } /* * Delete a footnote-link between two texts. * Only the author may do this. */ extern Success sub_footnote(Text_no child, /* 'child' is no longer a */ Text_no parent) /* footnote to 'parent' */ { Text_stat *child_s; Text_stat *parent_s; int misc_index; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_T_STAT(child_s, child, FAILURE); GET_T_STAT(parent_s, parent, FAILURE); if ((misc_index = find_textlink(child_s, parent)) == -1 || child_s->misc_items[misc_index].type != footn_to) { err_stat = child; kom_errno = KOM_NOT_FOOTNOTE; return FAILURE; } if (!is_supervisor(child_s->author, active_connection) && !ENA(wheel,8)) /* OK -- In an RPC call */ { err_stat = child; kom_errno = KOM_PERM; return FAILURE; } do_sub_footnote(child, child_s, parent, parent_s); return OK; } /* * Get mapping from Local_text_no to(global) Text_no for part of * a conference. */ extern Success get_map(Conf_no conf_no, Local_text_no first_local_no, unsigned long no_of_texts, L2g_iterator *result) { Conference * conf_c; Local_text_no highest; Local_text_no first_unwanted; Local_text_no res_first; int res_nr; enum access acc; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_C_STAT(conf_c, conf_no, FAILURE); acc = access_perm(conf_no, active_connection, limited); if (acc <= none) { err_stat = conf_no; kom_errno = KOM_UNDEF_CONF; return FAILURE; } if (acc == read_protected) { err_stat = conf_no; kom_errno = KOM_ACCESS; return FAILURE; } highest = l2g_first_appendable_key(&conf_c->texts) - 1; if (first_local_no > highest) { err_stat = first_local_no; kom_errno = KOM_NO_SUCH_LOCAL_TEXT; return FAILURE; } /* Get the lowest existing text, or, if no text exists, the next text number that will be used. */ res_first = l2g_next_key(&conf_c->texts, 0); if (res_first == 0) res_first = l2g_first_appendable_key(&conf_c->texts); /* Start where the user wants to start, unless that is too small. */ res_first = max(res_first, first_local_no); /* Find the endpoint. */ first_unwanted = min(highest+1, first_local_no + no_of_texts); if (first_unwanted >= res_first) res_nr = first_unwanted - res_first; else res_nr = 0; l2gi_searchsome(result, &conf_c->texts, res_first, res_first + res_nr); return OK; } extern Success local_to_global(Conf_no conf_no, Local_text_no first_local_no, unsigned long no_of_texts, Text_mapping *result) { Conference * conf_c; enum access acc; CHK_CONNECTION(FAILURE); if (first_local_no == 0) { err_stat = first_local_no; kom_errno = KOM_LOCAL_TEXT_ZERO; return FAILURE; } if (no_of_texts > 255) { err_stat = 255; kom_errno = KOM_LONG_ARRAY; return FAILURE; } CHK_LOGIN(FAILURE); GET_C_STAT(conf_c, conf_no, FAILURE); acc = access_perm(conf_no, active_connection, limited); if (acc <= none) { err_stat = conf_no; kom_errno = KOM_UNDEF_CONF; return FAILURE; } if (acc == read_protected) { err_stat = conf_no; kom_errno = KOM_ACCESS; return FAILURE; } if (first_local_no >= l2g_first_appendable_key(&conf_c->texts)) { err_stat = first_local_no; kom_errno = KOM_NO_SUCH_LOCAL_TEXT; return FAILURE; } result->first = first_local_no; result->no_of_texts = no_of_texts; result->l2g = &conf_c->texts; return OK; } extern Success local_to_global_reverse(Conf_no conf_no, Local_text_no local_no_ceiling, unsigned long no_of_texts, Text_mapping_reverse *result) { Conference * conf_c; enum access acc; Local_text_no ceiling; CHK_CONNECTION(FAILURE); if (no_of_texts > 255) { err_stat = 255; kom_errno = KOM_LONG_ARRAY; return FAILURE; } CHK_LOGIN(FAILURE); GET_C_STAT(conf_c, conf_no, FAILURE); acc = access_perm(conf_no, active_connection, limited); if (acc <= none) { err_stat = conf_no; kom_errno = KOM_UNDEF_CONF; return FAILURE; } if (acc == read_protected) { err_stat = conf_no; kom_errno = KOM_ACCESS; return FAILURE; } ceiling = l2g_first_appendable_key(&conf_c->texts); if (local_no_ceiling == 0 || local_no_ceiling > ceiling) result->ceiling = ceiling; else result->ceiling = local_no_ceiling; result->no_of_texts = no_of_texts; result->l2g = &conf_c->texts; return OK; } static void send_async_text_aux_changed(Text_no text_no, Text_stat *text_s, unsigned long highest_aux) { Connection *cptr; Session_no i = 0; Aux_item_list copy; while ((i = traverse_connections(i)) != 0) { cptr = get_conn_by_number(i); /* Check the want_async and handshake_ok here to avoid the expensive calls to access_perm and filter_aux_item_list. */ if (cptr->want_async[ay_text_aux_changed] == FALSE) continue; if (!handshake_ok(cptr, 0)) continue; if (!interested_party(cptr, text_no, text_s)) continue; if (!text_read_access(cptr, text_no, text_s)) continue; filter_aux_item_list(&text_s->aux_item_list, ©, cptr); async_text_aux_changed(cptr, text_no, ©, highest_aux); } } extern Success modify_text_info(Text_no text, Number_list *items_to_delete, Aux_item_list *aux) { Text_stat *text_s; unsigned long highest_aux; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); if (items_to_delete->length > param.max_delete_aux) { kom_errno = KOM_LONG_ARRAY; err_stat = param.max_delete_aux; return FAILURE; } if (aux->length > param.max_add_aux) { kom_errno = KOM_LONG_ARRAY; err_stat = param.max_add_aux; return FAILURE; } GET_T_STAT(text_s, text, FAILURE); if (!text_read_access(active_connection, text, text_s)) { err_stat = text; kom_errno = KOM_NO_SUCH_TEXT; return FAILURE; } /* Store the number of the oldest existing aux-item, so that we can send an async message about the new items. */ highest_aux = text_s->highest_aux; /* Check if we may delete and add the items */ prepare_aux_item_list(aux, ACTPERS); if (check_delete_aux_item_list(items_to_delete, &text_s->aux_item_list, text_s->author)!=OK) return FAILURE; delete_aux_item_list(items_to_delete, &text_s->aux_item_list, TEXT_OBJECT_TYPE, text, text_s); if (text_stat_check_add_aux_item_list(text_s, aux, active_connection) != OK) { undelete_aux_item_list(items_to_delete, &text_s->aux_item_list, TEXT_OBJECT_TYPE, text, text_s); return FAILURE; } text_stat_add_aux_item_list(text_s, text, aux, ACTPERS); send_async_text_aux_changed(text, text_s, highest_aux); commit_aux_item_list(&text_s->aux_item_list); mark_text_as_changed(text); return OK; } Success first_unused_text_no(Text_no *result) { CHK_CONNECTION(FAILURE); *result = query_next_text_num(); return OK; } lyskom-server-2.1.2/src/server/membership.c0000664000015100472110000015555607723506630014442 /* * $Id: membership.c,v 0.96 2003/08/28 23:13:06 ceder Exp $ * Copyright (C) 1991-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * membership.c * * All atomic calls that controlls who is a member in what. * (The person/conf relation). */ #ifdef HAVE_CONFIG_H # include #endif #define DEBUG_MARK_AS_READ #include #include #ifdef HAVE_STRING_H # include #endif #include #include "timewrap.h" #include #include #include "misc-types.h" #include "s-string.h" #include "kom-types.h" #include "services.h" #include "server/smalloc.h" #include "lyskomd.h" #include "com.h" #include "async.h" #include "connections.h" #include "internal-connections.h" #include "kom-errno.h" #include "manipulate.h" #include "cache.h" #include "send-async.h" #include "minmax.h" #include "kom-memory.h" #include "param.h" #include "local-to-global.h" #include "server-time.h" #ifdef DEBUG_MARK_AS_READ # include "log.h" # include "ram-output.h" #endif static void set_membership_type_bits(Membership_type *type, Bool invitation, Bool passive, Bool secret, Bool passive_message_invert, Bool reserved2, Bool reserved3, Bool reserved4, Bool reserved5) { type->invitation = invitation; type->passive = passive; type->secret = secret; type->passive_message_invert = passive_message_invert; type->reserved2 = reserved2; type->reserved3 = reserved3; type->reserved4 = reserved4; type->reserved5 = reserved5; } static enum memb_visibility check_unread(Pers_no member) { Person *memb_p; GET_P_STAT(memb_p, member, mv_none); if (memb_p->flags.unread_is_secret) return mv_censor_unread; else return mv_full; } enum memb_visibility membership_visible(const Connection *viewer_conn, Pers_no member, Conf_no conf_no, Membership_type type, Bool is_supervisor_of_member, Bool is_supervisor_of_conf) { enum access ma = error; enum access ca = error; if (ENA_C(viewer_conn, admin, 2) || ENA_C(viewer_conn, wheel, 8)) return mv_full; if (is_supervisor_of_member || (ma = access_perm(member, viewer_conn, unlimited)) >= unlimited) { return mv_full; } if (is_supervisor_of_conf || (ca = access_perm(conf_no, viewer_conn, unlimited)) >= unlimited) { return check_unread(member); } if (ma >= read_protected && ca >= read_protected && !type.secret) return check_unread(member); return mv_none; } /* * Copy all information that ACTPERS is authorized to know about ORIG_P's * membership in all conferences to CENSOR_P. * * This function is used in get_membership(). */ static void copy_public_confs (Connection * conn, /* The connection for which we copy */ Pers_no pers_no, /* The person being censored */ Person * censor_p, /* The censored Person-struct */ Person * orig_p, /* The uncensored Person-struct */ Bool keep_read, Bool want_read, unsigned long max_ranges) { int i; /* Number of mships lefte in ORIG_P */ Membership * censor_m; /* Pointer in CENSOR_P */ Membership * orig_m; /* Pointer in ORIG_P */ /* Copy all information except the secret. */ censor_p->conferences.confs = tmp_alloc( orig_p->conferences.no_of_confs * sizeof(Membership)); censor_p->conferences.no_of_confs = 0; censor_m = censor_p->conferences.confs; orig_m = orig_p->conferences.confs; for ( i = 0; i < orig_p->conferences.no_of_confs; i++, orig_m++ ) { enum memb_visibility vis = membership_visible( conn, pers_no, orig_m->conf_no, orig_m->type, FALSE, FALSE); if (vis > mv_none) { *censor_m = *orig_m; if (!want_read) { if (keep_read) censor_m->skip_read_texts = TRUE; else censor_m->read_ranges = NULL; } else { if (max_ranges > 0 && censor_m->no_of_read_ranges > max_ranges) censor_m->no_of_read_ranges = max_ranges; } if (vis == mv_censor_unread) { censor_m->last_time_read = NO_TIME; censor_m->no_of_read_ranges = 0; censor_m->read_ranges = NULL; } ++censor_m; ++censor_p->conferences.no_of_confs; } } } /* * Change the priority of a certain conference in a person. */ static void do_change_priority (Membership * mship, Conf_no conf_no, Conference * conf_c, unsigned char priority, unsigned short where, Pers_no pers_no, Person * pers_p, Membership_type * type, Bool fake_passive) { Membership tmp_conf; Member *mem; if (priority == 0 && fake_passive) { type->passive = 1; } else { mship->priority = priority; } mship->type = *type; /* Check range of where */ if ( where >= pers_p->conferences.no_of_confs ) { where = pers_p->conferences.no_of_confs - 1; } /* And now move the conference to slot number 'where' */ if ( mship < pers_p->conferences.confs + where ) { tmp_conf = *mship; while ( mship < pers_p->conferences.confs + where) { *mship = *(mship + 1); mship++; } *mship = tmp_conf; } else { tmp_conf = *mship; while ( mship > pers_p->conferences.confs + where) { *mship = *(mship - 1); mship--; } *mship = tmp_conf; } /* Sync the change with the corresponding member list */ mem = locate_member(pers_no, conf_c); if (mem != NULL) { mem->type = *type; mark_conference_as_changed( conf_no ); } mark_person_as_changed( pers_no ); } /* * Insert a rec_time misc item to a text_status. * The item is put at position POS on the list. (0 == first) * Take no action if the misc_item at POS is a rec_time. * This function is only used when a person marks his letters as read. * * Text_stat * text_stat_pointer Textstatus to modify * int pos Where to insert rec_time */ static void do_add_rec_time (Text_stat * text_stat_ptr, int pos) { int i; /* Defensive checks */ if ( pos < 0 || pos > text_stat_ptr->no_of_misc ) { restart_kom("do_add_rec_time() - illegal pos\n"); } /* Check that no rec_time exists */ if ( pos < text_stat_ptr->no_of_misc && text_stat_ptr->misc_items[ pos ].type == rec_time ) { return; } /* Allocate space */ text_stat_ptr->misc_items = srealloc(text_stat_ptr->misc_items, (++(text_stat_ptr->no_of_misc)) * sizeof(Misc_info)); /* Move items. */ for ( i = text_stat_ptr->no_of_misc - 1; i > pos; i-- ) { text_stat_ptr->misc_items[ i ] = text_stat_ptr->misc_items[ i - 1 ]; } /* Set type */ text_stat_ptr->misc_items[ pos ].type = rec_time; /* Set value */ text_stat_ptr->misc_items[ pos ].datum.received_at = current_time.tv_sec; } /* * add_rec_time adds a 'rec_time' misc_item to text number LOC_NO in * conference CONF_C. The item will follow a recpt or cc_recpt to pers_no. * No action is taken if PERS_NO is not a recipient of the text, or the text * no longer exists, or the text has already been received. */ static void add_rec_time(Conference * conf_c, Local_text_no local_no, Pers_no pers_no) { Bool found; Text_no text_no; Text_stat * t_stat; int i; text_no = l2g_lookup(&conf_c->texts, local_no); if ( text_no == 0 ) { return; /* Text is deleted. */ } VOID_GET_T_STAT(t_stat, text_no); /* locate the misc_item which says that ACTPERS is a recipient */ for ( found = FALSE, i = 0; !found && i < t_stat->no_of_misc; i++ ) { switch ( t_stat->misc_items[ i ].type ) { case recpt: case cc_recpt: case bcc_recpt: if ( t_stat->misc_items[ i ].datum.recipient == pers_no ) { do_add_rec_time( t_stat, i + 2 ); /* Add after loc_no */ found = TRUE; } break; case comm_to: case comm_in: case footn_to: case footn_in: case loc_no: case rec_time: case sent_by: case sent_at: break; case unknown_info: default: restart_kom("ERROR: bogus misc_info type detected in text %lu\n", text_no); } } if( found == FALSE ) { kom_log("ERROR: add_rec_time(): found==FALSE\n"); } mark_text_as_changed( text_no); return; } /* * Check if any read_ranges can be extended due to deleted texts. * Merge read_ranges blocks, if possible. * * This is currently only used from mark_as_read(), but it would be * good to have a background task that does this whenever a text has * been deleted. * * Returns non-zero if any change was performed. */ Bool adjust_read(Membership *m, const Conference *conf) { struct read_range *ptr; struct read_range *prev; struct read_range *next; struct read_range *tail; struct read_range *begin; struct read_range *end; Bool change = FALSE; Local_text_no conf_max; /* Highest used local_text_no in conf */ Local_text_no conf_min; /* Lowest used local_text_no in conf */ Local_text_no past_block; /* The next local_text_no after the current block. */ Local_text_no limit; /* If nothing is marked as read, there is nothing to adjust. */ if (m->no_of_read_ranges == 0) return change; /* (conf_min <= x < conf_max) if x is an existing local_text_no */ conf_min = l2g_next_key(&conf->texts, 0); if (conf_min == 0) conf_min = l2g_first_appendable_key(&conf->texts); conf_max = l2g_first_appendable_key(&conf->texts); begin = &m->read_ranges[0]; end = begin + m->no_of_read_ranges; #ifdef DEBUG_MARK_AS_READ /* Check that the items in read_texts really ARE sorted in ascending order. If not, there is probably a bug in this routine or in mark_as_read. */ for (ptr = begin; ptr < end; ptr++) { if (ptr->first_read > ptr->last_read) { kom_log("Bad input to adjust_read. Conference %lu, Priority %lu." " Range %lu-%lu is nonsensical.\n", (unsigned long)m->conf_no, (unsigned long)m->priority, (unsigned long)ptr->first_read, (unsigned long)ptr->last_read); return change; } if (ptr != begin && (ptr-1)->last_read >= ptr->first_read) { kom_log("Bad input to adjust_read. Conference %lu, Priority %lu." " Overlapping ranges: %lu-%lu, %lu-%lu.\n", (unsigned long)m->conf_no, (unsigned long)m->priority, (unsigned long)(ptr-1)->first_read, (unsigned long)(ptr-1)->last_read, (unsigned long)ptr->first_read, (unsigned long)ptr->last_read); return change; } } #endif for (ptr = begin; ptr < end; ptr++) { if (ptr == begin) prev = NULL; else prev = ptr - 1; next = ptr + 1; if (next == end) next = NULL; /* Try to lower first_read. */ while (ptr->first_read > 1 && (prev == NULL || prev->last_read + 1 < ptr->first_read) && l2g_lookup(&conf->texts, ptr->first_read - 1) == 0) { change = TRUE; ptr->first_read--; if (ptr->first_read < conf_min) ptr->first_read = 1; } /* Raise last_read past any deleted texts. */ past_block = l2g_next_key(&conf->texts, ptr->last_read); if (next != NULL) limit = next->first_read; else limit = conf_max; if (past_block == 0 || past_block > limit) past_block = limit; if (ptr->last_read != past_block - 1) { ptr->last_read = past_block - 1; change = TRUE; } } /* Join any ranges that became adjacent. */ tail = begin; for (ptr = begin + 1; ptr < end; ptr++) { if (tail->last_read + 1 == ptr->first_read) tail->last_read = ptr->last_read; else if (++tail != ptr) *tail = *ptr; } if (end != tail + 1) { end = tail + 1; m->no_of_read_ranges = end - begin; m->read_ranges = srealloc( m->read_ranges, m->no_of_read_ranges * sizeof(m->read_ranges[0])); change = TRUE; } #ifndef NDEFENSIVE_CHECKS /* Check that the items in read_texts really ARE sorted in ascending order. If not, there is probably a bug in this routine or in mark_as_read. */ for (ptr = begin; ptr < end; ptr++) { if (ptr->first_read > ptr->last_read) { kom_log("Bug in adjust_read. Conference %lu, Priority %lu." " Range %lu-%lu is nonsensical (fixed).\n", (unsigned long)m->conf_no, (unsigned long)m->priority, (unsigned long)ptr->first_read, (unsigned long)ptr->last_read); ptr->last_read = ptr->first_read; change = TRUE; return change; } if (ptr != begin && ptr->first_read <= (ptr-1)->last_read) { kom_log("Bug in adjust_read. Conference %lu, Priority %lu." " %lu not greater than %lu (fixed).\n", (unsigned long)m->conf_no, (unsigned long)m->priority, (unsigned long)ptr->first_read, (unsigned long)(ptr-1)->last_read); sfree(m->read_ranges); m->read_ranges = NULL; m->no_of_read_ranges = 0; change = TRUE; return change; } } #endif return change; } /* * insert TEXT in the set of read texts in M. * * Returns FAILURE if the text is already read. * * This is only used from mark_as_read(). */ static Success insert_loc_no(Local_text_no text, Membership * m) { struct read_range *lo; struct read_range *hi; struct read_range *mid; struct read_range *begin; struct read_range *end; ptrdiff_t save; struct read_range *gap; struct read_range *move; if (m->no_of_read_ranges == 0) { m->read_ranges = smalloc(sizeof(m->read_ranges[0])); m->no_of_read_ranges = 1; m->read_ranges[0].first_read = text; m->read_ranges[0].last_read = text; return OK; } begin = lo = &m->read_ranges[0]; end = hi = lo + m->no_of_read_ranges; while (hi - lo > 1) { mid = lo + (hi - lo) / 2; if (text < mid->first_read - 1) hi = mid; else if (text > mid->last_read + 1) lo = mid; else { lo = mid; hi = mid + 1; } } if (text >= lo->first_read && text <= lo->last_read) return FAILURE; /* This text was already read. */ if (text == lo->first_read - 1) { if (lo > begin && text == (lo-1)->last_read) return FAILURE; lo->first_read = text; return OK; } if (text == lo->last_read + 1) { if (lo < end && (lo+1) < end && text == (lo+1)->first_read) return FAILURE; lo->last_read = text; return OK; } /* We have to allocate a new block. */ if (lo->last_read < text) lo++; save = lo - begin; m->read_ranges = srealloc( m->read_ranges, ++(m->no_of_read_ranges) * sizeof(m->read_ranges[0])); begin = &m->read_ranges[0]; gap = begin + save; end = begin + m->no_of_read_ranges; for (move = end - 1; move > gap; move--) *move = *(move - 1); gap->first_read = gap->last_read = text; return OK; } static void remove_loc_no(Local_text_no text, Membership * m) { struct read_range *lo; struct read_range *hi; struct read_range *mid; struct read_range *begin; struct read_range *end; ptrdiff_t save; struct read_range *gap; struct read_range *move; if (m->no_of_read_ranges == 0) return; begin = lo = &m->read_ranges[0]; end = hi = lo + m->no_of_read_ranges; while (hi - lo > 1) { mid = lo + (hi - lo) / 2; if (text < mid->first_read - 1) hi = mid; else if (text > mid->last_read + 1) lo = mid; else { lo = mid; hi = mid + 1; } } if (text < lo->first_read || text > lo->last_read) return; /* This text was already unread. */ if (text == lo->first_read) { if (lo->first_read != lo->last_read) { /* Remove the first text of this range. */ lo->first_read++; return; } /* This range contains a single text. Remove the entire range. */ for (move = lo; move < (end-1); move++) *move = *(move+1); m->no_of_read_ranges--; if (m->no_of_read_ranges == 0) { sfree(m->read_ranges); m->read_ranges = NULL; } else m->read_ranges = srealloc( m->read_ranges, m->no_of_read_ranges * sizeof(m->read_ranges[0])); return; } if (text == lo->last_read) { assert(text != lo->first_read); /* Remove the last text of this range. */ lo->last_read--; return; } assert(lo->first_read < text && text < lo->last_read); /* We have to split this block. */ save = lo - begin; m->read_ranges = srealloc( m->read_ranges, ++(m->no_of_read_ranges) * sizeof(m->read_ranges[0])); begin = &m->read_ranges[0]; gap = begin + save; end = begin + m->no_of_read_ranges; for (move = end - 1; move > gap; move--) *move = *(move - 1); assert(gap->first_read == (gap+1)->first_read); assert(gap->last_read == (gap+1)->last_read); assert(text > gap->first_read); assert(text < gap->last_read); gap->last_read = text - 1; (gap+1)->first_read = text + 1; return; } /* * Send a new-membership message to the affected person */ static void send_async_new_membership(Pers_no pers_no, Conf_no conf_no) { Connection *cptr = NULL; Session_no i = 0; while ((i = traverse_connections(i)) != 0) { cptr = get_conn_by_number(i); if (cptr->pers_no == pers_no) { async_new_membership(cptr, pers_no, conf_no); } } } /* * Compute the derived last-text-read value. */ static inline Local_text_no last_text_read(const Membership *mship) { if (mship->no_of_read_ranges == 0) return 0; if (mship->read_ranges[0].first_read > 1) return 0; return mship->read_ranges[0].last_read; } /* * End of static functions */ /* * Functions that are exported to the server. */ /* * Add a member to a conference. All errorchecking should already * be done when this function is called. The person must not already * be a member of the conference. It is _not_ an error to make WHERE bigger * than the number of conferences the person is a member in. */ void do_add_member(Conf_no conf_no, /* Conference to add a new member to. */ Conference * conf_c, /* Conf. status. Must NOT be NULL. */ Pers_no pers_no, /* Person to be added. */ Person * pers_p, /* Pers. status. Must NOT be NULL. */ Pers_no added_by, /* Person doing the adding */ unsigned char priority, /* Prioritylevel to assign to this conf */ unsigned short where, /* Sequence number in the list */ Membership_type * type, /* Type of the membership */ Bool fake_passive ) { Membership * mship; Member * mem; if (fake_passive && priority == 0) { type->passive = 1; } /* First add the conference in the person-struct. * Make room for it. */ pers_p->conferences.confs = srealloc( pers_p->conferences.confs, ++(pers_p->conferences.no_of_confs) * sizeof(Membership)); /* Fill in the room */ /* Find last slot */ mship = pers_p->conferences.confs + pers_p->conferences.no_of_confs - 1 ; /* Move all data beyond WHERE */ while ( mship > pers_p->conferences.confs + where ) { *mship = *(mship - 1); mship--; } init_membership(mship); mship->added_by = added_by; mship->added_at = current_time.tv_sec; mship->conf_no = conf_no; mship->priority = priority; mship->last_time_read = current_time.tv_sec; mship->no_of_read_ranges = 0; mship->read_ranges = NULL; mship->type = *type; mship->skip_read_texts = FALSE; /* Make room for the person in the conference */ conf_c->members.members = srealloc( conf_c->members.members, ++(conf_c->members.no_of_members) * sizeof(Member)); /* New members go to the end of the list */ mem = (conf_c->members.members + conf_c->members.no_of_members - 1); mem->member = pers_no; mem->added_by = added_by; mem->added_at = current_time.tv_sec; mem->type = *type; mark_conference_as_changed( conf_no ); mark_person_as_changed( pers_no ); return; } /* * Send an asynchronous message to person pers_no (if he is logged on) * and tell him that he is no longer a member of conf_no. Also calls * leave_conf(). */ extern void forced_leave_conf(Pers_no pers_no, Conf_no conf_no) { Connection *real_active_connection; Session_no i = 0; real_active_connection = active_connection; while ( (i = traverse_connections(i)) != 0 ) { active_connection = get_conn_by_number(i); if ( active_connection->pers_no == pers_no ) { async_forced_leave_conf(active_connection, conf_no); if ( active_connection->cwc == conf_no ) leave_conf(active_connection); } } active_connection = real_active_connection; } /* * Delete a member from a conference. * No checks are made on the parameters. * The dynamically allocated areas conf_c->members.members and * pers_p->confs are NOT reallocated since they will anyhow sooner or later * be flushed from core. */ Success do_sub_member(Conf_no conf_no, /* Conf to delete member from. */ Conference * conf_c, /* May be NULL */ Member * mbr, /* May be NULL */ Pers_no pers_no, /* Person to be deleted. */ Person * pers_p, /* May be NULL */ Membership * mship) /* Pointer to the persons membership in conf., or NULL if not known. */ { if ( conf_c == NULL ) GET_C_STAT(conf_c, conf_no, FAILURE); if ( pers_p == NULL ) GET_P_STAT(pers_p, pers_no, FAILURE); if ( mship == NULL && (mship = locate_membership(conf_no, pers_p)) == NULL) restart_kom("do_sub_member() - can't find mship\n"); if ( mbr == NULL && (mbr = locate_member(pers_no, conf_c)) == NULL) restart_kom("do_sub_member() - can't find member.\n"); forced_leave_conf(pers_no, conf_no); /* Delete from Person */ sfree(mship->read_ranges); --pers_p->conferences.no_of_confs; while ( mship < pers_p->conferences.confs + pers_p->conferences.no_of_confs ) { *mship = *(mship + 1); ++mship; } /* Delete from Conference */ --conf_c->members.no_of_members; while ( mbr < conf_c->members.members + conf_c->members.no_of_members ) { *mbr = *(mbr + 1); ++mbr; } mark_person_as_changed( pers_no ); mark_conference_as_changed( conf_no ); return OK; } /* * VICTIM is a person or a conference. * Meaning of return values: * unlimited: ACTPERS is supervisor of VICTIM, or ACTPERS is admin, * or ACTPERS is VICTIM * none: VICTIM is secret, and ACTPERS is not a member * member: ACTPERS is a member in VICTIM, but doesn't have unlimited * access. * read_protected: The conference is rd_prot and ACTPERS is not a member. * limited: otherwise. * error: see kom_errno */ static enum access access_perm_helper(Conf_no victim, const Connection *conn, enum access wanted_access) { Conf_type victim_type; int victim_type_known = 0; static int maxwarnings = 10; if (!cached_conf_exists(victim)) { kom_errno = KOM_UNDEF_CONF; err_stat = victim; return error; } if (victim == conn->pers_no) return unlimited; if (ENA_C(conn, admin, 2) || ENA_C(conn, wheel, 8)) return unlimited; if (wanted_access <= limited) { victim_type = cached_get_conf_type(victim); victim_type_known = 1; if (victim_type.secret == 0) { if (victim_type.rd_prot) { if (wanted_access <= read_protected) return read_protected; } else return limited; } } if (is_supervisor(victim, conn)) return unlimited; if (conn->pers_no != 0) { if (conn->person == NULL) { if (maxwarnings > 0) { kom_log("WNG: conn->person unexpectedly NULL in " "access_perm_helper()\n"); if (--maxwarnings == 0) kom_log("WNG: Won't log the above warning any more.\n"); } kom_errno = KOM_INTERNAL_ERROR; err_stat = 0; return error; } /* FIXME (bug 155): no need to call the expensive locate_membership if supervisor(victim) == victim. */ if (locate_membership(victim, conn->person) != NULL) return member; } if (victim_type_known == 0) victim_type = cached_get_conf_type(victim); if (victim_type.secret) return none; if (victim_type.rd_prot) return read_protected; return limited; } enum access access_perm(Conf_no victim, const Connection *viewer_conn, enum access wanted_access) { enum access result; if (wanted_access != read_protected && wanted_access != limited && wanted_access != unlimited) { static int ctr = 0; if (ctr < 10) { kom_log("WNG: access_perm called with wanted_access=%d\n", (int)wanted_access); ctr++; if (ctr == 10) kom_log("WNG: won't log the above warning any more.\n"); } } result = access_perm_helper(victim, viewer_conn, wanted_access); if (wanted_access < result) return wanted_access; else return result; } Bool has_access(Conf_no victim, const Connection *viewer_conn, enum access wanted_access) { return access_perm(victim, viewer_conn, wanted_access) >= wanted_access; } Conf_no filter_conf_no(Conf_no victim, const Connection *viewer_conn) { if (has_access(victim, viewer_conn, read_protected)) return victim; else return 0; } /* * Locate the Member struct in CONF_C for person PERS_NO */ Member * locate_member(Pers_no pers_no, Conference * conf_c) { Member * mbr; int i; for(mbr = conf_c->members.members, i = conf_c->members.no_of_members; i > 0; i--, mbr++) { if ( mbr->member == pers_no ) { return mbr; } } return NULL; } /* * Find the data about PERS_P:s membership in CONF_NO. * Return NULL if not found */ Membership * locate_membership(Conf_no conf_no, const Person *pers_p) { Membership * confp; int i; for(confp = pers_p->conferences.confs, i = pers_p->conferences.no_of_confs; i > 0; i--, confp++) { if ( confp->conf_no == conf_no ) { confp->position = pers_p->conferences.no_of_confs - i; return confp; } } return NULL; } /* * Atomic functions. */ /* * Unsubscribe from a conference. * * You must be supervisor of either conf_no or pers_no to be allowed to * do this. */ extern Success sub_member( Conf_no conf_no, Pers_no pers_no ) { Conference * conf_c; Membership * mship; Person * pers_p; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_C_STAT(conf_c, conf_no, FAILURE); if ((pers_p = cached_get_person_stat(pers_no)) == NULL) { /* If the conference is secret, we have to return an error code for the conference instead of for the person. */ if (!has_access(conf_no, active_connection, read_protected)) { kom_errno = KOM_UNDEF_CONF; err_stat = conf_no; } return FAILURE; } if ((mship = locate_membership(conf_no, pers_p)) == NULL || membership_visible(active_connection, pers_no, conf_no, mship->type, FALSE, FALSE) == mv_none) { /* FIXME (bug 707): If the person is secret, and the viewer has no access to it, we should return KOM_UNDEF_PERS instead of KOM_NOT_MEMBER. */ set_conf_errno(active_connection, conf_no, KOM_NOT_MEMBER); return FAILURE; } if (!is_supervisor(conf_no, active_connection) && !is_supervisor(pers_no, active_connection) && !ENA(wheel,8) /* OK -- In an RPC call */ && !ENA(admin, 4) ) /* OK -- in an RPC call */ { set_conf_errno(active_connection, conf_no, KOM_PERM); return FAILURE; } return do_sub_member(conf_no, conf_c, NULL, pers_no, pers_p, mship); } /* * Add a member to a conference (join a conference) or * Change the priority of a conference. * * Anyone may add anyone as a member as long as the new member is not * secret and the conference is not rd_prot. This might be a bug. * * PRIORITY is the assigned priority for the conference. WHERE says * where on the list the person wants the conference. 0 is first. WHERE * is automatically set to the number of conferences that PERS_NO is member * in if WHERE is too big, so it is not an error to give WHERE == ~0 as * a parameter. * * You can only re-prioritize if you are supervisor of pers_no. */ static Success add_member_common(Conf_no conf_no, Pers_no pers_no, unsigned char priority, unsigned short where, /* Range of where is [0..] */ Membership_type *type, Bool fake_passive ) { Conference * conf_c; Person * pers_p; Membership * mship; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_C_STAT(conf_c, conf_no, FAILURE); GET_P_STAT(pers_p, pers_no, FAILURE); /* Force invitation bit if not adding as admin or supervisor */ if (param.invite_by_default && !is_supervisor(pers_no, active_connection) && !ENA(admin, 2)) /* OK -- Guarded */ { type->invitation = 1; } /* Check if secret membership bit is set and allowed */ if (type->secret && (!param.secret_memberships || conf_c->type.forbid_secret)) { err_stat = 0; kom_errno = KOM_INVALID_MEMBERSHIP_TYPE; return FAILURE; } /* Check access to the conference. We need limited access or more */ if (!has_access(conf_no, active_connection, limited) && !ENA(wheel, 8) ) /* OK -- Guarded */ { err_stat = conf_no; kom_errno = (conf_c->type).secret ? KOM_UNDEF_CONF : KOM_ACCESS; return FAILURE; } /* Is he already a member? */ if ( (mship = locate_membership( conf_no, pers_p )) != NULL) { Bool pers_supervisor; Bool conf_supervisor; pers_supervisor = is_supervisor(pers_no, active_connection); conf_supervisor = is_supervisor(conf_no, active_connection); /* Already a member, but a secret member? */ if (mship->type.secret && !pers_supervisor && !conf_supervisor && !ENA(admin,2) && /* OK -- Guarded */ !ENA(wheel,8)) /* OK -- Guarded */ { /* FIXME (bug 156): This leaks secret information */ /* The person is already a member, but we are not allowed to know this. Pretend that the addition worked, and hope that the user does not double-check */ return OK; } /* He is already a member. Only change the priority. */ if( !pers_supervisor && !ENA(admin,2) && !ENA(wheel, 8) ) { /* Noone else can change one's priorities. */ err_stat = pers_no; kom_errno = KOM_PERM; return FAILURE; } do_change_priority( mship, conf_no, conf_c, priority, where, pers_no, pers_p, type, fake_passive ); } else { if (pers_no != ACTPERS) { kom_log("Person %lu added to conference %lu by %lu.\n", (unsigned long)pers_no, (unsigned long)conf_no, (unsigned long)ACTPERS); } do_add_member(conf_no, conf_c, pers_no, pers_p, ACTPERS, priority, where, type, fake_passive); send_async_new_membership(pers_no, conf_no); } return OK; } extern Success add_member_old(Conf_no conf_no, Pers_no pers_no, unsigned char priority, unsigned short where) { Membership_type type; /* CHK_CONNECTION in add_member_common */ set_membership_type_bits(&type, 0,0,0,0,0,0,0,0); return add_member_common(conf_no, pers_no, priority, where, &type, TRUE); } extern Success add_member(Conf_no conf_no, Pers_no pers_no, unsigned char priority, unsigned short where, /* Range of where is [0..] */ Membership_type *type ) { /* CHK_CONNECTION in add_member_common */ return add_member_common(conf_no, pers_no, priority, where, type, FALSE); } #ifdef DEBUG_MARK_AS_READ static int check_membership(Pers_no pno, const Conference *conf, Membership *mship) { static int log_no = 0; int errors = 0; struct read_range *begin; struct read_range *end; struct read_range *ptr; if (mship->no_of_read_ranges == 0 && mship->read_ranges != NULL) { if (log_no < 80) kom_log("ERROR: check_membership(): (%d): " "no_of_read_ranges == 0 but read_ranges != NULL\n", ++log_no); /* We don't know what it points to, so we dare not free it. */ mship->read_ranges = NULL; errors++; } if (mship->no_of_read_ranges != 0 && mship->read_ranges == NULL) { if (log_no < 80) kom_log("ERROR: check_membership(): (%d): " "no_of_read_ranges == %ld but read_ranges == NULL\n", ++log_no, (long)mship->no_of_read_ranges); mship->no_of_read_ranges = 0; errors++; } if (mship->read_ranges == NULL) return errors; begin = &mship->read_ranges[0]; end = begin + mship->no_of_read_ranges; for (ptr = begin; ptr < end; ptr++) { if (ptr != begin && (ptr-1)->last_read + 1 >= ptr->first_read) { if (log_no < 80) kom_log("ERROR: check_membership(): (%d): " "bad range sequence %lu-%lu, %lu-%lu\n", ++log_no, (unsigned long)(ptr-1)->first_read, (unsigned long)(ptr-1)->last_read, (unsigned long)ptr->first_read, (unsigned long)ptr->last_read); errors++; } if (ptr->first_read > ptr->last_read) { if (log_no < 80) kom_log("ERROR: check_membership(): (%d): bad range %lu-%lu\n", ++log_no, (unsigned long)ptr->first_read, (unsigned long)ptr->last_read); errors++; } } if ((end-1)->last_read >= l2g_first_appendable_key(&conf->texts)) { if (log_no < 80) kom_log("ERROR: check_membership(): (%d): Person %lu has read text" " %lu in conf %lu, which only has %lu texts.\n", log_no, (unsigned long)pno, (unsigned long)(end-1)->last_read, (unsigned long)mship->conf_no, (unsigned long)(l2g_first_appendable_key(&conf->texts)-1)); errors++; } return errors; } static void read_ranges_precondition(Membership *m, Membership *save, const Conference *conf_c, const char *func) { if (check_membership(ACTPERS, conf_c, m) > 0) kom_log("%s(): the above error was detected on entry to me.\n", func); if (m->read_ranges == NULL && m->no_of_read_ranges != 0) { kom_log("%s(): m->read_ranges == NULL && " "m->no_of_read_ranges == %lu (corrected).\n", func, (unsigned long)m->no_of_read_ranges); m->no_of_read_ranges = 0; } *save = *m; if (m->read_ranges != NULL) { save->read_ranges = smalloc(m->no_of_read_ranges * sizeof(save->read_ranges[0])); memcpy(save->read_ranges, m->read_ranges, m->no_of_read_ranges * sizeof(save->read_ranges[0])); } } static int read_ranges_postcondition(Membership *m, Membership *save, const Conference *conf_c, const char *func) { static int log_no = 0; int ret = 0; /* Check that the membership is correct. Otherwise log all info. */ if (check_membership(ACTPERS, conf_c, m) > 0 && log_no < 40) { kom_log("%s(): (%d) Person %lu has a corrupt membership:\n", func, ++log_no, (unsigned long)ACTPERS); kom_log("Dump of data follows: " "\n"); foutput_membership(stderr, save); putc('\n', stderr); foutput_membership(stderr, m); putc('\n', stderr); ret = -1; } sfree(save->read_ranges); return ret; } #endif /* * mark_as_read() is used to tell LysKOM which texts you have read. * You can mark several texts in one chunk, but the chunk should not * be too big to prevent users from having to re-read texts in case of * a server/client/network crash. * * The texts are marked per conference. If there are several recipients * to a text it should be mark_as_read() in all the recipients. * * If conference is ACTPERS mailbox it will add a rec_time item in the * misc_items field. * * It is only possible to mark texts as read in a conference you are * member in. * * Attempts to mark non-existing texts as read are ignored if the text * has existed. If the text has not yet been created KOM_NO_SUCH_LOCAL_TEXT * will be returned in kom_errno. * * If CONFERENCE is the current working conference of ACTPERS, and the * text has not previously been marked as read, ACT_P->read_texts will * be increased. If the client cooperates this will be correct. If the * client change_conference()s to all recipients of a text before * marking it as read the read_texts field will be too big. (If anyone * cares about that, feel free to rewrite this code as long as it * doen't get too CPU-intensive.) */ extern Success mark_as_read (Conf_no conference, const Number_list *texts) { int i; Membership * m; Conference * conf_c; Success retval = OK; Local_text_no lno; #ifdef DEBUG_MARK_AS_READ Membership original; #endif CHK_CONNECTION(FAILURE); if (texts->length > param.mark_as_read_chunk) { kom_errno = KOM_LONG_ARRAY; err_stat = param.mark_as_read_chunk; return FAILURE; } CHK_LOGIN(FAILURE); GET_C_STAT(conf_c, conference, FAILURE); if ((m = locate_membership(conference, ACT_P)) == NULL) { set_conf_errno(active_connection, conference, KOM_NOT_MEMBER); return FAILURE; } #ifdef DEBUG_MARK_AS_READ read_ranges_precondition(m, &original, conf_c, "mark_as_read"); #endif for (i = 0; i < texts->length; i++) { lno = texts->data[i]; if (lno >= l2g_first_appendable_key(&conf_c->texts)) { kom_errno = KOM_NO_SUCH_LOCAL_TEXT; err_stat = i; retval = FAILURE; break; /* Exit for-loop */ } if (lno == 0) { kom_errno = KOM_LOCAL_TEXT_ZERO; err_stat = i; retval = FAILURE; break; /* Exit for-loop */ } } if (retval == OK) { for(i = 0; i < texts->length; i++) { lno = texts->data[i]; /* Is it a letter to ACTPERS? If so, add a rec_time item. */ if (conference == ACTPERS) add_rec_time(conf_c, lno, ACTPERS); /* Update the Membership struct */ if (insert_loc_no(lno, m) == OK && active_connection->cwc == conference) { ++ACT_P->read_texts; } } adjust_read(m, conf_c); mark_person_as_changed(ACTPERS); } #ifdef DEBUG_MARK_AS_READ if (read_ranges_postcondition(m, &original, conf_c, "mark_as_read") < 0) { kom_log("this was triggered by an attempt to mark this as read\n"); fprintf(stderr, "\n%lu { ", (unsigned long)texts->length); for (i = 0; i < texts->length; i++) fprintf(stderr, "\n%lu ", (unsigned long)texts->data[i]); fprintf(stderr, "}\n"); } #endif return retval; } extern Success mark_as_unread(Conf_no conference, Local_text_no lno) { Membership * m; Conference * conf_c; Success retval = OK; #ifdef DEBUG_MARK_AS_READ Membership original; #endif CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_C_STAT(conf_c, conference, FAILURE); if ((m = locate_membership(conference, ACT_P)) == NULL) { set_conf_errno(active_connection, conference, KOM_NOT_MEMBER); return FAILURE; } #ifdef DEBUG_MARK_AS_READ read_ranges_precondition(m, &original, conf_c, "unmark_as_read"); #endif if (lno == 0) { kom_errno = KOM_LOCAL_TEXT_ZERO; err_stat = 0; retval = FAILURE; } else if (lno >= l2g_first_appendable_key(&conf_c->texts)) { kom_errno = KOM_NO_SUCH_LOCAL_TEXT; err_stat = lno; retval = FAILURE; } else { remove_loc_no(lno, m); adjust_read(m, conf_c); mark_person_as_changed(ACTPERS); } #ifdef DEBUG_MARK_AS_READ if (read_ranges_postcondition(m, &original, conf_c, "unmark_as_read") < 0) { kom_log("this was triggered by an attempt to mark %lu as not read\n", (unsigned long)lno); } #endif return retval; } static Success check_range_list(const struct read_range_list *read_ranges) { Local_text_no last = 0; unsigned short i; if (read_ranges->length > param.max_read_ranges) { kom_errno = KOM_LONG_ARRAY; err_stat = param.max_read_ranges; return FAILURE; } for (i = 0; i < read_ranges->length; i++) { if (read_ranges->ranges[i].first_read > read_ranges->ranges[i].last_read) { kom_errno = KOM_INVALID_RANGE; err_stat = i; return FAILURE; } if (read_ranges->ranges[i].first_read <= last) { if (read_ranges->ranges[i].first_read == 0) kom_errno = KOM_LOCAL_TEXT_ZERO; else kom_errno = KOM_INVALID_RANGE_LIST; err_stat = i; return FAILURE; } last = read_ranges->ranges[i].last_read; } return OK; } Success set_read_ranges(Conf_no conference, const struct read_range_list *read_ranges) { Membership * m; Conference * conf_c; Success retval = OK; #ifdef DEBUG_MARK_AS_READ Membership original; #endif CHK_CONNECTION(FAILURE); if (check_range_list(read_ranges) == FAILURE) return FAILURE; CHK_LOGIN(FAILURE); GET_C_STAT(conf_c, conference, FAILURE); if ((m = locate_membership(conference, ACT_P)) == NULL) { set_conf_errno(active_connection, conference, KOM_NOT_MEMBER); return FAILURE; } #ifdef DEBUG_MARK_AS_READ read_ranges_precondition(m, &original, conf_c, "set_read_ranges"); #endif if (read_ranges->length == 0) { if (m->no_of_read_ranges != 0) { sfree(m->read_ranges); m->read_ranges = NULL; m->no_of_read_ranges = 0; mark_person_as_changed(ACTPERS); } } else if (read_ranges->ranges[read_ranges->length-1].last_read >= l2g_first_appendable_key(&conf_c->texts)) { kom_errno = KOM_NO_SUCH_LOCAL_TEXT; err_stat = read_ranges->ranges[read_ranges->length-1].last_read; retval = FAILURE; } else { if (m->no_of_read_ranges != read_ranges->length) { m->no_of_read_ranges = read_ranges->length; m->read_ranges = srealloc( m->read_ranges, m->no_of_read_ranges * sizeof(m->read_ranges[0])); } memcpy(m->read_ranges, read_ranges->ranges, m->no_of_read_ranges * sizeof(m->read_ranges[0])); adjust_read(m, conf_c); mark_person_as_changed(ACTPERS); } #ifdef DEBUG_MARK_AS_READ read_ranges_postcondition(m, &original, conf_c, "set_read_ranges"); #endif return retval; } /* * Ask what conferences a person is a member of. */ static Success do_get_membership(Pers_no pers_no, unsigned short first, unsigned short no_of_confs, Bool keep_ranges, Bool want_read_ranges, unsigned long max_ranges, Membership_list *memberships) { Person * p_orig; Person temp_pers; enum access acc; int i; CHK_CONNECTION(FAILURE); CHK_LOGIN (FAILURE); GET_P_STAT (p_orig, pers_no, FAILURE); acc = access_perm(pers_no, active_connection, unlimited); if (acc == error) return FAILURE; if (acc == none) { err_stat = pers_no; kom_errno = KOM_UNDEF_PERS; return FAILURE; } /* Make a copy of the struct. */ temp_pers = *p_orig; /* Delete all secret and filtered information. */ if ( acc != unlimited ) { copy_public_confs (active_connection, pers_no, &temp_pers, p_orig, keep_ranges, want_read_ranges, max_ranges); } else if (!want_read_ranges || max_ranges != 0) { /* Delete info about read texts. */ temp_pers.conferences.confs = tmp_alloc(temp_pers.conferences.no_of_confs * sizeof(Membership)); memcpy(temp_pers.conferences.confs, p_orig->conferences.confs, (temp_pers.conferences.no_of_confs * sizeof(Membership) )); if (!want_read_ranges) { for (i = 0; i < temp_pers.conferences.no_of_confs; i++) if (keep_ranges) temp_pers.conferences.confs[i].skip_read_texts = TRUE; else temp_pers.conferences.confs[i].read_ranges = NULL; } else { assert(max_ranges != 0); for (i = 0; i < temp_pers.conferences.no_of_confs; i++) if (temp_pers.conferences.confs[i].no_of_read_ranges > max_ranges) { temp_pers.conferences.confs[i].no_of_read_ranges = max_ranges; } } } *memberships = temp_pers.conferences; if ( first >= memberships->no_of_confs ) { err_stat = first; kom_errno = KOM_INDEX_OUT_OF_RANGE; return FAILURE; } memberships->confs += first; memberships->no_of_confs = min( memberships->no_of_confs - first, no_of_confs); for (i = 0; i < memberships->no_of_confs; i++) { memberships->confs[i].position = first + i; } return OK; } extern Success get_membership_old (Pers_no pers_no, unsigned short first, unsigned short no_of_confs, Bool want_read_texts, Membership_list * memberships ) { Success result; long i; CHK_BOOL(want_read_texts, FAILURE); /* CHK_CONNECTION in do_get_membership */ result = do_get_membership (pers_no, first, no_of_confs, TRUE, want_read_texts, 0, memberships ); if (result == OK) { /* Munge passive conferences */ for (i = 0; i < memberships->no_of_confs; i++) { if (memberships->confs[i].type.passive) { memberships->confs[i].priority = 0; } } } return result; } extern Success get_membership_10(Pers_no pers_no, unsigned short first, unsigned short no_of_confs, Bool want_read_texts, Membership_list *memberships) { CHK_BOOL(want_read_texts, FAILURE); /* CHK_CONNECTION in do_get_membership */ return do_get_membership (pers_no, first, no_of_confs, TRUE, want_read_texts, 0, memberships); } extern Success get_membership(Pers_no pers_no, unsigned short first, unsigned short no_of_confs, Bool want_read_ranges, unsigned long max_ranges, Membership_list * memberships) { CHK_BOOL(want_read_ranges, FAILURE); /* CHK_CONNECTION in do_get_membership */ return do_get_membership (pers_no, first, no_of_confs, FALSE, want_read_ranges, max_ranges, memberships); } /* * first starts at 0. */ static Success do_get_members(Conf_no conf_no, unsigned short first, unsigned short no_of_members, Member_list *members) { Conference *conf_c; enum access acc; unsigned long src; unsigned long dst; Bool is_supervisor_of_conf; CHK_CONNECTION(FAILURE); GET_C_STAT(conf_c, conf_no, FAILURE); acc = access_perm(conf_no, active_connection, read_protected); if (acc == error) return FAILURE; if (acc == none) { err_stat = conf_no; kom_errno = KOM_UNDEF_CONF; return FAILURE; } if (first >= (conf_c->members).no_of_members) { err_stat = first; kom_errno = KOM_INDEX_OUT_OF_RANGE; return FAILURE; } *members = conf_c->members; members->members += first; members->no_of_members = min(no_of_members, members->no_of_members - first); members->members = tmp_alloc(members->no_of_members * sizeof(Member)); is_supervisor_of_conf = is_supervisor(conf_no, active_connection); for (src = first, dst = 0; dst < members->no_of_members; src++, dst++) { const Member *current = &conf_c->members.members[src]; if (membership_visible(active_connection, current->member, conf_no, current->type, FALSE, is_supervisor_of_conf) > mv_none) { members->members[dst] = *current; } else { init_member(&members->members[dst]); members->members[dst].type.secret = 1; } } return OK; } extern Success get_members (Conf_no conf_no, unsigned short first, unsigned short no_of_members, Member_list *members ) { /* CHK_CONNECTION in do_get_members */ return do_get_members(conf_no, first, no_of_members, members); } extern Success get_members_old (Conf_no conf_no, unsigned short first, unsigned short no_of_members, Member_list * members) { /* CHK_CONNECTION in do_get_members */ return do_get_members (conf_no, first, no_of_members, members); } /* * Get a list of all conferences where it is possible that a person has * unread articles. */ Success get_unread_confs(Pers_no pers_no, Conf_no_list *result) { Person *pers_p; const Membership *confs; const Membership *end; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_P_STAT(pers_p, pers_no, FAILURE); result->conf_nos = tmp_alloc (pers_p->conferences.no_of_confs * sizeof(Conf_no)); result->no_of_confs = 0; end = &pers_p->conferences.confs[pers_p->conferences.no_of_confs]; for (confs = pers_p->conferences.confs; confs < end; confs++) { Conf_no conf_no = confs->conf_no; if (confs->type.passive == 0 && (last_text_read(confs) < cached_get_highest_local_no(conf_no)) && membership_visible(active_connection, pers_no, conf_no, confs->type, FALSE, FALSE) > mv_none) { result->conf_nos[result->no_of_confs++] = conf_no; } } return OK; } /* * Tell the server that I want to mark/unmark texts as read so that I * get (approximately) no_of_unread unread texts in conf_no. */ extern Success set_unread (Conf_no conf_no, Text_no no_of_unread) { Membership *mship; Conference *conf_c; Local_text_no highest; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_C_STAT(conf_c, conf_no, FAILURE); if ( (mship = locate_membership(conf_no, ACT_P)) == NULL ) { err_stat = conf_no; kom_errno = KOM_NOT_MEMBER; return FAILURE; } highest = l2g_first_appendable_key(&conf_c->texts) - 1; if (highest > no_of_unread) { mship->no_of_read_ranges = 1; mship->read_ranges = srealloc(mship->read_ranges, 1 * sizeof(mship->read_ranges[0])); mship->read_ranges[0].first_read = 1; mship->read_ranges[0].last_read = highest - no_of_unread; } else { sfree(mship->read_ranges); mship->read_ranges = NULL; mship->no_of_read_ranges = 0; } mark_person_as_changed(ACTPERS); return OK; } /* * Tell the server that I want to mark/unmark texts as read so that * last_read is the last read text in conf_no. */ extern Success set_last_read (Conf_no conf_no, Local_text_no last_read) { Membership *mship; Conference *conf_c; Local_text_no last; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_C_STAT(conf_c, conf_no, FAILURE); if ( (mship = locate_membership(conf_no, ACT_P)) == NULL ) { err_stat = conf_no; kom_errno = KOM_NOT_MEMBER; return FAILURE; } last = l2g_first_appendable_key(&conf_c->texts) - 1; if (last_read > last) last_read = last; if (last_read > 0) { mship->no_of_read_ranges = 1; mship->read_ranges = srealloc(mship->read_ranges, 1 * sizeof(mship->read_ranges[0])); mship->read_ranges[0].first_read = 1; mship->read_ranges[0].last_read = last_read; } else { sfree(mship->read_ranges); mship->read_ranges = NULL; mship->no_of_read_ranges = 0; } mark_person_as_changed(ACTPERS); return OK; } extern Success set_membership_type(Pers_no pers_no, Conf_no conf_no, Membership_type *type) { Conference *conf_c; Person *pers_p; Membership *membership; Member *mbr; enum access acc; /* Check for logon */ CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); /* Find the conference and person in question */ GET_C_STAT(conf_c, conf_no, FAILURE); /* Make sure that ACTPERS may know about conf */ acc = access_perm(conf_no, active_connection, read_protected); if (acc == error) { return FAILURE; } if (acc == none) { err_stat = conf_no; kom_errno = KOM_UNDEF_CONF; return FAILURE; } GET_P_STAT(pers_p, pers_no, FAILURE); /* Check that ACTPERS may modify memberships of person */ acc = access_perm(pers_no, active_connection, unlimited); if (acc != unlimited && !ENA(wheel, 8) && /* OK -- In an RPC call */ !ENA(admin, 6)) /* OK -- In an RPC call */ { err_stat = pers_no; kom_errno = conf_c->type.secret ? KOM_UNDEF_CONF : KOM_PERM; return FAILURE; } /* Find person's membership in the conference */ membership = locate_membership(conf_no, pers_p); if (membership == NULL) { err_stat = conf_no; kom_errno = KOM_NOT_MEMBER; return FAILURE; } /* Find entry in conference's member list */ mbr = locate_member(pers_no, conf_c); if (mbr == NULL) { /* FIXME (bug 158): If this happens we should do something more drastic since it indicates that the database is FUBAR. The problem is that the member list and the membership list are not in sync. We could add the membership record. */ kom_log("Membership and member record mismatch for pers %lu" " in conf %lu\n", (unsigned long)pers_no, (unsigned long)conf_no); kom_log("You should run dbck\n"); err_stat = conf_no; kom_errno = KOM_NOT_MEMBER; return FAILURE; } /* Check type restrictions */ if ((type->secret && !param.secret_memberships) || (type->secret && conf_c->type.forbid_secret) || (!param.allow_reinvite && type->invitation && !membership->type.invitation)) { err_stat = 0; kom_errno = KOM_INVALID_MEMBERSHIP_TYPE; return FAILURE; } /* Modify member and membership */ membership->type = *type; mbr->type = *type; /* Mark the conference and person as changed */ mark_conference_as_changed(conf_no); mark_person_as_changed(pers_no); /* Return success */ return OK; } lyskom-server-2.1.2/src/server/person.c0000664000015100472110000007020607721716127013603 /* * $Id: person.c,v 0.86 2003/08/23 16:38:15 ceder Exp $ * Copyright (C) 1991-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * person.c * * All atomic calls that deals with persons. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #ifdef HAVE_STDLIB_H # include #endif #ifdef HAVE_STRING_H # include #endif #include "timewrap.h" #ifdef HAVE_UNISTD_H # include /* for crypt() on Linux */ #endif #include #include #ifdef HAVE_CRYPT_H # include #endif #include "misc-types.h" #include "s-string.h" #include "kom-types.h" #include "services.h" #include "com.h" #include "async.h" #include "connections.h" #include "kom-errno.h" #include "manipulate.h" #include "string-malloc.h" #include "debug.h" #include "cache.h" #include "server/smalloc.h" #include "kom-config.h" #include "log.h" #include "minmax.h" #include "lyskomd.h" #include "param.h" #include "aux-items.h" #include "local-to-global.h" #include "kom-memory.h" #include "server-time.h" #include "send-async.h" #include "stats.h" BUGDECL; /* * Static functions. */ static Bool legal_passwd(const String pwd) { int i; for (i = 0; i < s_strlen(pwd); i++) if (pwd.string[i] == '\0') return FALSE; return TRUE; } static Success do_set_passwd( Password pwd, const String new_pwd) { #ifdef ENCRYPT_PASSWORDS char salt[3]; static char crypt_seed[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./"; char *password; if ( !legal_passwd(new_pwd) ) return FAILURE; salt[0] = crypt_seed [rand() % (sizeof (crypt_seed) - 1)]; salt[1] = crypt_seed [rand() % (sizeof (crypt_seed) - 1)]; salt[2] = '\0'; password = s_crea_c_str(new_pwd); if (password == NULL) return FAILURE; else { strcpy((char *)pwd, (const char *)crypt(password, salt)); string_free(password); return OK; } #else /* Compatibility mode... */ if ( !legal_passwd(new_pwd) ) return FAILURE; *pwd++ = new_pwd.len; /* Indeed too easy crypt... */ strncpy(pwd, (const char *)new_pwd.string, min( PASSWD_LEN-1, new_pwd.len )); return OK; #endif } /* * Mark a text. No check is done if pers_p is really allowed to mark it. * This function can mark a text with mark_type == 0. If a previous mark * existed it is changed to the given mark_type. */ static Success do_mark_text(Pers_no pers_no, Person *pers_p, /* May be NULL */ Text_no text_no, Text_stat *text_s, /* May be NULL */ u_char mark_type) { Mark *markp; Mark *old_mark = NULL; int i; if ( pers_p == NULL ) GET_P_STAT(pers_p, pers_no, FAILURE); /* Locate the mark. */ for ( i = pers_p->marks.no_of_marks, markp = pers_p->marks.marks; i > 0 && old_mark == NULL; i--, markp++ ) { if ( markp->text_no == text_no ) old_mark = markp; } if (old_mark != NULL) { /* Change marktype of an already marked text. (No need to check that the text exists). */ BUG(("do_mark_text(): Change type of mark.\n")); old_mark->mark_type = mark_type; mark_person_as_changed(pers_no); } else { /* A new mark. Check that the text exists. */ BUG(("do_mark_text(): new mark.\n")); if ( text_s == NULL ) GET_T_STAT(text_s, text_no, FAILURE); if (text_s->no_of_marks >= param.max_marks_text || pers_p->marks.no_of_marks >= param.max_marks_person) { err_stat = text_no; kom_errno = KOM_MARK_LIMIT; return FAILURE; } text_s->no_of_marks++; mark_text_as_changed(text_no); pers_p->marks.marks = srealloc(pers_p->marks.marks, ++pers_p->marks.no_of_marks * sizeof(Mark)); pers_p->marks.marks[pers_p->marks.no_of_marks - 1].text_no = text_no; pers_p->marks.marks[pers_p->marks.no_of_marks - 1].mark_type = mark_type; mark_person_as_changed(pers_no); } return OK; } /* Unmark a text. Returns a failure if the text was not marked. */ static Success do_unmark_text(Pers_no pers_no, Person *pers_p, /* May be NULL */ Text_no text_no, Text_stat *text_s) /* May be NULL */ { Mark *markp; Mark *old_mark = NULL; int i; if ( pers_p == NULL ) GET_P_STAT(pers_p, pers_no, FAILURE); /* Locate the mark. */ for ( i = pers_p->marks.no_of_marks, markp = pers_p->marks.marks; i > 0 && old_mark == NULL; i--, markp++ ) { if ( markp->text_no == text_no ) old_mark = markp; } if (old_mark != NULL) { /* Delete this mark. */ BUG(("do_unmark_text(): Delete mark.\n")); while ( old_mark < ( pers_p->marks.marks + pers_p->marks.no_of_marks - 1 )) { *old_mark = *(old_mark + 1); old_mark++; } pers_p->marks.no_of_marks--; mark_person_as_changed(pers_no); /* ...and don't forget to decrease the ref_cnt in the text_stat... */ if ( (text_s = cached_get_text_stat(text_no)) != NULL ) { if ( text_s->no_of_marks == 0 ) { kom_log("WNG: do_unmark_text(): Text %lu has no_of_marks==0," " but person %d had marked the text.\n", (unsigned long)text_no, pers_no); } else { text_s->no_of_marks--; mark_text_as_changed(text_no); } } /* ...but it is not an error if someone has deleted the text. */ } else { /* An attempt to delete a non-existent mark. */ BUG(("do_unmark_text(): delete non-existent mark.\n")); err_stat = text_no; kom_errno = KOM_NOT_MARKED; return FAILURE; } return OK; } /* * Change user_area of a person. If text_no is 0, there will be * no user_area. */ static Success do_set_user_area(Pers_no pers_no, Person * pers_p, /* May be NULL */ Text_no new_area) { Text_no old_area; Text_stat *old_stat; Text_stat *new_stat = NULL; /* To stop gcc complaining. */ /* Check that the new user_area exists before deleting the old*/ if (new_area != 0) { GET_T_STAT(new_stat, new_area, FAILURE); if (!text_read_access(active_connection, new_area, new_stat) && !ENA(admin, 2)) /* OK -- In an RPC call */ { kom_errno = KOM_NO_SUCH_TEXT; err_stat = new_area; return FAILURE; } if (new_stat->no_of_marks >= param.max_marks_text) { kom_log("LIMIT: set_user_area(%d, %lu): " "New user_area's mark count (%d) > %d.\n", pers_no, (unsigned long)new_area, new_stat->no_of_marks, param.max_marks_text); err_stat = new_area; kom_errno = KOM_MARK_LIMIT; return FAILURE; } } if (pers_p == NULL) GET_P_STAT(pers_p, pers_no, FAILURE); /* Unmark the previous user_area if it exists. */ old_area = pers_p->user_area; if (old_area != 0 && (old_stat = cached_get_text_stat(old_area)) != NULL) { if (old_stat->no_of_marks > 0) { --old_stat->no_of_marks; mark_text_as_changed(old_area); } else { kom_log("ERROR: set_user_area(%d, %lu): " "Old user_area %lu unmarked.\n", pers_no, (unsigned long)new_area, (unsigned long)old_area); } } /* Mark the new user_area */ if (new_area != 0) { ++new_stat->no_of_marks; mark_text_as_changed(new_area); } pers_p->user_area = new_area; mark_person_as_changed(pers_no); if (old_area != new_area) async_new_user_area(pers_no, old_area, new_area); return OK; } /* * End of static functions. */ /* * Functions that are exported to the server. */ /* * Delete a person. (The mailbox is not deleted). */ Success do_delete_pers (Pers_no pers_no) { Person * pers_p; int i; GET_P_STAT(pers_p, pers_no, FAILURE); /* Cancel membership in all confs. */ /* Note that because of the way do_sub_member is written the */ /* loop must be executed this way. */ for ( i = pers_p->conferences.no_of_confs - 1; i >= 0; i-- ) { if ( do_sub_member( pers_p->conferences.confs[ i ].conf_no, NULL, NULL, pers_no, pers_p, pers_p->conferences.confs + i) != OK) { kom_log("ERROR: do_delete_pers(): can't sub_member\n"); } } for ( i = pers_p->marks.no_of_marks; i > 0; i-- ) { if ( do_unmark_text(pers_no, pers_p, pers_p->marks.marks[0].text_no, NULL) != OK ) { kom_log("WNG: do_delete_pers(): can't unmark text %lu (i == %d)\n", (unsigned long)pers_p->marks.marks[0].text_no, i); } } if ( do_set_user_area(pers_no, pers_p, 0) != OK ) { kom_log("WNG: do_delete_pers(): can't unmark user_area\n"); } s_clear( &pers_p->username ); l2g_clear(&pers_p->created_texts); cached_delete_person(pers_no); update_stat(STAT_PERSONS, -1); /* ASYNC */ return OK; } /* * Check a password */ Success chk_passwd (Password pwd, const String try) { #ifdef ENCRYPT_PASSWORDS char *c_try; c_try = s_crea_c_str(try); if (c_try == NULL) return FAILURE; if (strcmp ((const char *)pwd, (const char *)crypt(c_try, (const char *)pwd)) != 0) { string_free(c_try); return FAILURE; } else { string_free(c_try); return OK; } #else int i; if ( try.len != *pwd ) return FAILURE; for ( i = 0; i < try.len; i++ ) if ( pwd[ i + 1 ] != try.string[ i ] ) return FAILURE; return OK; #endif } /* * Mark a text. * * If the you already have marked the text the mark-type will be changed. * If mark_type == 0 the mark will be deleted. You can only mark texts * that you are allowed to read. You are always allowed to read all * texts that you have marked even if you are no longer a recipient * of the text. */ extern Success mark_text_old(Text_no text_no, u_char mark_type) { /* CHK_CONNECTION in mark_text and unmark_text */ if (mark_type == 0) return unmark_text(text_no); else return mark_text(text_no, mark_type); } extern Success mark_text(Text_no text_no, /* Will fail if the user is not */ u_char mark_type) /* allowed to read the text. */ { Text_stat *text_s = NULL; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); /* Check that the user is allowed to read the text. */ GET_T_STAT(text_s, text_no, FAILURE); if ( !text_read_access(active_connection, text_no, text_s) ) { err_stat = text_no; kom_errno = KOM_NO_SUCH_TEXT; return FAILURE; } BUG(("Person %d markerar text %lu med typ %d\n", ACTPERS, text_no, mark_type)); return do_mark_text(ACTPERS, ACT_P, text_no, text_s, mark_type); } extern Success unmark_text(Text_no text_no) { Text_stat *text_s = NULL; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); BUG(("Person %d avmarkerar text %lu\n", ACTPERS, text_no)); return do_unmark_text(ACTPERS, ACT_P, text_no, text_s); } /* * Create a new person. * * If parameter ``Anyone can create new persons'' is true * anyone can create themself. Otherwise you must be logged in to * create a new person, and you must have the ``create_pers'' bit * set, or ``Anyone can create_new_persons'' must be set. * * If you are not logged in an auto-login as the created person is * performed. (This is so that it is impossible to create a million * persons (and so destroy the database) anonymously. This way it will * at least be possible to see from which machine the attack came). * * If you are logged in you will be supervisor and creator of the new * person, otherwise the new person will be supervisor and creator. * * The new person will be rd_prot, but not secret. He will have no * privileges, except maybe change_name (if ``Default change name * capability'' is true). * * This function returns the Pers_no of the new person, or 0 if an error * occured. (0 is an illegal Pers_no). */ static Pers_no create_person_generic ( const String name, const String passwd, Aux_item_list *conf_aux, Personal_flags flags, Bool do_auto_login ) { Pers_no new_user; Conference * mailbox; Person * pers_p; Membership_type mship_type; CHK_CONNECTION(0); if (ACTPERS == 0) { if (!param.create_person_before_login && ACTPERS == 0 ) { err_stat = 0; kom_errno = KOM_LOGIN; return 0; } } else { if (param.anyone_can_create_new_persons == FALSE && !HAVE_PRIV(ACT_P, create_pers)) { err_stat = 0; kom_errno = KOM_PERM; return 0; } } if ( !legal_name( name ) ) { /* kom_errno will be set by legal_name(). */ return 0; } if ( !unique_name( name, 0 ) ) { err_stat = 0; kom_errno = KOM_PERS_EXISTS; return 0; } if ( !legal_passwd( passwd ) ) { err_stat = 0; kom_errno = KOM_PWD; return 0; } new_user = cached_create_conf( name ); if (new_user == 0) { /* kom_errno and err_stat set in cached_create_conf */ kom_log("ERROR: Couldn't create person. Too many conferences.\n"); return 0; } if ( (mailbox = cached_get_conf_stat( new_user ) ) == NULL) { restart_kom("create_person() - can't get conf_stat"); } mailbox->creator = ACTPERS ? ACTPERS : new_user; mailbox->creation_time = current_time.tv_sec; mailbox->presentation = 0; /* No presentation yet */ mailbox->supervisor = ACTPERS ? ACTPERS : new_user; mailbox->permitted_submitters = 0; mailbox->super_conf = ACTPERS; mailbox->type.rd_prot = 1; mailbox->type.original = 0; mailbox->type.secret = 0; mailbox->type.letter_box = 1; mailbox->type.allow_anon = 1; mailbox->type.forbid_secret = 0; mailbox->type.reserved2 = 0; mailbox->type.reserved3 = 0; mailbox->last_written = mailbox->creation_time; mailbox->msg_of_day = 0; mailbox->nice = param.default_nice; mailbox->keep_commented = param.default_keep_commented; mark_conference_as_changed (new_user); /* allocate Person */ if ( cached_create_person( new_user ) == FAILURE ) { cached_delete_conf( new_user ); /* FIXME (bug 159): The next line will call restart_kom(). */ mark_conference_as_changed(new_user); return 0; } if ( ( pers_p = cached_get_person_stat( new_user )) == NULL ) { cached_delete_conf( new_user ); /* FIXME (bug 159): The next line will call restart_kom(). */ mark_conference_as_changed(new_user); restart_kom("create_person() - can't get pers_stat"); } /* Fill in Person */ if ( do_set_passwd( pers_p->pwd, passwd) != OK ) restart_kom("create_person(): can't set passwd\n"); pers_p->privileges.change_name = param.default_change_name; pers_p->flags = flags; mark_person_as_changed( new_user ); mship_type.invitation = 0; mship_type.passive = 0; mship_type.secret = 0; mship_type.passive_message_invert = 0; mship_type.reserved2 = 0; mship_type.reserved3 = 0; mship_type.reserved4 = 0; mship_type.reserved5 = 0; do_add_member( new_user, mailbox, new_user, pers_p, ACTPERS ? ACTPERS : new_user, UCHAR_MAX, 0, &mship_type, FALSE ); prepare_aux_item_list(conf_aux, new_user); if (conf_stat_check_add_aux_item_list(mailbox, new_user, conf_aux, active_connection, TRUE) != OK) { /* FIXME (bug 160): Conf_no leak: We create a person, check the aux-items, determine that the aux-items are bogus, and immediately delete the person. This leaks a conference number. We can live with that, but it isn't pretty. */ cached_delete_conf(new_user); cached_delete_person(new_user); return 0; } conf_stat_add_aux_item_list(mailbox, new_user, conf_aux, new_user); mark_conference_as_changed(new_user); if ( ACTPERS ) { ACT_P->created_persons++; mark_person_as_changed( ACTPERS ); } else if (do_auto_login) { /* Auto login, always visible */ login (new_user, passwd, FALSE); } update_stat(STAT_CONFS, 1); update_stat(STAT_PERSONS, 1); return new_user; } extern Pers_no create_person_old(const String name, const String passwd) { Personal_flags flags; /* CHK_CONNECTION in create_person_generic */ init_personal_flags(&flags); return create_person_generic(name, passwd, NULL, flags, TRUE); } extern Pers_no create_person(const String name, const String passwd, Personal_flags flags, Aux_item_list *conf_aux) { Pers_no pers; /* CHK_CONNECTION in create_person_generic */ pers = create_person_generic(name, passwd, conf_aux, flags, FALSE); if (pers != 0) { /* FIXME (bug 909): Send asynch message */ } return pers; } /* * Get the person status of PERSON. */ extern Success get_person_stat (Pers_no person, Person * result) { Person *p_orig; enum access acc; CHK_CONNECTION(FAILURE); GET_P_STAT(p_orig, person, FAILURE); acc = access_perm(person, active_connection, unlimited); if ( acc == error ) return FAILURE; if ( acc <= none ) { err_stat = person; kom_errno = KOM_UNDEF_PERS; return FAILURE; } *result = *p_orig; /* Make a copy of the struct. */ /* The user area is normally secret. */ if( acc != unlimited ) result->user_area = 0; return OK; } /* As get_person_stat, but only return the name if bit 0 in mask is set. */ extern Success get_person_stat_old (Pers_no person, int mask, Person * result) { Person *p_orig; enum access acc; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_P_STAT(p_orig, person, FAILURE); acc = access_perm(person, active_connection, unlimited); if ( acc == error ) return FAILURE; if ( acc <= none ) { err_stat = person; kom_errno = KOM_UNDEF_PERS; return FAILURE; } *result = *p_orig; /* Make a copy of the struct. */ /* The user area is normally secret. */ if( acc != unlimited ) result->user_area = 0; if ( !(mask & 1 ) ) result->username = EMPTY_STRING; return OK; } extern Success get_created_texts(Pers_no pers_no, Local_text_no first, u_long len, L2g_iterator * result) { Person *pers_p; enum access acc; Local_text_no new_first; Local_text_no new_len; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_P_STAT(pers_p, pers_no, FAILURE); acc = access_perm(pers_no, active_connection, read_protected); if (acc == error) return FAILURE; if (acc <= none) { err_stat = pers_no; kom_errno = KOM_UNDEF_PERS; return FAILURE; } new_first = l2g_next_key(&pers_p->created_texts, 0); if (new_first == 0) new_first = l2g_first_appendable_key(&pers_p->created_texts); new_first = max(new_first, first); if (first >= l2g_first_appendable_key(&pers_p->created_texts)) { err_stat = first; kom_errno = KOM_NO_SUCH_LOCAL_TEXT; return FAILURE; } new_len = l2g_first_appendable_key(&pers_p->created_texts) - new_first; new_len = min(new_len, len); l2gi_searchsome(result, &pers_p->created_texts, new_first, new_first + new_len); return OK; } extern Success map_created_texts(Pers_no pers_no, Local_text_no first_local_no, unsigned long no_of_texts, Text_mapping *result) { Person *pers_p; enum access acc; CHK_CONNECTION(FAILURE); if (first_local_no == 0) { err_stat = first_local_no; kom_errno = KOM_LOCAL_TEXT_ZERO; return FAILURE; } if (no_of_texts > 255) { err_stat = 255; kom_errno = KOM_LONG_ARRAY; return FAILURE; } GET_P_STAT(pers_p, pers_no, FAILURE); CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); acc = access_perm(pers_no, active_connection, read_protected); if (acc == error) return FAILURE; if (acc <= none) { err_stat = pers_no; kom_errno = KOM_UNDEF_PERS; return FAILURE; } if (first_local_no >= l2g_first_appendable_key(&pers_p->created_texts)) { err_stat = first_local_no; kom_errno = KOM_NO_SUCH_LOCAL_TEXT; return FAILURE; } result->first = first_local_no; result->no_of_texts = no_of_texts; result->l2g = &pers_p->created_texts; return OK; } extern Success map_created_texts_reverse(Pers_no pers_no, Local_text_no local_no_ceiling, unsigned long no_of_texts, Text_mapping_reverse *result) { Person *pers_p; enum access acc; Local_text_no ceiling; CHK_CONNECTION(FAILURE); if (no_of_texts > 255) { err_stat = 255; kom_errno = KOM_LONG_ARRAY; return FAILURE; } GET_P_STAT(pers_p, pers_no, FAILURE); CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); acc = access_perm(pers_no, active_connection, read_protected); if (acc == error) return FAILURE; if (acc <= none) { err_stat = pers_no; kom_errno = KOM_UNDEF_PERS; return FAILURE; } ceiling = l2g_first_appendable_key(&pers_p->created_texts); if (local_no_ceiling == 0 || local_no_ceiling > ceiling) result->ceiling = ceiling; else result->ceiling = local_no_ceiling; result->no_of_texts = no_of_texts; result->l2g = &pers_p->created_texts; return OK; } /* * Set privilege bits of a person. You must have the wheel bit set * to be allowed to do this. */ extern Success set_priv_bits( Pers_no person, Priv_bits privileges ) { Person *p; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_P_STAT(p, person, FAILURE); if ( ENA(wheel, 6) ) /* OK -- In an RPC call */ { p->privileges = privileges; mark_person_as_changed( person ); return OK; } else { err_stat = 0; kom_errno = KOM_PERM; return FAILURE; } } /* * Set password. You may set the password of yourself and all persons that * you are supervisor of. OLD_PWD is your password. */ extern Success set_passwd (Pers_no person, const String old_pwd, /* of the one who is changing the pwd, not necessarily the person whose pwd is changed. */ const String new_pwd) /* of person */ { Person *p; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_P_STAT(p, person, FAILURE); if (!is_supervisor(person, active_connection) && !ENA(wheel, 7)) /* OK -- In an RPC call */ { err_stat = person; kom_errno = KOM_PERM; return FAILURE; /* Not allowed to change the other persons pwd */ } if ( chk_passwd( ACT_P->pwd, old_pwd ) == FAILURE ) { err_stat = person; kom_errno = KOM_PWD; return FAILURE; } if ( do_set_passwd( p->pwd, new_pwd ) != OK) { err_stat = 0; kom_errno = KOM_PWD; return FAILURE; } mark_person_as_changed( person ); return OK; } /* * Ask which texts a person has read in a certain conference. * Can be done before login. Will return an empty membership if VICTIM * has his unread_is_secret-flag set. This can not be distinguished * from the case when VICTIM has not read any texts in CONF_NO. This * is a feature, not a bug. * * Will fail if VICTIM is not a member of CONF_NO. */ static Success do_query_read_texts(Pers_no victim, Conf_no conf_no, Bool want_read_ranges, unsigned long max_ranges, Membership *result) { Person * victim_p; Membership * membp; enum memb_visibility vis; CHK_CONNECTION(FAILURE); GET_P_STAT( victim_p, victim, FAILURE); if (!has_access(victim, active_connection, read_protected)) { err_stat = victim; kom_errno = KOM_UNDEF_PERS; return FAILURE; } membp = locate_membership (conf_no, victim_p); if (membp == NULL) { set_conf_errno(active_connection, conf_no, KOM_NOT_MEMBER); return FAILURE; } vis = membership_visible(active_connection, victim, conf_no, membp->type, FALSE, FALSE); if (vis == mv_none) { set_conf_errno(active_connection, conf_no, KOM_NOT_MEMBER); return FAILURE; } if (want_read_ranges == TRUE) { const Conference *conf_c; if ((conf_c = cached_get_conf_stat(conf_no)) == NULL) { kom_log("do_query_read_texts: %lu is a member of %lu, but " "that conference doesn't exist\n", (unsigned long)victim, (unsigned long)conf_no); return FAILURE; } if (adjust_read(membp, conf_c) == TRUE) mark_person_as_changed(victim); } *result = *membp; if (vis == mv_censor_unread) { result->last_time_read = NO_TIME; result->no_of_read_ranges = 0; result->read_ranges = NULL; } if (want_read_ranges) { if (max_ranges != 0 && result->no_of_read_ranges > max_ranges) result->no_of_read_ranges = max_ranges; } else { result->read_ranges = NULL; } return OK; } extern Success query_read_texts(Pers_no pers_no, Conf_no conf_no, Bool want_read_ranges, unsigned long max_ranges, Membership *result) { CHK_BOOL(want_read_ranges, FAILURE); /* CHK_CONNECTION in do_query_read_texts */ return do_query_read_texts(pers_no, conf_no, want_read_ranges, max_ranges, result); } extern Success query_read_texts_10(Pers_no victim, Conf_no conf_no, Membership *result) { /* CHK_CONNECTION in do_query_read_texts */ return do_query_read_texts(victim, conf_no, TRUE, 0, result); } extern Success query_read_texts_old(Pers_no victim, Conf_no conf_no, Membership *result) { /* CHK_CONNECTION in do_query_read_texts */ return do_query_read_texts(victim, conf_no, TRUE, 0, result); } /* * Set user_area. The text is a text which has previously been created * with create_text(). It typically contains option-settings for the * clients, e. g. if you want to be interrupted when new mail arrives. * The format of this text is not yet defined. * * set_user_area(0) to clear the user area. */ extern Success set_user_area(Pers_no pers_no, Text_no user_area) { Person *pers_p; enum access acc; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_P_STAT(pers_p, pers_no, FAILURE); acc = access_perm(pers_no, active_connection, unlimited); if (acc <= none) { err_stat = pers_no; kom_errno = KOM_UNDEF_PERS; return FAILURE; } if (acc != unlimited) { err_stat = pers_no; kom_errno = KOM_PERM; return FAILURE; } return do_set_user_area (pers_no, pers_p, user_area); } /* * Set the personal flags */ extern Success set_pers_flags(Pers_no pers_no, Personal_flags flags) { Person *pers_p; enum access acc; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_P_STAT(pers_p, pers_no, FAILURE); acc = access_perm(pers_no, active_connection, unlimited); if (acc <= none) { err_stat = pers_no; kom_errno = KOM_UNDEF_PERS; return FAILURE; } if (acc != unlimited) { err_stat = pers_no; kom_errno = KOM_PERM; return FAILURE; } pers_p->flags = flags; mark_person_as_changed(pers_no); return OK; } lyskom-server-2.1.2/src/server/conference.c0000664000015100472110000011115007721716126014375 /* * $Id: conference.c,v 0.92 2003/08/23 16:38:17 ceder Exp $ * Copyright (C) 1991-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * conference.c * * All atomic calls that deals with conferences. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include "timewrap.h" #include #include #include "s-string.h" #include "kom-types.h" #include "log.h" #include "services.h" #include "s-string.h" #include "cache.h" #include "misc-types.h" #include "s-collat-tabs.h" #include "com.h" #include "async.h" #include "connections.h" #include "kom-errno.h" #include "manipulate.h" #include "server/smalloc.h" #include "kom-config.h" #include "parser.h" #include "internal-connections.h" #include "lyskomd.h" #include "debug.h" #include "send-async.h" #include "param.h" #include "aux-items.h" #include "local-to-global.h" #include "server-time.h" #include "stats.h" BUGDECL; /* * Static functions */ /* * Delete a conference. Delete all references to this conf. */ static void do_delete_conf (Conf_no conf_no, Conference * conf_c) /* Not NULL */ { int i; if ( do_set_presentation(conf_no, conf_c, 0) != OK ) { kom_log("ERROR: do_delete_conf() - couldn't unmark presentation.\n"); } if ( do_set_etc_motd(conf_no, conf_c, 0) != OK ) { kom_log("ERROR: do_delete_conf() - couldn't unmark motd.\n"); } /* Delete all members */ /* Note that because of the way do_sub_member is written it is important */ /* that the loop is executed this way. */ for ( i = conf_c->members.no_of_members - 1; i >= 0; i-- ) { do_sub_member( conf_no, conf_c, conf_c->members.members + i, conf_c->members.members[ i ].member, NULL, NULL); } sfree( conf_c->members.members ); conf_c->members.members = NULL; /* texts */ /* * The texts are not deleted at once, but since they now have no recipient * they will not live long. */ /* * Note that there will still be a recipient in the texts, but it * will not exist in reality. This is maybe unfortunate, but * there might be thousands of texts in the conference, and we * cannot modify all those text statuses in a single atomic call. */ /* FIXME (bug 905): There should be an async message about the deletion. */ cached_delete_conf( conf_no ); update_stat(STAT_CONFS, -1); return; } /* * Functions that are exported to the server. */ void set_conf_errno(const Connection *viewer_conn, Conf_no conf_no, enum kom_err errcode) { err_stat = conf_no; if (!has_access(conf_no, viewer_conn, read_protected)) kom_errno = KOM_UNDEF_CONF; else kom_errno = errcode; } /* * Return TRUE if NAME is not already used. Set kom_errno to * KOM_LONG_STR or KOM_BAD_NAME if it fails. */ Bool legal_name( String name ) { if (name.len == 0 || name.len > param.conf_name_len ) { err_stat = name.len? param.conf_name_len : 0; kom_errno = name.len? KOM_LONG_STR : KOM_BAD_NAME; return FALSE; } while( name.len-- ) { #ifdef HAVE_LOCALE_H if (param.force_iso_8859_1 ? (*name.string < ' ' || (*name.string > 126 && *name.string < ' ' + 128)) : !isprint(*name.string)) { err_stat = 0; kom_errno = KOM_BAD_NAME; return FALSE; } #else if (*name.string < ' ' || (*name.string > 126 && *name.string < ' ' + 128)) { err_stat = 0; kom_errno = KOM_BAD_NAME; return FALSE; } #endif name.string++; } return TRUE; } /* * Return TRUE if name is unique, or if the only match is conf_no. Use 0 * as conf_no if it should not be allowed to be changed. */ Bool unique_name( const String name, Conf_no conf_no ) { Parse_info parse_info; Parse_token *name_token; Parse_token *existing_token; Bool exact_match_found; Bool diff_found; int i; int n; parse_info = parse(name, match_table, FALSE, TRUE, s_fcrea_str(WHITESPACE), DEFAULT_COLLAT_TAB); if ( parse_info.no_of_matches == 0 ) /* Doesn't match any name. */ { sfree(parse_info.indexes); return TRUE; } if ( parse_info.no_of_matches == -1 ) /* Error. */ { kom_log("unique_name(): parse returned error.\n"); sfree(parse_info.indexes); return FALSE; } if ( parse_info.no_of_matches == 1 && parse_info.indexes[ 0 ] == -1 ) { /* Empty name is not allowed. */ sfree(parse_info.indexes); return FALSE; } /* The name matches some conference. Check if they are equal. */ name_token = tokenize(name, s_fcrea_str(WHITESPACE)); exact_match_found = FALSE; for ( i = 0; !exact_match_found && i < parse_info.no_of_matches; i++ ) { existing_token = match_table[ parse_info.indexes[ i ] ].tokens; diff_found = FALSE; for ( n = 0; (!diff_found && !s_empty(existing_token[ n ].word) && !s_empty(name_token[ n ].word)); ++n) { if ( !s_usr_streq(existing_token[ n ].word, name_token[ n ].word, DEFAULT_COLLAT_TAB) ) { diff_found = TRUE; } } if (! s_empty(existing_token[ n ].word) || ! s_empty(name_token[ n ].word) ) { /* The length (number of words) differed. */ diff_found = TRUE; } if ( !diff_found && match_table[ parse_info.indexes[ i ] ].conf_no != conf_no ) exact_match_found = TRUE; } sfree(parse_info.indexes); free_tokens(name_token); return exact_match_found ? FALSE : TRUE; } /* * Create a conference. */ static Conf_no do_create_conf(String name, Pers_no creator, Conf_no supervisor, Conf_no super_conf, Conf_type type, Connection *creating_connection, Aux_item_list *aux) { Conf_no conf_no; Conference * conf_c; /* Prepare, then check the aux items */ /* Allocate memory for conf_c */ conf_no = cached_create_conf( name ); if (conf_no == 0) { /* kom_errno and err_stat set in cached_create_conf */ kom_log("ERROR: Couldn't create conference. Too many conferences.\n"); return 0; } if ( (conf_c = cached_get_conf_stat( conf_no ) ) == NULL) { restart_kom("create_conf() - can't get conf_stat\n"); } conf_c->creator = creator; conf_c->creation_time = current_time.tv_sec; conf_c->presentation= 0; /* No presentation yet */ conf_c->supervisor = supervisor; conf_c->permitted_submitters = 0; conf_c->super_conf = super_conf; conf_c->type = type; conf_c->last_written= conf_c->creation_time; conf_c->msg_of_day = 0; conf_c->nice = param.default_nice; conf_c->keep_commented = param.default_keep_commented; conf_c->highest_aux = 0; conf_c->expire = 0; /* Update small_conf_arr before conf_stat_check_add_aux_item_list uses it to check that the user is allowed to add the aux-items. */ mark_conference_as_changed (conf_no); prepare_aux_item_list(aux, creator); if (conf_stat_check_add_aux_item_list(conf_c, conf_no, aux, creating_connection, TRUE) != OK) { /* FIXME (bug 146): Conf_no leak: We create a conference, check the aux-items, determine that the aux-items are bogus, and immediately delete the conference. This leaks a conference number. We can live with that, but it isn't pretty. */ cached_delete_conf(conf_no); return 0; } conf_stat_add_aux_item_list(conf_c, conf_no, aux, creator); mark_conference_as_changed (conf_no); update_stat(STAT_CONFS, 1); return conf_no; } /* * Return TRUE if viewer is a supervisor to CONF. */ Bool is_supervisor(Conf_no conf, const Connection *viewer) { if (viewer->pers_no == 0) return FALSE; /* A person is ALWAYS supervisor to his/her own mailbox! */ if (viewer->pers_no == conf) return TRUE; return is_strictly_supervisor(conf, viewer->pers_no, viewer->person); } Bool is_strictly_supervisor(Conf_no conf, Pers_no viewer, const Person *viewer_p) /* May be NULL */ { Conf_no supervisor; if (viewer == 0) /* Not yet logged in. */ return FALSE; if (!cached_conf_exists(conf)) return FALSE; if ((supervisor = cached_get_conf_supervisor(conf)) == 0) return FALSE; if (viewer == supervisor) return TRUE; if (viewer_p == NULL) GET_P_STAT(viewer_p, viewer, FALSE); if (locate_membership(supervisor, viewer_p) != NULL) return TRUE; return FALSE; } /* * Atomic functions */ /* * Change name of a person or conference. You must be supervisor * of the conference to use this call. */ extern Success change_name (Conf_no conf_no, const String new_name) { Conference * conf_c; enum access acc; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_C_STAT(conf_c, conf_no, FAILURE); acc = access_perm(conf_no, active_connection, unlimited); if ( acc <= none ) { err_stat = conf_no; kom_errno = KOM_UNDEF_CONF; return FAILURE; } if ( !ACT_P->privileges.change_name || (acc != unlimited && !ENA(admin, 3))) /* OK -- In an RPC call */ { err_stat = conf_no; kom_errno = KOM_PERM; return FAILURE; } if ( !legal_name( new_name ) ) { /* kom_errno will be set by legal_name(). */ return FAILURE; } if ( !unique_name( new_name, conf_no ) ) { err_stat = 0; kom_errno = KOM_CONF_EXISTS; return FAILURE; } async_new_name(conf_no, conf_c->name, new_name); s_strcpy(&conf_c->name, new_name); mark_conference_as_changed(conf_no); cached_change_name(conf_no, new_name); return OK; } /* * Create a conference: Default modes: * ACTPERS becomes supervisor and super_conf. * Anyone can submitt texts. * Noone (not even the creator) is a member in the conf. * * If ANYONE_CAN_CREATE_NEW_CONFS (#defined in config.h) is not true * you must have the 'create_conf' capability. * * It is currently not allowed to have a conference that is secret * and not rd_prot. This restriction might be lifted in the future * (but I don't understand the use of such a conference...) */ static Conf_no create_conf_generic(const String name, Conf_type type, Aux_item_list *aux) { Conf_no conf_no; CHK_CONNECTION(0); CHK_LOGIN(0); if (param.anyone_can_create_new_confs == FALSE && !HAVE_PRIV(ACT_P, create_conf)) { err_stat = 0; kom_errno = KOM_PERM; return 0; } if ( !legal_name( name ) ) { /* kom_errno will be set by legal_name(). */ return 0; } if ( !unique_name( name, 0 ) ) { err_stat = 0; kom_errno = KOM_CONF_EXISTS; return 0; } if ( type.letter_box ) /* A letter_box can only be created via */ { /* create_person. */ kom_errno = KOM_PERM; return 0; } if ( type.secret && !type.rd_prot ) { err_stat = 0; kom_errno = KOM_SECRET_PUBLIC; return 0; } conf_no = do_create_conf(name, ACTPERS, ACTPERS, ACTPERS, type, active_connection, aux); if ( conf_no != 0) { ACT_P->created_confs++; mark_person_as_changed( ACTPERS ); } return conf_no; } Conf_no create_conf_old(const String name, Conf_type type) { /* CHK_CONNECTION in create_conf_generic */ return create_conf_generic(name, type, NULL); } Conf_no create_conf(const String name, Conf_type type, Aux_item_list *aux) { Conf_no conf; /* CHK_CONNECTION in create_conf_generic */ conf = create_conf_generic(name, type, aux); if (conf != 0) { /* Send message no. 2 */ } return conf; } /* * Log out a person from any connection he might be logged on to. */ static void logout_person(Pers_no pers_no) { Session_no i = 0; Connection *real_active_connection; real_active_connection = active_connection; while ( (i = traverse_connections(i)) != 0) { active_connection = get_conn_by_number(i); if ( active_connection->pers_no == pers_no ) logout(); } active_connection = real_active_connection; } /* * Delete a conference or person. You must be supervisor of the * conference to be allowed to delete it. */ extern Success delete_conf (Conf_no conf_no ) { Conference * conf_c; enum access acc; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_C_STAT(conf_c, conf_no, FAILURE); acc = access_perm(conf_no, active_connection, unlimited); if ( acc != unlimited ) { err_stat = conf_no; kom_errno = (acc <= none) ? KOM_UNDEF_CONF : KOM_PERM ; return FAILURE; } if ( conf_c->type.letter_box ) { /* Make sure the person that is deleted is not logged in. */ logout_person (conf_no); if ( do_delete_pers (conf_no) != OK ) { kom_log("ERROR: delete_conf(): can't delete person.\n"); } } do_delete_conf (conf_no, conf_c); return OK; } /* * Map conference name to number. Can be done without logging in. * Secret conferences will not be returned unless ACTPERS is supervisor * of, or member in, that conference. */ extern Success lookup_name (const String name, Conf_list_old * result) { Conf_no * no, * no_copy; Conf_type * type, *type_copy; int i; CHK_CONNECTION(FAILURE); if ( cached_lookup_name( name, result ) != OK ) return FAILURE; no = no_copy = result->conf_nos; type = type_copy = result->type_of_conf; for ( i = result->no_of_conf_nos; i > 0; i-- ) { if (!has_access(*no, active_connection, read_protected)) --result->no_of_conf_nos; else { *no_copy++ = *no; *type_copy++ = *type; } ++no; ++type; } return OK; } extern Success lookup_z_name (const String name, int want_persons, int want_confs, Conf_z_info_list * result) { Conf_no *no; Conf_type *type; Conf_z_info *res; int i; int n_filtered; Conf_list_old raw_matches; CHK_CONNECTION(FAILURE); CHK_BOOL(want_persons, FAILURE); CHK_BOOL(want_confs, FAILURE); if (cached_lookup_name(name, &raw_matches) != OK) return FAILURE; no = raw_matches.conf_nos; type = raw_matches.type_of_conf; n_filtered = raw_matches.no_of_conf_nos; for (i = raw_matches.no_of_conf_nos; i > 0; i--) { if (*no == 0) restart_kom("Internal error detected in lookup_z_name\n"); if ((type->letter_box ? want_persons : want_confs) == 0 || !has_access(*no, active_connection, read_protected)) { *no = 0; n_filtered--; } no++; type++; } result->no_of_confs = n_filtered; result->confs = tmp_alloc(n_filtered * sizeof(Conf_z_info)); no = raw_matches.conf_nos; type = raw_matches.type_of_conf; res = result->confs; for (i = raw_matches.no_of_conf_nos; i > 0; i--) { if (*no != 0) { res->conf_no = *no; res->type = *type; res->name = cached_get_name(*no); res++; } no++; type++; } if (res != result->confs + n_filtered) restart_kom("Internal error in lookup_z_name\n"); return OK; } static Success do_lookup (Connection *conn, const String name, Conf_no_list * result, Bool want_persons) { Conf_list_old raw_match; unsigned long i; unsigned short retsize; unsigned int letterflag = want_persons; if ( cached_lookup_name( name, &raw_match ) != OK ) return FAILURE; /* Find out how much space we need to allocate */ retsize = 0; for (i = 0; i < raw_match.no_of_conf_nos; i++) { /* Don't call check access permissions here. It doesn't matter that much if we allocate slightly too much memory. */ if (raw_match.type_of_conf[i].letter_box == letterflag) { retsize++; /* i is "unsigned long", and retsize is "unsigned short". They should probably both be "Conf_no" or "Conf_no_iterator". This should never be a problem in practice as long as Conf_no is a short. */ if (retsize == 0) { kom_log("WNG: do_lookup: far too many matches\n"); --retsize; } } } result->conf_nos = tmp_alloc(sizeof(Conf_no) * retsize); result->no_of_confs = 0; for (i = 0; i < raw_match.no_of_conf_nos; i++) { if (raw_match.type_of_conf[i].letter_box == letterflag && has_access(raw_match.conf_nos[i], conn, read_protected)) { result->conf_nos[result->no_of_confs++] = raw_match.conf_nos[i]; if (result->no_of_confs > retsize) restart_kom("ERROR: conference.c: do_lookup: error.\n"); } } return OK; } extern Success lookup_person (const String pattern, Conf_no_list *result) { CHK_CONNECTION(FAILURE); return do_lookup(active_connection, pattern, result, TRUE); } extern Success lookup_conf (const String pattern, Conf_no_list *result) { CHK_CONNECTION(FAILURE); return do_lookup(active_connection, pattern, result, FALSE); } /* * Get status for a conference. */ extern Success get_conf_stat(Conf_no conf_no, Conference * result) { Aux_item_list filtered; CHK_CONNECTION(FAILURE); if (get_conf_stat_old(conf_no, result) == OK) { filter_aux_item_list(&result->aux_item_list, &filtered, active_connection); result->aux_item_list = filtered; return OK; } return FAILURE; } extern Success get_conf_stat_old (Conf_no conf_no, Conference * result ) { Conference * conf_c; enum access acc; CHK_CONNECTION(FAILURE); GET_C_STAT(conf_c, conf_no, FAILURE); acc = access_perm(conf_no, active_connection, read_protected); if ( acc == error ) return FAILURE; if ( acc <= none ) { err_stat = conf_no; kom_errno = KOM_UNDEF_CONF; return FAILURE; } *result = *conf_c; return OK; } /* * Get small status for a conference */ extern Success get_uconf_stat (Conf_no conf_no, Small_conf * result) { enum access acc; Small_conf * conf_c; CHK_CONNECTION(FAILURE); conf_c = cached_get_small_conf_stat(conf_no); if (conf_c != NULL) acc = access_perm(conf_no, active_connection, read_protected); else acc = error; switch (acc) { case error: return FAILURE; case none: err_stat = conf_no; kom_errno = KOM_UNDEF_CONF; return FAILURE; default: *result = *conf_c; return OK; } } extern Success get_conf_stat_older (Conf_no conf_no, int mask, Conference * result ) { Conference * conf_c; enum access acc; CHK_CONNECTION(FAILURE); GET_C_STAT(conf_c, conf_no, FAILURE); acc = access_perm(conf_no, active_connection, read_protected); if ( acc == error ) return FAILURE; if ( acc <= none ) { err_stat = conf_no; kom_errno = KOM_UNDEF_CONF; return FAILURE; } *result = *conf_c; if ( !(mask & 1) ) result->name = EMPTY_STRING; return OK; } /* * Set or delete the presentation of a conference. If text_no == 0 there * will be no presentation. * * The text's mark-count will be increased so that it will not be deleted * when it gets old. */ extern Success set_presentation (Conf_no conf_no, Text_no text_no ) { Conference * conf_c; enum access acc; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_C_STAT(conf_c, conf_no, FAILURE); acc = access_perm(conf_no, active_connection, unlimited); if ( acc < unlimited ) { err_stat = conf_no; kom_errno = (acc <= none) ? KOM_UNDEF_CONF : KOM_PERM; return FAILURE; } return do_set_presentation(conf_no, conf_c, text_no); } /* * Set a message-of-the-day for a conference. There should normally * be no motd unless something extraordinary happens. If there is * a motd the client should show it as soon as possible. * * Only the supervisor can change the motd. * * FIXME (bug 906): There is no asynchronous message that reports new motds. */ extern Success set_etc_motd( Conf_no conf_no, Text_no text_no ) { Conference * conf_c; enum access acc; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_C_STAT(conf_c, conf_no, FAILURE); if ((acc = access_perm(conf_no, active_connection, unlimited)) < unlimited) { err_stat = conf_no; kom_errno = (acc <= none ) ? KOM_UNDEF_CONF : KOM_PERM; BUG(("set_etc_motd failed. Conf %ld Text %ld Acc %ld < %ld (%d).\n", (u_long)conf_no, (u_long)text_no, (u_long)acc, (u_long)unlimited, acc < unlimited)); return FAILURE; } return do_set_etc_motd(conf_no, conf_c, text_no); } /* * Set a new supervisor for a conference. May only be used by * the old supervisor. * * NEW_SUPER is either a person or a conference number. If it is a * conference number it means that all the members in NEW_SUPER become * supervisors to CONF_NO. (NEW_SUPER should normally be rd_prot to * prevent anyone from makeing themselves supervisors). */ extern Success set_supervisor( Conf_no conf_no, Conf_no new_super ) { Conference * conf_c; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_C_STAT(conf_c, conf_no, FAILURE); if (new_super != 0) CHK_EXIST(new_super, FAILURE); if ( !is_strictly_supervisor(conf_no, ACTPERS, ACT_P) && !ENA(wheel, 8) && /* OK -- in an RPC call */ !ENA(admin, 6) ) /* OK -- in an RPC call */ { err_stat = conf_no; kom_errno = conf_c->type.secret ? KOM_UNDEF_CONF : KOM_PERM; return FAILURE; } conf_c->supervisor = new_super; mark_conference_as_changed( conf_no ); return OK; } /* * Allow certain users to submit texts to CONF_NO. * * If NEW_PERM_SUB == 0 anyone may submit texts. * If it is a person only that person can submit texts to CONF_NO. * If it is a conference only the members in that conference can * submit texts. * * If anyone tries to submit a text to a conference he is not allowed * to submit texts to the text will silently be redirected to the * superconf. If he is not allowed to submit to that conference either * it will be redirected again and so forth, but there is a limit * (MAX_SUPER_CONF_LOOP) on how many redirections will be done. * * It is possible to have a secret conference as super_conf. Users * will then be able to send texts to it, but they will not see * where the text went... */ extern Success set_permitted_submitters (Conf_no conf_no, Conf_no new_perm_sub ) { Conference * conf_c; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); if (new_perm_sub != 0) CHK_EXIST(new_perm_sub, FAILURE); GET_C_STAT(conf_c, conf_no, FAILURE); if (!is_supervisor(conf_no, active_connection) && !ENA(wheel, 8) /* OK -- In an RPC call */ && !ENA(admin, 6)) /* OK -- In an RPC call */ { err_stat = conf_no; kom_errno = conf_c->type.secret ? KOM_UNDEF_CONF : KOM_PERM; return FAILURE; } conf_c->permitted_submitters = new_perm_sub; mark_conference_as_changed( conf_no ); return OK; } /* * Set the super_conf of CONF_NO. This call may only be used of a * supervisor of CONF_NO. * * See documentation for set_permitted_submitters(). */ extern Success set_super_conf (Conf_no conf_no, Conf_no new_super_conf ) { Conference * conf_c; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_C_STAT(conf_c, conf_no, FAILURE); if (new_super_conf != 0) CHK_EXIST(new_super_conf, FAILURE); if (!is_supervisor(conf_no, active_connection) && !ENA(wheel, 8) /* OK -- In an RPC call */ && !ENA(admin, 5)) /* OK -- In an RPC call */ { err_stat = conf_no; kom_errno = conf_c->type.secret ? KOM_UNDEF_CONF : KOM_PERM; return FAILURE; } conf_c->super_conf = new_super_conf; mark_conference_as_changed( conf_no ); return OK; } /* * Set the type of a conference. Only the supervisor of a conference can * set the conf_type. The letter_box flag can not be changed. * * FIXME (bug 70): It is allowed to set the type to 'secret' for * persons. I don't think we want it to be that way. /ceder */ extern Success set_conf_type (Conf_no conf_no, Conf_type type ) { Conference *conf_c; Member *memb; enum access acc; unsigned long i; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_C_STAT(conf_c, conf_no, FAILURE); /* * Can't be secret and public at the same time? */ if ( type.secret && !type.rd_prot ) { err_stat = 0; kom_errno = KOM_SECRET_PUBLIC; return FAILURE; } acc = access_perm(conf_no, active_connection, unlimited); /* * Can't change type without privs */ if ( acc < unlimited ) { err_stat = conf_no; kom_errno = ( acc <= none ) ? KOM_UNDEF_CONF : KOM_PERM ; return FAILURE; } /* * Can't change the letterbox flag. */ if ( type.letter_box != conf_c->type.letter_box ) { err_stat = conf_no; kom_errno = KOM_LETTER_BOX; return FAILURE; } /* * Can't change to secret if there are secret memberships * Only check this if we are changing the forbid_secret * flag to on from off */ if (type.forbid_secret && !conf_c->type.forbid_secret) { for (i = 0; i < conf_c->members.no_of_members; i++) { memb = &conf_c->members.members[i]; if (memb->type.secret) { err_stat = memb->member; kom_errno = KOM_INVALID_MEMBERSHIP_TYPE; return FAILURE; } } } conf_c->type = type; mark_conference_as_changed (conf_no); return OK; } /* * Set garb_nice for a conference. This controls how long messages * to a conference will live. The argument is probably the number of * days a message will live. Only the supervisor of the conference * may change the garb_nice. */ extern Success set_garb_nice( Conf_no conf_no, Garb_nice nice ) /* number of days */ { Conference * conf_c; enum access acc; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_C_STAT(conf_c, conf_no, FAILURE); acc = access_perm(conf_no, active_connection, unlimited); if ( acc < unlimited ) { err_stat = conf_no; kom_errno = (acc <= none) ? KOM_UNDEF_CONF : KOM_PERM; return FAILURE; } conf_c->nice = nice; mark_conference_as_changed( conf_no ); return OK; } /* * Set expire for a conference. This controls nothing at the moment, but * will probably control when a conference is killed automatically by * the server in cases of extreme inactivity. */ extern Success set_expire( Conf_no conf_no, Garb_nice expire ) /* number of days */ { Conference * conf_c; enum access acc; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_C_STAT(conf_c, conf_no, FAILURE); acc = access_perm(conf_no, active_connection, unlimited); if ( acc < unlimited ) { err_stat = conf_no; kom_errno = (acc <= none) ? KOM_UNDEF_CONF : KOM_PERM; return FAILURE; } conf_c->expire = expire; mark_conference_as_changed( conf_no ); return OK; } /* * Set keep_commented for a conference. */ extern Success set_keep_commented(Conf_no conf_no, Garb_nice keep_commented) /* number of days */ { Conference * conf_c; enum access acc; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); GET_C_STAT(conf_c, conf_no, FAILURE); acc = access_perm(conf_no, active_connection, unlimited); if ( acc < unlimited ) { err_stat = conf_no; kom_errno = (acc <= none) ? KOM_UNDEF_CONF : KOM_PERM; return FAILURE; } conf_c->keep_commented = keep_commented; mark_conference_as_changed( conf_no ); return OK; } static void send_async_new_presentation(Conf_no conf_no, Text_no old_tno, Text_stat *old_stat, Text_no new_tno, Text_stat *new_stat) { Session_no i = 0; Connection *cptr; Text_no used_old; Text_no used_new; if (!param.send_async_messages) return; while ((i = traverse_connections(i)) != 0) { cptr = get_conn_by_number(i); /* Check the want_async here to avoid the potentially expensive calls to access_perm. */ if (cptr->want_async[ay_new_presentation] == FALSE) continue; if (!has_access(conf_no, cptr, read_protected)) continue; used_old = text_read_access(cptr, old_tno, old_stat) ? old_tno : 0; used_new = text_read_access(cptr, new_tno, new_stat) ? new_tno : 0; if (used_old == used_new) continue; async_new_presentation(cptr, conf_no, used_old, used_new); } } /* * Change presentation of a conference. If text_no is 0, there will be * no presentation. */ Success do_set_presentation(Conf_no conf_no, Conference * conf_c, Text_no new_text_no) { Text_stat * old_stat = NULL; Text_stat * new_stat = NULL; Text_no old_text_no = 0; /* Check that the new presentation exists before deleting the old*/ if (new_text_no != 0) { GET_T_STAT(new_stat, new_text_no, FAILURE); if (new_stat->no_of_marks >= param.max_marks_text) { kom_log("LIMIT: do_set_presentation(%d, ptr, %lu): " "New presentation has %d marks.\n", conf_no, (unsigned long)new_text_no, new_stat->no_of_marks); err_stat = new_text_no; kom_errno = KOM_MARK_LIMIT; return FAILURE; } } /* Unmark the previous presentation if it exists. */ old_text_no = conf_c->presentation; if (old_text_no != 0) { if ((old_stat = cached_get_text_stat(old_text_no)) == NULL) { /* FIXME (bug 85): This is not currently an error, but it will be once bug 85 is fixed. */ kom_log("do_set_presentation(): Old presentation %lu of conf %lu" " does not exist.\n", (unsigned long)old_text_no, (unsigned long)conf_no); old_text_no = 0; } else if (old_stat->no_of_marks > 0) { --old_stat->no_of_marks; mark_text_as_changed(old_text_no); } else { kom_log("ERROR: do_set_presentation(%d, ptr, %lu): " "Old presentation %lu not marked.\n", conf_no, (unsigned long)new_text_no, (unsigned long)old_text_no); } } /* Mark the new presentation */ if (new_text_no != 0) { ++new_stat->no_of_marks; mark_text_as_changed(new_text_no); } conf_c->presentation = new_text_no; mark_conference_as_changed(conf_no); send_async_new_presentation(conf_no, old_text_no, old_stat, new_text_no, new_stat); return OK; } static void send_async_new_motd(Conf_no conf_no, Text_no old_tno, Text_stat *old_stat, Text_no new_tno, Text_stat *new_stat) { Session_no i = 0; Connection *cptr; Text_no used_old; Text_no used_new; if (!param.send_async_messages) return; while ((i = traverse_connections(i)) != 0) { cptr = get_conn_by_number(i); /* Check the want_async here to avoid the potentially expensive calls to access_perm. */ if (cptr->want_async[ay_new_motd] == FALSE) continue; if (!has_access(conf_no, cptr, read_protected)) continue; used_old = text_read_access(cptr, old_tno, old_stat) ? old_tno : 0; used_new = text_read_access(cptr, new_tno, new_stat) ? new_tno : 0; if (used_old == used_new) continue; async_new_motd(cptr, conf_no, used_old, used_new); } } /* * Change motd of a conference. If text_no is 0, there will be * no motd. */ Success do_set_etc_motd(Conf_no conf_no, Conference * conf_c, Text_no new_text_no) { Text_stat * old_stat = NULL; Text_stat * new_stat = NULL; Text_no old_text_no = 0; /* Check that the new motd exists before deleting the old*/ if (new_text_no != 0) { GET_T_STAT(new_stat, new_text_no, FAILURE); if (new_stat->no_of_marks >= param.max_marks_text) { kom_log("LIMIT: do_set_etc_motd(%d, ptr, %lu): " "New motd has %d marks.\n", conf_no, (unsigned long)new_text_no, new_stat->no_of_marks); err_stat = new_text_no; kom_errno = KOM_MARK_LIMIT; return FAILURE; } } /* Unmark the previous motd if it exists. */ old_text_no = conf_c->msg_of_day; if (old_text_no != 0) { if ((old_stat = cached_get_text_stat(old_text_no)) == NULL) { /* FIXME (bug 86): This is not currently an error, but it will be once bug 86 is fixed. */ kom_log("do_set_etc_motd(): Old motd %lu of conf %lu" " does not exist.\n", (unsigned long)old_text_no, (unsigned long)conf_no); old_text_no = 0; } else if (old_stat->no_of_marks > 0) { --old_stat->no_of_marks; mark_text_as_changed(old_text_no); } else { kom_log("ERROR: do_set_etc_motd(%d, ptr, %lu): " "Old motd %lu not marked.\n", conf_no, (unsigned long)new_text_no, (unsigned long)old_text_no); } } /* Mark the new motd */ if (new_text_no != 0) { ++new_stat->no_of_marks; mark_text_as_changed(new_text_no); } conf_c->msg_of_day = new_text_no; mark_conference_as_changed(conf_no); send_async_new_motd(conf_no, old_text_no, old_stat, new_text_no, new_stat); return OK; } extern Success modify_conf_info(Conf_no conf_no, Number_list *items_to_delete, Aux_item_list *aux) { Conference *conf; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); if (items_to_delete->length > param.max_delete_aux) { kom_errno = KOM_LONG_ARRAY; err_stat = param.max_delete_aux; return FAILURE; } if (aux->length > param.max_add_aux) { kom_errno = KOM_LONG_ARRAY; err_stat = param.max_add_aux; return FAILURE; } GET_C_STAT(conf, conf_no, FAILURE); if (!has_access(conf_no, active_connection, read_protected)) { err_stat = conf_no; kom_errno = KOM_UNDEF_CONF; return FAILURE; } /* Check if we may delete and add the items */ prepare_aux_item_list(aux, ACTPERS); if (check_delete_aux_item_list(items_to_delete, &conf->aux_item_list, conf_no)!=OK) return FAILURE; delete_aux_item_list(items_to_delete, &conf->aux_item_list, CONF_OBJECT_TYPE, conf_no, conf); if (conf_stat_check_add_aux_item_list(conf, conf_no, aux, active_connection, FALSE) != OK) { undelete_aux_item_list(items_to_delete, &conf->aux_item_list, CONF_OBJECT_TYPE, conf_no, conf); return FAILURE; } /* Then add the items */ conf_stat_add_aux_item_list(conf, conf_no, aux, ACTPERS); commit_aux_item_list(&conf->aux_item_list); /* FIXME (bug 907): async_conf_changed(conf_no, conf); */ mark_conference_as_changed(conf_no); return OK; } Success first_unused_conf_no(Conf_no *result) { CHK_CONNECTION(FAILURE); *result = query_next_conf_no(); return OK; } Success find_next_conf_no(Conf_no start, Conf_no *result) { Conf_no highest = query_next_conf_no(); CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); err_stat = start; while (++start < highest) if (has_access(start, active_connection, read_protected)) { *result = start; return OK; } kom_errno = KOM_UNDEF_CONF; return FAILURE; } extern Success find_previous_conf_no(Conf_no start, Conf_no *result) { Conf_no next_cno; const Conf_no saved_start = start; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); if (start > (next_cno = query_next_conf_no())) start = next_cno; while (start-- > 0) if (has_access(start, active_connection, read_protected)) { *result = start; return OK; } kom_errno = KOM_UNDEF_CONF; err_stat = saved_start; return FAILURE; } lyskom-server-2.1.2/src/server/session.c0000664000015100472110000006272107721716130013755 /* * $Id: session.c,v 0.78 2003/08/23 16:38:13 ceder Exp $ * Copyright (C) 1991-1994, 1996-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * session.c * * Session control and miscellaneous. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include "timewrap.h" #include #include "oop.h" #include "ldifftime.h" #include "s-string.h" #include "kom-types.h" #include "services.h" #include "com.h" #include "async.h" #include "connections.h" #include "internal-connections.h" #include "kom-errno.h" #include "manipulate.h" #include "lyskomd.h" #include "log.h" #include "cache.h" #include "send-async.h" #include "kom-config.h" #include "server/smalloc.h" #include "param.h" #include "kom-memory.h" #include "string-malloc.h" #include "server-time.h" #include "timeval-util.h" #include "isc-interface.h" /* * Create an oldstyle username, user%host.domain@host.domain. * The RESULT must be initialized to a string (such as EMPTY_STRING). * A new string will be allocated in RESULT. (The old will be freed). */ static void create_oldstyle_username(String *result, Connection *connection) { if ( s_strcpy(result, connection->username) != OK ) restart_kom("create_oldstyle_username(): s_strcpy\n"); if ( s_strcat(result, s_fcrea_str("@")) != OK ) restart_kom("create_oldstyle_username: s_strcat\n"); if ( s_strcat(result, connection->isc_session->remote) != OK ) restart_kom("create_oldstyle_username: s_strcat II\n"); } /* * This function is called whenever a person leaves a conf, * i e when he change_conference():s or logout():s. */ extern void leave_conf(Connection *conn) { Membership * mship; if (conn->cwc != 0 ) { if ((mship = locate_membership( conn->cwc, conn->person )) != NULL ) { mship->last_time_read = current_time.tv_sec; mark_person_as_changed (conn->pers_no); } else { kom_log("ERROR: leave_conf(): Can't find membership of cwc.\n"); } cached_unlock_conf( conn->cwc ); conn->cwc = 0; } } /* * Log in as user pers_no. If ACTPERS is a supervisor of pers_no the login * will succeed regardless of the passwd. An logout() will automatically * be performed if ACTPERS is logged in. */ extern Success login_old (Pers_no pers_no, const String passwd) { Person *pers_p; CHK_CONNECTION(FAILURE); GET_P_STAT(pers_p, pers_no, FAILURE); if (!is_supervisor(pers_no, active_connection) && !ENA(wheel, 8) /* OK -- In an RPC call */ && chk_passwd(pers_p->pwd, passwd) == FAILURE) { err_stat = pers_no; kom_errno = KOM_PWD; return FAILURE; } logout(); active_connection->flags.invisible = FALSE; ACTPERS = pers_no; ACT_P = pers_p; cached_lock_person(pers_no); pers_p->last_login = current_time.tv_sec; active_connection->login_time = current_time; ++pers_p->sessions; s_strcpy(&pers_p->username, active_connection->username); /* A Person should have separate fields for ident_user and hostname. But for now, we use the syntax username(ident_user)@hostname. */ if (!s_empty(active_connection->ident_user)) { if ( s_strcat(&pers_p->username, s_fcrea_str("(")) != OK ) restart_kom("login_old: s_strcat (\n"); if ( s_strcat(&pers_p->username, active_connection->ident_user) != OK ) restart_kom("login_old: s_strcat ident_user\n"); if ( s_strcat(&pers_p->username, s_fcrea_str(")")) != OK ) restart_kom("login_old: s_strcat )\n"); } if ( s_strcat(&pers_p->username, s_fcrea_str("@")) != OK ) restart_kom("login_old: s_strcat\n"); if (s_strcat(&pers_p->username, active_connection->isc_session->remote) != OK) restart_kom("login_old: s_strcat II\n"); mark_person_as_changed( pers_no ); if (param.log_login == TRUE) { char *id = s_crea_c_str (pers_p->username); kom_log ("Login %d %s\n", ACTPERS, id); string_free (id); } isc_set_acceptable_idle(active_connection->isc_session, param.active_timeout); async_login(ACTPERS, active_connection->session_no); return OK; } /* * Log in as user pers_no. If ACTPERS is a supervisor of pers_no the login * will succeed regardless of the passwd. An logout() will automatically * be performed if ACTPERS is logged in. */ extern Success login (Pers_no pers_no, const String passwd, Bool invisible) { Person *pers_p; Bool same_person; CHK_CONNECTION(FAILURE); CHK_BOOL(invisible, FAILURE); GET_P_STAT(pers_p, pers_no, FAILURE); if (!is_supervisor(pers_no, active_connection) && !ENA(wheel, 8) /* OK -- In an RPC call */ && chk_passwd(pers_p->pwd, passwd) == FAILURE) { err_stat = pers_no; kom_errno = KOM_PWD; return FAILURE; } same_person = (ACTPERS == pers_no) ? TRUE : FALSE; logout(); if (invisible) active_connection->flags.invisible = TRUE; else active_connection->flags.invisible = FALSE; /* Don't count this as a new session if the person already was logged on. The elisp-client version 0.38.1 logs on invisibly automatically to indicate that the user is inactve. */ if (same_person == FALSE) ++pers_p->sessions; ACTPERS = pers_no; ACT_P = pers_p; cached_lock_person(pers_no); pers_p->last_login = current_time.tv_sec; active_connection->login_time = current_time; s_strcpy(&pers_p->username, active_connection->username); /* A Person should have separate fields for ident_user and hostname. But for now, we use the syntax username(ident_user)@hostname. */ if (!s_empty(active_connection->ident_user)) { if ( s_strcat(&pers_p->username, s_fcrea_str("(")) != OK ) restart_kom("login: s_strcat (\n"); if ( s_strcat(&pers_p->username, active_connection->ident_user) != OK ) restart_kom("login: s_strcat ident_user\n"); if ( s_strcat(&pers_p->username, s_fcrea_str(")")) != OK ) restart_kom("login: s_strcat )\n"); } if ( s_strcat(&pers_p->username, s_fcrea_str("@")) != OK ) restart_kom("login: s_strcat\n"); if (s_strcat(&pers_p->username, active_connection->isc_session->remote) != OK) restart_kom("login: s_strcat II\n"); mark_person_as_changed( pers_no ); if (param.log_login == TRUE && same_person == FALSE) { char *id = s_crea_c_str (pers_p->username); kom_log ("Login %d %s\n", ACTPERS, id); string_free (id); } if (!active_connection->flags.invisible) async_login(ACTPERS, active_connection->session_no); isc_set_acceptable_idle(active_connection->isc_session, param.active_timeout); return OK; } /* * Log out. Does not disconnect the client. The person is also automatically * logged out if the connection is closed. Takes no action if noone is logged * in on this line. Never fails. */ extern Success logout( void ) { CHK_CONNECTION(FAILURE); if ( ACTPERS != 0 ) /* Is he logged in? Then log him out. */ { if (!active_connection->flags.invisible) { async_logout( ACTPERS, active_connection->session_no ); } leave_conf(active_connection); ACT_P->last_login = current_time.tv_sec; ACT_P->total_time_present += timeval_diff_sec(current_time, active_connection->login_time); active_connection->login_time = current_time; cached_unlock_person( ACTPERS ); mark_person_as_changed( ACTPERS ); } s_clear(&active_connection -> what_am_i_doing); active_connection->person = NULL; active_connection->cwc = 0; active_connection->pers_no = 0; active_connection->ena_level = 0; isc_set_acceptable_idle(active_connection->isc_session, param.login_timeout); return OK; } /* * Change Conference. * * You are not allowed to change to a conference unless you are a * member in the conference. * * You can change_conference(0) to indicate that you are no longer in * a certain conference. * * There are two reasons to use this call: * 1) Other persons want to know what you are doing. * 2) When the server checks that you have permission to * read a certain text it first checks if you current working * conference is a recipient of the text, since that is a * cheap test. If that test fails it will have to read in the * conference structs for the recipients of the text until it * finds an open one. * * In the future the server might read in the conference in advance when * someone change_conference's to it to allow faster response times. */ extern Success change_conference (Conf_no conference) { Who_info info; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); if ( conference != 0 ) { CHK_EXIST(conference, FAILURE); if ( locate_membership( conference, ACT_P) == NULL ) { err_stat = conference; kom_errno = KOM_NOT_MEMBER; return FAILURE; } } leave_conf(active_connection); active_connection->cwc = conference; if ( conference != 0 ) cached_lock_conf( conference ); init_who_info(&info); if (!active_connection->flags.invisible) { info.person = ACTPERS; info.what_am_i_doing = active_connection->what_am_i_doing; info.working_conference = conference; info.session_no = active_connection->session_no; /* Bug compatibility. */ create_oldstyle_username(&info.username, active_connection); async_i_am_on(info); s_clear(&info.username); } return OK; } /* * Tell the server what you are doing. This string is sent to anyone * who does a 'who_is_on()'. */ extern Success change_what_i_am_doing (String what_am_i_doing) { Who_info info; CHK_CONNECTION(FAILURE); init_who_info(&info); if ( s_strlen( what_am_i_doing ) > param.what_do_len ) { s_clear ( &what_am_i_doing ); err_stat = param.what_do_len; kom_errno = KOM_LONG_STR; return FAILURE; } s_clear ( &active_connection->what_am_i_doing ); active_connection->what_am_i_doing = what_am_i_doing; if (!active_connection->flags.invisible) { info.person = ACTPERS; info.what_am_i_doing = active_connection->what_am_i_doing; create_oldstyle_username(&info.username, active_connection); info.working_conference = active_connection->cwc; info.session_no = active_connection->session_no; async_i_am_on(info); s_clear(&info.username); } return OK; } /* * Get info about what all the currently logged in persons are doing. */ extern Success who_is_on( Who_info_list *result ) { Connection *cptr; int no_of_clients = 0; int i; Session_no session; CHK_CONNECTION(FAILURE); session = traverse_connections(0); while (session != 0) { cptr = get_conn_by_number(session); if ( cptr->person != NULL && cptr->flags.invisible == FALSE ) ++no_of_clients; session = traverse_connections(session); } result->no_of_persons = no_of_clients; result->info = tmp_alloc ( no_of_clients * sizeof(Who_info)); i = 0; session = traverse_connections(0); while ( i < no_of_clients && session != 0) { cptr = get_conn_by_number(session); if ( cptr->person != NULL && cptr->flags.invisible == FALSE ) { init_who_info(&result->info[ i ]); result->info[ i ].person = cptr->pers_no; result->info[ i ].what_am_i_doing = cptr->what_am_i_doing; /* Backward compatibility: Old clients want the username to be user%host@host. result->info[i].username is free()d in prot_a_output_who_info_list() in prot-a-output.c. */ create_oldstyle_username(&result->info[i].username, cptr); result->info[ i ].working_conference = filter_conf_no( cptr->cwc, active_connection); result->info[ i ].session_no = cptr->session_no; ++i; } session = traverse_connections(session); } if ( i != no_of_clients ) kom_log("who_is_on: i == %d, no_of_clients == %d\n", i, no_of_clients); return OK; } /* * Get info about what all the currently logged in persons are doing. */ extern Success who_is_on_ident( Who_info_ident_list *result ) { Connection *cptr; int no_of_clients = 0; int i; Session_no session; CHK_CONNECTION(FAILURE); session = traverse_connections(0); while (session != 0) { cptr = get_conn_by_number(session); if ( cptr->person != NULL && cptr->flags.invisible == FALSE ) ++no_of_clients; session = traverse_connections(session); } result->no_of_persons = no_of_clients; result->info = tmp_alloc ( no_of_clients * sizeof(Who_info_ident)); i = 0; session = traverse_connections(0); while ( i < no_of_clients && session != 0) { cptr = get_conn_by_number(session); if ( cptr->person != NULL && cptr->flags.invisible == FALSE ) { init_who_info_ident(&result->info[i]); result->info[i].person = cptr->pers_no; result->info[i].what_am_i_doing = cptr->what_am_i_doing; result->info[i].username = cptr->username; result->info[i].hostname = cptr->isc_session->remote; result->info[i].ident_user = cptr->ident_user; result->info[i].working_conference = filter_conf_no( cptr->cwc, active_connection); result->info[i].session_no = cptr->session_no; ++i; } session = traverse_connections(session); } if ( i != no_of_clients ) kom_log("who_is_on_ident: i == %d, no_of_clients == %d\n", i, no_of_clients); return OK; } /* * Get info about what all the currently logged in persons are doing. */ extern Success who_is_on_dynamic(int want_visible, int want_invisible, long active_last, Dynamic_session_info_list *result) { Connection *cptr; long no_of_clients = 0; long i; Session_no session; int include_it = 0; CHK_CONNECTION(FAILURE); CHK_BOOL(want_visible, FAILURE); CHK_BOOL(want_invisible, FAILURE); session = traverse_connections(0); while (session != 0) { cptr = get_conn_by_number(session); if (!handshake_ok(cptr, 0)) include_it = 0; else if (cptr->person == NULL || cptr->flags.invisible == TRUE) include_it = want_invisible; else include_it = want_visible; if (active_last != 0 && include_it && timeval_diff_sec(current_time, cptr->active_time) > active_last && cptr->flags.user_active_used) include_it = 0; if (include_it != 0) ++no_of_clients; session = traverse_connections(session); } result->no_of_sessions = no_of_clients; result->sessions = tmp_alloc(no_of_clients * sizeof(Dynamic_session_info)); i = 0; session = traverse_connections(0); while ( i < no_of_clients && session != 0) { cptr = get_conn_by_number(session); if (!handshake_ok(cptr, 0)) include_it = 0; else if (cptr->person == NULL || cptr->flags.invisible == TRUE) include_it = want_invisible; else include_it = want_visible; if (active_last != 0 && include_it && timeval_diff_sec(current_time, cptr->active_time) > active_last && cptr->flags.user_active_used) include_it = 0; if (include_it != 0) { init_dynamic_session_info(&result->sessions[i]); result->sessions[i].session = cptr->session_no; result->sessions[i].person = cptr->pers_no; result->sessions[i].working_conference = filter_conf_no( cptr->cwc, active_connection); result->sessions[i].idle_time = timeval_diff_sec( current_time, cptr->active_time); result->sessions[i].flags = cptr->flags; /* Special case: sessions that are not logged in are always invisible. */ if (cptr->person == NULL) result->sessions[i].flags.invisible = TRUE; result->sessions[i].what_am_i_doing = cptr->what_am_i_doing; ++i; } session = traverse_connections(session); } if ( i != no_of_clients ) kom_log("who_is_on_dynamic: i == %ld, no_of_clients == %ld\n", i, no_of_clients); return OK; } extern Success get_session_info (Session_no session_no, Session_info *result) { Connection *cptr; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); cptr = get_conn_by_number(session_no); if (cptr != NULL && handshake_ok(cptr, 0)) { init_session_info(result); result->person = cptr->pers_no; result->what_am_i_doing = cptr->what_am_i_doing; result->working_conference = filter_conf_no(cptr->cwc, active_connection); result->session = cptr->session_no; result->connection_time = cptr->connect_time.tv_sec; result->idle_time = timeval_diff_sec(current_time, cptr->active_time); /* Backward compatibility. result->username is free()d in prot_a_reply() prot-a.c. */ create_oldstyle_username(&result->username, cptr); return OK; } else { err_stat = session_no; kom_errno = KOM_UNDEF_SESSION; return FAILURE; } } extern Success get_static_session_info (Session_no session_no, Static_session_info *result) { Connection *cptr; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); cptr = get_conn_by_number(session_no); if (cptr != NULL && handshake_ok(cptr, 0)) { init_static_session_info(result); result->username = cptr->username; result->hostname = cptr->isc_session->remote; result->ident_user = cptr->ident_user; result->connection_time = cptr->connect_time.tv_sec; return OK; } else { err_stat = session_no; kom_errno = KOM_UNDEF_SESSION; return FAILURE; } } extern Success get_session_info_ident (Session_no session_no, Session_info_ident *result) { Connection *cptr; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); cptr = get_conn_by_number(session_no); if (cptr != NULL && handshake_ok(cptr, 0)) { init_session_info_ident(result); result->person = cptr->pers_no; result->what_am_i_doing = cptr->what_am_i_doing; result->working_conference = filter_conf_no(cptr->cwc, active_connection); result->session = cptr->session_no; result->connection_time = cptr->connect_time.tv_sec; result->idle_time = timeval_diff_sec(current_time, cptr->active_time); result->username = cptr->username; result->hostname = cptr->isc_session->remote; result->ident_user = cptr->ident_user; return OK; } else { err_stat = session_no; kom_errno = KOM_UNDEF_SESSION; return FAILURE; } } extern Success who_am_i (Session_no *session_no) { CHK_CONNECTION(FAILURE); *session_no = active_connection->session_no; return OK; } extern Success disconnect (Session_no session_no) { Connection *cptr; CHK_CONNECTION(FAILURE); if ( session_no != active_connection->session_no && session_no != 0 ) CHK_LOGIN(FAILURE); cptr = get_conn_by_number(session_no); if (cptr != NULL && handshake_ok(cptr, 0)) { if (session_no == active_connection->session_no || session_no == 0 || ENA(wheel, 8) /* OK -- In an RPC call */ || is_supervisor(cptr->pers_no, active_connection) == TRUE) { add_to_kill_list(cptr); return OK; } else { err_stat = session_no; kom_errno = KOM_PERM; return FAILURE; } } else { err_stat = session_no; kom_errno = KOM_UNDEF_SESSION; return FAILURE; } } /* Get less info */ extern Success who_is_on_old( Who_info_list_old *result ) { Connection *cptr; int no_of_clients = 0; int i; Session_no session; CHK_CONNECTION(FAILURE); session = traverse_connections(0); while (session != 0) { cptr = get_conn_by_number(session); if ( cptr->person != NULL && cptr->flags.invisible == FALSE ) ++no_of_clients; session = traverse_connections(session); } result->no_of_persons = no_of_clients; result->info = tmp_alloc ( no_of_clients * sizeof(Who_info)); i = 0; session = traverse_connections(0); while (session != 0 && i < no_of_clients) { cptr = get_conn_by_number(session); if ( cptr->person != NULL && cptr->flags.invisible == FALSE ) { init_who_info_old(&result->info[ i ]); result->info[ i ].person = cptr->pers_no; result->info[ i ].what_am_i_doing = cptr->what_am_i_doing; result->info[i].working_conference = filter_conf_no( cptr->cwc, active_connection); ++i; } session = traverse_connections(session); } if ( i != no_of_clients ) kom_log("who_is_on_old: i == %d, no_of_clients == %d\n", i, no_of_clients); return OK; } /* * Ask the server what it thinks the time is. */ extern Success get_time( time_t *clk ) { CHK_CONNECTION(FAILURE); *clk = current_time.tv_sec; return OK; } /* * Set ena_level. 0 means don't use any privileges. */ extern Success enable (u_char ena_level) { CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); active_connection->ena_level = ena_level; return OK; } extern Success set_client_version (const String client_name, const String client_version) { CHK_CONNECTION(FAILURE); if (s_strlen(client_name) > param.client_data_len || s_strlen(client_version) > param.client_data_len) { err_stat = param.client_data_len; kom_errno = KOM_LONG_STR; return FAILURE; } if (s_empty(active_connection->client_name) == FALSE || s_empty(active_connection->client_version) == FALSE) { err_stat = 0; kom_errno = KOM_CLIENT_IS_CRAZY; return FAILURE; } s_strcpy(&active_connection->client_name, client_name); s_strcpy(&active_connection->client_version, client_version); return OK; } extern Success get_client_name (Session_no session_no, String *result) { Connection *cptr; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); cptr = get_conn_by_number(session_no); if (cptr != NULL && handshake_ok(cptr, 0)) { *result = cptr->client_name; return OK; } else { err_stat = session_no; kom_errno = KOM_UNDEF_SESSION; return FAILURE; } } extern Success get_client_version (Session_no session_no, String *result) { Connection *cptr; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); cptr = get_conn_by_number(session_no); if (cptr != NULL && handshake_ok(cptr, 0)) { *result = cptr->client_version; return OK; } else { err_stat = session_no; kom_errno = KOM_UNDEF_SESSION; return FAILURE; } } extern Success accept_async(Number_list *num_list) { int i; Success result; int found; CHK_CONNECTION(FAILURE); result = OK; /* * Check against maliciously long arrays. */ if (num_list->length > param.accept_async_len) { err_stat = 0; kom_errno = KOM_LONG_ARRAY; return FAILURE; } /* * Clear the accept list */ for (i = 0; i < ay_dummy_last; i++) { active_connection->want_async[i] = FALSE; } /* * Enter the new accept list -- non-silently ignore requests for * messages that this version of the server doesn't understand. */ for (i = 0; i < num_list->length; i++) { found = 0; if (num_list->data[i] >= 0 && num_list->data[i] < ay_dummy_last) { switch ((enum async)num_list->data[i]) { case ay_new_text_old: case ay_new_name: case ay_i_am_on: case ay_sync_db: case ay_leave_conf: case ay_login: case ay_rejected_connection: case ay_send_message: case ay_logout: case ay_deleted_text: case ay_new_text: case ay_new_recipient: case ay_sub_recipient: case ay_new_membership: case ay_new_user_area: case ay_new_presentation: case ay_new_motd: case ay_text_aux_changed: #ifdef DEBUG_CALLS case ay_garb_ended: #endif found = 1; active_connection->want_async[num_list->data[i]] = TRUE; break; case ay_dummy_last: break; /* Trick: since we don't use a default label here gcc will warn if new values are added to ``enum async'' but not to this switch. */ } } if (!found && result == OK) /* Remember the first offender. */ { err_stat = num_list->data[i]; kom_errno = KOM_UNKNOWN_ASYNC; result = FAILURE; } } return result; } extern Success query_async(Number_list *result) { /* (This static buffer is mentioned in async.h). */ static long temp[ay_dummy_last]; int i; CHK_CONNECTION(FAILURE); result->length = 0; for (i = 0; i < ay_dummy_last; i++) { if (active_connection->want_async[i] != FALSE) { temp[result->length] = i; result->length += 1; } } result->data = temp; return OK; } extern Success user_active(void) { CHK_CONNECTION(FAILURE); active_connection->active_time = current_time; active_connection->flags.user_active_used = TRUE; return OK; } extern Success set_connection_time_format(int use_utc) { CHK_CONNECTION(FAILURE); CHK_BOOL(use_utc, FAILURE); active_connection->use_utc = use_utc; return OK; } lyskom-server-2.1.2/src/server/admin.c0000664000015100472110000002434407721716126013366 /* * $Id: admin.c,v 0.61 2003/08/23 16:38:18 ceder Exp $ * Copyright (C) 1991, 1993-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * admin.c * * Administrative calls. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include "timewrap.h" #include #include "oop.h" #include "misc-types.h" #include "s-string.h" #include "kom-types.h" #include "com.h" #include "async.h" #include "connections.h" #include "kom-errno.h" #include "manipulate.h" #include "cache.h" #include "kom-config.h" #include "log.h" #include "send-async.h" #include "param.h" #include "string-malloc.h" #include "services.h" #include "version-info.h" #include "aux-items.h" #include "unused.h" #include "sigflags.h" #include "isc-interface.h" /* All of the fields in this structure except the version number is set from the configuration file at startup (see ramkomd.c). The default values are also set in ramkomd.c; the values below are never used. The defaults are as of this writing (1994-01-11 19:57:22) equal to the values below, but don't trust that that is so when you read this. */ /* Actually, these values are (except for the server compatibility version number) stored in the database */ Info kom_info = { #include "version.incl" , /* version */ 1, /* conf_pres_conf */ 2, /* pers_pres_conf */ 3, /* motd_conf */ 4, /* kom_news_conf */ 0, /* motd_of_lyskom */ 0, /* highest_aux_no */ { 0, NULL } /* aux_item_list */ }; /* * Return info about this server. This can (and should) be done * before logging in. motd_of_lyskom should be displayed before * prompting for username if it isn't 0. */ extern Success get_info_old( Info *result ) { *result = kom_info; return OK; } extern Success get_info( Info *result ) { Aux_item_list filtered; CHK_CONNECTION(FAILURE); *result = kom_info; filter_aux_item_list(&result->aux_item_list, &filtered, active_connection); result->aux_item_list = filtered; return OK; } extern Success get_version_info( Version_info *result ) { /* Allowed before login. */ result->protocol_version = kom_version_info.protocol_version; result->server_name = s_fcrea_str(kom_version_info.server_name); result->server_version = s_fcrea_str(kom_version_info.server_version); return OK; } extern Success set_info(Info *info) { Conference *conf; Text_stat *text; Success tmp; CHK_LOGIN(FAILURE); if ( !ENA(admin, 1) ) /* OK -- in an RPC call */ { err_stat = 0; kom_errno = KOM_PERM; return FAILURE; } /* Check that everything mentioned exists */ if (info->motd_of_lyskom != 0) { GET_T_STAT(text, info->motd_of_lyskom, FAILURE); } GET_C_STAT(conf, info->conf_pres_conf, FAILURE); GET_C_STAT(conf, info->pers_pres_conf, FAILURE); GET_C_STAT(conf, info->motd_conf, FAILURE); GET_C_STAT(conf, info->kom_news_conf, FAILURE); if ((tmp = set_motd_of_lyskom(info->motd_of_lyskom)) != OK) return tmp; kom_info.conf_pres_conf = info->conf_pres_conf; kom_info.pers_pres_conf = info->pers_pres_conf; kom_info.motd_conf = info->motd_conf; kom_info.kom_news_conf = info->kom_news_conf; return OK; } extern Success set_motd_of_lyskom (Text_no motd) { Text_stat *old_motd = NULL; Text_stat *new_motd = NULL; CHK_LOGIN(FAILURE); if ( !ENA(admin, 1) ) /* OK -- In an RPC call */ { err_stat = 0; kom_errno = KOM_PERM; return FAILURE; } /* Check that the new motd exists before deleting the old*/ if ( motd != 0 ) { GET_T_STAT(new_motd, motd, FAILURE); if ( new_motd->no_of_marks >= param.max_marks_text ) { kom_log("LIMIT: set_motd_of_lyskom(%lu): New motd has %d marks.\n", (unsigned long)motd, new_motd->no_of_marks); err_stat = motd; kom_errno = KOM_MARK_LIMIT; return FAILURE; } } /* Unmark the previous motd if it exists. */ if ( kom_info.motd_of_lyskom != 0 && (old_motd = cached_get_text_stat(kom_info.motd_of_lyskom)) != NULL) { if ( old_motd->no_of_marks > 0 ) { --old_motd->no_of_marks; mark_text_as_changed( kom_info.motd_of_lyskom ); } else { kom_log("ERROR: set_motd_of_lyskom(): Old motd not marked.\n"); } } /* Mark the new motd */ if ( motd != 0 ) { ++new_motd->no_of_marks; mark_text_as_changed( motd ); } /* FIXME (bug 912): send an async message about a new motd. */ kom_info.motd_of_lyskom = motd; return OK; } /* * Force all clients to read a message. * Sends an asynchronous message. This is obsoleted by send_message. */ extern Success broadcast (const String message) { return send_message(0, message); } /* * Send a message */ extern Success send_message (Conf_no recipient, const String message) { Conference *conf_c; unsigned short end; unsigned short ix; Success retval; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); /* Check that the message is not too long */ if (s_strlen(message) > param.broadcast_len) { err_stat = param.broadcast_len; kom_errno = KOM_LONG_STR; return FAILURE; } /* If the recipient is not everyone, send it to all members */ if (recipient != 0) { GET_C_STAT(conf_c, recipient, FAILURE); /* Check that the conference is not secret */ if (!has_access(recipient, active_connection, read_protected)) { err_stat = recipient; kom_errno = KOM_UNDEF_CONF; return FAILURE; } /* Conference is not secret. Traverse its members */ end = conf_c->members.no_of_members; retval = FAILURE; err_stat = 0; kom_errno = KOM_MESSAGE_NOT_SENT; for (ix = 0; ix < end; ix++) { /* Don't send messages to passive members */ if (conf_c->members.members[ix].type.passive ^ conf_c->members.members[ix].type.passive_message_invert) continue; /* Send message to appropriate sessions */ if (async_send_group_message(conf_c->members.members[ix].member, recipient, ACTPERS, message, ENA(admin, 1)) == OK) { retval = OK; } } } else { /* Attempting to broadcast */ retval = async_send_message(recipient, ACTPERS, message, ENA(admin, 1)); } return retval; } /* * Make LysKOM sync its files. */ extern Success sync_kom (void) { if (!param.permissive_sync) { CHK_LOGIN(FAILURE); if ( !ENA(admin, 1) ) /* OK -- In an RPC call */ { err_stat = 0; kom_errno = KOM_PERM; return FAILURE; } } cache_sync_all(); dump_statistics(); return OK; } /* * Close LysKOM. exit_val is (currently) not used. The database is synced. */ extern Success shutdown_kom (int UNUSED(exit_val)) { char *name; char *user; char *host; CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); if ( !ENA(admin, 1) ) /* OK -- In an RPC call */ { err_stat = 0; kom_errno = KOM_PERM; return FAILURE; } name = s_crea_c_str (active_connection->username); user = s_crea_c_str (active_connection->ident_user); host = s_crea_c_str (active_connection->isc_session->remote); kom_log("shutdown initiated by person %d (%s) via %s@%s.\n", ACTPERS, name, user, host); string_free(host); string_free(user); string_free(name); go_and_die = TRUE; return OK; } extern Success modify_system_info(Number_list *items_to_delete, Aux_item_list *items_to_add) { CHK_CONNECTION(FAILURE); CHK_LOGIN(FAILURE); if (items_to_delete->length > param.max_delete_aux) { kom_errno = KOM_LONG_ARRAY; err_stat = param.max_delete_aux; return FAILURE; } if (items_to_add->length > param.max_add_aux) { kom_errno = KOM_LONG_ARRAY; err_stat = param.max_add_aux; return FAILURE; } if ( !ENA(admin, 1) ) /* OK -- in an RPC call */ { err_stat = 0; kom_errno = KOM_PERM; return FAILURE; } prepare_aux_item_list(items_to_add, ACTPERS); if (check_delete_aux_item_list(items_to_delete, &kom_info.aux_item_list, 0)!=OK) return FAILURE; delete_aux_item_list(items_to_delete, &kom_info.aux_item_list, INFO_OBJECT_TYPE, 0, NULL); if (system_check_add_aux_item_list(&kom_info, items_to_add, active_connection) != OK) { undelete_aux_item_list(items_to_delete, &kom_info.aux_item_list, INFO_OBJECT_TYPE, 0, NULL); return FAILURE; } system_add_aux_item_list(&kom_info, items_to_add, ACTPERS); commit_aux_item_list(&kom_info.aux_item_list); return OK; } extern Success get_collate_table (String * result) { CHK_CONNECTION(FAILURE); result->string = DEFAULT_COLLAT_TAB; result->len = COLLAT_TAB_SIZE; return OK; } lyskom-server-2.1.2/src/server/regex-match.c0000664000015100472110000001127507721716130014474 /* * $Id: regex-match.c,v 1.38 2003/08/23 16:38:14 ceder Exp $ * Copyright (C) 1992-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * Regexp matching */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include "timewrap.h" #ifdef HAVE_STDLIB_H # include #endif #ifdef HAVE_STRING_H # include #endif #include "s-string.h" #include "misc-types.h" #include "kom-types.h" #include "services.h" #include "regex.h" #include "server/smalloc.h" #include "cache.h" #include "kom-errno.h" #include "com.h" #include "async.h" #include "connections.h" #include "manipulate.h" #include "log.h" #include "kom-config.h" #include "param.h" static Success lookup_regexp (Connection *conn, const String regexp, Conf_z_info_list *result, Bool want_persons, Bool want_confs) { struct re_pattern_buffer pat_buf; Conf_no conf_no; String name = EMPTY_STRING; const char *errmsg; Conf_type type; /* FIXME (bug 163): It is unnecessary to allocate this much if only one conference matches. */ result->confs = tmp_alloc (cached_no_of_existing_conferences() * sizeof(Conf_z_info)); result->no_of_confs = 0; re_syntax_options = RE_SYNTAX_GREP; pat_buf.translate = NULL; /* We have to use malloc() instead of smalloc() when allocating the fastmap, since regfree will use free() to free the memory. If malloc fails here we simply continue without a fastmap. The match will be a little slower, but that is not fatal. */ pat_buf.fastmap = malloc(256); pat_buf.allocated = 0; pat_buf.buffer = 0; if ((errmsg = re_compile_pattern((char*)regexp.string, s_strlen(regexp), &pat_buf)) != NULL) { regfree(&pat_buf); err_stat = 0; kom_errno = KOM_REGEX_ERROR; return FAILURE; } for (conf_no = 0; (conf_no = traverse_conference(conf_no)) != 0;) { type = cached_get_conf_type(conf_no); if ((type.letter_box ? want_persons : want_confs) && has_access(conf_no, conn, read_protected)) { name = cached_get_name(conf_no); switch ( re_search (&pat_buf, (char*)name.string, s_strlen(name), 0, s_strlen(name), NULL) ) { case -1: break; case -2: kom_log("Internal error in regex.\n"); break; default: /* It matched. (Ignore where it matched). */ result->confs[result->no_of_confs].conf_no = conf_no; result->confs[result->no_of_confs].name = name; result->confs[result->no_of_confs++].type = type; break; } } } regfree(&pat_buf); return OK; } static void downgrade(Conf_z_info_list *in, Conf_no_list *out) { int ix; out->conf_nos = tmp_alloc(sizeof(Conf_no) * in->no_of_confs); out->no_of_confs = in->no_of_confs; for (ix = 0; ix < in->no_of_confs; ix++) { out->conf_nos[ix] = in->confs[ix].conf_no; } } Success re_lookup_person (const String regexp, Conf_no_list *result) { Conf_z_info_list tmp; Success retval; CHK_CONNECTION(FAILURE); retval = lookup_regexp(active_connection, regexp, &tmp, TRUE, FALSE); if (retval == OK) downgrade(&tmp, result); return retval; } Success re_lookup_conf (const String regexp, Conf_no_list *result) { Conf_z_info_list tmp; Success retval; CHK_CONNECTION(FAILURE); retval = lookup_regexp(active_connection, regexp, &tmp, FALSE, TRUE); if (retval == OK) downgrade(&tmp, result); return retval; } Success re_z_lookup (const String regexp, int want_persons, int want_confs, Conf_z_info_list *result) { CHK_CONNECTION(FAILURE); CHK_BOOL(want_persons, FAILURE); CHK_BOOL(want_confs, FAILURE); return lookup_regexp(active_connection, regexp, result, want_persons, want_confs); } lyskom-server-2.1.2/src/server/aux-items.c0000664000015100472110000017002107722446226014206 /* * $Id: aux-items.c,v 1.61 2003/08/25 17:24:23 ceder Exp $ * Copyright (C) 1994-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ #ifdef HAVE_CONFIG_H # include #endif #include #ifdef HAVE_STDLIB_H # include #endif #ifdef HAVE_STRING_H # include #endif #include #include #include "timewrap.h" #include "aux-no.h" #include "kom-types.h" #include "com.h" #include "async.h" #include "connections.h" #include "kom-errno.h" #include "manipulate.h" #include "aux-items.h" #include "kom-memory.h" #include "server/smalloc.h" #include "cache.h" #include "s-string.h" #include "lyskomd.h" #include "kom-config.h" #include "regex.h" #include "log.h" #include "services.h" #include "admin.h" #include "param.h" #include "server-time.h" #include "string-malloc.h" #define AUX_ADJUST_FLAG(flg) item->flags.flg = (def->clear_flags.flg)?0:((def->set_flags.flg)?1:item->flags.flg) /* Externally accessible variables (used by the parser) */ Aux_item_definition *aux_item_definition_list = NULL; unsigned long num_aux_item_definitions = 0; /* Variables local to this file */ #if COMPILED_AUX_ITEMS static Aux_item_definition compiled_aux_items[] = {}; #endif /* Forward declaration of triggers */ static void aux_item_trigger_mark_text(Aux_item_trigger_data *); static void aux_item_trigger_unmark_text(Aux_item_trigger_data *); static void aux_item_trigger_mirror_faq(Aux_item_trigger_data *); static void aux_item_trigger_link_item(Aux_item_trigger_data *data); /* Forward declarations of validators */ static Success aux_item_validate_existing_text(Aux_item_validation_data *data); /* Other forward declarations */ static const Aux_item * find_aux_item(const Aux_item_list *list, unsigned long aux_no); static void prepare_aux_item(Aux_item *item, Pers_no creator, const Aux_item_definition *def); /* Symbol table for the triggers */ static Aux_item_trigger_mapping aux_item_triggers [] = { { "mark-text", aux_item_trigger_mark_text }, { "unmark-text", aux_item_trigger_unmark_text }, { "link-faq", aux_item_trigger_mirror_faq }, { "link-item", aux_item_trigger_link_item }, { NULL, NULL } }; /* Symbol table for the validators */ static Aux_item_validator_mapping aux_item_validators [] = { { "existing-readable-text", aux_item_validate_existing_text }, { NULL, NULL } }; /* Use this to initialize an empty definition */ Aux_item_definition empty_aux_item_definition = { NULL, /* Name */ 0, /* Tag */ { 0,0,0,0,0,0,0,0 }, /* Clear flags */ { 0,0,0,0,0,0,0,0 }, /* Set flags */ 0, /* Disabled */ 0, /* Author only */ 0, /* Supervisor only */ 0, /* System only */ 0, /* Unique */ 0, /* Unique-data */ 0, /* Can't delete */ 0, /* Owner delete */ 0, /* Inherit limit */ FALSE, /* Texts */ 0, FALSE, /* Confs */ 0, FALSE, /* Letterbox */ FALSE, /* System */ 0, /* Number of validators */ NULL, /* Validator list */ 0, NULL, 0, NULL, 0, NULL, NULL /* Next */ }; /* * simple_aux_item is the default definition for simple * items (non-reserved tags) */ static Aux_item_definition simple_aux_item = { (char*)"simple", /* Name */ 0, /* Tag */ { 0,0,0,0,0,0,0,0 }, /* Clear flags */ { 0,0,0,0,0,0,0,0 }, /* Set flags */ 0, /* Disabled */ 0, /* Author only */ 0, /* Supervisor only */ 0, /* System only */ 0, /* Unique */ 0, /* Unique-data */ 0, /* Can't delete */ 0, /* Owner delete */ 0, /* Inherit limit */ TRUE, /* Texts */ 0, TRUE, /* Confs */ 0, TRUE, /* Letterbox */ TRUE, /* System */ 0, NULL, /* Validators */ 0, NULL, /* Add triggers */ 0, NULL, /* Delete triggers */ 0, NULL, /* Undelete triggers */ NULL }; /* Forward declarations */ static Bool aux_item_check_unique(const Aux_item *item, const Aux_item_definition *xdef, Aux_item_list *add_to_list, unsigned long start_looking_at); /* * aux_item_default_definition * * Return the default definition of ITEM or NULL if ITEM cannot * be created without an explicit definition */ static Aux_item_definition * aux_item_default_definition(const Aux_item *item) { /* A predefined aux_item that we didn't find a definition for is illegal. */ if (AUX_IS_ILLEGAL(item->tag)) return NULL; if (AUX_IS_PREDEFINED(item->tag)) return NULL; return &simple_aux_item; } /* * aux_item_find_trigger */ Aux_item_trigger aux_item_find_trigger(const char *trigger_name) { unsigned long i = 0; while (aux_item_triggers[i].name != NULL) { if (!strcmp(aux_item_triggers[i].name, trigger_name)) return aux_item_triggers[i].function; i += 1; } return NULL; } Aux_item_validation_function aux_item_find_validator(const char *validator_name) { unsigned long i = 0; while (aux_item_validators[i].name != NULL) { if (!strcmp(aux_item_validators[i].name, validator_name)) return aux_item_validators[i].function; i += 1; } return NULL; } /* * find_aux_item_definition * * Return the definition of ITEM or NULL if it does not * have a valid information. */ static const Aux_item_definition * find_aux_item_definition(const Aux_item *item) { Aux_item_definition *def; def = aux_item_definition_list; while (def != NULL) { if (def->tag == item->tag) return def; def = def->next; } return aux_item_default_definition(item); } /* * ====================================================================== * UTILITY FUNCTIONS * ====================================================================== */ /* TRIGGER THINGS */ static void aux_item_fix_trigger_data(Aux_item_trigger_data *data) { switch (data->object_type) { case TEXT_OBJECT_TYPE: data->item = &((Text_stat *)data->object)->aux_item_list.items[data->item_index]; break; case CONF_OBJECT_TYPE: data->item = &((Conference *)data->object)->aux_item_list.items[data->item_index]; break; case INFO_OBJECT_TYPE: data->item = &((Info *)data->object)->aux_item_list.items[data->item_index]; break; default: break; } } static void aux_item_call_add_triggers(const Aux_item_definition *def, enum object_type object_type, unsigned long item_index, unsigned long integer_argument, void * pointer_argument, Aux_item * item) { unsigned long i; Aux_item_trigger_data data; data.action = AUX_ITEM_ADD_ACTION; data.object_type = object_type; data.item_index = item_index; data.object_no = integer_argument; data.object = pointer_argument; data.item = item; for (i = 0; i < def->num_add_triggers; i++) { (*(def->add_triggers[i]))(&data); aux_item_fix_trigger_data(&data); } } static void aux_item_call_delete_triggers(const Aux_item_definition *def, enum object_type object_type, unsigned long item_index, unsigned long integer_argument, void * pointer_argument, Aux_item *item) { unsigned long i; Aux_item_trigger_data data; data.action = AUX_ITEM_DELETE_ACTION; data.object_type = object_type; data.item_index = item_index; data.object_no = integer_argument; data.object = pointer_argument; data.item = item; for (i = 0; i < def->num_delete_triggers; i++) { (*(def->delete_triggers[i]))(&data); } } static void aux_item_call_undelete_triggers(const Aux_item_definition *def, enum object_type object_type, unsigned long item_index, unsigned long integer_argument, void * pointer_argument, Aux_item * item) { unsigned long i; Aux_item_trigger_data data; data.action = AUX_ITEM_UNDELETE_ACTION; data.object_type = object_type; data.item_index = item_index; data.object_no = integer_argument; data.object = pointer_argument; data.item = item; for (i = 0; i < def->num_undelete_triggers; i++) { (*(def->undelete_triggers[i]))(&data); } } /* * initialize_aux_items * * Initialize this code and its data structures */ void aux_item_definition_add(Aux_item_definition *def) { Aux_item_definition *new_definition; new_definition = smalloc(sizeof(Aux_item_definition)); if (new_definition == NULL) { restart_kom("out of memory adding aux-item definition"); } *new_definition = *def; num_aux_item_definitions += 1; new_definition->next = aux_item_definition_list; aux_item_definition_list = new_definition; } /* * Compile the verification regexp for the definition in DEF * and put the result somewhere convenient. */ static void aux_item_definition_cache_regexp(const Aux_item_definition *def, unsigned long ix) { struct re_pattern_buffer *pat_buf; const char *errmsg; re_syntax_options = RE_SYNTAX_POSIX_EXTENDED; def->validators[ix].v.re.cached_re_buf = smalloc(sizeof(*pat_buf)); if (def->validators[ix].v.re.cached_re_buf == NULL) { kom_log("Out of memory compiling aux-item regexp %lu (%s).\n", def->tag, def->name); return; } pat_buf = def->validators[ix].v.re.cached_re_buf; pat_buf->translate = NULL; pat_buf->fastmap = 0; pat_buf->allocated = 0; pat_buf->buffer = 0; if ((errmsg = re_compile_pattern(def->validators[ix].v.re.regexp, strlen(def->validators[ix].v.re.regexp), pat_buf)) != NULL) { kom_log("%s in validate regexp of aux-item definition %lu (%s).\n", errmsg, def->tag, def->name); if (def->validators[ix].v.re.cached_re_buf) { /* If re_compile_pattern fails, it can leave allocated stuff in the buffer. */ regfree(def->validators[ix].v.re.cached_re_buf); sfree(def->validators[ix].v.re.cached_re_buf); } if (def->validators[ix].v.re.regexp) string_free(def->validators[ix].v.re.regexp); def->validators[ix].v.re.cached_re_buf = NULL; def->validators[ix].v.re.regexp = NULL; return; } } void initialize_aux_items(char *aux_def_file) { #if COMPILED_AUX_ITEMS unsigned long i; /* Set up precompiled items */ for (i = 0; i < (sizeof(compiled_aux_items)/sizeof(*compiled_aux_items)); i++) { aux_item_definition_add(&compiled_aux_items[i]); } #endif /* Read definitions from configuration file */ parse_aux_item_definitions(aux_def_file); } void free_aux_item_definitions(void) { unsigned long i; Aux_item_definition *def; Aux_item_definition *tmp; def = aux_item_definition_list; while (def != NULL) { string_free(def->name); for (i = 0; i < def->num_validators; i++) { if (def->validators[i].type == AUX_VALIDATE_REGEXP) { if (def->validators[i].v.re.regexp != NULL) string_free(def->validators[i].v.re.regexp); if (def->validators[i].v.re.cached_re_buf != NULL) { regfree(def->validators[i].v.re.cached_re_buf); sfree(def->validators[i].v.re.cached_re_buf); } } } if (def->validators != NULL) { sfree(def->validators); def->validators = NULL; def->num_validators = 0; } if (def->add_triggers != NULL) { sfree(def->add_triggers); def->add_triggers = NULL; def->num_add_triggers = 0; } if (def->delete_triggers != NULL) { sfree(def->delete_triggers); def->delete_triggers = NULL; def->num_delete_triggers = 0; } if (def->undelete_triggers != NULL) { sfree(def->undelete_triggers); def->undelete_triggers = NULL; def->num_undelete_triggers = 0; } tmp = def->next; sfree(def); def = tmp; } aux_item_definition_list = NULL; } static long find_aux_item_index(const Aux_item_list *list, unsigned long aux_no) { unsigned long i; for (i = 0; i < list->length; i++) { if (list->items[i].aux_no == aux_no) return i; } return -1; } /* Find the aux item list containing the item that ITEM is linked to */ static Aux_item_list * find_linked_aux_item_list(Aux_item *item) { Text_stat *text_stat; Conference *conf_stat; switch (item->linked_item.target_type) { case NO_OBJECT_TYPE: return NULL; case TEXT_OBJECT_TYPE: GET_T_STAT(text_stat, item->linked_item.target_object.text, NULL); return &text_stat->aux_item_list; case CONF_OBJECT_TYPE: GET_C_STAT(conf_stat, item->linked_item.target_object.conf, NULL); return &conf_stat->aux_item_list; case INFO_OBJECT_TYPE: return &kom_info.aux_item_list; default: /* No lists in these items */ kom_log("find_linked_aux_item_list: Bad aux_item somewhere: " "link to person or other kind.\n"); return NULL; } } /* Find the aux item that ITEM is linked to */ static const Aux_item * find_linked_aux_item(Aux_item *item) { Aux_item_list *target_list; target_list = find_linked_aux_item_list(item); if (target_list == NULL) return NULL; return find_aux_item(target_list, item->linked_item.target_item); } /* Mark the object linked to by an aux_item as changed */ static void mark_linked_object_as_changed(Aux_item *item) { Text_stat *text_stat; Conference *conf_stat; switch (item->linked_item.target_type) { case TEXT_OBJECT_TYPE: VOID_GET_T_STAT(text_stat, item->linked_item.target_object.text); mark_text_as_changed(item->linked_item.target_object.text); break; case CONF_OBJECT_TYPE: VOID_GET_C_STAT(conf_stat, item->linked_item.target_object.conf); mark_conference_as_changed(item->linked_item.target_object.conf); break; case INFO_OBJECT_TYPE: default: /* Need no commit for these objects */ ; } } /* * Utility function for linking aux items. This function will take * care of adding the appropriate item to the appropriate list. * * Note that this may cause aux-item lists to be realloced, so pointers * into such lists may become invalid. Take particular care with the * pointers in aux-item trigger data * * Call aux_item_fix_trigger_data if you need to fix the contents of * trigger data after calling this function. */ static void aux_item_link_items(enum object_type src_type, /* Source object type */ unsigned long src_no, /* Source object pointer */ void *src_ptr, /* Source pointer */ Aux_item *src_item, /* Source item */ enum object_type dst_type, /* Destination obj type */ unsigned long dst_no, /* Destination obj pointer */ void *dst_ptr, /* Destination pointer */ Aux_item *dst_item_data) { Aux_item_list item_list; /* Get a pointer to the destination object */ if (dst_ptr == NULL) { switch (dst_type) { case TEXT_OBJECT_TYPE: dst_ptr = cached_get_text_stat(dst_no); break; case CONF_OBJECT_TYPE: dst_ptr = cached_get_conf_stat(dst_no); break; case INFO_OBJECT_TYPE: dst_ptr = &kom_info; break; default: break; } } if (dst_ptr == NULL || src_ptr == NULL) return; /* Set up the linking information in the destination item */ dst_item_data->linked_item.target_type = src_type; dst_item_data->linked_item.target_item = src_item->aux_no; switch (src_type) { case TEXT_OBJECT_TYPE: dst_item_data->linked_item.target_object.text = src_no; break; case CONF_OBJECT_TYPE: dst_item_data->linked_item.target_object.conf = src_no; break; case INFO_OBJECT_TYPE: default: dst_item_data->linked_item.target_object.text = 0; } /* Set up the linking information in the source item */ src_item->linked_item.target_type = dst_type; src_item->linked_item.target_item = 0; switch (dst_type) { case TEXT_OBJECT_TYPE: src_item->linked_item.target_object.text = dst_no; src_item->linked_item.target_item = ((Text_stat *)dst_ptr)->highest_aux + 1; break; case CONF_OBJECT_TYPE: src_item->linked_item.target_object.conf = dst_no; src_item->linked_item.target_item = ((Conference *)dst_ptr)->highest_aux + 1; break; case INFO_OBJECT_TYPE: src_item->linked_item.target_item = ((Info *)dst_ptr)->highest_aux_no + 1; src_item->linked_item.target_object.text = 0; src_item->linked_item.target_object.conf = 0; break; default: src_item->linked_item.target_item = 0; src_item->linked_item.target_object.text = 0; src_item->linked_item.target_object.conf = 0; } /* Set up an item list to add */ item_list.length = 1; item_list.items = dst_item_data; prepare_aux_item_list(&item_list, src_item->creator); /* * Add the item and mark the destination as changed * * Note that these calls may cause the aux item list of the * destination to move in memory due to calls to realloc. */ switch (dst_type) { case TEXT_OBJECT_TYPE: text_stat_add_aux_item_list((Text_stat *)dst_ptr, (Text_no)dst_no, &item_list, src_item->creator); /* FIXME (bug 141): is this necessary? The call to mark_linked_object_as_changed below seems to fix this, right? --ceder 1999-07-10. */ mark_text_as_changed((Text_no)dst_no); break; case CONF_OBJECT_TYPE: conf_stat_add_aux_item_list((Conference *)dst_ptr, (Conf_no)dst_no, &item_list, src_item->creator); /* FIXME (bug 141): is this necessary? The call to mark_linked_object_as_changed below seems to fix this, right? --ceder 1999-07-10. */ mark_conference_as_changed((Conf_no)dst_no); break; case INFO_OBJECT_TYPE: system_add_aux_item_list((Info *)dst_ptr, &item_list, src_item->creator); break; default: break; } /* * Set src_item to NULL since there is a chance that it is * no longer valid (this happens when the source and destination * objects are the same and reallocing the aux item list causes * it to move in memory */ /* FIXME (bug 142): but src_item isn't used below this point! What is the point of setting it to NULL? --ceder 1999-07-10. */ src_item = NULL; /* * Mark the source object as changed */ mark_linked_object_as_changed(dst_item_data); } static void aux_item_list_add_items(Aux_item_list *add_to_list, Aux_item_list *items_to_add, enum object_type object_type, unsigned long object_no, void *object_ptr, unsigned long *highest_ptr, Pers_no item_creator) { unsigned long i; unsigned long highest_local; unsigned long start_index; if (items_to_add == NULL) return; /* * Make local copies of variables we need in their original state */ start_index = add_to_list->length; highest_local = *highest_ptr; /* * Set up the target list so it looks like we've added * items to it already. That way it is semi-safe to call * this function recursively. */ add_to_list->length += items_to_add->length; add_to_list->items = srealloc(add_to_list->items, add_to_list->length * sizeof(Aux_item)); *highest_ptr = *highest_ptr + items_to_add->length; for (i = 0; i < items_to_add->length; i++) { init_aux_item(&add_to_list->items[start_index + i]); } /* * Now add the items and call the add triggers */ for (i = 0; i < items_to_add->length; i++) { highest_local += 1; copy_aux_item(&add_to_list->items[i + start_index], &items_to_add->items[i]); add_to_list->items[i + start_index].aux_no = highest_local; add_to_list->items[i + start_index].creator = item_creator; aux_item_call_add_triggers( find_aux_item_definition(&items_to_add->items[i]), object_type, i + start_index, object_no, object_ptr, &add_to_list->items[i + start_index]); } } /* * prepare_aux_item_list * * Prepare items in LIST for checking and addition. You *have* * to call this before any of the addition or checking * function. CREATOR is the person who wants to create the * item list. This function will set various fields in the * items. UTSL. */ void prepare_aux_item_list(Aux_item_list *list, Pers_no creator) { unsigned long i; if (list == NULL) return; for (i = 0; i < list->length; i++) prepare_aux_item(&list->items[i], creator, NULL); } static void prepare_aux_item(Aux_item *item, Pers_no creator, const Aux_item_definition *def) { if (item == NULL) return; def = def ? def : find_aux_item_definition(item); if (def == NULL) return; AUX_ADJUST_FLAG(inherit); AUX_ADJUST_FLAG(secret); AUX_ADJUST_FLAG(hide_creator); AUX_ADJUST_FLAG(dont_garb); AUX_ADJUST_FLAG(reserved3); AUX_ADJUST_FLAG(reserved4); AUX_ADJUST_FLAG(reserved5); /* AUX_ADJUST_FLAG(deleted); */ item->flags.deleted = 0; if (def->inherit_limit != 0 && (item->inherit_limit > def->inherit_limit || item->inherit_limit == 0)) { item->inherit_limit = def->inherit_limit; } item->creator = creator; item->sent_at = current_time.tv_sec; } static Success aux_item_validate(Aux_item_validation_data validation_data) { unsigned long i; const Aux_item_definition *def; def = validation_data.def; for (i = 0; i < def->num_validators; i++) { switch (def->validators[i].type) { case AUX_VALIDATE_FUNCTION: /* * Call the validation function * If it returns FAILURE, then abort validation * If it returns OK, then continue with the * next validator */ if ((*def->validators[i].v.fn.function)(&validation_data) != OK) { return FAILURE; } break; case AUX_VALIDATE_REGEXP: /* * Ensure that the regexp is cached */ if (def->validators[i].v.re.cached_re_buf == NULL) { aux_item_definition_cache_regexp(def, i); } /* * If the RE is still not cached there is a problem * in this case to not validate the item at all and * log a problem */ if (def->validators[i].v.re.cached_re_buf == NULL) { kom_log("Failed to cache regexp validator for \"%s\". " "Rejecting all such items.\n", def->name); sfree(def->validators[i].v.re.regexp); def->validators[i].v.re.regexp = NULL; def->validators[i].type = AUX_VALIDATE_REJECT; kom_errno = KOM_ILL_AUX; return FAILURE; } /* * RE is compiled and can be used */ switch (re_search(def->validators[i].v.re.cached_re_buf, (char*)validation_data.item->data.string, s_strlen(validation_data.item->data), 0, s_strlen(validation_data.item->data), NULL)) { case -1: /* No match */ kom_errno = KOM_ILL_AUX; return FAILURE; case -2: /* Internal error may (be temporary) */ kom_log("Internal error in regex matching aux-item data.\n"); kom_errno = KOM_ILL_AUX; return FAILURE; break; default: /* Matched */ break; } break; case AUX_VALIDATE_REJECT: /* * Just reject the item. Used when we detect a problem * with a validator */ kom_errno = KOM_ILL_AUX; return FAILURE; break; default: kom_log("BUG: unknown aux_item validator type\n"); } } /* * If we got all the way to here we passed all the validators */ return OK; } /* * aux_item_add_perm * * Check if it is alright to add an aux_item. * * ITEM is the item that you want to add. * DEF is the item's definition or NULL. * CREATING_CONN is the connection that is causing this item to be * added. It is NULL if the item is created due to inheritance. * SUBORDINATE. If author-only or supervisor-only, the person logged * in on CREATING_CONN must be a supervisor of the SUBORDINATE to * be allowed to create the item. For a text, the SUBORDINATE * should be set to the author of the text. For a conference or * person, this is the conference or person itself. * ADD_TO_LIST is the item list the item should be added to, or NULL. * START_LOOKING_AT is the first index in add_to_list to start * looking at for possible duplicates. * CREATING is true if we are checking while creating the object that * the item will be added to. * OBJECT_TYPE is the type of the object the item is added to. */ static Bool aux_item_add_perm(const Aux_item *item, const Aux_item_definition *def, Connection *creating_conn, Pers_no subordinate, Aux_item_list *add_to_list, unsigned long start_looking_at, Bool creating, enum object_type object_type) { short can_add_when = 0; kom_errno = KOM_NO_ERROR; /* Either there is a connection responsible for the creation, or we are inheriting. If we are inheriting, creating must be true. */ assert(creating_conn != NULL || creating); if (def == NULL) def = find_aux_item_definition(item); /* Can't create an item with no definition */ if (def == NULL) { kom_errno = KOM_ILL_AUX; return FALSE; } if (def->disabled) { kom_errno = KOM_ILL_AUX; return FALSE; } switch (object_type) { case TEXT_OBJECT_TYPE: can_add_when = def->text_a; break; case CONF_OBJECT_TYPE: can_add_when = def->conf_a; break; default: can_add_when = 0; } if (can_add_when) { if (!((creating && (can_add_when & AUX_ITEM_ADD_ON_CREATE)) || (!creating && (can_add_when & AUX_ITEM_ADD_ON_MODIFY)))) { kom_errno = KOM_AUX_PERM; return FALSE; } } if (def->system_only) { kom_errno = KOM_AUX_PERM; return FALSE; } if ((def->author_only || def->supervisor_only) && !creating && creating_conn != NULL && !ENA_C(creating_conn, wheel, 8)) { if (def->author_only && !is_supervisor(subordinate, creating_conn)) { kom_errno = KOM_AUX_PERM; return FALSE; } /* FIXME (bug 313): is_strictly_supervisor() or is_supervisor()? */ if (def->supervisor_only && !is_strictly_supervisor(subordinate, creating_conn->pers_no, creating_conn->person)) { kom_errno = KOM_AUX_PERM; return FALSE; } } /* Even the administrator can't override this */ kom_errno = KOM_NO_ERROR; if (!aux_item_check_unique(item, def, add_to_list, start_looking_at)) { kom_errno = kom_errno?kom_errno:KOM_AUX_PERM; return FALSE; } /* Check the contents */ if (def->num_validators > 0) { Aux_item_validation_data validation_data; validation_data.item = item; validation_data.def = def; validation_data.creating_conn = creating_conn; validation_data.creating = creating; validation_data.subordinate = subordinate; #if 0 /* Since no validator currently uses these fields, they have been temporarily removed from the Aux_item_validation_data type. */ validation_data.add_to_list = add_to_list; validation_data.start_looking_at = start_looking_at; validation_data.object_type = object_type; #endif if (aux_item_validate(validation_data) != OK) { kom_errno = KOM_ILL_AUX; return FALSE; } } return TRUE; } /* * aux_item_check_unique * * Check whether there are items that block creation of a new item. * ITEM is the item we want to add. * DEF is the item's definitioon * ADD_TO_LIST is the list we want to add to * START_LOOKING_AT is the first index in the list to look at. */ static Bool aux_item_check_unique(const Aux_item *item, const Aux_item_definition *def, Aux_item_list *add_to_list, unsigned long start_looking_at) { unsigned long i; if (add_to_list == NULL || item == NULL || start_looking_at >= add_to_list->length) { return TRUE; } if (def != NULL) def = find_aux_item_definition(item); if (def == NULL) return TRUE; for (i = start_looking_at; i < add_to_list->length; i++) { if (def->one_per_person && add_to_list->items[i].tag == item->tag && add_to_list->items[i].creator == item->creator && !add_to_list->items[i].flags.deleted) return FALSE; if (def->unique_data && add_to_list->items[i].tag == item->tag && s_streq(add_to_list->items[i].data, item->data)) { kom_errno = KOM_ILL_AUX; return FALSE; } } return TRUE; } /* * aux_inherit_items * * Inherit aux items from PARENT to TARGET. COUNTER is a pointer to * the aux_no counter in the object being inherited to and SUBORDINATE * is the author of the target object. The object is a text. */ void aux_inherit_items(Aux_item_list *target, const Aux_item_list *parent, unsigned long *counter, Conf_no subordinate, Text_no object_no, Text_stat *object) { int i; Aux_item item; const Aux_item_definition *def; /* Inheriting linked items is strange, but works. */ if (!target || !parent) return; for (i = 0; i < parent->length; i++) { if (parent->items[i].flags.inherit && !parent->items[i].flags.deleted && parent->items[i].inherit_limit != 1) { def = find_aux_item_definition(&parent->items[i]); if (def == NULL || !aux_item_add_perm(&parent->items[i], def, NULL, subordinate, target, 0, TRUE, TEXT_OBJECT_TYPE)) continue; copy_aux_item(&item, &parent->items[i]); init_aux_item_link(&item.linked_item); prepare_aux_item(&item, parent->items[i].creator, def); if (item.inherit_limit != 0) item.inherit_limit -= 1; target->items = srealloc(target->items, (target->length + 1) * sizeof(Aux_item)); target->items[target->length] = item; *counter += 1; target->items[target->length].aux_no = *counter; target->length += 1; aux_item_call_add_triggers(def, TEXT_OBJECT_TYPE, target->length - 1, object_no, object, &target->items[target->length]); } } } /* Filter the items in ORIGINAL for sending to the person logged in on * connection CONN. On entry, RESULT should be a pointer to an empty * aux_item_list. It will be filled with copies of those items in * ORIGINAL that CONN is allowed to see. All memory allocated in this * call is allocated with tmp_alloc. */ void filter_aux_item_list(const Aux_item_list *original, Aux_item_list *result, const Connection *viewer_conn) { Aux_item *orig_aux; unsigned long from, to; assert(viewer_conn != NULL); result->items = tmp_alloc(original->length * sizeof (Aux_item)); result->length = 0; to = 0; for (from = 0; from < original->length; from++) { orig_aux = &original->items[from]; if (orig_aux->flags.secret && !is_supervisor(orig_aux->creator, viewer_conn) && !ENA_C(viewer_conn, admin, 4)) { continue; } result->items[to] = *orig_aux; if (orig_aux->flags.hide_creator && !is_supervisor(orig_aux->creator, viewer_conn) && !ENA_C(viewer_conn, admin, 4)) { result->items[to].creator = 0; } result->length += 1; to += 1; } } /* * check_delete_aux * * Return TRUE if ACTPERS may delete ITEM. DEF is the item's definition * or NULL. */ Success check_delete_aux_item_list(const Number_list *items_to_delete, const Aux_item_list *list_to_delete_from, const Conf_no subordinate) { long i; const Aux_item *item; const Aux_item_definition *def; for (i = 0; i < items_to_delete->length; i++) { if (items_to_delete->data[i] == 0) continue; /* Get pointer to the item and to its definition */ if ((item = find_aux_item(list_to_delete_from, items_to_delete->data[i])) == NULL) { kom_errno = KOM_AUX_PERM; err_stat = i; return FAILURE; } /* Check all sorts of permissions */ def = find_aux_item_definition(item); if (def == NULL) { kom_errno = KOM_AUX_PERM; err_stat = i; return FAILURE; } else if (def->may_not_delete) { kom_errno = KOM_AUX_PERM; err_stat = i; return FAILURE; } else if (item->creator == 0) { if (!ENA(wheel, 8)) { kom_errno = KOM_AUX_PERM; err_stat = i; return FAILURE; } } else if (item->creator != ACTPERS) { if (!ENA(wheel, 8) && !is_supervisor(item->creator, active_connection) && (!def->owner_delete || !is_supervisor(subordinate, active_connection))) { kom_errno = KOM_AUX_PERM; err_stat = i; return FAILURE; } } /* For already deleted items, clear them out of the list */ if (item->flags.deleted) items_to_delete->data[i] = 0; } return OK; } /* * delete_aux_item_list * * Mark ITEM as deleted. LIST is the list we're deleting * the item from. * * Call commit_aux_item_list to make the changes permanent */ void delete_aux_item_list(const Number_list *items_to_delete, Aux_item_list *list_to_delete_from, enum object_type object_type, unsigned long object_no, void *object) { long i; Aux_item *item; const Aux_item *linked_item; long item_index; long item_to_delete; unsigned long linked_object_no; Number_list linked_delete; Aux_item_list *linked_item_list; void *linked_object; for (i = 0; i < items_to_delete->length; i++) { if (items_to_delete->data[i] == 0) continue; item_index = find_aux_item_index(list_to_delete_from, items_to_delete->data[i]); if (item_index == -1) restart_kom("Call to delete_aux_item_list without call to check_delete_aux_item_list"); item = &list_to_delete_from->items[item_index]; item->flags.deleted = 1; aux_item_call_delete_triggers(find_aux_item_definition(item), object_type, item_index, object_no, object, item); /* If we have linked items, delete them too. It is safe to do this with a recursive call since we have marked this item as deleted. But just to avoid pointless recursion, only do the recursive call if the corresponding item isn't marked as deleted */ linked_item = find_linked_aux_item(item); if (linked_item && !linked_item->flags.deleted) { /* Set up the delete list for the target object */ item_to_delete = item->linked_item.target_item; linked_delete.length = 1; linked_delete.data = &item_to_delete; /* Find the item list to delete from */ linked_item_list = find_linked_aux_item_list(item); /* Set up the object and object_no parameters for delete */ switch (item->linked_item.target_type) { case CONF_OBJECT_TYPE: linked_object_no = item->linked_item.target_object.conf; linked_object = (void*)cached_get_conf_stat(linked_object_no); break; case TEXT_OBJECT_TYPE: linked_object_no = item->linked_item.target_object.text; linked_object = (void*)cached_get_text_stat(linked_object_no); break; case INFO_OBJECT_TYPE: linked_object_no = 0; linked_object = NULL; break; default: kom_log("delete_aux_item_list(): bad target type\n"); return; } /* We only get here if the link type is known */ delete_aux_item_list(&linked_delete, linked_item_list, item->linked_item.target_type, linked_object_no, linked_object); } } } /* * Reverse tentative deletions from an aux-item-list * Only deletions that have not been made permanent by a call to * commit_aux_item_list can be undeleted. */ void undelete_aux_item_list(const Number_list *items_to_undelete, Aux_item_list *list_to_undelete_from, enum object_type object_type, unsigned long object_no, void *object) { enum kom_err saved_kom_errno; unsigned long saved_err_stat; long i; Aux_item *item; const Aux_item *linked_item; Aux_item_list *linked_item_list; long item_index; long item_to_undelete; unsigned long linked_object_no; Number_list linked_undelete; void *linked_object; saved_kom_errno = kom_errno; saved_err_stat = err_stat; for (i = 0; i < items_to_undelete->length; i++) { if (items_to_undelete->data[i] == 0) continue; item_index = find_aux_item_index(list_to_undelete_from, items_to_undelete->data[i]); if (item_index == -1) restart_kom("Call to undelete_aux_item_list without call to check_delete_aux_item_list"); item = &list_to_undelete_from->items[item_index]; item->flags.deleted = 0; aux_item_call_undelete_triggers(find_aux_item_definition(item), object_type, item_index, object_no, object, item); /* If we have linked items, undelete them too. It is safe to do this with a recursive call since we have marked this item as undeleted. But just to avoid pointless recursion, only do the recursive call if the corresponding item is marked as deleted */ linked_item = find_linked_aux_item(item); if (linked_item && linked_item->flags.deleted) { /* Set up the undelete list for the target object */ item_to_undelete = item->linked_item.target_item; linked_undelete.length = 1; linked_undelete.data = &item_to_undelete; /* Find the item list to undelete from */ linked_item_list = find_linked_aux_item_list(item); /* Set up the object and object_no parameters for undelete */ switch (item->linked_item.target_type) { case CONF_OBJECT_TYPE: linked_object_no = item->linked_item.target_object.conf; linked_object = (void*)cached_get_conf_stat(linked_object_no); break; case TEXT_OBJECT_TYPE: linked_object_no = item->linked_item.target_object.text; linked_object = (void*)cached_get_text_stat(linked_object_no); break; case INFO_OBJECT_TYPE: linked_object_no = 0; linked_object = NULL; break; default: kom_log("undelete_aux_item_list(): bad link type\n"); kom_errno = saved_kom_errno; err_stat = saved_err_stat; return; } /* We only get here if the link type is known */ undelete_aux_item_list(&linked_undelete, linked_item_list, item->linked_item.target_type, linked_object_no, linked_object); } } kom_errno = saved_kom_errno; err_stat = saved_err_stat; } /* * Commit deletions in the aux-item-list. After this has been called * undelete_aux_item_list has no effect. The memory associated with * the deleted items is not released until the entire list is * released from memory or reallocated. */ static void commit_aux_item_list_internal(Aux_item_list *list_to_commit, Bool shallow) { long i; /* Loop index */ long target; /* Where to move items when compacting */ const Aux_item *linked_item; Aux_item_list *aux_item_list; target = 0; for (i = 0; i < list_to_commit->length; i++) { if (list_to_commit->items[i].flags.deleted) { /* Clear the data in the aux item */ s_clear(&list_to_commit->items[i].data); /* If the item we're looking at is linked to another item, we have to commit the list of the object the link points to. To avoid infinite recursion only do this if the linked item is marked as deleted */ linked_item = find_linked_aux_item(&list_to_commit->items[i]); if (linked_item && linked_item->flags.deleted && !shallow) { aux_item_list = find_linked_aux_item_list(&list_to_commit->items[i]); commit_aux_item_list_internal(aux_item_list, TRUE); mark_linked_object_as_changed(&list_to_commit->items[i]); } } else if (target != i) { /* If we have deleted an item earlier, compact the list */ list_to_commit->items[target] = list_to_commit->items[i]; list_to_commit->items[i].data = EMPTY_STRING; target += 1; } else { /* If we have not deleted an item, bump target up one */ target += 1; } } /* Zero out all the unused slots in the array. This is not strictly necessary but looks better and makes finding bugs a bit easier */ memset(&list_to_commit->items[target], 0, (list_to_commit->length - target) * sizeof(Aux_item)); /* Target points to one index more than the last non-deleted item */ list_to_commit->length = target; } void commit_aux_item_list(Aux_item_list *list_to_commit) { commit_aux_item_list_internal(list_to_commit, FALSE); } /* * find_aux_item * * Return a pointer to the item in LIST with aux_no AUX-NO. * Returns NULL if there is no such item. */ static const Aux_item * find_aux_item(const Aux_item_list *list, unsigned long aux_no) { long item_index = find_aux_item_index(list, aux_no); if (item_index == -1) return NULL; return &list->items[item_index]; } /* ********************************************************************** * ********************************************************************** * * The following calls are specific for various types of items. They * are here simply to collect all of them in the same place. * * The following functions are defined for each type * * X_check_add_aux_item_list(X *obj, Aux_item_list *list, * Connection *creating_conn) * * Return OK if CREATOR is allowed to add ITEM or LIST to OBJ. * DEF is a pointer to the definition of ITEM or NULL. You must call * prepare_aux_item_list before calling these. * * * X_add_aux_item_list(X *obj, Aux_item_definition *list, Pers_no creator) * * Add ITEM or all the items in LIST to OBJ. CREATOR is the person * adding the items. The creator field of the items are set to * creator. This call does not check permissions first. You need * to call prepare_aux_item_list before calling these, and you * should use X_check_add_aux_item_list or X_check_add_aux_item * before calling these. * * */ Success text_stat_check_add_aux_item_list(Text_stat *text_s, Aux_item_list *list, Connection *creating_conn) { Aux_item *item; unsigned long i; const Aux_item_definition *def; assert(creating_conn != NULL); if (list == NULL) return OK; kom_errno = KOM_NO_ERROR; for (i = 0; i < list->length; i++) { item = &list->items[i]; def = find_aux_item_definition(item); if (def == NULL) { kom_errno = KOM_ILL_AUX; err_stat = i; return FAILURE; } if (!aux_item_add_perm(item, def, creating_conn, text_s?text_s->author:creating_conn->pers_no, text_s?&text_s->aux_item_list:NULL, 0, text_s == NULL, TEXT_OBJECT_TYPE) || !aux_item_check_unique(item, def, list, i + 1) || !def->texts) { kom_errno = kom_errno?kom_errno:KOM_AUX_PERM; err_stat = i; return FAILURE; } } return OK; } void text_stat_add_aux_item_list(Text_stat *text_s, Text_no text_no, Aux_item_list *item_list, Pers_no item_creator) { aux_item_list_add_items(&text_s->aux_item_list, item_list, TEXT_OBJECT_TYPE, text_no, text_s, &text_s->highest_aux, item_creator); } /* ================================================================== */ Success conf_stat_check_add_aux_item_list(Conference *conf, Conf_no conf_no, Aux_item_list *list, Connection *creating_conn, Bool creating) { unsigned long i; Aux_item *item; const Aux_item_definition *def; assert(conf != NULL); assert(conf_no != 0); assert(creating_conn != NULL); if (list == NULL) return OK; kom_errno = KOM_NO_ERROR; for (i = 0; i < list->length; i++) { item = &list->items[i]; def = find_aux_item_definition(item); if (def == NULL) { kom_errno = KOM_ILL_AUX; err_stat = i; return FAILURE; } if (!aux_item_add_perm(item, def, creating_conn, conf_no, &conf->aux_item_list, 0, creating, CONF_OBJECT_TYPE) || !aux_item_check_unique(item, def, list, i + 1) || (!conf->type.letter_box && !def->confs) || (conf->type.letter_box && !def->letterboxes)) { kom_errno = kom_errno?kom_errno:KOM_AUX_PERM; err_stat = i; return FAILURE; } } return OK; } void conf_stat_add_aux_item_list(Conference *conf, Conf_no conf_no, Aux_item_list *item_list, Pers_no item_creator) { aux_item_list_add_items(&conf->aux_item_list, item_list, CONF_OBJECT_TYPE, conf_no, conf, &conf->highest_aux, item_creator); } Success system_check_add_aux_item_list(Info *info, Aux_item_list *list, Connection *creating_conn) { unsigned long i; Aux_item *item; const Aux_item_definition *def; assert(creating_conn != NULL); if (list == NULL) return OK; kom_errno = KOM_NO_ERROR; for (i = 0; i < list->length; i++) { item = &list->items[i]; def = find_aux_item_definition(item); if (def == NULL) { kom_errno = KOM_ILL_AUX; err_stat = i; return FAILURE; } /* Pass creating_conn->pers_no as the subordinate, so that the owner checks will be short-circuited. When we arrive here, we already know that the user has enough privileges to create aux-items on the system. See modify_system_info(), especially the call to ENA(). */ if (!aux_item_add_perm(item, /* item */ def, /* definition */ creating_conn, /* creating_conn */ creating_conn->pers_no, /* subordinate */ &info->aux_item_list, /* add_to_list */ 0, /* start_looking_at */ FALSE, /* creating */ INFO_OBJECT_TYPE) || !aux_item_check_unique(item, def, list, i + 1) || !def->system) { kom_errno = kom_errno?kom_errno:KOM_AUX_PERM; err_stat = i; return FAILURE; } } return OK; } void system_add_aux_item_list(Info *info, Aux_item_list *item_list, Pers_no item_creator) { aux_item_list_add_items(&info->aux_item_list, item_list, INFO_OBJECT_TYPE, 0, info, &info->highest_aux_no, item_creator); } extern Success query_predefined_aux_items(Number_list *result) { Aux_item_definition *def; result->data = tmp_alloc(sizeof(unsigned long) * num_aux_item_definitions); if (result->data == NULL) { restart_kom("Out of memory in query_predefined_aux_items.\n"); } result->length = 0; def = aux_item_definition_list; while (def != NULL) { if (def->tag != 0) { assert((unsigned long)result->length < num_aux_item_definitions); result->data[result->length] = def->tag; result->length += 1; } def = def->next; } return OK; } static void aux_item_trigger_mark_text(Aux_item_trigger_data *data) { Text_no text_no; Text_stat *text_stat; String_size ill_char; text_no = s_strtol(data->item->data, &ill_char); VOID_GET_T_STAT(text_stat, text_no); if (text_stat->no_of_marks < param.max_marks_text) text_stat->no_of_marks += 1; mark_text_as_changed(text_no); } static void aux_item_trigger_unmark_text(Aux_item_trigger_data *data) { Text_no text_no; Text_stat *text_stat; String_size ill_char; text_no = s_strtol(data->item->data, &ill_char); VOID_GET_T_STAT(text_stat, text_no); if (text_stat->no_of_marks > 0) text_stat->no_of_marks -= 1; mark_text_as_changed(text_no); } static void aux_item_trigger_mirror_faq(Aux_item_trigger_data *data) { Text_no text_no; Aux_item item_data; char conf_no_string[2+3*sizeof(unsigned long)]; String_size ill_char; String str; if (data->object == NULL) return; if (data->object_type != CONF_OBJECT_TYPE && data->object_type != INFO_OBJECT_TYPE) { return; } /* Get the object number of where we want to put the new item */ text_no = s_strtol(data->item->data, &ill_char); /* Create the string for the new item */ sprintf(conf_no_string, "%lu", (unsigned long)data->object_no); str = s_fcrea_str(conf_no_string); /* Fill in the new item */ init_aux_item(&item_data); item_data.tag = aux_faq_for_conf; /* Mirror of FAQ item */ item_data.data = str; /* Create the link */ aux_item_link_items(data->object_type, data->object_no, data->object, data->item, TEXT_OBJECT_TYPE, text_no, NULL, &item_data ); } /* * Generic link trigger. This is primarily for testing. * * The item must contain three fields, separated with a space character. * Field one is a character containing specifying the object type the * other end of the link is supposed to be in. If it is 'C', the link is * to a conference. If it is 'T', the link is to a text. If it is 'I', * the link is to the system info. * * The second field is the item tag to use for the other end of the link. * * The third field is the object id of the target object. For the * system info it is ignored but must be present. * * Some examples: * "C 99 123": Link to an item of type 99 in conference 123 * "I 92 9": Link to an item of type 92 in the system info * "T 22 191": Link to an item of type 22 in text 191 * * The created item will contain the same kind of information. */ static void aux_item_trigger_link_item(Aux_item_trigger_data *data) { char object_no_string[100]; char *tmp_str; char type_char; enum object_type target_object_type; unsigned long target_item_tag, target_object_no; int nread; Aux_item item_data; init_aux_item(&item_data); /* ---------------------------------------- * Find the data for the linked item * * The object type, object id and item tag * are in the item the trigger is called * for * * The string is given by the current item */ tmp_str = s_crea_c_str(data->item->data); nread = sscanf(tmp_str, "%c %lu %lu", &type_char, &target_item_tag, &target_object_no); string_free(tmp_str); if (nread != 3) return; switch (type_char) { case 'T': target_object_type = TEXT_OBJECT_TYPE; break; case 'C': target_object_type = CONF_OBJECT_TYPE; break; case 'I': target_object_type = INFO_OBJECT_TYPE; break; default: return; } /* Create the string for the linked item */ switch (data->object_type) { case TEXT_OBJECT_TYPE: type_char = 'T'; break; case CONF_OBJECT_TYPE: type_char = 'C'; break; case INFO_OBJECT_TYPE: type_char = 'I'; break; default: type_char = '?'; break; } sprintf(object_no_string, "%c %lu %lu", type_char, (unsigned long)data->item->tag, (unsigned long)data->object_no); /* * Create the mirror item in item_data * * Item tag is found above * Item data is found above * Item link target item is the item-no of the current item * Item link target object type is the object type in the trigger data * Item link target object no is the object no in the trigger data */ item_data.tag = target_item_tag; item_data.data = s_fcrea_str(object_no_string); aux_item_link_items(data->object_type, data->object_no, data->object, data->item, target_object_type, target_object_no, NULL, &item_data ); } /* * Aux item validators */ static Success aux_item_validate_existing_text(Aux_item_validation_data *v_data) { Text_stat *text_stat; Text_no text_no; String_size ill_char; text_no = s_strtol(v_data->item->data, &ill_char); GET_T_STAT(text_stat, text_no, FAILURE); if (v_data->creating_conn != NULL && text_read_access(v_data->creating_conn, text_no, text_stat)) { return OK; } return FAILURE; } lyskom-server-2.1.2/src/server/debug.c0000664000015100472110000001075107722446226013363 /* * $Id: debug.c,v 1.12 2003/08/25 17:13:27 ceder Exp $ * Copyright (C) 1991, 1993-1996, 1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * debug.c * * Testing and debugging calls. */ #ifdef HAVE_CONFIG_H # include #endif #ifdef DEBUG_CALLS # ifdef HAVE_MALLINFO # include # endif #endif #include #include #include "timewrap.h" #include "misc-types.h" #include "kom-types.h" #include "kom-errno.h" #include "cache.h" #include "async.h" #include "com.h" #include "connections.h" #include "services.h" #include "manipulate.h" #include "log.h" #include "lyskomd.h" #ifdef DEBUG_CALLS extern Success get_memory_info (Memory_info *result) { struct mallinfo info; CHK_CONNECTION(FAILURE); #ifdef HAVE_MALLINFO info = mallinfo(); result->arena = info.arena; result->ordblks = info.ordblks; result->smblks = info.smblks; result->hblks = info.hblks; result->hblkhd = info.hblkhd; result->usmblks = info.usmblks; result->fsmblks = info.fsmblks; result->uordblks = info.uordblks; result->fordblks = info.fordblks; result->keepcost = info.keepcost; #else result->arena = 0; result->ordblks = 0; result->smblks = 0; result->hblks = 0; result->hblkhd = 0; result->usmblks = 0; result->fsmblks = 0; result->uordblks = 0; result->fordblks = 0; result->keepcost = 0; #endif return OK; } extern Success set_marks (Text_no text_no, unsigned long no_of_marks) { Text_stat *text_s; CHK_LOGIN(FAILURE); GET_T_STAT(text_s, text_no, FAILURE); text_s->no_of_marks = no_of_marks; mark_text_as_changed(text_no); return OK; } extern Success backdate_text(Text_no text_no, unsigned long seconds) { Text_stat *text_s; CHK_LOGIN(FAILURE); GET_T_STAT(text_s, text_no, FAILURE); text_s->creation_time -= seconds; mark_text_as_changed(text_no); return OK; } extern Success backdate_comment_link(Text_no parent, Text_no child, unsigned long seconds) { Text_stat *child_s; unsigned short nmisc; Misc_info *misc; Bool in_comm_group = FALSE; Bool link_found = FALSE; CHK_LOGIN(FAILURE); GET_T_STAT(child_s, child, FAILURE); for (nmisc = child_s->no_of_misc, misc = child_s->misc_items; nmisc > 0; --nmisc, ++misc) { switch (misc->type) { case recpt: case cc_recpt: case bcc_recpt: case comm_in: case footn_in: in_comm_group = FALSE; break; case comm_to: case footn_to: in_comm_group = (misc->datum.text_link == parent); if (in_comm_group) link_found = TRUE; break; case loc_no: case rec_time: case sent_by: break; case sent_at: if (in_comm_group) { misc->datum.sent_at -= seconds; mark_text_as_changed(child); return OK; } break; #ifndef COMPILE_CHECKS default: #endif case unknown_info: restart_kom("backdate_comment_link(): Illegal misc-item.\n"); } } if (link_found) { kom_errno = KOM_INDEX_OUT_OF_RANGE; kom_log("backdate_comment_link(): Test suite error:" " no sent_at found for parent=%ld, child=%ld\n", (unsigned long)parent, (unsigned long)child); } else { kom_errno = KOM_NOT_COMMENT; kom_log("backdate_comment_link(): Test suite error:" " %ld is neither comment nor footnote to %ld.\n", (unsigned long)child, (unsigned long)parent); } return FAILURE; } extern Success server_sleep(int seconds) { CHK_CONNECTION(FAILURE); sleep(seconds); return OK; } /* start_garb is in text-garb.c since it needs access to static variables */ #endif lyskom-server-2.1.2/src/server/send-async.c0000664000015100472110000003307107721716130014332 /* * $Id: send-async.c,v 0.50 2003/08/23 16:38:14 ceder Exp $ * Copyright (C) 1991, 1993-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * send-async.c -- Send messages about events to all connected clients. * * Written by Per Cederqvist 1990-07-22--23 */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include "timewrap.h" #include #include "misc-types.h" #include "s-string.h" #include "kom-types.h" #include "com.h" #include "async.h" #include "connections.h" #include "internal-connections.h" #include "async.h" #include "send-async.h" #include "prot-a-send-async.h" #include "lyskomd.h" #include "log.h" #include "param.h" #include "ldifftime.h" #include "kom-errno.h" #include "manipulate.h" #include "server-time.h" #include "timeval-util.h" void async_new_text_old(struct connection *cptr, Text_no text_no, Text_stat *text_s) { if (!param.send_async_messages) return; switch(cptr->protocol) { case 0: break; case 'A': if (handshake_ok(cptr, 0)) prot_a_async_new_text_old(cptr, text_no, text_s); break; default: restart_kom("async_new_text(): bad protocol.\n"); break; } } void async_new_text(struct connection *cptr, Text_no text_no, Text_stat *text_s) { if (!param.send_async_messages) return; switch(cptr->protocol) { case 0: break; case 'A': if (handshake_ok(cptr, 0)) prot_a_async_new_text(cptr, text_no, text_s); break; default: restart_kom("async_new_text(): bad protocol.\n"); break; } } void async_i_am_on(Who_info info) { Connection *cptr; Session_no i = 0; Who_info filtered; if (!param.send_async_messages) return; while ( (i = traverse_connections(i)) != 0 ) { cptr = get_conn_by_number(i); filtered = info; filtered.working_conference = filter_conf_no( info.working_conference, cptr); switch(cptr->protocol) { case 0: /* Not yet logged on. */ break; case 'A': if (handshake_ok(cptr, 0)) prot_a_async_i_am_on(cptr, filtered); break; default: restart_kom("async_i_am_on(): bad protocol.\n"); break; } } } void async_logout(Pers_no pers_no, Session_no session_no) { Connection *cptr; Session_no i = 0; if (!param.send_async_messages) return; while ( (i = traverse_connections(i)) != 0) { cptr = get_conn_by_number(i); if ( cptr == NULL ) { kom_log("async_logout(): cptr == NULL\n"); return; } switch(cptr->protocol) { case 0: break; case 'A': if (handshake_ok(cptr, 0)) prot_a_async_logout(cptr, pers_no, session_no); break; default: restart_kom("async_logout(): bad protocol.\n"); break; } } } void async_new_name(Conf_no conf_no, const String old_name, const String new_name) { Connection *cptr; Session_no i = 0; if (!param.send_async_messages) return; while ( (i = traverse_connections(i)) != 0) { cptr = get_conn_by_number(i); if ( cptr == NULL ) { kom_log("async_new_name(): cptr == NULL\n"); return; } switch(cptr->protocol) { case 0: break; case 'A': /* Check that cptr has enough privileges to know anything about the conference. */ if (handshake_ok(cptr, 0) && (has_access(conf_no, cptr, read_protected) || ENA_C(cptr, admin, 2) /* OK -- Uses ENA_C */ || ENA_C(cptr, wheel, 8))) /* OK -- Uses ENA_C */ { prot_a_async_new_name(cptr, conf_no, old_name, new_name); } break; default: restart_kom("async_new_name(): bad protocol.\n"); break; } } } #if 0 conf_deleted conf_created #endif void async_sync_db(void) { Connection *cptr; Session_no i = 0; if (!param.send_async_messages) return; while ( (i = traverse_connections(i)) != 0 ) { cptr = get_conn_by_number(i); if ( cptr == NULL ) { kom_log("async_sync_db(): cptr == NULL\n"); return; } switch(cptr->protocol) { case 0: break; case 'A': if (handshake_ok(cptr, ignore_dns)) prot_a_async_sync_db(cptr); break; default: restart_kom("async_sync_db(): bad protocol.\n"); break; } } } extern void async_forced_leave_conf (struct connection *cptr, Conf_no conf_no) { if (!param.send_async_messages) return; switch(cptr->protocol) { case 0: break; case 'A': if (handshake_ok(cptr, 0)) prot_a_async_forced_leave_conf(cptr, conf_no); break; default: restart_kom("async_forced_leave_conf(): bad protocol.\n"); break; } } void async_login(Pers_no pers_no, int client_no) { Connection *cptr; Session_no i = 0; if (!param.send_async_messages) return; while ( (i = traverse_connections(i)) != 0) { cptr = get_conn_by_number(i); if ( cptr == NULL ) { kom_log("async_login(): cptr == NULL\n"); return; } switch(cptr->protocol) { case 0: break; case 'A': if (handshake_ok(cptr, 0)) prot_a_async_login(cptr, pers_no, client_no); break; default: restart_kom("async_login(): bad protocol.\n"); break; } } } void async_rejected_connection(void) { Connection *cptr; Session_no i = 0; static struct timeval last_time = {0, 0}; if (!param.send_async_messages) return; if (timeval_nonzero(last_time) && timeval_diff_sec(current_time, last_time) < 60) { return; } last_time = current_time; while ( (i = traverse_connections(i)) != 0) { cptr = get_conn_by_number(i); if ( cptr == NULL ) { kom_log("async_rejected_connections(): cptr == NULL\n"); return; } switch(cptr->protocol) { case 0: break; case 'A': if (handshake_ok(cptr, ignore_dns)) prot_a_async_rejected_connection(cptr); break; default: restart_kom("async_rejected_connection(): bad protocol.\n"); break; } } } /* * Returns failure if no message was sent. */ Success async_send_message(Pers_no recipient, Pers_no sender, String message, Bool force_message) { return async_send_group_message(recipient, recipient, sender, message, force_message); } Success async_send_group_message(Pers_no recipient, Conf_no group_recipient, Pers_no sender, String message, Bool force_message) { Connection *cptr; Session_no i = 0; Success retval = FAILURE; Bool tmp = FALSE; kom_errno = KOM_MESSAGE_NOT_SENT; if (!param.send_async_messages) { err_stat = 0; kom_errno = KOM_FEATURE_DISABLED; return FAILURE; } while ( (i = traverse_connections(i)) != 0) { cptr = get_conn_by_number(i); if ( cptr == NULL ) { kom_log("async_send_message(): cptr == NULL\n"); err_stat = 0; kom_errno = KOM_INTERNAL_ERROR; return FAILURE; } switch(cptr->protocol) { case 0: break; case 'A': if ((recipient == 0 || (recipient == cptr->pers_no && recipient != 0 )) && handshake_ok(cptr, ignore_dns)) { if (force_message) { tmp = cptr->want_async[ay_send_message]; cptr->want_async[ay_send_message] = TRUE; } prot_a_async_send_message(cptr, group_recipient, sender, message); if (force_message) cptr->want_async[ay_send_message] = tmp; retval = OK; } break; default: restart_kom("async_send_message(): bad protocol.\n"); break; } } return retval; } void async_deleted_text(struct connection *cptr, Text_no text_no, Text_stat *text_s) { if (!param.send_async_messages) return; switch(cptr->protocol) { case 0: break; case 'A': if (handshake_ok(cptr, 0)) prot_a_async_deleted_text(cptr, text_no, text_s); break; default: restart_kom("async_deleted_text(): bad protocol.\n"); break; } } void async_new_recipient(struct connection *cptr, Text_no text_no, Conf_no conf_no, enum info_type type) { if (!param.send_async_messages) return; switch(cptr->protocol) { case 0: break; case 'A': if (handshake_ok(cptr, 0)) prot_a_async_new_recipient(cptr, text_no, conf_no, type); break; default: restart_kom("async_new_recipient(): bad protocol.\n"); break; } } void async_sub_recipient(struct connection *cptr, Text_no text_no, Conf_no conf_no, enum info_type type) { if (!param.send_async_messages) return; switch(cptr->protocol) { case 0: break; case 'A': if (handshake_ok(cptr, 0)) prot_a_async_sub_recipient(cptr, text_no, conf_no, type); break; default: restart_kom("async_sub_recipient(): bad protocol.\n"); break; } } void async_new_membership(struct connection *cptr, Pers_no pers_no, Conf_no conf_no) { if (!param.send_async_messages) return; switch(cptr->protocol) { case 0: break; case 'A': if (handshake_ok(cptr, 0)) prot_a_async_new_membership(cptr, pers_no, conf_no); break; default: restart_kom("async_new_membership(): bad protocol.\n"); break; } } void async_new_user_area(Pers_no person, Text_no old_user_area, Text_no new_user_area) { Connection *cptr; Session_no i = 0; if (!param.send_async_messages) return; while ((i = traverse_connections(i)) != 0) { cptr = get_conn_by_number(i); switch(cptr->protocol) { case 0: /* No protocol specified yet */ break; case 'A': /* Check that connection is logged on and allowed to see the user-area of PERSON. Check the want_async here to avoid the potentially expensive call to access_perm. */ if (handshake_ok(cptr, 0) && cptr->want_async[ay_new_user_area] == TRUE && has_access(person, cptr, unlimited)) { prot_a_async_new_user_area(cptr, person, old_user_area, new_user_area); } break; default: restart_kom("async_new_user_area(): bad protocol.\n"); break; } } } void async_new_presentation(Connection *cptr, Conf_no conf_no, Text_no old_presentation, Text_no new_presentation) { if (!param.send_async_messages) return; switch(cptr->protocol) { case 0: /* No protocol specified yet */ break; case 'A': if (handshake_ok(cptr, 0) && cptr->want_async[ay_new_presentation] == TRUE) { prot_a_async_new_presentation(cptr, conf_no, old_presentation, new_presentation); } break; default: restart_kom("async_new_presentation(): bad protocol.\n"); break; } } void async_new_motd(Connection *cptr, Conf_no conf_no, Text_no old_motd, Text_no new_motd) { if (!param.send_async_messages) return; switch(cptr->protocol) { case 0: /* No protocol specified yet */ break; case 'A': if (handshake_ok(cptr, 0) && cptr->want_async[ay_new_motd] == TRUE) prot_a_async_new_motd(cptr, conf_no, old_motd, new_motd); break; default: restart_kom("async_new_motd(): bad protocol.\n"); break; } } void async_text_aux_changed(Connection *cptr, Text_no text_no, Aux_item_list *aux_list, unsigned long highest_old_aux) { if (!param.send_async_messages) return; switch(cptr->protocol) { case 0: /* No protocol specified yet */ break; case 'A': if (handshake_ok(cptr, 0) && cptr->want_async[ay_text_aux_changed]) prot_a_async_text_aux_changed(cptr, text_no, aux_list, highest_old_aux); break; default: restart_kom("async_text_aux_changed(): bad protocol.\n"); break; } } #ifdef DEBUG_CALLS void async_garb_ended(int no_deleted) { Connection *cptr; Session_no i = 0; if (!param.send_async_messages) return; while ((i = traverse_connections(i)) != 0) { cptr = get_conn_by_number(i); switch(cptr->protocol) { case 0: /* No protocol specified yet */ break; case 'A': /* Check that connection is logged on. */ if (handshake_ok(cptr, 0)) prot_a_async_garb_ended(cptr, no_deleted); break; default: restart_kom("async_garb_ended(): bad protocol.\n"); break; } } } #endif lyskom-server-2.1.2/src/server/text-garb.c0000664000015100472110000002610407723627265014176 /* * $Id: text-garb.c,v 0.54 2003/08/29 10:43:33 ceder Exp $ * Copyright (C) 1991-1995, 1997-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * This file contains the functions that deletes old texts. * * Author: Per Cederqvist. */ #ifdef HAVE_CONFIG_H # include #endif #include #include "timewrap.h" #include #include #include #include #include "oop.h" #include "ldifftime.h" #include "s-string.h" #include "timeval-util.h" #include "kom-types.h" #include "text-garb.h" #include "kom-errno.h" #include "misc-types.h" #include "debug.h" #include "cache.h" #include "lyskomd.h" #include "log.h" #include "param.h" #include "server-time.h" #include "com.h" #include "async.h" #include "connections.h" #include "manipulate.h" #include "text.h" #include "unused.h" #include "isc-interface.h" #ifdef DEBUG_CALLS # include "send-async.h" # include "services.h" #endif BUGDECL; /* * This comment is a description of how this _could_ be done in a more * efficient way. It is not yet implemented. Design by Inge Wallin * and Per Cederqvist 1992-10-07. FIXME (bug 176). * * Today, all text statuses are read into the core during the garbage * collection phase. Due to step 3 below we think that we can reduce * the number of text-status-fetches by 95 %. * * 1) Allocate a bitmap with one bit for each text. Clear all bits. * This bit is set as soon as it is certain that this text should * not be deleted during this garbage collection pass. * 2) Loop over all persons: * + Set the bit for all his/her marked texts. * (This step may, or may not, be efficient. Profile your code!) * 3) Loop over all conferences: * + Loop over all texts in the conference: * + If the bit is already set, skip the text. * + Retrieve the text status from the data base. * + If it is old enough (in all the recipient conferences) * delete it. * else * set the bit. * + If it is too young to be deleted (only * considering this conferene) * + Set the bit for this text and all subsequent * texts in this conference. * 4) Loop over all remaining texts: * + If the bit is not set, * + delete the text. (It has no recipients). * 5) Deallocate the bitmap and wait 24 hours. */ static Text_no last_checked = 0; static struct timeval garb_timer; static Bool garb_timer_running = FALSE; static const double day_to_sec = 24 * 3600; static const double default_save = 1.0 * 24 * 3600; static Bool saved_by_aux(Text_stat *text_s) { unsigned short naux; for (naux = 0; naux < text_s->aux_item_list.length; ++naux) if (text_s->aux_item_list.items[naux].flags.dont_garb) return TRUE; return FALSE; } static Bool saved_by_recipient(Text_stat *text_s, double age) { unsigned short nmisc; Misc_info *misc; double limit = 0; Bool in_rec_group = FALSE; for (nmisc = text_s->no_of_misc, misc = text_s->misc_items; nmisc > 0; --nmisc, ++misc) { switch (misc->type) { case recpt: case cc_recpt: case bcc_recpt: if (cached_conf_exists(misc->datum.recipient)) { limit = (day_to_sec * cached_get_garb_nice(misc->datum.recipient)); if (age < limit) return TRUE; in_rec_group = TRUE; } else in_rec_group = FALSE; break; case comm_to: case comm_in: case footn_to: case footn_in: in_rec_group = FALSE; break; case loc_no: case rec_time: case sent_by: break; case sent_at: if (in_rec_group && ldifftime(current_time.tv_sec, misc->datum.sent_at) < limit) { return TRUE; } break; #ifndef COMPILE_CHECKS default: #endif case unknown_info: restart_kom("saved_by_recipient(): Illegal misc-item.\n"); } } return FALSE; } static Bool saved_by_comment(Text_stat *text_s) { unsigned short nmisc; Misc_info *misc; Bool in_comm_group = FALSE; for (nmisc = text_s->no_of_misc, misc = text_s->misc_items; nmisc > 0; --nmisc, ++misc) { switch (misc->type) { case recpt: case cc_recpt: case bcc_recpt: in_comm_group = FALSE; break; case comm_to: case comm_in: case footn_to: case footn_in: in_comm_group = TRUE; break; case loc_no: case rec_time: case sent_by: break; case sent_at: if (in_comm_group && ldifftime(current_time.tv_sec, misc->datum.sent_at) < default_save) { return TRUE; } break; #ifndef COMPILE_CHECKS default: #endif case unknown_info: restart_kom("saved_by_comment(): Illegal misc-item.\n"); } } return FALSE; } /* Examine ``text_no''. (``text_s'' is the text-stat of ``text_no'', or NULL). If ``text_no'' has a comment or footnote, return TRUE, else FALSE. If ``text_no'' is a comment or footnote to ``parent'', the number of seconds that has passed since it became so will be returned in ``comment_age''. Set ``limit'' to the greatest keep-commented value found on any of the recipients of ``text_no'', converted to seconds. (``parent'' is not involved in this computation.) */ static Bool find_comment_limit_and_age(Text_no text_no, Text_stat *text_s, Text_no parent, double *comment_age, double *limit) { unsigned short nmisc; Misc_info *misc; Bool in_comm_group = FALSE; Bool has_comments = FALSE; double tmp; if (text_s == NULL) text_s = cached_get_text_stat(text_no); if (text_s == NULL) { *comment_age = 0; *limit = 0; return FALSE; } *comment_age = ldifftime(current_time.tv_sec, text_s->creation_time); *limit = default_save; for (nmisc = text_s->no_of_misc, misc = text_s->misc_items; nmisc > 0; --nmisc, ++misc) { switch (misc->type) { case recpt: case cc_recpt: case bcc_recpt: in_comm_group = FALSE; if (cached_conf_exists(misc->datum.recipient)) { tmp = day_to_sec * cached_get_keep_commented( misc->datum.recipient); if (tmp > *limit) *limit = tmp; } break; case comm_to: case footn_to: in_comm_group = (misc->datum.text_link == parent); break; case comm_in: case footn_in: in_comm_group = FALSE; has_comments = TRUE; break; case loc_no: case rec_time: case sent_by: break; case sent_at: if (in_comm_group) *comment_age = ldifftime(current_time.tv_sec, misc->datum.sent_at); break; #ifndef COMPILE_CHECKS default: #endif case unknown_info: restart_kom("find_comment_limit_and_age(): Illegal misc-item.\n"); } } return has_comments; } static Bool saved_by_keep_commented(Text_no text_no, Text_stat *text_s) { unsigned short nmisc; Misc_info *misc; double comment_age; double parent_limit; double limit; if (!find_comment_limit_and_age(text_no, text_s, 0, &comment_age, &parent_limit)) return FALSE; for (nmisc = text_s->no_of_misc, misc = text_s->misc_items; nmisc > 0; --nmisc, ++misc) { switch (misc->type) { case comm_in: case footn_in: find_comment_limit_and_age(misc->datum.text_link, NULL, text_no, &comment_age, &limit); if (limit < parent_limit) limit = parent_limit; if (comment_age < limit) return TRUE; break; case recpt: case cc_recpt: case bcc_recpt: case comm_to: case footn_to: case loc_no: case rec_time: case sent_by: case sent_at: break; #ifndef COMPILE_CHECKS default: #endif case unknown_info: restart_kom("saved_by_keep_commented(): Illegal misc-item.\n"); } } return FALSE; } static Bool saved(Text_no text_no, Text_stat *text_s) { double age; if (text_s->no_of_marks > 0) return TRUE; age = ldifftime(current_time.tv_sec, text_s->creation_time); if (age < default_save) return TRUE; if (saved_by_aux(text_s)) return TRUE; if (saved_by_recipient(text_s, age)) return TRUE; if (saved_by_comment(text_s)) return TRUE; if (saved_by_keep_commented(text_no, text_s)) return TRUE; return FALSE; } /* * Delete old texts. * * Return value is TRUE if there is nothing more to do right now, * FALSE if this function should be called again as soon as the * server has some time over. */ static Bool garb_text(void) { static long deleted_texts = 0; Text_stat *text_s; if (param.garb_enable == FALSE) return TRUE; if (last_checked == 0) kom_log("MSG: garb started.\n"); tell_cache_garb_text(1); last_checked = traverse_text( last_checked ); if (last_checked == 0) { kom_log("MSG: garb ready. %lu texts deleted.\n", (unsigned long)deleted_texts); tell_cache_garb_text(0); #ifdef DEBUG_CALLS async_garb_ended(deleted_texts); #endif deleted_texts = 0; return TRUE; } if ((text_s = cached_get_text_stat(last_checked)) == NULL) { kom_log("ERROR: garb_text(): Can't get text-stat.\n"); tell_cache_garb_text(0); return FALSE; } if (!saved(last_checked, text_s)) { VBUG(("garb_text: deleting %lu\n", last_checked)); do_delete_text(last_checked, text_s); deleted_texts++; } tell_cache_garb_text(0); return FALSE; } static void * garb_callback(oop_source *source, struct timeval UNUSED(tv), void *UNUSED(user)) { int rv = 0; set_time(); if (garb_text() == FALSE) if (server_idle()) rv = setup_timer(&garb_timer, param.garbtimeout); else rv = setup_timer(&garb_timer, param.garb_busy_postponement); else rv = setup_timer(&garb_timer, param.garb_interval); if (rv < 0) kom_log("gettimeofday failed: %s\n", strerror(errno)); source->on_time(source, garb_timer, garb_callback, NULL); return OOP_CONTINUE; } void start_garb_thread(oop_source *src) { stop_garb_thread(src); garb_timer = OOP_TIME_NOW; src->on_time(src, garb_timer, garb_callback, NULL); garb_timer_running = TRUE; } void stop_garb_thread(oop_source *src) { if (garb_timer_running) { src->cancel_time(src, garb_timer, garb_callback, NULL); garb_timer_running = FALSE; } } #ifdef DEBUG_CALLS Success start_garb(void) { CHK_CONNECTION(FAILURE); kom_log("MSG: garb restarted.\n"); last_checked = 0; start_garb_thread(oop_sys_source(kom_server_oop_src)); return OK; } #endif lyskom-server-2.1.2/src/server/isc-parse.c0000664000015100472110000000351107721716127014156 /* * $Id: isc-parse.c,v 0.23 2003/08/23 16:38:16 ceder Exp $ * Copyright (C) 1991, 1993-1994, 1996, 1998-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * Generic parse routines. */ #ifdef HAVE_CONFIG_H # include #endif #ifdef HAVE_STRING_H # include #else # ifdef HAVE_STRINGS_H # include # endif #endif #ifndef HAVE_STRCHR # define strchr index #endif #include #include "timewrap.h" #include #include "s-string.h" #include "kom-types.h" #include "com.h" #include "async.h" #include "connections.h" #include "isc-parse.h" #include "kom-config.h" int parse_char(Connection *client) { if ( client->unparsed.len <= client->first_to_parse ) longjmp(parse_env, KOM_MSG_INCOMPLETE); return client->unparsed.string[ client->first_to_parse++ ]; } int parse_nonwhite_char(Connection *client) { int c; while (strchr(WHITESPACE, c = parse_char(client)) != NULL) ; return c; } lyskom-server-2.1.2/src/server/prot-a-output.c0000664000015100472110000010332107721716127015030 /* * $Id: prot-a-output.c,v 0.71 2003/08/23 16:38:15 ceder Exp $ * Copyright (C) 1991-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * prot-a-output.c - write objects through an ISC connection. * * Written by ceder 1990-07-13 */ #ifdef HAVE_CONFIG_H # include #endif #include "timewrap.h" #include #include #include #ifdef HAVE_STDARG_H # include #endif #include #include "oop.h" #include "s-string.h" #include "kom-types.h" #include "isc-interface.h" #include "com.h" #include "async.h" #include "connections.h" #include "prot-a-output.h" #include "lyskomd.h" #include "param.h" #include "local-to-global.h" void prot_a_output_ul(Connection *fp, unsigned long ul) { isc_putc(' ', fp->isc_session); isc_putul(ul, fp->isc_session); } static void prot_a_output_float(Connection *fp, float v) { char buf[80]; #ifdef HAVE_SNPRINTF snprintf(buf, sizeof(buf), " %g", v); #else sprintf(buf, " %g", v); #endif isc_puts(buf, fp->isc_session); } void prot_a_output_person (Connection *fp, Person *person) { Local_text_no first_created = l2g_next_key(&person->created_texts, 0); Local_text_no uncreated = l2g_first_appendable_key(&person->created_texts); Local_text_no num_created; if (first_created == 0) first_created = uncreated; num_created = uncreated - first_created; prot_a_output_string (fp, person->username); prot_a_output_priv_bits (fp, person->privileges); prot_a_output_personal_flags (fp, person->flags); prot_a_output_time(fp, person->last_login); prot_a_output_ul(fp, person->user_area); prot_a_output_ul(fp, person->total_time_present); prot_a_output_ul(fp, person->sessions); prot_a_output_ul(fp, person->created_lines); prot_a_output_ul(fp, person->created_bytes); prot_a_output_ul(fp, person->read_texts); prot_a_output_ul(fp, person->no_of_text_fetches); prot_a_output_ul(fp, person->created_persons); prot_a_output_ul(fp, person->created_confs); prot_a_output_ul(fp, first_created); prot_a_output_ul(fp, num_created); prot_a_output_ul(fp, person->marks.no_of_marks); prot_a_output_ul(fp, person->conferences.no_of_confs); } void prot_a_output_membership_type(Connection *fp, const Membership_type type) { isc_putc(' ', fp->isc_session); isc_putc(type.invitation + '0', fp->isc_session); isc_putc(type.passive + '0', fp->isc_session); isc_putc(type.secret + '0', fp->isc_session); isc_putc(type.passive_message_invert + '0', fp->isc_session); isc_putc(type.reserved2 + '0', fp->isc_session); isc_putc(type.reserved3 + '0', fp->isc_session); isc_putc(type.reserved4 + '0', fp->isc_session); isc_putc(type.reserved5 + '0', fp->isc_session); } void prot_a_output_membership(Connection *fp, const Membership *mship) { unsigned int i; prot_a_output_ul(fp, mship->position); prot_a_output_time(fp, mship->last_time_read); prot_a_output_ul(fp, mship->conf_no); prot_a_output_ul(fp, mship->priority); prot_a_output_ul(fp, mship->no_of_read_ranges); if (mship->read_ranges != NULL && mship->no_of_read_ranges > 0) { isc_puts(" {", fp->isc_session); for (i = 0; i < mship->no_of_read_ranges; i++) { prot_a_output_ul(fp, mship->read_ranges[i].first_read); prot_a_output_ul(fp, mship->read_ranges[i].last_read); } isc_puts(" }", fp->isc_session); } else isc_puts(" *", fp->isc_session); prot_a_output_ul(fp, mship->added_by); prot_a_output_time(fp, mship->added_at); prot_a_output_membership_type(fp, mship->type); } void prot_a_output_membership_10(Connection *fp, const Membership *mship) { prot_a_output_ul(fp, mship->position); prot_a_output_membership_old(fp, mship); prot_a_output_ul(fp, mship->added_by); prot_a_output_time(fp, mship->added_at); prot_a_output_membership_type(fp, mship->type); } static void prot_a_output_read_texts(Connection *fp, const Membership *mship) { if (mship->read_ranges == NULL) isc_puts(" 0 0 *", fp->isc_session); else { struct read_range *begin; struct read_range *end; assert(mship->read_ranges != NULL); assert(mship->no_of_read_ranges > 0); begin = &mship->read_ranges[0]; end = begin + mship->no_of_read_ranges; if (begin->first_read == 1) { prot_a_output_ul(fp, begin->last_read); begin++; } else isc_puts(" 0", fp->isc_session); if (begin == end) isc_puts(" 0 *", fp->isc_session); else { unsigned long no_of_read = 0; const struct read_range *ptr; for (ptr = begin; ptr < end; ++ptr) no_of_read += ptr->last_read - ptr->first_read + 1; prot_a_output_ul(fp, no_of_read); if (mship->skip_read_texts) isc_puts(" *", fp->isc_session); else { isc_puts(" {", fp->isc_session); for (ptr = begin; ptr < end; ++ptr) { Local_text_no lno; for (lno = ptr->first_read; lno <= ptr->last_read; lno++) prot_a_output_ul(fp, lno); } isc_puts(" }", fp->isc_session); } } } } void prot_a_output_membership_old(Connection *fp, const Membership *mship) { prot_a_output_time(fp, mship->last_time_read ); prot_a_output_ul(fp, mship->conf_no); prot_a_output_ul(fp, mship->priority); prot_a_output_read_texts(fp, mship); } void prot_a_output_membership_list(Connection *fp, Membership_list mlist) { int i; prot_a_output_ul(fp, mlist.no_of_confs); if ( mlist.confs != NULL && mlist.no_of_confs > 0 ) { isc_puts(" {", fp->isc_session); for ( i = 0; i < mlist.no_of_confs; i++) prot_a_output_membership(fp, mlist.confs + i); isc_puts(" }", fp->isc_session); } else isc_puts(" *", fp->isc_session); } void prot_a_output_membership_list_old (Connection * fp, Membership_list mlist) { int i; prot_a_output_ul(fp, mlist.no_of_confs); if ( mlist.confs != NULL && mlist.no_of_confs > 0 ) { isc_puts(" {", fp->isc_session); for ( i = 0; i < mlist.no_of_confs; i++) prot_a_output_membership_old(fp, mlist.confs + i); isc_puts(" }", fp->isc_session); } else isc_puts(" *", fp->isc_session); } void prot_a_output_membership_list_10(Connection *fp, Membership_list mlist) { int i; prot_a_output_ul(fp, mlist.no_of_confs); if ( mlist.confs != NULL && mlist.no_of_confs > 0 ) { isc_puts(" {", fp->isc_session); for ( i = 0; i < mlist.no_of_confs; i++) prot_a_output_membership_10(fp, mlist.confs + i); isc_puts(" }", fp->isc_session); } else isc_puts(" *", fp->isc_session); } void prot_a_output_conf_list(Connection *fp, Conf_list_old conf_list) { unsigned long i; prot_a_output_ul(fp, conf_list.no_of_conf_nos); if ( conf_list.conf_nos != NULL && conf_list.no_of_conf_nos > 0 ) { isc_puts(" {", fp->isc_session); for ( i = 0; i < conf_list.no_of_conf_nos; i++ ) prot_a_output_ul(fp, conf_list.conf_nos[i]); isc_puts(" }", fp->isc_session); } else isc_puts(" *", fp->isc_session); if ( conf_list.type_of_conf != NULL && conf_list.no_of_conf_nos > 0 ) { isc_puts(" {", fp->isc_session); for ( i = 0; i < conf_list.no_of_conf_nos; i++ ) prot_a_output_conf_type(fp, conf_list.type_of_conf[ i ]); isc_puts(" }", fp->isc_session); } else isc_puts(" *", fp->isc_session); } void prot_a_output_conf_no_list(Connection *fp, Conf_no_list conf_no_list) { int i; prot_a_output_ul(fp, conf_no_list.no_of_confs); if ( conf_no_list.conf_nos != NULL && conf_no_list.no_of_confs > 0 ) { isc_puts(" {", fp->isc_session); for ( i = 0; i < conf_no_list.no_of_confs; i++ ) prot_a_output_ul(fp, conf_no_list.conf_nos[i]); isc_puts(" }", fp->isc_session); } else isc_puts(" *", fp->isc_session); } void prot_a_output_conference (Connection *fp, Conference *conf_c) { Local_text_no first_local_no = l2g_next_key(&conf_c->texts, 0); Local_text_no uncreated = l2g_first_appendable_key(&conf_c->texts); Local_text_no no_of_texts; if (first_local_no == 0) first_local_no = uncreated; no_of_texts = uncreated - first_local_no; prot_a_output_string(fp, conf_c->name); prot_a_output_extended_conf_type(fp, conf_c->type); prot_a_output_time(fp, conf_c->creation_time ); prot_a_output_time(fp, conf_c->last_written ); prot_a_output_ul(fp, conf_c->creator); prot_a_output_ul(fp, conf_c->presentation); prot_a_output_ul(fp, conf_c->supervisor); prot_a_output_ul(fp, conf_c->permitted_submitters); prot_a_output_ul(fp, conf_c->super_conf); prot_a_output_ul(fp, conf_c->msg_of_day); prot_a_output_ul(fp, conf_c->nice); prot_a_output_ul(fp, conf_c->keep_commented); prot_a_output_ul(fp, conf_c->members.no_of_members); prot_a_output_ul(fp, first_local_no); prot_a_output_ul(fp, no_of_texts); prot_a_output_ul(fp, conf_c->expire); prot_a_output_aux_item_list (fp, &conf_c->aux_item_list); } void prot_a_output_conference_old (Connection *fp, Conference *conf_c) { Local_text_no first_local_no = l2g_next_key(&conf_c->texts, 0); Local_text_no uncreated = l2g_first_appendable_key(&conf_c->texts); Local_text_no no_of_texts; if (first_local_no == 0) first_local_no = uncreated; no_of_texts = uncreated - first_local_no; prot_a_output_string(fp, conf_c->name); prot_a_output_conf_type(fp, conf_c->type); prot_a_output_time(fp, conf_c -> creation_time ); prot_a_output_time(fp, conf_c -> last_written ); prot_a_output_ul(fp, conf_c->creator); prot_a_output_ul(fp, conf_c->presentation); prot_a_output_ul(fp, conf_c->supervisor); prot_a_output_ul(fp, conf_c->permitted_submitters); prot_a_output_ul(fp, conf_c->super_conf); prot_a_output_ul(fp, conf_c->msg_of_day); prot_a_output_ul(fp, conf_c->nice); prot_a_output_ul(fp, conf_c->members.no_of_members); prot_a_output_ul(fp, first_local_no); prot_a_output_ul(fp, no_of_texts); } void prot_a_output_uconference(Connection *fp, Small_conf *conf_c) { prot_a_output_string(fp, conf_c -> name); prot_a_output_extended_conf_type(fp, conf_c -> type); prot_a_output_ul(fp, conf_c->highest_local_no); prot_a_output_ul(fp, conf_c->nice); } void prot_a_output_mark_list(Connection *fp, Mark_list mark_list) { int i; prot_a_output_ul(fp, mark_list.no_of_marks); if ( mark_list.marks != NULL && mark_list.no_of_marks > 0 ) { isc_puts(" {", fp->isc_session); for ( i = 0; i < mark_list.no_of_marks; i++ ) prot_a_output_mark(fp, mark_list.marks[ i ]); isc_puts(" }", fp->isc_session); } else isc_puts(" *", fp->isc_session); } void prot_a_output_aux_item_flags(Connection *fp, Aux_item_flags flags) { isc_putc(' ', fp->isc_session); isc_putc(flags.deleted + '0', fp->isc_session); isc_putc(flags.inherit + '0', fp->isc_session); isc_putc(flags.secret + '0', fp->isc_session); isc_putc(flags.hide_creator + '0', fp->isc_session); isc_putc(flags.dont_garb + '0', fp->isc_session); isc_putc(flags.reserved3 + '0', fp->isc_session); isc_putc(flags.reserved4 + '0', fp->isc_session); isc_putc(flags.reserved5 + '0', fp->isc_session); } void prot_a_output_aux_item(Connection *fp, Aux_item *item) { prot_a_output_ul(fp, item->aux_no); prot_a_output_ul(fp, item->tag); prot_a_output_ul(fp, item->creator); prot_a_output_time(fp, item->sent_at); prot_a_output_aux_item_flags(fp, item->flags); prot_a_output_ul(fp, item->inherit_limit); prot_a_output_string(fp, item->data); } void prot_a_output_text_stat_old(Connection *fp, Text_stat *t_stat) { int i; prot_a_output_time(fp, t_stat->creation_time); prot_a_output_ul(fp, t_stat->author); prot_a_output_ul(fp, t_stat->no_of_lines); prot_a_output_ul(fp, t_stat->no_of_chars); prot_a_output_ul(fp, t_stat->no_of_marks); prot_a_output_ul(fp, t_stat->no_of_misc); if ( t_stat->misc_items != NULL && t_stat->no_of_misc > 0 ) { isc_puts(" {", fp->isc_session); for ( i = 0; i < t_stat->no_of_misc; i++ ) prot_a_output_misc_info(fp, t_stat->misc_items[ i ]); isc_puts(" }", fp->isc_session); } else isc_puts(" *", fp->isc_session); } void prot_a_output_aux_item_list(Connection *fp, Aux_item_list *aux) { int i; prot_a_output_ul(fp, aux->length); if ( aux->items != NULL && aux->length > 0 ) { isc_puts(" {", fp->isc_session); for (i = 0; i < aux->length; i++) prot_a_output_aux_item(fp, &aux->items[i]); isc_puts(" }", fp->isc_session); } else isc_puts(" *", fp->isc_session); } void prot_a_output_text_stat(Connection *fp, Text_stat *t_stat) { prot_a_output_text_stat_old(fp, t_stat); prot_a_output_aux_item_list(fp, &t_stat->aux_item_list); } static void prot_a_output_who_info_ident(Connection *fp, Who_info_ident *info) { prot_a_output_ul(fp, info->person); prot_a_output_ul(fp, info->working_conference); prot_a_output_ul(fp, info->session_no); prot_a_output_string(fp, info->what_am_i_doing); prot_a_output_string(fp, info->username); prot_a_output_string(fp, info->hostname); prot_a_output_string(fp, info->ident_user); } void prot_a_output_who_info(Connection *fp, Who_info *info) { prot_a_output_ul(fp, info->person); prot_a_output_ul(fp, info->working_conference); prot_a_output_ul(fp, info->session_no); prot_a_output_string(fp, info->what_am_i_doing); prot_a_output_string(fp, info->username); } void prot_a_output_who_info_list(Connection *fp, Who_info_list info) { int i; prot_a_output_ul(fp, info.no_of_persons); if ( info.info != NULL && info.no_of_persons > 0 ) { isc_puts(" {", fp->isc_session); for ( i = 0; i < info.no_of_persons; i++ ) { prot_a_output_who_info(fp, &info.info[ i ]); /* The username is specially alloced in who_is_on() in session.c. */ s_clear(&info.info[i].username); } isc_puts(" }", fp->isc_session); } else isc_puts(" *", fp->isc_session); } void prot_a_output_who_info_ident_list(Connection *fp, Who_info_ident_list info) { int i; prot_a_output_ul(fp, info.no_of_persons); if ( info.info != NULL && info.no_of_persons > 0 ) { isc_puts(" {", fp->isc_session); for ( i = 0; i < info.no_of_persons; i++ ) { prot_a_output_who_info_ident(fp, &info.info[ i ]); } isc_puts(" }", fp->isc_session); } else isc_puts(" *", fp->isc_session); } void prot_a_output_who_info_list_old(Connection *fp, Who_info_list_old info) { int i; prot_a_output_ul(fp, info.no_of_persons); if ( info.info != NULL && info.no_of_persons > 0 ) { isc_puts(" {", fp->isc_session); for ( i = 0; i < info.no_of_persons; i++ ) { prot_a_output_ul(fp, info.info[i].person); prot_a_output_ul(fp, info.info[i].working_conference); prot_a_output_string(fp, info.info[ i ].what_am_i_doing); } isc_puts(" }", fp->isc_session); } else isc_puts(" *", fp->isc_session); } void prot_a_output_session_info(Connection *fp, Session_info *info) { prot_a_output_ul(fp, info->person); prot_a_output_ul(fp, info->working_conference); prot_a_output_ul(fp, info->session); prot_a_output_string(fp, info->what_am_i_doing); prot_a_output_string(fp, info->username); prot_a_output_ul(fp, info->idle_time); prot_a_output_time(fp, info->connection_time); } void prot_a_output_session_info_ident(Connection *fp, Session_info_ident *info) { prot_a_output_ul(fp, info->person); prot_a_output_ul(fp, info->working_conference); prot_a_output_ul(fp, info->session); prot_a_output_string(fp, info->what_am_i_doing); prot_a_output_string(fp, info->username); prot_a_output_string(fp, info->hostname); prot_a_output_string(fp, info->ident_user); prot_a_output_ul(fp, info->idle_time); prot_a_output_time(fp, info->connection_time); } void prot_a_output_info(Connection *fp, Info *info) { prot_a_output_info_old(fp, info); prot_a_output_aux_item_list(fp, &info->aux_item_list); } void prot_a_output_info_old(Connection *fp, Info *info) { prot_a_output_ul(fp, info->version); prot_a_output_ul(fp, info->conf_pres_conf); prot_a_output_ul(fp, info->pers_pres_conf); prot_a_output_ul(fp, info->motd_conf); prot_a_output_ul(fp, info->kom_news_conf); prot_a_output_ul(fp, info->motd_of_lyskom); } extern void prot_a_output_string(Connection *fp, String str) { prot_a_output_ul(fp, str.len); isc_putc('H', fp->isc_session); isc_write(fp->isc_session, str.string, str.len); } extern void prot_a_output_priv_bits(Connection *fp, Priv_bits bits) { isc_putc(' ', fp->isc_session); isc_putc(bits.wheel + '0', fp->isc_session); isc_putc(bits.admin + '0', fp->isc_session); isc_putc(bits.statistic + '0', fp->isc_session); isc_putc(bits.create_pers + '0', fp->isc_session); isc_putc(bits.create_conf + '0', fp->isc_session); isc_putc(bits.change_name + '0', fp->isc_session); isc_putc(bits.flg7 + '0', fp->isc_session); isc_putc(bits.flg8 + '0', fp->isc_session); isc_putc(bits.flg9 + '0', fp->isc_session); isc_putc(bits.flg10 + '0', fp->isc_session); isc_putc(bits.flg11 + '0', fp->isc_session); isc_putc(bits.flg12 + '0', fp->isc_session); isc_putc(bits.flg13 + '0', fp->isc_session); isc_putc(bits.flg14 + '0', fp->isc_session); isc_putc(bits.flg15 + '0', fp->isc_session); isc_putc(bits.flg16 + '0', fp->isc_session); } extern void prot_a_output_personal_flags(Connection *fp, Personal_flags flags) { isc_putc(' ', fp->isc_session); isc_putc(flags.unread_is_secret + '0', fp->isc_session); isc_putc(flags.flg2 + '0', fp->isc_session); isc_putc(flags.flg3 + '0', fp->isc_session); isc_putc(flags.flg4 + '0', fp->isc_session); isc_putc(flags.flg5 + '0', fp->isc_session); isc_putc(flags.flg6 + '0', fp->isc_session); isc_putc(flags.flg7 + '0', fp->isc_session); isc_putc(flags.flg8 + '0', fp->isc_session); } extern void prot_a_output_conf_type(Connection *fp, Conf_type type) { isc_putc(' ', fp->isc_session); isc_putc(type.rd_prot + '0', fp->isc_session); isc_putc(type.original + '0', fp->isc_session); isc_putc(type.secret + '0', fp->isc_session); isc_putc(type.letter_box + '0', fp->isc_session); } extern void prot_a_output_extended_conf_type(Connection *fp, Conf_type type) { isc_putc(' ', fp->isc_session); isc_putc(type.rd_prot + '0', fp->isc_session); isc_putc(type.original + '0', fp->isc_session); isc_putc(type.secret + '0', fp->isc_session); isc_putc(type.letter_box + '0', fp->isc_session); isc_putc(type.allow_anon + '0', fp->isc_session); isc_putc(type.forbid_secret + '0', fp->isc_session); isc_putc(type.reserved2 + '0', fp->isc_session); isc_putc(type.reserved3 + '0', fp->isc_session); } extern void prot_a_output_member_list(Connection *fp, Member_list m_list) { int i; prot_a_output_ul(fp, m_list.no_of_members); if ( m_list.members != NULL && m_list.no_of_members > 0 ) { isc_puts(" {", fp->isc_session); for ( i = 0; i < m_list.no_of_members; i++ ) prot_a_output_member(fp, m_list.members[ i ]); isc_puts(" }", fp->isc_session); } else isc_puts(" *", fp->isc_session); } extern void prot_a_output_member_list_old(Connection *fp, Member_list m_list) { int i; prot_a_output_ul(fp, m_list.no_of_members); if ( m_list.members != NULL && m_list.no_of_members > 0 ) { isc_puts(" {", fp->isc_session); for ( i = 0; i < m_list.no_of_members; i++ ) prot_a_output_member_old(fp, m_list.members[ i ]); isc_puts(" }", fp->isc_session); } else isc_puts(" *", fp->isc_session); } void prot_a_output_member(Connection *fp, Member member) { prot_a_output_ul(fp, member.member); prot_a_output_ul(fp, member.added_by); prot_a_output_time(fp, member.added_at); prot_a_output_membership_type(fp, member.type); } void prot_a_output_member_old(Connection *fp, Member member) { prot_a_output_ul(fp, member.member); } extern void prot_a_output_mark(Connection *fp, Mark mark) { prot_a_output_ul(fp, mark.text_no); prot_a_output_ul(fp, mark.mark_type); } extern void prot_a_output_misc_info(Connection *fp, Misc_info misc) { prot_a_output_ul(fp, misc.type); switch(misc.type) { case recpt: case cc_recpt: case bcc_recpt: prot_a_output_ul(fp, misc.datum.recipient); break; case loc_no: prot_a_output_ul(fp, misc.datum.local_no); break; case rec_time: prot_a_output_time(fp, misc.datum.received_at); break; case comm_to: case comm_in: case footn_to: case footn_in: prot_a_output_ul(fp, misc.datum.text_link); break; case sent_by: prot_a_output_ul(fp, misc.datum.sender); break; case sent_at: prot_a_output_time(fp, misc.datum.sent_at); break; #ifndef COMPILE_CHECKS default: #endif case unknown_info: restart_kom("prot_a_output_misc_info: Illegal misc\n"); } } void prot_a_output_time(Connection *fp, time_t clk) { struct tm *t; if (fp->use_utc) t = gmtime(&clk); else t = localtime(&clk); prot_a_output_ul(fp, t->tm_sec); prot_a_output_ul(fp, t->tm_min); prot_a_output_ul(fp, t->tm_hour); prot_a_output_ul(fp, t->tm_mday); prot_a_output_ul(fp, t->tm_mon); prot_a_output_ul(fp, t->tm_year); prot_a_output_ul(fp, t->tm_wday); prot_a_output_ul(fp, t->tm_yday); prot_a_output_ul(fp, t->tm_isdst); } void prot_a_output_session_no(Connection *fp, Session_no session_no) { prot_a_output_ul(fp, session_no); } void prot_a_output_text_no(Connection *fp, Text_no text) { prot_a_output_ul(fp, text); } void prot_a_output_conf_no(Connection *fp, Conf_no conf) { prot_a_output_ul(fp, conf); } static void prot_a_output_conf_z_info (Connection *fp, Conf_z_info *conf_c) { prot_a_output_string(fp, conf_c->name); prot_a_output_conf_type(fp, conf_c->type); prot_a_output_ul(fp, conf_c->conf_no); } extern void prot_a_output_conf_z_info_list(Connection *fp, Conf_z_info_list c_list) { int i; prot_a_output_ul(fp, c_list.no_of_confs); if ( c_list.confs != NULL && c_list.no_of_confs > 0 ) { isc_puts(" {", fp->isc_session); for ( i = 0; i < c_list.no_of_confs; i++ ) prot_a_output_conf_z_info(fp, &c_list.confs[ i ]); isc_puts(" }", fp->isc_session); } else isc_puts(" *", fp->isc_session); } void prot_a_output_version_info (Connection *fp, Version_info *v_info) { prot_a_output_ul(fp, v_info->protocol_version); prot_a_output_string(fp, v_info->server_name); prot_a_output_string(fp, v_info->server_version); } void prot_a_output_num_list (Connection *fp, Number_list *num_list) { int i; prot_a_output_ul(fp, num_list->length); if (num_list->length == 0) isc_puts(" *", fp->isc_session); else { isc_puts(" {", fp->isc_session); for (i = 0; i < num_list->length; i++) prot_a_output_ul(fp, num_list->data[i]); isc_puts(" }", fp->isc_session); } } static void prot_a_output_session_flags(Connection *fp, Session_flags flags) { isc_putc(' ', fp->isc_session); isc_putc(flags.invisible + '0', fp->isc_session); isc_putc(flags.user_active_used + '0', fp->isc_session); isc_putc(flags.user_absent + '0', fp->isc_session); isc_putc(flags.reserved3 + '0', fp->isc_session); isc_putc(flags.reserved4 + '0', fp->isc_session); isc_putc(flags.reserved5 + '0', fp->isc_session); isc_putc(flags.reserved6 + '0', fp->isc_session); isc_putc(flags.reserved7 + '0', fp->isc_session); } static void prot_a_output_dynamic_session_info (Connection *fp, Dynamic_session_info *info) { prot_a_output_ul(fp, info->session); prot_a_output_ul(fp, info->person); prot_a_output_ul(fp, info->working_conference); prot_a_output_ul(fp, info->idle_time); prot_a_output_session_flags(fp, info->flags); prot_a_output_string(fp, info->what_am_i_doing); } void prot_a_output_static_session_info (Connection *fp, Static_session_info *info) { prot_a_output_string(fp, info->username); prot_a_output_string(fp, info->hostname); prot_a_output_string(fp, info->ident_user); prot_a_output_time(fp, info->connection_time); } void prot_a_output_dynamic_session_info_list (Connection *fp, Dynamic_session_info_list *list) { long i; prot_a_output_ul(fp, list->no_of_sessions); if (list->no_of_sessions == 0) isc_puts(" *", fp->isc_session); else { isc_puts(" {", fp->isc_session); for (i = 0; i < list->no_of_sessions; i++) prot_a_output_dynamic_session_info(fp, &list->sessions[i]); isc_puts(" }", fp->isc_session); } } void prot_a_output_l2g_iterator_as_text_list(Connection *fp, L2g_iterator *iter) { Local_text_no lno = l2gi_begin(iter); Local_text_no limit = l2gi_end(iter); prot_a_output_ul(fp, lno); prot_a_output_ul(fp, limit - lno); if (limit - lno > 0) { isc_puts(" {", fp->isc_session); for (; !iter->search_ended; l2gi_next(iter)) { /* Write the correct number of zeroes. */ for (; lno < iter->lno; ++lno) isc_puts(" 0", fp->isc_session); /* Write this piece of data. */ prot_a_output_ul(fp, iter->tno); ++lno; } /* Write any trailing zeroes */ for (; lno < limit; ++lno) isc_puts(" 0", fp->isc_session); isc_puts(" }", fp->isc_session); } else isc_puts(" *", fp->isc_session); } void prot_a_output_text_mapping(Connection *fp, Text_mapping *map) { Local_text_no lowest; Local_text_no highest; Local_text_no limit; Local_text_no zeroes = 0; Local_text_no nonzeroes = 0; L2g_iterator iter; /* Initialize iter to something. Otherwise some tools will flag a read uninitialized memory in the for initializer. */ iter.l2g = NULL; iter.binfo = NULL; iter.arrindex = 0; iter.beginval = 0; iter.endval = 0; iter.search_ended = 0; iter.lno = 0; iter.tno = 0; /* Count the number of internal zeroes to determine if we should use a dense or sparse representation. */ for (l2gi_searchsome(&iter, map->l2g, map->first, 0), highest = (lowest = iter.search_ended?map->first:iter.lno) - 1; !iter.search_ended && nonzeroes < map->no_of_texts; l2gi_next(&iter)) { zeroes += (iter.lno - highest) - 1; nonzeroes++; highest = iter.lno; } limit = highest + 1; prot_a_output_ul(fp, map->first); if (iter.search_ended) prot_a_output_ul(fp, l2g_first_appendable_key(map->l2g)); else prot_a_output_ul(fp, limit); /* Emit the "more-texts-exists" flag. */ isc_puts(iter.search_ended ? " 0" : " 1", fp->isc_session); /* Emit the block, either a sparse or a dense one. */ if (nonzeroes == 0) { /* Special case: an empty array. Use the sparse format so that we don't have to philosophize about what the lower limit in the text-list should be. */ isc_puts(" 0 0 *", fp->isc_session); } else if (zeroes >= nonzeroes) { /* There are at least as many zeroes as real mappings, so use a sparse representation. */ isc_puts(" 0", fp->isc_session); prot_a_output_ul(fp, nonzeroes); isc_puts(" {", fp->isc_session); for (l2gi_searchsome(&iter, map->l2g, map->first, limit); !iter.search_ended; l2gi_next(&iter)) { prot_a_output_ul(fp, iter.lno); prot_a_output_ul(fp, iter.tno); } isc_puts(" }", fp->isc_session); } else { /* Emit a dense block. */ isc_puts(" 1", fp->isc_session); prot_a_output_ul(fp, lowest); prot_a_output_ul(fp, zeroes + nonzeroes); isc_puts(" {", fp->isc_session); highest = lowest; for (l2gi_searchsome(&iter, map->l2g, map->first, limit); !iter.search_ended; l2gi_next(&iter)) { while (highest++ < iter.lno) isc_puts(" 0", fp->isc_session); prot_a_output_ul(fp, iter.tno); } isc_puts(" }", fp->isc_session); } } void prot_a_output_text_mapping_reverse(Connection *fp, Text_mapping_reverse *map) { Local_text_no lowest; Local_text_no zeroes = 0; Local_text_no nonzeroes = 0; L2g_iterator iter; L2g_reverse_iterator riter; /* Initialize iterators to something. Otherwise some tools will flag a read uninitialized memory in the for initializer. */ iter.l2g = NULL; iter.binfo = NULL; iter.arrindex = 0; iter.beginval = 0; iter.endval = 0; iter.search_ended = 0; iter.lno = 0; iter.tno = 0; riter.l2g = NULL; riter.binfo = NULL; riter.arrindex = 0; riter.beginval = 0; riter.endval = 0; riter.search_ended = 0; riter.lno = 0; riter.tno = 0; /* Count the number of internal zeroes to determine if we should use a dense or sparse representation. */ for (l2gi_searchsome_reverse(&riter, map->l2g, 0, map->ceiling), lowest = riter.search_ended ? map->ceiling : riter.lno + 1; !riter.search_ended && nonzeroes < map->no_of_texts; l2gi_prev(&riter)) { zeroes += (lowest - riter.lno) - 1; nonzeroes++; lowest = riter.lno; } prot_a_output_ul(fp, lowest); prot_a_output_ul(fp, map->ceiling); /* Emit the "more-texts-exists" flag. */ isc_puts(riter.search_ended ? " 0" : " 1", fp->isc_session); /* Emit the block, either a sparse or a dense one. */ if (nonzeroes == 0) { /* Special case: an empty array. Use the sparse format so that we don't have to philosophize about what the lower limit in the text-list should be. */ isc_puts(" 0 0 *", fp->isc_session); } else if (zeroes >= nonzeroes) { /* There are at least as many zeroes as real mappings, so use a sparse representation. */ isc_puts(" 0", fp->isc_session); prot_a_output_ul(fp, nonzeroes); isc_puts(" {", fp->isc_session); for (l2gi_searchsome(&iter, map->l2g, lowest, map->ceiling); !iter.search_ended; l2gi_next(&iter)) { prot_a_output_ul(fp, iter.lno); prot_a_output_ul(fp, iter.tno); } isc_puts(" }", fp->isc_session); } else { /* Emit a dense block. */ isc_puts(" 1", fp->isc_session); prot_a_output_ul(fp, lowest); prot_a_output_ul(fp, zeroes + nonzeroes); isc_puts(" {", fp->isc_session); for (l2gi_searchsome(&iter, map->l2g, lowest, map->ceiling); !iter.search_ended; l2gi_next(&iter)) { while (lowest++ < iter.lno) isc_puts(" 0", fp->isc_session); prot_a_output_ul(fp, iter.tno); } isc_puts(" }", fp->isc_session); } } void prot_a_output_stats_description(Connection *fp, Stats_description *result) { int i; prot_a_output_ul(fp, result->no_of_stats); if (result->no_of_stats == 0) isc_puts(" *", fp->isc_session); else { isc_puts(" {", fp->isc_session); for (i = 0; i < result->no_of_stats; i++) prot_a_output_string(fp, result->stat_names[i]); isc_puts(" }", fp->isc_session); } prot_a_output_num_list(fp, &result->intervals); } static void prot_a_output_stats(Connection *fp, const Stats *result) { prot_a_output_float(fp, result->average); prot_a_output_float(fp, result->ascent_rate); prot_a_output_float(fp, result->descent_rate); } void prot_a_output_stats_list(Connection *fp, const Stats_list *result) { int i; prot_a_output_ul(fp, result->no_of_stats); if (result->no_of_stats == 0) isc_puts(" *", fp->isc_session); else { isc_puts(" {", fp->isc_session); for (i = 0; i < result->no_of_stats; i++) prot_a_output_stats(fp, &result->stats[i]); isc_puts(" }", fp->isc_session); } } void prot_a_output_static_server_info(Connection *fp, const Static_server_info *result) { prot_a_output_time(fp, result->boot_time); prot_a_output_time(fp, result->save_time); prot_a_output_string(fp, result->db_status); prot_a_output_ul(fp, result->existing_texts); prot_a_output_ul(fp, result->highest_text_no); prot_a_output_ul(fp, result->existing_confs); prot_a_output_ul(fp, result->existing_persons); prot_a_output_ul(fp, result->highest_conf_no); } void prot_a_output_scheduling_info(Connection *fp, const Scheduling_info *result) { prot_a_output_ul(fp, result->priority); prot_a_output_ul(fp, result->weight); } #ifdef DEBUG_CALLS void prot_a_output_memory_info(Connection *fp, Memory_info *result) { prot_a_output_ul(fp, result->arena); prot_a_output_ul(fp, result->ordblks); prot_a_output_ul(fp, result->smblks); prot_a_output_ul(fp, result->hblks); prot_a_output_ul(fp, result->hblkhd); prot_a_output_ul(fp, result->usmblks); prot_a_output_ul(fp, result->fsmblks); prot_a_output_ul(fp, result->uordblks); prot_a_output_ul(fp, result->fordblks); prot_a_output_ul(fp, result->keepcost); } #endif lyskom-server-2.1.2/src/server/prot-a-parse.c0000664000015100472110000007717007721716127014616 /* * $Id: prot-a-parse.c,v 0.63 2003/08/23 16:38:15 ceder Exp $ * Copyright (C) 1991-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * prot-a-parse.c - parse protocol-A messages. * * FIXME (bug 342): Not all functions are used, I think. /ceder */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include "timewrap.h" #include #include #ifdef HAVE_STDLIB_H # include #endif #include #include "oop.h" #include "debug.h" #include "s-string.h" #include "kom-types.h" #include "server/smalloc.h" #include "com.h" #include "async.h" #include "connections.h" #include "prot-a-parse.h" #include "isc-parse.h" #include "kom-config.h" #include "isc-interface.h" #include "log.h" #include "minmax.h" #include "param.h" #include "kom-memory.h" BUGDECL; /* Forward declarations */ static void prot_a_hunt_array_end(Connection *client); /* * Return next token from the input stream. Note that the String returned * by this call points into data that might be freed by the next call to * get_token or any function which reads from the stream. */ static String prot_a_get_token(Connection *client) { String result; String_size old_first; old_first = client->first_to_parse; result = s_strtok(client->unparsed, &client->first_to_parse, s_fcrea_str(WHITESPACE)); /* Check that there was at least one trailing blank. */ if ( client->first_to_parse >= s_strlen(client->unparsed) ) { if (client->first_to_parse - old_first > 1000) { isc_puts("%%Insane token length.\n", client->isc_session); isc_flush(client->isc_session); longjmp(parse_env, KOM_LOGOUT); } client->first_to_parse = old_first; longjmp(parse_env, KOM_MSG_INCOMPLETE); } return result; } long prot_a_parse_long(Connection *client) { String token; String_size end; long res; token = prot_a_get_token(client); res = s_strtol(token, &end); if (end != s_strlen(token)) longjmp(parse_env, KOM_PROTOCOL_ERR); return res; } void prot_a_parse_num_list(Connection *client, Number_list *res, int maxlen) { static unsigned long err_cnt = 0; switch (client->array_parse_pos) { case 0: /* The array size. */ /* This could just as well have been an assertion. */ if ((res->length != 0 || res->data != NULL) && err_cnt++ < 20) { kom_log("WNG: prot_a_parse_num_list(): len = %lu data = %lu\n", (unsigned long)res->length, (unsigned long)res->data); res->length = 0; res->data = NULL; if (err_cnt == 20) kom_log("The above warning is now turned off.\n"); } client->array_parse_parsed_length = prot_a_parse_long(client); if (client->array_parse_parsed_length < 0) { isc_puts("%%Insane array size.\n", client->isc_session); isc_flush(client->isc_session); longjmp(parse_env, KOM_LOGOUT); } client->array_parse_pos = 1; /* Fall through */ case 1: /* The opening curly brace. */ if ( parse_nonwhite_char(client) != '{' ) longjmp(parse_env, KOM_PROTOCOL_ERR); res->length = min(maxlen+1, client->array_parse_parsed_length); res->data = smalloc(sizeof(*res->data) * res->length); client->array_parse_index = 0; client->array_parse_pos = 2; /* Fall through */ case 2: /* The elements in the array. */ while (client->array_parse_index < client->array_parse_parsed_length) { long tmp = prot_a_parse_long(client); /* Enter the value into the array only if the parse index is inside the allocated array */ if (client->array_parse_index < res->length) { res->data[client->array_parse_index] = tmp; } client->array_parse_index += 1; } client->array_parse_pos = 3; /* Fall through */ case 3: /* Closing brace. */ /* Adjust the result length if we were parsing a long array */ /* Read the closing brace */ if ( parse_nonwhite_char(client) != '}' ) longjmp(parse_env, KOM_PROTOCOL_ERR); default: client->array_parse_pos = 0; } } void prot_a_parse_priv_bits(Connection *client, Priv_bits *res) { String token; String_size len; token = prot_a_get_token(client); len = s_strlen(token); if (len <= 0 ) longjmp(parse_env, KOM_PROTOCOL_ERR); init_priv_bits(res); switch (len) { default: case 16: res->flg16 = token.string[ 15 ] != '0'; case 15: res->flg15 = token.string[ 14 ] != '0'; case 14: res->flg14 = token.string[ 13 ] != '0'; case 13: res->flg13 = token.string[ 12 ] != '0'; case 12: res->flg12 = token.string[ 11 ] != '0'; case 11: res->flg11 = token.string[ 10 ] != '0'; case 10: res->flg10 = token.string[ 9 ] != '0'; case 9: res->flg9 = token.string[ 8 ] != '0'; case 8: res->flg8 = token.string[ 7 ] != '0'; case 7: res->flg7 = token.string[ 6 ] != '0'; case 6: res->change_name = token.string[ 5 ] != '0'; case 5: res->create_conf = token.string[ 4 ] != '0'; case 4: res->create_pers = token.string[ 3 ] != '0'; case 3: res->statistic = token.string[ 2 ] != '0'; case 2: res->admin = token.string[ 1 ] != '0'; case 1: res->wheel = token.string[ 0 ] != '0'; } } void prot_a_parse_pers_flags(Connection *client, Personal_flags *res) { String token; String_size len; token = prot_a_get_token(client); len = s_strlen(token); if (len <= 0) longjmp(parse_env, KOM_PROTOCOL_ERR); init_personal_flags(res); switch (len) { default: case 8: res->flg8 = token.string[ 7 ] != '0'; case 7: res->flg7 = token.string[ 6 ] != '0'; case 6: res->flg6 = token.string[ 5 ] != '0'; case 5: res->flg5 = token.string[ 4 ] != '0'; case 4: res->flg4 = token.string[ 3 ] != '0'; case 3: res->flg3 = token.string[ 2 ] != '0'; case 2: res->flg2 = token.string[ 1 ] != '0'; case 1: res->unread_is_secret = token.string[ 0 ] != '0'; } } void prot_a_parse_membership_type(Connection *client, Membership_type *res) { String token; String_size len; token = prot_a_get_token(client); len = s_strlen(token); if (len <= 0) longjmp(parse_env, KOM_PROTOCOL_ERR); init_membership_type(res); switch (len) { default: case 8: res->reserved5 = token.string[ 7 ] != '0'; case 7: res->reserved4 = token.string[ 6 ] != '0'; case 6: res->reserved3 = token.string[ 5 ] != '0'; case 5: res->reserved2 = token.string[ 4 ] != '0'; case 4: res->passive_message_invert = token.string[ 3 ] != '0'; case 3: res->secret = token.string[ 2 ] != '0'; case 2: res->passive = token.string[ 1 ] != '0'; case 1: res->invitation = token.string[ 0 ] != '0'; } } void prot_a_parse_conf_type(Connection *client, Conf_type *res) { String token; String_size len; token = prot_a_get_token(client); len = s_strlen(token); if (len <= 0) longjmp(parse_env, KOM_PROTOCOL_ERR); init_conf_type(res); switch (len) { default: case 8: res->reserved3 = token.string[ 7 ] != '0'; case 7: res->reserved2 = token.string[ 6 ] != '0'; case 6: res->forbid_secret = token.string[ 5 ] != '0'; case 5: res->allow_anon = token.string[ 4 ] != '0'; case 4: res->letter_box = token.string[ 3 ] != '0'; case 3: res->secret = token.string[ 2 ] != '0'; case 2: res->original = token.string[ 1 ] != '0'; case 1: res->rd_prot = token.string[ 0 ] != '0'; } } /* * Parse a string. At most 'maxlen' characters are allowed. If the * client sends a longer string only the first 'maxlen+1' characters * are read. Any remaining characters are discarded. */ void prot_a_parse_string(Connection *client, String *result, int maxlen) { String_size hptr; /* Pointer to 'H' */ String_size client_len; /* The len the client is sending. */ String_size truncated_len; /* How much the server will receive. */ String_size to_skip; static unsigned long err_cnt = 0; switch ( client->string_parse_pos ) { case 0: if ( (result->len != 0 || result->string != NULL) && err_cnt++ < 20 ) { kom_log ("%s == %lu, result->string == %lu. %s\n", "prot_a_parse_string(): result->len", (unsigned long)result->len, (unsigned long)result->string, "This memory will not be free()'d."); *result = EMPTY_STRING; if ( err_cnt == 20 ) kom_log("Won't log the above warning no more.\n"); } /* Get number and discard trailing 'H' */ client_len = s_strtol(s_fsubstr(client->unparsed, client->first_to_parse, END_OF_STRING), &hptr); if ( hptr == -1 || client->first_to_parse + hptr >= s_strlen(client->unparsed) ) { longjmp(parse_env, KOM_MSG_INCOMPLETE); } if (client_len < 0) { isc_puts("%%Insane string length.\n", client->isc_session); isc_flush(client->isc_session); BUG(("%%%%Insane string length.\n")); longjmp(parse_env, KOM_LOGOUT); } /* Check that a) there is a trailing H b) there was at least one digit before the H */ if ( client->unparsed.string[ client->first_to_parse + hptr ] != 'H' || hptr <= 0 ) { longjmp(parse_env, KOM_PROTOCOL_ERR); } client->first_to_parse += 1 + hptr; client->string_parse_pos = 1; /* Transfer the total length across the restart point, by storing it in result->len. */ /* FIXME (bug 162): It would be better to add a client_len field to the Connection struct. Adding four bytes to that struct won't measurably change the size of the lyskomd process, and it will make this code easier to maintain. This is also dangerous, since it means that result->len > 0 while result->string == NULL, and that might confuse some code somewhere. */ result->len = client_len; /* Fall through */ case 1: client_len = result->len; /* Check that the entire string is transmitted. */ /* (Don't care about the trailing part that will be skipped if the * string is longer than maxlen) */ truncated_len = min(maxlen + 1, client_len); if ( client->first_to_parse + truncated_len > s_strlen(client->unparsed) ) { longjmp(parse_env, KOM_MSG_INCOMPLETE); } *result = EMPTY_STRING; s_mem_crea_str(result, client->unparsed.string + client->first_to_parse, truncated_len); /* Transfer the length across the restart point. This is slightly ugly: if the string is truncated, we are not allowed to access all of the string! */ /* FIXME (bug 162): It would be better to add a client_len field to the Connection struct. Adding four bytes to that struct won't measurably change the size of the lyskomd process, and it will make this code easier to maintain. */ result->len = client_len; client->first_to_parse += truncated_len; client->string_parse_pos = 2; /* Fall through */ case 2: /* Was the string too long? If so, skip the truncated data. */ /* It looks like we're leaving one extra character in the string here, which is necessary if we want clients of this function to be able to detect long strings. */ client_len = result->len; truncated_len = min(maxlen+1, client_len); if ( client_len > truncated_len ) { to_skip = min(client_len - truncated_len, client->unparsed.len - client->first_to_parse); client_len -= to_skip; client->first_to_parse += to_skip; } result->len = client_len; if ( client_len > truncated_len ) longjmp(parse_env, KOM_MSG_INCOMPLETE); /* Fall through */ default: client->string_parse_pos = 0; } } extern void prot_a_parse_aux_item_flags(Connection *client, Aux_item_flags *res) { String token; String_size len; token = prot_a_get_token(client); len = s_strlen(token); if (len <= 0) longjmp(parse_env, KOM_PROTOCOL_ERR); init_aux_item_flags(res); switch (len) { default: case 8: res->reserved5 = token.string[ 7 ] != '0'; case 7: res->reserved4 = token.string[ 6 ] != '0'; case 6: res->reserved3 = token.string[ 5 ] != '0'; case 5: res->dont_garb = token.string[ 4 ] != '0'; case 4: res->hide_creator = token.string[ 3 ] != '0'; case 3: res->secret = token.string[ 2 ] != '0'; case 2: res->inherit = token.string[ 1 ] != '0'; case 1: res->deleted = token.string[ 0 ] != '0'; } } extern void prot_a_parse_aux_item(Connection *client, Aux_item *result) { switch ( client->struct_parse_pos ) { case 0: init_aux_item(result); result->tag = prot_a_parse_long(client); client->struct_parse_pos = 1; case 1: prot_a_parse_aux_item_flags(client, &result->flags); client->struct_parse_pos = 2; case 2: result->inherit_limit = prot_a_parse_long(client); client->struct_parse_pos = 3; case 3: prot_a_parse_string(client, &(result->data), param.aux_len); default: client->struct_parse_pos = 0; } } extern void prot_a_parse_aux_item_list(Connection *client, Aux_item_list *result, int maxlen) { static unsigned long err_cnt = 0; int i; switch (client->array_parse_pos) { case 0: if ((result->length != 0 || result->items != NULL) && err_cnt++ < 20) { kom_log("WNG: prot_a_parse_aux_item_list(): len = %lu data = %lu\n", (unsigned long)result->length, (unsigned long)result->items); result->length = 0; result->items = NULL; if (err_cnt == 20) kom_log("The above warning is now turned off.\n"); } client->array_parse_parsed_length = prot_a_parse_long(client); if (client->array_parse_parsed_length < 0) { isc_puts("%%Insane array size.\n", client->isc_session); isc_flush(client->isc_session); longjmp(parse_env, KOM_LOGOUT); } client->array_parse_pos = 1; /* Fall through */ case 1: if ( parse_nonwhite_char(client) != '{' ) longjmp(parse_env, KOM_PROTOCOL_ERR); result->length = min(maxlen+1, client->array_parse_parsed_length); result->items = smalloc(result->length * sizeof(Aux_item)); for (i = 0; i < result->length; i++) { result->items[i].data = EMPTY_STRING; } client->array_parse_index = 0; client->array_parse_pos = 2; case 2: while( client->array_parse_index < client->array_parse_parsed_length) { /* Enter a parsed aux item into the list only if we have parsed less than the length of the list */ if (client->array_parse_index < result->length) { prot_a_parse_aux_item(client, &result->items[ client->array_parse_index]); } else { prot_a_parse_aux_item(client, &client->dummy_aux_item); clear_aux_item(&client->dummy_aux_item); } client->array_parse_index += 1; } client->array_parse_pos = 3; case 3: /* Adjust the length of the result to the length allocated */ /* Read the closing brace */ if ( parse_nonwhite_char(client) != '}' ) longjmp(parse_env, KOM_PROTOCOL_ERR); default: client->array_parse_pos = 0; } } extern void prot_a_parse_misc_info_list(Connection *client, Misc_info_list *result, int maxlen) { static unsigned long err_cnt = 0; int i; Misc_info dummy_misc_info; switch (client->array_parse_pos) { case 0: if ((result->no_of_misc != 0 || result->misc != NULL) && err_cnt++ < 20) { kom_log("WNG: prot_a_parse_misc_info_list():" " len = %lu data = %lu\n", (unsigned long)result->no_of_misc, (unsigned long)result->misc); result->no_of_misc = 0; result->misc = NULL; if (err_cnt == 20) kom_log("The above warning is now turned off.\n"); } client->array_parse_parsed_length = prot_a_parse_long(client); if (client->array_parse_parsed_length < 0) { isc_puts("%%Insane array size.\n", client->isc_session); isc_flush(client->isc_session); longjmp(parse_env, KOM_LOGOUT); } client->array_parse_pos = 1; /* Fall through */ case 1: if ( parse_nonwhite_char(client) != '{' ) longjmp(parse_env, KOM_PROTOCOL_ERR); result->no_of_misc = min(maxlen+1, client->array_parse_parsed_length); result->misc = smalloc(result->no_of_misc * sizeof(Misc_info)); for (i = 0; i < result->no_of_misc; i++) { result->misc[i].type = unknown_info; } client->array_parse_index = 0; client->array_parse_pos = 2; case 2: while(client->array_parse_index < client->array_parse_parsed_length) { /* Enter a parsed aux item into the list only if we have parsed less than the no_of_misc of the list */ if (client->array_parse_index < result->no_of_misc) { prot_a_parse_misc_info(client, &result->misc[ client->array_parse_index]); /* If the most recently parsed item is an unknown, the misc-info parser will have skipped to the end of the array. Make allowances for this. */ if (result->misc[client->array_parse_index].type == unknown_info) { result->no_of_misc = client->array_parse_index + 1; } } else { prot_a_parse_misc_info(client, &dummy_misc_info); } client->array_parse_index += 1; } client->array_parse_pos = 3; case 3: /* Adjust the no_of_misc of the result to the length allocated */ /* Read the closing brace */ if ( parse_nonwhite_char(client) != '}' ) longjmp(parse_env, KOM_PROTOCOL_ERR); default: client->array_parse_pos = 0; } } extern void prot_a_parse_misc_info(Connection *client, Misc_info *result) { struct tm tmp_time; switch ( client->struct_parse_pos ) { case 0: result->type = prot_a_parse_long(client); client->struct_parse_pos = 1; /* Fall through */ case 1: switch( result->type ) { case recpt: case cc_recpt: case bcc_recpt: result->datum.recipient = prot_a_parse_long(client); break; case loc_no: result->datum.local_no = prot_a_parse_long(client); break; case comm_to: case footn_to: case comm_in: case footn_in: result->datum.text_link = prot_a_parse_long(client); break; case rec_time: prot_a_parse_time_date(client, &tmp_time); /* This value is never used. It is illegal to send a rec_time to the server. To avoid portability problems with timegm() we simply store a 0, instead of switching between using timegm or mktime depending on the use_utc setting. We used to store "mktime(&tmp_time)". */ result->datum.received_at = 0; break; case sent_by: result->datum.sender = prot_a_parse_long(client); break; case sent_at: prot_a_parse_time_date(client, &tmp_time); /* This value is never used. It is illegal to send a sent_at to the server. To avoid portability problems with timegm() we simply store a 0, instead of switching between using timegm or mktime depending on the use_utc setting. We used to store "mktime(&tmp_time)". */ result->datum.sent_at = 0; break; default: result->datum.unknown_type = result->type; result->type = unknown_info; client->array_hunt_depth = 1; prot_a_hunt_array_end(client); } default: client->struct_parse_pos = 0; } } static void prot_a_parse_read_range(Connection *client, struct read_range *result) { switch (client->struct_parse_pos) { case 0: result->first_read = prot_a_parse_long(client); client->struct_parse_pos = 1; /* Fall through */ case 1: result->last_read = prot_a_parse_long(client); /* Fall through */ default: client->struct_parse_pos = 0; } } void prot_a_parse_read_range_list(Connection *client, struct read_range_list *res, int maxlen) { static unsigned long err_cnt = 0; struct read_range dummy_read_range; switch (client->array_parse_pos) { case 0: if ((res->length != 0 || res->ranges != NULL) && err_cnt < 20) { kom_log("WNG: prot_a_parse_read_range_list():" " len = %lu data = %lu\n", (unsigned long)res->length, (unsigned long)res->ranges); res->length = 0; res->ranges = NULL; if (++err_cnt == 20) kom_log("The above warning is now turned off.\n"); } client->array_parse_parsed_length = prot_a_parse_long(client); if (client->array_parse_parsed_length < 0) { isc_puts("%%Insane array size.\n", client->isc_session); isc_flush(client->isc_session); longjmp(parse_env, KOM_LOGOUT); } client->array_parse_pos = 1; /* Fall through */ case 1: if (parse_nonwhite_char(client) != '{') longjmp(parse_env, KOM_PROTOCOL_ERR); res->length = min(maxlen+1, client->array_parse_parsed_length); res->ranges = smalloc(res->length * sizeof(struct read_range)); client->array_parse_index = 0; client->array_parse_pos = 2; case 2: while(client->array_parse_index < client->array_parse_parsed_length) { /* Enter a parsed range into the list only if we have parsed less than the no_of_misc of the list. */ if (client->array_parse_index < res->length) prot_a_parse_read_range( client, &res->ranges[client->array_parse_index]); else prot_a_parse_read_range(client, &dummy_read_range); client->array_parse_index += 1; } client->array_parse_pos = 3; case 3: /* Read the closing brace */ if ( parse_nonwhite_char(client) != '}' ) longjmp(parse_env, KOM_PROTOCOL_ERR); default: client->array_parse_pos = 0; } } void prot_a_parse_time_date(Connection *client, struct tm *result) { /* A time never occur inside a string, and a string never occur inside a time. Thus I use string_parse_pos here instead of inventing a new variable. */ switch( client->string_parse_pos ) { case 0: result->tm_sec = prot_a_parse_long(client); client->string_parse_pos = 1; /* Fall through */ case 1: result->tm_min = prot_a_parse_long(client); client->string_parse_pos = 2; /* Fall through */ case 2: result->tm_hour = prot_a_parse_long(client); client->string_parse_pos = 3; /* Fall through */ case 3: result->tm_mday = prot_a_parse_long(client); client->string_parse_pos = 4; /* Fall through */ case 4: result->tm_mon = prot_a_parse_long(client); client->string_parse_pos = 5; /* Fall through */ case 5: result->tm_year = prot_a_parse_long(client); client->string_parse_pos = 6; /* Fall through */ case 6: result->tm_wday = prot_a_parse_long(client); client->string_parse_pos = 7; /* Fall through */ case 7: result->tm_yday = prot_a_parse_long(client); client->string_parse_pos = 8; /* Fall through */ case 8: result->tm_isdst = prot_a_parse_long(client); /* Fall through */ default: client->string_parse_pos = 0; } } void prot_a_parse_info(Connection *client, Info *result) { switch( client->struct_parse_pos ) { case 0: result->version = prot_a_parse_long(client); client->struct_parse_pos = 1; /* Fall through */ case 1: result->conf_pres_conf = prot_a_parse_long(client); client->struct_parse_pos = 2; /* Fall through */ case 2: result->pers_pres_conf = prot_a_parse_long(client); client->struct_parse_pos = 3; /* Fall through */ case 3: result->motd_conf = prot_a_parse_long(client); client->struct_parse_pos = 4; /* Fall through */ case 4: result->kom_news_conf = prot_a_parse_long(client); client->struct_parse_pos = 5; /* Fall through */ case 5: result->motd_of_lyskom = prot_a_parse_long(client); /* Fall through */ default: client->struct_parse_pos = 0; } } void prot_a_hunt_nl(Connection *client) { String_size number_end; String_size len; while (1) { switch (client->fnc_parse_pos) { case 0: /* whitspace/simple tokens */ if ( client->first_to_parse >= s_strlen(client->unparsed) ) longjmp(parse_env, KOM_MSG_INCOMPLETE); switch(client->unparsed.string[client->first_to_parse]) { case ' ': case '\r': case '\t': case '{': case '}': case '*': client->first_to_parse++; break; case '\n': /* We found a newline -- end of message. Return now. */ client->first_to_parse++; return; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* Entering a number -- possibly a string. */ /* Don't increase first_to_parse. */ client->fnc_parse_pos = 1; break; default: longjmp(parse_env, KOM_PROTOCOL_ERR); } break; case 1: /* number/string */ /* Entering a number. The first char is known to be a digit. Parse the entire number at once. */ len = client->unparsed.string[client->first_to_parse] - '0'; for (number_end = client->first_to_parse + 1; number_end < s_strlen(client->unparsed); number_end++) { if (client->unparsed.string[number_end] >= '0' && client->unparsed.string[number_end] <= '9') { len = 10 * len + client->unparsed.string[number_end] - '0'; } else { /* The end of the number was reached. */ break; } } if (number_end == s_strlen(client->unparsed)) longjmp(parse_env, KOM_MSG_INCOMPLETE); if (client->unparsed.string[number_end] == 'H') { /* We are entering a string. Use num0 to store the lenght of the string to skip. */ client->num0 = len; client->first_to_parse = number_end + 1; client->fnc_parse_pos = 2; } else { /* We have just skipped past a number that was not the start of a string. */ client->first_to_parse = number_end; client->fnc_parse_pos = 0; } break; case 2: /* Skipping a string. */ if (client->num0 == 0) { /* The entire string has been skipped. */ client->fnc_parse_pos = 0; break; } len = s_strlen(client->unparsed) - client->first_to_parse; if (client->num0 <= len) { /* The entire string is present. Skip it. */ client->first_to_parse += client->num0; client->fnc_parse_pos = 0; break; } else { /* Skip as much of the string as possible. */ client->num0 -= len; client->first_to_parse = s_strlen(client->unparsed); longjmp(parse_env, KOM_MSG_INCOMPLETE); } abort(); default: abort(); } } } /* * Hunt for the end of an array. For this to work you need to set * array_hunt_depth to the number of nested arrays you want to * break out of (normally 1.) After this call the next token on * the input stream from the client will be the closing brace of * the array. */ static void prot_a_hunt_array_end(Connection *client) { String_size number_end; String_size len; while (1) { switch (client->hunt_parse_pos) { case 0: /* whitspace/simple tokens */ if ( client->first_to_parse >= s_strlen(client->unparsed) ) longjmp(parse_env, KOM_MSG_INCOMPLETE); switch(client->unparsed.string[client->first_to_parse]) { case ' ': case '\r': case '\t': case '*': case '\n': client->first_to_parse++; break; case '{': client->array_hunt_depth += 1; client->first_to_parse++; break; case '}': client->array_hunt_depth -= 1; if (client->array_hunt_depth <= 0) { client->hunt_parse_pos = 0; return; } else { client->first_to_parse++; } break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* Entering a number -- possibly a string. */ /* Don't increase first_to_parse. */ client->hunt_parse_pos = 1; break; default: longjmp(parse_env, KOM_PROTOCOL_ERR); } break; case 1: /* number/string */ /* Entering a number. The first char is known to be a digit. Parse the entire number at once. */ len = client->unparsed.string[client->first_to_parse] - '0'; for (number_end = client->first_to_parse + 1; number_end < s_strlen(client->unparsed); number_end++) { if (client->unparsed.string[number_end] >= '0' && client->unparsed.string[number_end] <= '9') { len = 10 * len + client->unparsed.string[number_end] - '0'; } else { /* The end of the number was reached. */ break; } } if (number_end == s_strlen(client->unparsed)) longjmp(parse_env, KOM_MSG_INCOMPLETE); if (client->unparsed.string[number_end] == 'H') { /* We are entering a string. Use num0 to store the lenght of the string to skip. */ client->array_hunt_num = len; client->first_to_parse = number_end + 1; client->hunt_parse_pos = 2; } else { /* We have just skipped past a number that was not the start of a string. */ client->first_to_parse = number_end; client->hunt_parse_pos = 0; } break; case 2: /* Skipping a string. */ if (client->array_hunt_num == 0) { /* The entire string has been skipped. */ client->hunt_parse_pos = 0; break; } len = s_strlen(client->unparsed) - client->first_to_parse; if (client->array_hunt_num <= len) { /* The entire string is present. Skip it. */ client->first_to_parse += client->array_hunt_num; client->hunt_parse_pos = 0; break; } else { /* Skip as much of the string as possible. */ client->array_hunt_num -= len; client->first_to_parse = s_strlen(client->unparsed); longjmp(parse_env, KOM_MSG_INCOMPLETE); } abort(); /* NOTREACHED */ default: abort(); } } } void prot_a_parse_skip_whitespace(Connection *client) { while (client->first_to_parse < client->unparsed.len && strchr(WHITESPACE, client->unparsed.string[client->first_to_parse]) != NULL) client->first_to_parse++; } lyskom-server-2.1.2/src/server/prot-a.c0000664000015100472110000003204607721716130013471 /* * $Id: prot-a.c,v 0.90 2003/08/23 16:38:14 ceder Exp $ * Copyright (C) 1991-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * Protocol A. */ #ifdef HAVE_CONFIG_H # include #endif #ifdef HAVE_STDDEF_H # include #endif #ifdef HAVE_STDARG_H # include #endif #include #include "timewrap.h" #include #include #include "oop.h" #include "misc-types.h" #include "s-string.h" #include "kom-types.h" #include "com.h" #include "async.h" #include "connections.h" #include "debug.h" #include "isc-interface.h" #include "kom-errno.h" #include "server/smalloc.h" #include "prot-a.h" #include "prot-a-output.h" #include "prot-a-parse.h" #include "isc-parse.h" #include "param.h" #include "kom-memory.h" BUGDECL; void prot_a_reply(Connection *client, Success status, union result_holder *res) { /* * The function is called. Now return the answer. */ if ( status == OK ) { isc_putc('=', client->isc_session); isc_putul(client->ref_no, client->isc_session); switch ( fnc_defs[ client->function_index ].result ) { case rt_number: isc_putc(' ', client->isc_session); isc_putul(res->number, client->isc_session); BUG(("=%lu\n", res->number)); break; case rt_success: BUG(("=Success\n")); break; case rt_person: prot_a_output_person(client, &res->person); BUG(("={Person struct not listed}\n")); break; case rt_membership: prot_a_output_membership(client, &res->membership); BUG(("={Membership struct not listed}\n")); break; case rt_membership_old: prot_a_output_membership_old(client, &res->membership_old); BUG(("={Membership_old struct not listed}\n")); break; case rt_membership_10: prot_a_output_membership_10(client, &res->membership_10); BUG(("={Membership_10 struct not listed}\n")); break; case rt_conf_list: prot_a_output_conf_list(client, res->conf_list); BUG(("={Conf_list not listed}\n")); break; case rt_conf_no_list: prot_a_output_conf_no_list(client, res->conf_no_list); BUG(("={Conf_no_list not listed}\n")); break; case rt_conference: prot_a_output_conference(client, &res->conference); BUG(("={Conference struct not listed}\n")); break; case rt_conference_old: prot_a_output_conference_old(client, &res->conference); BUG(("={Conference (old) struct not listed}\n")); break; case rt_string: prot_a_output_string(client, res->string); BUG(("={%luH", res->string.len)); BUGSTR(res->string); BUG(("}\n")); break; case rt_mark_list: prot_a_output_mark_list(client, res->mark_list); BUG(("={Mark_list not listed}\n")); break; case rt_text_stat_old: prot_a_output_text_stat_old(client, &res->text_stat); BUG(("={Text_stat (old) struct not listed}\n")); break; case rt_text_stat: prot_a_output_text_stat(client, &res->text_stat); BUG(("={Text_stat struct not listed}\n")); break; case rt_who_info_list: prot_a_output_who_info_list(client, res->who_info_list); BUG(("={Who_info_list not listed}\n")); break; case rt_who_info_list_old: prot_a_output_who_info_list_old(client, res->who_info_list_old); BUG(("={Old who_info_list not listed}\n")); break; case rt_session_info: prot_a_output_session_info(client, &res->session_info); /* Clear username, since it is allocated (in get_session_info() in session.c). See comment abover the definition of union result_holder in connections.h. */ s_clear(&res->session_info.username); BUG(("={Session_info not listed}\n")); break; case rt_info: prot_a_output_info(client, &res->info); BUG(("={Who_info struct not listed}\n")); break; case rt_info_old: prot_a_output_info_old(client, &res->info); BUG(("={Who_info struct not listed}\n")); break; case rt_membership_list: prot_a_output_membership_list(client, res->membership_list); BUG (("={Membership_list not listed}\n")); break; case rt_membership_list_10: prot_a_output_membership_list_10(client, res->membership_list_10); BUG (("={Membership_list_10 not listed}\n")); break; case rt_membership_list_old: prot_a_output_membership_list_old (client, res->membership_list_old); BUG (("={Membership_list_old not listed}\n")); break; case rt_member_list: prot_a_output_member_list (client, res->member_list); BUG(("={Member_list not listed}\n")); break; case rt_member_list_old: prot_a_output_member_list_old (client, res->member_list); BUG(("={Member_list not listed}\n")); break; case rt_time_date: prot_a_output_time (client, res->time_date); BUG(("=(time_t)%lu\n", (unsigned long)res->time_date)); break; case rt_session_no: prot_a_output_session_no (client, res->session_no); BUG(("=(Session_no)%lu\n", res->session_no)); break; case rt_text_no: prot_a_output_text_no (client, res->text_no); BUG(("=(Text_no)%lu\n", res->text_no)); break; case rt_conf_no: prot_a_output_conf_no (client, res->conf_no); BUG(("=(Conf_no)%lu\n", (unsigned long)res->conf_no)); break; case rt_who_info_ident_list: prot_a_output_who_info_ident_list(client, res->who_info_ident_list); BUG(("={Who_info_ident_list not listed}\n")); break; case rt_session_info_ident: prot_a_output_session_info_ident(client, &res->session_info_ident); BUG(("={Session_info_ident not listed}\n")); break; case rt_conf_z_info_list: prot_a_output_conf_z_info_list(client, res->conf_z_info_list); BUG(("={Conf_z_info_list not listed}\n")); break; case rt_version_info: prot_a_output_version_info(client, &res->version_info); BUG(("={Version_info not listed}\n")); break; case rt_uconference: prot_a_output_uconference(client, &res->uconference); BUG(("={UConference not listed}\n")); break; case rt_num_list: prot_a_output_num_list(client, &res->num_list); BUG(("={num_list not listed}\n")); break; case rt_dynamic_session_info_list: prot_a_output_dynamic_session_info_list( client, &res->dynamic_session_info_list); BUG(("={dynamic_session_list not listed}\n")); break; case rt_static_session_info: prot_a_output_static_session_info(client, &res->static_session_info); BUG(("={static_session_info not listed")); break; case rt_l2g_iterator_as_text_list: prot_a_output_l2g_iterator_as_text_list( client, &res->l2g_iterator_as_text_list); BUG(("={l2g_iterator_as_text_list not listed")); break; case rt_text_mapping: prot_a_output_text_mapping(client, &res->text_mapping); BUG(("={text_mapping not listed")); break; case rt_text_mapping_reverse: prot_a_output_text_mapping_reverse(client, &res->text_mapping_reverse); BUG(("={text_mapping_reverse not listed")); break; case rt_stats_description: prot_a_output_stats_description(client, &res->stats_description); BUG(("={stats_description not listed")); break; case rt_stats_list: prot_a_output_stats_list(client, &res->stats_list); BUG(("={stats_list not listed")); break; case rt_static_server_info: prot_a_output_static_server_info(client, &res->static_server_info); BUG(("={static_server_info not listed")); break; case rt_scheduling_info: prot_a_output_scheduling_info(client, &res->scheduling_info); BUG(("={scheduling_info not listed")); break; #ifdef DEBUG_CALLS case rt_memory_info: prot_a_output_memory_info(client, &res->memory_info); BUG(("={memory_info not listed")); break; #endif } isc_putc('\n', client->isc_session); } else { /* Failure. Give a reply with the error message. */ isc_putc('%', client->isc_session); isc_putul(client->ref_no, client->isc_session); prot_a_output_ul(client, kom_errno); prot_a_output_ul(client, err_stat); isc_putc('\n', client->isc_session); BUG(("%%Err %d\n", kom_errno)); } } /* * Set up all data structures that are private to protocol A. This * function is called from connections.c whenever a connection says * that it is of type A. */ void prot_a_init(Connection *conn) { conn->parse_pos = 0; conn->fnc_parse_pos = 0; conn->array_parse_index = 0; conn->array_parse_parsed_length = 0; conn->array_parse_pos = 0; conn->struct_parse_pos = 0; conn->string_parse_pos = 0; conn->hunt_parse_pos = 0; conn->array_hunt_num = 0; conn->array_hunt_depth = 0; conn->ref_no = 0; conn->function = call_fnc_login_old; conn->function_index = 0; conn->num0 = 0; conn->num1 = 0; conn->num2 = 0; conn->num3 = 0; conn->c_string0 = EMPTY_STRING; conn->c_string1 = EMPTY_STRING; conn->string0 = EMPTY_STRING; conn->misc_info_list.misc = NULL; conn->misc_info_list.no_of_misc = 0; conn->aux_item_list.items = NULL; conn->aux_item_list.length = 0; conn->aux_item.data = EMPTY_STRING; conn->dummy_aux_item.data = EMPTY_STRING; init_priv_bits(&conn->priv_bits); init_conf_type(&conn->conf_type); } void prot_a_destruct(Connection *conn) { int i; /* * All strings et c should already by free:d - that is done at the * end of each atomic call. But free them anyhow, just in case * this client is forced off while unparsed data is present. */ s_clear(&conn->string0); s_clear(&conn->c_string0); s_clear(&conn->c_string1); s_clear(&conn->aux_item.data); s_clear(&conn->dummy_aux_item.data); for (i = 0; i < conn->aux_item_list.length; i++) s_clear(&conn->aux_item_list.items[i].data); conn->aux_item_list.length = 0; sfree(conn->aux_item_list.items); conn->aux_item_list.items = NULL; conn->misc_info_list.no_of_misc = 0; sfree(conn->misc_info_list.misc); conn->misc_info_list.misc = NULL; conn->num_list.length = 0; sfree(conn->num_list.data); conn->num_list.data = NULL; sfree(conn->read_range_list.ranges); conn->read_range_list.ranges = NULL; conn->read_range_list.length = 0; } /* * Check if it is a legal function. */ static int prot_a_is_legal_fnc(enum call_header fnc) { #include "prot-a-is-legal-fnc.incl" } void prot_a_parse_packet(Connection *client) { if ( client->username_valid == FALSE ) { /* Connection not established yet */ prot_a_parse_string(client, &client->c_string0, param.username_len); client->username = client->c_string0; /* Kludge to deal with */ client->c_string0 = EMPTY_STRING; /* "A5B" as first input. */ /* Protokoll B will not suffer from this... */ client->username_valid = TRUE; isc_puts("LysKOM\n", client->isc_session); isc_flush(client->isc_session); isc_set_acceptable_idle(client->isc_session, param.login_timeout); BUG(("[Handshake with client %lu completed]\n", client->session_no)); } if (client->dns_done == FALSE) { prot_a_parse_skip_whitespace(client); isc_disable(client->isc_session); client->blocked_by_dns = TRUE; return; } switch(client->parse_pos) { case 0: /* Get ref_no */ /* Delete any leading whitespace. This is not strictly necessary, as prot_a_parse_long will skip whitespace, but if we don't get a complete packet this will ensure that the leading whitespace is discarded now. */ prot_a_parse_skip_whitespace(client); client->ref_no = prot_a_parse_long(client); client->parse_pos = 1; /* Fall through */ case 1: /* Get fnc_no */ client->function = (enum call_header)(int)prot_a_parse_long(client); if ((client->function_index = prot_a_is_legal_fnc(client->function)) == -1 ) { client->function = illegal_fnc; client->function_index = num_fnc_defs - 1; } client->parse_pos = 2; /* Fall through */ case 2: /* Call the function that parses the arguments for this call. */ (*fnc_defs[client->function_index].parser)(client); /* Delete any trailing whitespace. */ prot_a_parse_skip_whitespace(client); /* Fall through */ default: client->parse_pos = 0; } } lyskom-server-2.1.2/src/server/prot-a-send-async.c0000664000015100472110000002170407721716127015540 /* * $Id: prot-a-send-async.c,v 0.38 2003/08/23 16:38:14 ceder Exp $ * Copyright (C) 1991, 1993-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * Asynchronous messages in protocol A. */ #ifdef HAVE_CONFIG_H # include #endif #include #include "timewrap.h" #include #include #ifdef HAVE_STDARG_H # include #endif #include "oop.h" #include "misc-types.h" #include "s-string.h" #include "kom-types.h" #include "com.h" #include "async.h" #include "connections.h" #include "prot-a-send-async.h" #include "async.h" #include "isc-interface.h" #include "prot-a-output.h" static void async_header(Connection *fp, int no_of_tokens, enum async fnc) { isc_putc(':', fp->isc_session); isc_putul(no_of_tokens, fp->isc_session); prot_a_output_ul(fp, fnc); } static void async_trailer(Connection *fp) { isc_putc('\n', fp->isc_session); /* FIXME (bug 107): Maybe we shouldn't flush each and every asynchronous message at once. We would probably get a better performance if we spread them out over a few seconds. */ isc_flush(fp->isc_session); } void prot_a_async_new_text_old(Connection *cptr, Text_no text_no, Text_stat *text_s) { ASYNC_CHECK_ACCEPT(cptr, ay_new_text_old); async_header(cptr, 16, ay_new_text_old); prot_a_output_ul(cptr, text_no); prot_a_output_text_stat_old(cptr, text_s); async_trailer(cptr); } void prot_a_async_new_text(Connection *cptr, Text_no text_no, Text_stat *text_s) { ASYNC_CHECK_ACCEPT(cptr, ay_new_text); async_header(cptr, 18, ay_new_text); prot_a_output_ul(cptr, text_no); prot_a_output_text_stat(cptr, text_s); async_trailer(cptr); } void prot_a_async_i_am_on(Connection *cptr, Who_info info) { ASYNC_CHECK_ACCEPT(cptr, ay_i_am_on); async_header(cptr, 5, ay_i_am_on); prot_a_output_who_info(cptr, &info); async_trailer(cptr); } void prot_a_async_logout(Connection *cptr, Pers_no pers_no, Session_no session_no) { ASYNC_CHECK_ACCEPT(cptr, ay_logout); async_header(cptr, 2, ay_logout); prot_a_output_ul(cptr, pers_no); prot_a_output_ul(cptr, session_no); async_trailer(cptr); } void prot_a_async_new_name(Connection *cptr, Conf_no conf_no, String old_name, String new_name) { ASYNC_CHECK_ACCEPT(cptr, ay_new_name); async_header(cptr, 3, ay_new_name); prot_a_output_ul(cptr, conf_no); prot_a_output_string(cptr, old_name); prot_a_output_string(cptr, new_name); async_trailer(cptr); } void prot_a_async_sync_db(Connection *cptr) { ASYNC_CHECK_ACCEPT(cptr, ay_sync_db); async_header(cptr, 0, ay_sync_db); async_trailer(cptr); } void prot_a_async_forced_leave_conf(Connection *cptr, Conf_no conf_no) { ASYNC_CHECK_ACCEPT(cptr, ay_leave_conf); async_header(cptr, 1, ay_leave_conf); prot_a_output_ul(cptr, conf_no); async_trailer(cptr); } void prot_a_async_login(Connection *cptr, Pers_no pers_no, int session_no) { ASYNC_CHECK_ACCEPT(cptr, ay_login); async_header(cptr, 2, ay_login); prot_a_output_ul(cptr, pers_no); prot_a_output_ul(cptr, session_no); async_trailer(cptr); } void prot_a_async_rejected_connection(Connection *cptr) { ASYNC_CHECK_ACCEPT(cptr, ay_rejected_connection); async_header(cptr, 0, ay_rejected_connection); async_trailer(cptr); } void prot_a_async_send_message(Connection *cptr, Conf_no recipient, Pers_no sender, String message) { ASYNC_CHECK_ACCEPT(cptr, ay_send_message); async_header(cptr, 3, ay_send_message); prot_a_output_ul(cptr, recipient); prot_a_output_ul(cptr, sender); prot_a_output_string(cptr, message); async_trailer(cptr); } void prot_a_async_deleted_text(Connection *cptr, Text_no text_no, Text_stat *text_s) { ASYNC_CHECK_ACCEPT(cptr, ay_deleted_text); async_header(cptr, 18, ay_deleted_text); prot_a_output_ul(cptr, text_no); prot_a_output_text_stat(cptr, text_s); async_trailer(cptr); } void prot_a_async_new_recipient(Connection *cptr, Text_no text_no, Conf_no conf_no, enum info_type type) { ASYNC_CHECK_ACCEPT(cptr, ay_new_recipient); async_header(cptr, 3, ay_new_recipient); prot_a_output_ul(cptr, text_no); prot_a_output_ul(cptr, conf_no); prot_a_output_ul(cptr, type); async_trailer(cptr); } void prot_a_async_sub_recipient(Connection *cptr, Text_no text_no, Conf_no conf_no, enum info_type type) { ASYNC_CHECK_ACCEPT(cptr, ay_sub_recipient); async_header(cptr, 3, ay_sub_recipient); prot_a_output_ul(cptr, text_no); prot_a_output_ul(cptr, conf_no); prot_a_output_ul(cptr, type); async_trailer(cptr); } void prot_a_async_new_membership(Connection *cptr, Pers_no pers_no, Conf_no conf_no) { ASYNC_CHECK_ACCEPT(cptr, ay_new_membership); async_header(cptr, 2, ay_new_membership); prot_a_output_ul(cptr, pers_no); prot_a_output_ul(cptr, conf_no); async_trailer(cptr); } void prot_a_async_new_user_area(Connection *cptr, Pers_no pers_no, Text_no old_user_area, Text_no new_user_area) { ASYNC_CHECK_ACCEPT(cptr, ay_new_user_area); async_header(cptr, 3, ay_new_user_area); prot_a_output_ul(cptr, pers_no); prot_a_output_ul(cptr, old_user_area); prot_a_output_ul(cptr, new_user_area); async_trailer(cptr); } void prot_a_async_new_presentation(Connection *cptr, Conf_no conf_no, Text_no old_presentation, Text_no new_presentation) { ASYNC_CHECK_ACCEPT(cptr, ay_new_presentation); async_header(cptr, 3, ay_new_presentation); prot_a_output_ul(cptr, conf_no); prot_a_output_ul(cptr, old_presentation); prot_a_output_ul(cptr, new_presentation); async_trailer(cptr); } void prot_a_async_new_motd(Connection *cptr, Conf_no conf_no, Text_no old_motd, Text_no new_motd) { ASYNC_CHECK_ACCEPT(cptr, ay_new_motd); async_header(cptr, 3, ay_new_motd); prot_a_output_ul(cptr, conf_no); prot_a_output_ul(cptr, old_motd); prot_a_output_ul(cptr, new_motd); async_trailer(cptr); } void prot_a_async_text_aux_changed(Connection *cptr, Text_no text_no, Aux_item_list *aux_list, unsigned long highest_old_aux) { unsigned short added = 0; unsigned short deleted = 0; unsigned short ix; ASYNC_CHECK_ACCEPT(cptr, ay_text_aux_changed); for (ix = 0; ix < aux_list->length; ix++) { if (aux_list->items[ix].flags.deleted) deleted++; if (aux_list->items[ix].aux_no > highest_old_aux) added++; } if (deleted + added == 0) return; async_header(cptr, 5, ay_text_aux_changed); prot_a_output_ul(cptr, text_no); prot_a_output_ul(cptr, deleted); if (deleted == 0) isc_puts(" *", cptr->isc_session); else { isc_puts(" {", cptr->isc_session); for (ix = 0; ix < aux_list->length; ix++) if (aux_list->items[ix].flags.deleted) prot_a_output_aux_item(cptr, &aux_list->items[ix]); isc_puts(" }", cptr->isc_session); } prot_a_output_ul(cptr, added); if (added == 0) isc_puts(" *", cptr->isc_session); else { isc_puts(" {", cptr->isc_session); for (ix = 0; ix < aux_list->length; ix++) if (aux_list->items[ix].aux_no > highest_old_aux) prot_a_output_aux_item(cptr, &aux_list->items[ix]); isc_puts(" }", cptr->isc_session); } async_trailer(cptr); } #ifdef DEBUG_CALLS void prot_a_async_garb_ended(Connection *cptr, int deleted_texts) { ASYNC_CHECK_ACCEPT(cptr, ay_garb_ended); async_header(cptr, 1, ay_garb_ended); prot_a_output_ul(cptr, deleted_texts); async_trailer(cptr); } #endif lyskom-server-2.1.2/src/server/internal-connections.c0000664000015100472110000002421507723606125016426 /* * $Id: internal-connections.c,v 0.67 2003/08/29 08:16:50 ceder Exp $ * Copyright (C) 1991-1994, 1996-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * internal-connections.c * * Abstract routines on the data type Connection. */ #ifdef HAVE_CONFIG_H # include #endif #include #include "timewrap.h" #include #include #include #include "exp.h" #include "s-string.h" #include "kom-types.h" #include "com.h" #include "async.h" #include "connections.h" #include "internal-connections.h" #include "kom-config.h" #include "server/smalloc.h" #include "lyskomd.h" #include "log.h" #include "async.h" #include "kom-memory.h" #include "server-time.h" #include "timeval-util.h" #include "stats.h" INTERNAL Connection *all_connections = NULL; INTERNAL Session_no no_of_connection_attempts = 0; /* Used in get_conn_by_number to speed things up. */ INTERNAL Connection *last_conn = NULL; static int no_of_allocated_connections = 0; static void init_connection(Connection *conn) { static const enum async default_want_async[] = ASYNC_DEFAULT_MESSAGES; int i; conn->prev = NULL; conn->next = NULL; conn->pers_no = 0; conn->person = NULL; conn->connect_time = timeval_ctor(0, 0); conn->login_time = timeval_ctor(0, 0); conn->cwc = 0; conn->what_am_i_doing = EMPTY_STRING; conn->ena_level = 0; conn->username = EMPTY_STRING; conn->ident_user = EMPTY_STRING; conn->client_name = EMPTY_STRING; conn->client_version = EMPTY_STRING; conn->flags.invisible = FALSE; conn->flags.user_active_used = FALSE; conn->flags.user_absent = FALSE; conn->flags.reserved3 = FALSE; conn->flags.reserved4 = FALSE; conn->flags.reserved5 = FALSE; conn->flags.reserved6 = FALSE; conn->flags.reserved7 = FALSE; conn->username_valid = FALSE; conn->dns_done = FALSE; conn->blocked_by_dns = FALSE; conn->isc_session = NULL; conn->remote_ip = EMPTY_STRING; conn->peer = NULL; conn->protocol = '\0'; conn->use_utc = FALSE; conn->parse_pos = 0; conn->fnc_parse_pos = 0; conn->array_parse_pos = 0; conn->array_parse_index = 0; conn->array_parse_parsed_length = 0; conn->struct_parse_pos = 0; conn->string_parse_pos = 0; conn->hunt_parse_pos = 0; conn->array_hunt_num = 0; conn->array_hunt_depth = 0; conn->ref_no = 0; conn->function = call_fnc_login_old; conn->function_index = 0; conn->num_list.length = 0; conn->num_list.data = NULL; conn->num0 = 0; conn->num1 = 0; conn->num2 = 0; conn->num3 = 0; conn->num4 = 0; conn->c_string0 = EMPTY_STRING; conn->c_string1 = EMPTY_STRING; conn->string0 = EMPTY_STRING; conn->misc_info_list.no_of_misc = 0; conn->misc_info_list.misc = NULL; conn->aux_item_list.items = NULL; conn->aux_item_list.length = 0; conn->aux_item.data = EMPTY_STRING; conn->dummy_aux_item.data = EMPTY_STRING; conn->read_range_list.ranges = NULL; conn->read_range_list.length = 0; init_priv_bits(&conn->priv_bits); init_conf_type(&conn->conf_type); init_membership_type(&conn->membership_type); init_struct_tm(&conn->time); conn->info.pers_pres_conf = 0; conn->info.conf_pres_conf = 0; conn->info.motd_conf = 0; conn->info.kom_news_conf = 0; conn->info.motd_of_lyskom = 0; conn->info.version = 0; conn->info.highest_aux_no = 0; conn->info.aux_item_list.length = 0; conn->info.aux_item_list.items = NULL; init_personal_flags(&conn->pers_flags); conn->unparsed = EMPTY_STRING; conn->first_to_parse = 0; conn->more_to_parse = FALSE; conn->kill_status = ks_none; conn->penalty = 0; conn->penalty_generation = 0; conn->queue_next = NULL; conn->queue_prev = NULL; conn->on_queue = FALSE; conn->schedule.priority = 0; conn->schedule.weight = 1; conn->active_time = current_time; conn->session_no = 0; for (i = 0; i < ay_dummy_last; i++) conn->want_async[i] = FALSE; for (i = 0; (size_t)i < sizeof(default_want_async)/sizeof(*default_want_async); i++) conn->want_async[default_want_async[i]] = TRUE; } static Connection * alloc_connection(void) { Connection *res; res = smalloc ( sizeof(Connection) ); init_connection(res); ++no_of_allocated_connections; return res; } EXPORT Connection * new_client(void) { Connection *c; c = alloc_connection(); if (all_connections != NULL) { all_connections->prev->next = c; c->prev = all_connections->prev; all_connections->prev = c; c->next = all_connections; } else { c->prev = c; c->next = c; } all_connections = c; c->session_no = ++no_of_connection_attempts; c->protocol = '\0'; /* Reserved to mean 'no protocol specified yet' */ c->unparsed = EMPTY_STRING; c->first_to_parse = 0; c->kill_status = ks_none; c->more_to_parse = TRUE; c->active_time = current_time; c->pers_no = 0; c->person = NULL; c->connect_time = current_time; c->login_time = current_time; c->cwc = 0; c->what_am_i_doing = EMPTY_STRING; c->ena_level = 0; c->username = EMPTY_STRING; c->ident_user = EMPTY_STRING; c->client_name = EMPTY_STRING; c->client_version = EMPTY_STRING; c->flags.invisible = FALSE; c->flags.user_active_used = FALSE; c->flags.user_absent = FALSE; c->flags.reserved3 = FALSE; c->flags.reserved4 = FALSE; c->flags.reserved5 = FALSE; c->flags.reserved6 = FALSE; c->flags.reserved7 = FALSE; c->username_valid = FALSE; c->dns_done = FALSE; c->blocked_by_dns = FALSE; c->use_utc = FALSE; return c; } /* * Only used from logout_client */ EXPORT void kill_client(Connection *cp) { if ( all_connections == NULL ) restart_kom("kill_client(): No clients in all_connections list\n"); if (all_connections == all_connections->next) { if (all_connections->prev != all_connections) restart_kom("kill_client(): all_connections corrupt (LINK)\n"); if (all_connections != cp) restart_kom("kill_client(): all_connections corrupt (SINGLE)\n"); all_connections = NULL; } else { if (cp->prev == NULL || cp->next == NULL) restart_kom("kill_client(): all_connections corrupt (NULL)\n"); cp->prev->next = cp->next; cp->next->prev = cp->prev; if (all_connections == cp) all_connections = cp->next; } if ( last_conn == cp ) last_conn = NULL; update_stat(STAT_RECV_QUEUE, -(s_strlen(cp->unparsed) - cp->first_to_parse)); s_clear(&cp->unparsed); s_clear(&cp->what_am_i_doing); s_clear(&cp->username); s_clear(&cp->ident_user); s_clear(&cp->client_name); s_clear(&cp->client_version); s_clear(&cp->remote_ip); if ( cp->isc_session != NULL ) { kom_log("kill_client(): client %ld has isc_session != NULL.\n", cp->session_no); } assert(cp->on_queue == FALSE); if ( !s_empty(cp->c_string0) || !s_empty(cp->c_string1) || !s_empty(cp->string0) ) { kom_log("kill_client(): unexpected string remains.\n"); } if (cp->misc_info_list.misc != NULL) kom_log("kill_client(): unexpected misc_info_list remains.\n"); if (cp->num_list.data != NULL) kom_log("kill_client(): unexpected num_list remains.\n"); if (!s_empty(cp->aux_item.data)) kom_log("kill_client(): unexpected aux_item string remains.\n"); if (!s_empty(cp->dummy_aux_item.data)) kom_log("kill_client(): unexpected dummy_aux_item string remains.\n"); if (cp->aux_item_list.items != NULL) kom_log("kill_client(): unexpected aux-item list reamins.\n"); sfree(cp->peer); sfree(cp); --no_of_allocated_connections; } /* * Session_nos must NOT be recycled, or this code might break! */ EXPORT Connection * get_conn_by_number (Session_no session_no) { Connection *end; if (all_connections == NULL) return NULL; if (last_conn == NULL) last_conn = all_connections; end = last_conn; if (session_no == 0) { if (active_connection == NULL) restart_kom("get_conn_by_number:" " No session-no and no active connection"); session_no = active_connection->session_no; } do { if (last_conn->session_no == session_no) return last_conn; last_conn = last_conn->next; } while (last_conn != end); return NULL; } EXPORT Session_no traverse_connections (Session_no session_no) { Connection *prev = NULL; if ( all_connections == NULL ) return 0; if (session_no == 0) prev = NULL; else prev = get_conn_by_number ( session_no ); /* prev is NULL if session_no is 0, or if session_no was logged out. */ if ( prev == NULL ) return all_connections->session_no; else if ( prev->next == all_connections ) return 0; /* Full circle. */ else return prev->next->session_no; } void dump_allocated_connections(FILE *fp) { fprintf(fp, "---%s:\n\tConnections: %d\n", __FILE__, no_of_allocated_connections); fprintf(fp, "\tConnection attempts: %lu\n", (unsigned long)no_of_connection_attempts); } Bool handshake_ok(struct connection *cptr, enum ignored_conditions ignored) { if (!cptr->dns_done && !(ignored & ignore_dns)) return FALSE; if (!cptr->username_valid) return FALSE; return TRUE; } lyskom-server-2.1.2/src/server/rfc931.c0000664000015100472110000000543007721716130013273 /* * $Id: rfc931.c,v 1.28 2003/08/23 16:38:14 ceder Exp $ * Copyright (C) 1991-1994, 1998-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * This function retrieves the real user that owns the TCP/IP link * that is connecting via the IscSession "scb". The returned string * points to static data which is overwritten on the next call. * * Link with "-lauthuser". */ #ifdef HAVE_CONFIG_H # include #endif #include #include #ifdef HAVE_LIBAUTHUSER # include #endif #include #include #include "timewrap.h" #include "oop.h" #include "log.h" #include "s-string.h" #include "isc-interface.h" #include "misc-types.h" #include "kom-types.h" #include "param.h" #include "rfc931.h" #include "unused.h" #include "stats.h" #ifdef HAVE_LIBAUTHUSER # define USE_IF_LIBAUTHUSER(x) x #else # define USE_IF_LIBAUTHUSER(x) UNUSED(x) #endif const char * get_real_username(struct isc_scb *USE_IF_LIBAUTHUSER(scb), char *USE_IF_LIBAUTHUSER(hostname)) { #ifdef HAVE_LIBAUTHUSER unsigned long inlocal; unsigned long inremote; unsigned short local; unsigned short remote; char *result; time_t before, after; if (param.authentication_level == 0) return NULL; if (auth_fd2(scb->fd, &inlocal, &inremote, &local, &remote) == -1) return NULL; time(&before); update_stat(STAT_IDENT_QUEUE, 1); result = auth_tcpuser3(inlocal, inremote, local, remote, 20); update_stat(STAT_IDENT_QUEUE, -1); update_stat(STAT_PROCESSED_IDENT, -1); if (result == NULL && errno == ETIMEDOUT) kom_log ("Identd request to %s timed out.\n", hostname); else { time(&after); if (difftime(after, before) > 15) kom_log ("Identd at %s said %s after %d seconds.\n", hostname, result == NULL ? "(error)" : result, (int)difftime(after, before)); } return result; #else return "unknown"; #endif } lyskom-server-2.1.2/src/server/isc-malloc.c0000664000015100472110000000364707721716127014325 /* * $Id: isc-malloc.c,v 1.17 2003/08/23 16:38:16 ceder Exp $ * Copyright (C) 1991-1995, 1998-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * Malloc wrappers for the isc package. * * These functions call smalloc and also counts * how many allocated blocks there are. */ #ifdef HAVE_CONFIG_H # include #endif #include #ifdef HAVE_STDDEF_H # include #endif #include #include "exp.h" #include "isc-malloc.h" #include "server/smalloc.h" static int no_of_allocated_blocks = 0; EXPORT void * isc_malloc_wrapper(size_t size) { ++no_of_allocated_blocks; return smalloc (size); } EXPORT void isc_free_wrapper(void * ptr) { --no_of_allocated_blocks; sfree(ptr); } EXPORT void * isc_realloc_wrapper (void * ptr, size_t size) { if ( ptr == NULL ) return isc_malloc_wrapper (size); return srealloc (ptr, size); } EXPORT void dump_isc_alloc_counts(FILE *stat_file) { fprintf(stat_file, "---%s:\n\tAllocated blocks by isc: %d\n", __FILE__, no_of_allocated_blocks); } lyskom-server-2.1.2/src/server/aux-item-def-parse.y0000664000015100472110000004660307721716126015723 %{ /* * $Id: aux-item-def-parse.y,v 1.22 2003/08/23 16:38:18 ceder Exp $ * Copyright (C) 1994-1996, 1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* Rename hack from the automake 1.4 manual. */ #define yymaxdepth aid_maxdepth #define yyparse aid_parse #define yylex aid_lex #define yyerror aid_error #define yylval aid_lval #define yychar aid_char #define yydebug aid_debug #define yypact aid_pact #define yyr1 aid_r1 #define yyr2 aid_r2 #define yydef aid_def #define yychk aid_chk #define yypgo aid_pgo #define yyact aid_act #define yyexca aid_exca #define yyerrflag aid_errflag #define yynerrs aid_nerrs #define yyps aid_ps #define yypv aid_pv #define yys aid_s #define yy_yys aid_yys #define yystate aid_state #define yytmp aid_tmp #define yyv aid_v #define yy_yyv aid_yyv #define yyval aid_val #define yylloc aid_lloc #define yyreds aid_reds #define yytoks aid_toks #define yylhs aid_yylhs #define yylen aid_yylen #define yydefred aid_yydefred #define yydgoto aid_yydgoto #define yysindex aid_yysindex #define yyrindex aid_yyrindex #define yygindex aid_yygindex #define yytable aid_yytable #define yycheck aid_yycheck #define yyname aid_yyname #define yyrule aid_yyrule #ifdef HAVE_CONFIG_H # include #endif #if STDC_HEADERS || HAVE_STRING_H # include #else # include #endif #ifdef HAVE_STDARG_H # include #endif #include #include #include "timewrap.h" #include "kom-types.h" #include "com.h" #include "async.h" #include "connections.h" #include "aux-items.h" #include "s-string.h" #include "server/smalloc.h" #include "lyskomd.h" #include "debug.h" #include "log.h" #include "string-malloc.h" #include "eintr.h" BUGDECL; #define YYDEBUG 1 static Aux_item_definition def; static Bool errorFlag = FALSE; #define CHK_ASSIGN(_i_, _f_, _t_, _d_, _e_, _l_) \ found = found || aux_item_def_check_assign(_i_,_d_,&def._f_,_t_,&(_e_),_l_) #define CHK_FLAG_A(_i_, _f_, _d_, _e_, _l_) \ if (!s_strcmp(s_fcrea_str(_i_),_d_)) \ { \ found = 1; \ if (_e_.type != BOOLEAN ) \ { \ aux_item_def_error_line = _l_; \ yyerror("invalid type: expected %s, got %s", \ aux_item_def_typename(BOOLEAN), \ aux_item_def_typename(_e_.type)); \ } \ if (_e_.val.num) { def.set_flags._f_ = 1; } \ else { def.clear_flags._f_ = 1; } \ } extern int yylex(void); static char *inputFile; int aux_item_def_error_line; extern int yylineno; #if defined(HAVE_VFPRINTF) && defined(HAVE_STDARG_H) void yyerror(const char * format, ...) # if HAVE_ATTRIBUTE_FORMAT_PRINTF __attribute__ ((format (printf, 1, 2))) # endif ; #else void yyerror(); #endif struct aux_item_def_value_type; static int aux_item_def_check_assign(const char *, String, void *, int, struct aux_item_def_value_type *, int); static const char *aux_item_def_typename(int); static short aux_item_def_check_trigger(const char *check_name, int type, String trigger_name, String function_name, unsigned long *counter, Aux_item_trigger **triggers); static short aux_item_def_check_validate(const char *check_name, String field_name, int type, String data, Aux_item_definition *def); #define YYERROR_VERBOSE %} %union { String str; unsigned long num; struct aux_item_def_value_type { int type; union { String str; unsigned long num; } val; } value; } %token NUMBER BOOLEAN %token ID STRING %token DISABLED TEXT CONFERENCE LETTERBOX TOK_SERVER TOK_ANY %token VOID CREATE MODIFY %type value %type action %% items : items item | /* Empty */ ; item : head '{' body '}' { if (def.tag != 0) { aux_item_definition_add(&def); } def = empty_aux_item_definition; } ; head : NUMBER ':' ID '(' targets ')' { def.tag = $1; def.name = s_crea_c_str($3); if (buglevel) { kom_log("Parsing definition of aux-item %ld (%s)\n", def.tag, def.name); } s_clear(&($3)); $3 = EMPTY_STRING; yylval.str = EMPTY_STRING; } | NUMBER ':' ID '(' targets ')' DISABLED { def.tag = $1; def.name = s_crea_c_str($3); def.disabled = TRUE; s_clear(&($3)); $3 = EMPTY_STRING; yylval.str = EMPTY_STRING; } ; targets : targets ',' target | target ; target : action TEXT { def.texts = TRUE; def.text_a = $1; } | action CONFERENCE { def.confs = TRUE; def.conf_a = $1; } | action LETTERBOX { def.letterboxes = TRUE; def.conf_a = $1; } | TOK_SERVER { def.system = TRUE; } | action TOK_ANY { def.texts = TRUE; def.text_a = $1; def.confs = TRUE; def.conf_a = $1; def.letterboxes = TRUE; def.system = TRUE; } ; action : action CREATE { $$ = $1 | AUX_ITEM_ADD_ON_CREATE; } | action MODIFY { $$ = $1 | AUX_ITEM_ADD_ON_MODIFY; } | /* Empty */ { $$ = 0; } ; body : body assign | body error | /* Empty */ ; assign : ID '=' value ';' { int found = 0; CHK_ASSIGN("author-only", author_only, BOOLEAN, $1, $3, @3.first_line); CHK_ASSIGN("supervisor-only", supervisor_only, BOOLEAN, $1, $3, @3.first_line); CHK_ASSIGN("system-only", system_only, BOOLEAN, $1, $3, @3.first_line); CHK_ASSIGN("inherit-limit", inherit_limit, NUMBER, $1, $3, @3.first_line); CHK_ASSIGN("unique", one_per_person, BOOLEAN, $1, $3, @3.first_line); CHK_ASSIGN("unique-data", unique_data, BOOLEAN, $1, $3, @3.first_line); CHK_ASSIGN("permanent", may_not_delete, BOOLEAN, $1, $3, @3.first_line); CHK_ASSIGN("owner-delete", owner_delete, BOOLEAN, $1, $3, @3.first_line); CHK_FLAG_A("inherit", inherit, $1, $3, @3.first_line); CHK_FLAG_A("secret", secret, $1, $3, @3.first_line); CHK_FLAG_A("hide-creator", hide_creator, $1, $3, @3.first_line); CHK_FLAG_A("dont-garb", dont_garb, $1, $3, @3.first_line); CHK_FLAG_A("reserved-2", reserved3, $1, $3, @3.first_line); CHK_FLAG_A("reserved-3", reserved4, $1, $3, @3.first_line); CHK_FLAG_A("reserved-4", reserved5, $1, $3, @3.first_line); found = found ? 1 : aux_item_def_check_validate("validate", $1, $3.type, $3.val.str, &def); found = found ? 1 : aux_item_def_check_trigger("delete-trigger", $3.type, $1, $3.val.str, &def.num_delete_triggers, &def.delete_triggers); found = found ? 1 : aux_item_def_check_trigger("undelete-trigger", $3.type, $1, $3.val.str, &def.num_undelete_triggers, &def.undelete_triggers); found = found ? 1 : aux_item_def_check_trigger("add-trigger", $3.type, $1, $3.val.str, &def.num_add_triggers, &def.add_triggers); if (found == 0) { char *tmp; tmp = s_crea_c_str($1); aux_item_def_error_line = @1.first_line; yyerror("invalid field name: %s", tmp); string_free(tmp); } if ($3.type == STRING || $3.type == ID) { s_clear(&($3).val.str); $3.val.str = EMPTY_STRING; yylval.value.val.str = EMPTY_STRING; } s_clear(&($1)); $1 = EMPTY_STRING; yylval.str = EMPTY_STRING; } ; value : BOOLEAN { $$.val.num = $1; $$.type = BOOLEAN; } | STRING { $$.val.str = $1; $$.type = STRING; } | NUMBER { $$.val.num = $1; $$.type = NUMBER; } | ID '(' ')' { $$.val.str = $1; $$.type = ID;} | VOID { YYERROR; } ; %% extern FILE *yyin; #if defined(HAVE_VFPRINTF) && defined(HAVE_STDARG_H) void yyerror(const char *format, ...) { va_list AP; va_start(AP, format); fprintf(stderr, "%s: %d: ", inputFile, aux_item_def_error_line); vfprintf(stderr, format, AP); fprintf(stderr, "\n"); fflush(stderr); errorFlag = TRUE; va_end(AP); } #else void yyerror(const char *s, int a, int b, int c, int d, int e, int f, int g) { fprintf(stderr, "%s: %d: ", inputFile, aux_item_def_error_line); fprintf(stderr, format, a, b, c, d, e, f, g); fprintf(stderr, "\n"); fflush(stderr); errorFlag = TRUE; } #endif static const char *aux_item_def_typename(int type) { switch (type) { case STRING: return "string"; case NUMBER: return "number"; case BOOLEAN: return "boolean"; case ID: return "identifier"; default: return "unknown"; } } static int aux_item_def_check_assign(const char *id, String field, void *data, int type, struct aux_item_def_value_type *val, int lineno) { if (!s_strcmp(s_fcrea_str(id), field)) { if (type != val->type) { aux_item_def_error_line = lineno; yyerror("invalid type: expected %s, got %s", aux_item_def_typename(type), aux_item_def_typename(val->type)); return 0; } else if (type == STRING) { *((char **)data) = s_crea_c_str(val->val.str); } else if (type == NUMBER) { *((unsigned long *)data) = val->val.num; } else if (type == BOOLEAN) { *((Bool *)data) = val->val.num ? TRUE : FALSE; } else { restart_kom("Internal error: bad type in aux-item definition " "assignment (can't happen.)\n"); } return 1; } else { return 0; } } static short aux_item_def_check_trigger(const char *check_name, int type, String trigger_name, String function_name, unsigned long *counter, Aux_item_trigger **triggers) { Aux_item_trigger trigger; char *tmp_string; if (s_strcmp(s_fcrea_str(check_name), trigger_name) == 0) { if (type != ID) { yyerror("invalid type: expected %s, got %s", aux_item_def_typename(ID), aux_item_def_typename(type)); return 0; } tmp_string = s_crea_c_str(function_name); trigger = aux_item_find_trigger(tmp_string); string_free(tmp_string); if (trigger == NULL) { yyerror("undefined function: %s", tmp_string); return 1; } *counter += 1; *triggers = srealloc(*triggers, *counter * sizeof(Aux_item_trigger)); *triggers[*counter-1] = trigger; return 1; } return 0; } void parse_aux_item_definitions(char *file) { inputFile = file; yyin = i_fopen(file, "r"); if (yyin == NULL) { perror(file); restart_kom("Unable to open aux-item definition file\n"); } def = empty_aux_item_definition; yyparse(); i_fclose(yyin); if (errorFlag == TRUE) { restart_kom("Errors reading aux-item definition file\n"); } /* { extern Aux_item_definition *aux_item_definition_list; extern unsigned long num_aux_item_definitions; Aux_item_definition *def; fprintf(stderr, "Number of defs: %ld\n", num_aux_item_definitions); def = aux_item_definition_list; while (def != NULL) { fprintf(stderr, "Name: '%s'\n", def->name); fprintf(stderr, "Tag: %ld\n", def->tag); fprintf(stderr, "Clear flags: "); if (def->clear_flags.deleted) fprintf(stderr, "deleted "); if (def->clear_flags.inherit) fprintf(stderr, "inherit "); if (def->clear_flags.secret) fprintf(stderr, "secret "); if (def->clear_flags.hide_creator) fprintf(stderr,"hide_creator "); if (def->clear_flags.reserved2) fprintf(stderr, "reserved2 "); if (def->clear_flags.reserved3) fprintf(stderr, "reserved3 "); if (def->clear_flags.reserved4) fprintf(stderr, "reserved4 "); if (def->clear_flags.reserved5) fprintf(stderr, "reserved5 "); fprintf(stderr, "\n"); fprintf(stderr, "Set flags: "); if (def->set_flags.deleted) fprintf(stderr, "deleted "); if (def->set_flags.inherit) fprintf(stderr, "inherit "); if (def->set_flags.secret) fprintf(stderr, "secret "); if (def->set_flags.hide_creator) fprintf(stderr,"hide_creator "); if (def->set_flags.reserved2) fprintf(stderr, "reserved2 "); if (def->set_flags.reserved3) fprintf(stderr, "reserved3 "); if (def->set_flags.reserved4) fprintf(stderr, "reserved4 "); if (def->set_flags.reserved5) fprintf(stderr, "reserved5 "); fprintf(stderr, "\n"); fprintf(stderr, "Author only: %d\n", def->author_only); fprintf(stderr, "Supervisor only: %d\n", def->supervisor_only); fprintf(stderr, "Unique: %d\n", def->one_per_person); fprintf(stderr, "Unique-data: %d\n", def->unique_data); fprintf(stderr, "Permanent: %d\n", def->may_not_delete); fprintf(stderr, "Inherit limit: %ld\n", def->inherit_limit); fprintf(stderr, "Texts: %d\n", def->texts); fprintf(stderr, "Conferences: %d\n", def->confs); fprintf(stderr, "Letterboxes: %d\n", def->letterboxes); fprintf(stderr, "Validate regexp: '%s'\n", def->validate_regexp?def->validate_regexp:"0x0"); def = def->next; } } */ } static short aux_item_def_check_validate(const char *check_name, String field_name, int type, String data, Aux_item_definition *def) { Aux_item_validation_function validator; char *tmp_string; if (s_strcmp(s_fcrea_str(check_name), field_name) == 0) { /* * Validator is a function */ if (type == ID) { tmp_string = s_crea_c_str(data); validator = aux_item_find_validator(tmp_string); string_free(tmp_string); if (validator == NULL) { yyerror("undefined function: %s", tmp_string); return 1; } def->num_validators += 1; def->validators = srealloc(def->validators, def->num_validators * sizeof(*def->validators)); def->validators[def->num_validators-1].type = AUX_VALIDATE_FUNCTION; def->validators[def->num_validators-1].v.fn.function = validator; return 1; } else if (type == STRING) { /* * Validator is a string (regexp) */ def->num_validators += 1; def->validators = srealloc(def->validators, def->num_validators * sizeof(*def->validators)); def->validators[def->num_validators-1].type = AUX_VALIDATE_REGEXP; def->validators[def->num_validators-1].v.re.regexp = s_crea_c_str(data); def->validators[def->num_validators-1].v.re.cached_re_buf = NULL; } else { yyerror("invalid type: expected %s or %s, got %s", aux_item_def_typename(ID), aux_item_def_typename(STRING), aux_item_def_typename(type)); return 0; } return 1; } return 0; } lyskom-server-2.1.2/src/server/aux-item-def-scan.l0000664000015100472110000002027607721716126015516 %{ /* * $Id: aux-item-def-scan.l,v 1.7 2003/08/23 16:38:18 ceder Exp $ * Copyright (C) 1994-1996, 1999, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ #ifdef HAVE_CONFIG_H # include #endif #include #include /* Rename hack from the automake 1.4 manual. */ #define yymaxdepth aid_maxdepth #define yyparse aid_parse #define yylex aid_lex #define yyerror aid_error #define yylval aid_lval #define yychar aid_char #define yydebug aid_debug #define yypact aid_pact #define yyr1 aid_r1 #define yyr2 aid_r2 #define yydef aid_def #define yychk aid_chk #define yypgo aid_pgo #define yyact aid_act #define yyexca aid_exca #define yyerrflag aid_errflag #define yynerrs aid_nerrs #define yyps aid_ps #define yypv aid_pv #define yys aid_s #define yy_yys aid_yys #define yystate aid_state #define yytmp aid_tmp #define yyv aid_v #define yy_yyv aid_yyv #define yyval aid_val #define yylloc aid_lloc #define yyreds aid_reds #define yytoks aid_toks #define yylhs aid_yylhs #define yylen aid_yylen #define yydefred aid_yydefred #define yydgoto aid_yydgoto #define yysindex aid_yysindex #define yyrindex aid_yyrindex #define yygindex aid_yygindex #define yytable aid_yytable #define yycheck aid_yycheck #define yyname aid_yyname #define yyrule aid_yyrule extern int yylex(void); #include "s-string.h" #include "aux-item-def-parse.h" #include "server/smalloc.h" #if defined(HAVE_VFPRINTF) && defined(HAVE_STDARG_H) void yyerror(const char * format, int lineno, ...) # if HAVE_ATTRIBUTE_FORMAT_PRINTF __attribute__ ((format (printf, 1, 3))) # endif ; #else void yyerror(); #endif static String stringBuffer = EMPTY_STRING_i; extern YYLTYPE yylloc; extern int aux_item_def_error_line; #define RETURN aux_item_def_error_line = yylineno; return %} %option yylineno %option noyywrap %x string %% (true|on|yes) { yylval.num = 1; yylloc.first_line = yylineno; RETURN BOOLEAN; } (false|off|no) { yylval.num = 0; yylloc.first_line = yylineno; RETURN BOOLEAN; } disabled { yylloc.first_line = yylineno; RETURN DISABLED; } text { yylloc.first_line = yylineno; RETURN TEXT; } conference { yylloc.first_line = yylineno; RETURN CONFERENCE; } letterbox { yylloc.first_line = yylineno; RETURN LETTERBOX; } server { yylloc.first_line = yylineno; RETURN TOK_SERVER; } any { yylloc.first_line = yylineno; RETURN TOK_ANY; } create { yylloc.first_line = yylineno; RETURN CREATE; } modify { yylloc.first_line = yylineno; RETURN MODIFY; } #[^\n]* /* Eat comments */ [ \t\n]+ /* Eat whitespace */ [[:alpha:]][\-[:alnum:]_]* { char *s = yytext; do { *s=tolower(*s); } while(*(++s)); yylval.str = EMPTY_STRING; s_crea_str(&yylval.str, yytext); yylloc.first_line = yylineno; RETURN ID; } ([0-9]+) { yylloc.first_line = yylineno; yylval.num = atoi(yytext); RETURN NUMBER; } \" { BEGIN(string); stringBuffer = EMPTY_STRING; yylloc.first_line = yylineno; } { "[ \t\n]*" /* Concatenate strings */ \" { BEGIN(INITIAL); yylval.str = stringBuffer; stringBuffer = EMPTY_STRING; RETURN STRING; } \\[0-9]{1,3} { unsigned int tmp; sscanf(yytext+1, "%o", &tmp); if (tmp > 255) s_strcat(&stringBuffer, s_fcrea_str(yytext)); else { sprintf(yytext, "%c", (unsigned char)tmp); yytext[1] = '\0'; s_strcat(&stringBuffer, s_fcrea_str(yytext)); } } \\n s_strcat(&stringBuffer, s_fcrea_str("\n")); \\t s_strcat(&stringBuffer, s_fcrea_str("\t")); \\r s_strcat(&stringBuffer, s_fcrea_str("\r")); \\b s_strcat(&stringBuffer, s_fcrea_str("\b")); \\f s_strcat(&stringBuffer, s_fcrea_str("\f")); \\' s_strcat(&stringBuffer, s_fcrea_str("\'")); \\\" s_strcat(&stringBuffer, s_fcrea_str("\"")); \\\n[ \t]+ /* Eat escaped whitespace */ \\. s_strcat(&stringBuffer, s_fcrea_str(yytext+1)); [^\\\n\"]+ s_strcat(&stringBuffer, s_fcrea_str(yytext)); \n { yyerror("unterminated string", yylloc.first_line); RETURN VOID; } } . RETURN yytext[0]; %% lyskom-server-2.1.2/src/server/admin.h0000664000015100472110000000212307721716126013362 /* * $Id: admin.h,v 0.5 2003/08/23 16:38:18 ceder Exp $ * Copyright (C) 1991, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: admin.h,v 0.5 2003/08/23 16:38:18 ceder Exp $ * * admin.h */ extern Info kom_info; lyskom-server-2.1.2/src/server/async.h0000664000015100472110000000674307721716126013423 /* * $Id: async.h,v 0.25 2003/08/23 16:38:18 ceder Exp $ * Copyright (C) 1991, 1994-1999, 2001, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: async.h,v 0.25 2003/08/23 16:38:18 ceder Exp $ * * This file contains the parts of the async protocol that are common * to the server and the client. */ #ifndef LYSKOM_ASYNC_H #define LYSKOM_ASYNC_H /* * What does this packet contain? (See doc/Protocol-A.texi) */ enum async { ay_new_text_old = 0, /* 1 is no longer used. */ /* 2 is no longer used. */ #if 0 ay_conf_deleted = 3, /* Reserved for future use. */ ay_conf_created = 4, /* Reserved for future use. */ #endif ay_new_name = 5, ay_i_am_on = 6, /* Sends a Who_info when changeinge conference or what-am-i-doing. */ ay_sync_db = 7, /* Database is syncing. */ ay_leave_conf = 8, ay_login = 9, /* Sends a Pers_no and connection when someone logs in. */ /* 10 is no longer used. */ ay_rejected_connection = 11, /* A connection attempt was rejected because LysKOM is full. */ ay_send_message = 12, /* A message is sent. */ ay_logout = 13, /* Someone logs out. */ ay_deleted_text = 14, /* A text is deleted */ ay_new_text = 15, /* New format created text */ ay_new_recipient = 16, /* New recipient added */ ay_sub_recipient = 17, /* Recipient removed */ ay_new_membership = 18, /* Membership added or modified */ ay_new_user_area = 19, /* User-area changed. */ ay_new_presentation = 20, /* Presentation changed. */ ay_new_motd = 21, /* Motd of conference changed. */ ay_text_aux_changed = 22, /* Added and/or removed items. */ #ifdef DEBUG_CALLS ay_garb_ended = 1000, /* Garb cycle complete */ #endif /* When you add stuff here, don't forget to add it to the switch in accept_async in session.c */ ay_dummy_last /* Keep this last in the list. When adding new async messages you might want to increase the default value for parameter "Max accept_async len" in server-config.c. If this becomes too large you may want to change query_async to use a tmp_alloc()d buffer instead of the static buffer it currently uses. */ }; #define ASYNC_DEFAULT_MESSAGES { ay_new_text_old, \ ay_new_name, \ ay_sync_db, \ ay_leave_conf, \ ay_login, \ ay_rejected_connection, \ ay_send_message, \ ay_logout } #endif lyskom-server-2.1.2/src/server/aux-items.h0000664000015100472110000002356707721716126014225 /* * $Id: aux-items.h,v 1.26 2003/08/23 16:38:18 ceder Exp $ * Copyright (C) 1994-2001, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* Requires kom-types.h */ #define AUX_PREDEFINED_MIN 1 #define AUX_PREDEFINED_MAX 9999 #define AUX_CLIENT_SPECIFIC_MIN 10000 #define AUX_CLIENT_SPECIFIC_MAX 19999 #define AUX_EXPERIMENTAL_MIN 20000 #define AUX_EXPERIMENTAL_MAX 29999 #define AUX_IS_ILLEGAL(x) ((x) < 1) #define AUX_IS_EXPERIMENTAL(x) ((x) >= AUX_EXPERIMENTAL_MIN && (x) <= AUX_EXPERIMENTAL_MAX) #define AUX_IS_CLIENT_SPECIFIC(x) ((x) >= AUX_CLIENT_SPECIFIC_MIN && (x) <= AUX_CLIENT_SPECIFIC_MAX) #define AUX_IS_PREDEFINED(x) (((x) >= AUX_PREDEFINED_MIN && (x) <= AUX_PREDEFINED_MAX) || (x) > AUX_EXPERIMENTAL_MAX) /* Valid values for text_a etc. */ #define AUX_ITEM_ADD_ON_CREATE 1 #define AUX_ITEM_ADD_ON_MODIFY 2 /* Valid values for action trigger data field */ #define AUX_ITEM_ADD_ACTION 1 #define AUX_ITEM_DELETE_ACTION 2 #define AUX_ITEM_UNDELETE_ACTION 3 typedef struct Aux_item_definition_s Aux_item_definition; typedef struct Aux_item_trigger_data_s { short action; enum object_type object_type; unsigned long item_index; unsigned long object_no; void * object; Aux_item * item; } Aux_item_trigger_data; typedef void (*Aux_item_trigger)(Aux_item_trigger_data *); enum aux_item_validation_type { AUX_VALIDATE_FUNCTION, AUX_VALIDATE_REGEXP, AUX_VALIDATE_REJECT, }; typedef struct { const Aux_item *item; const Aux_item_definition *def; Connection *creating_conn; Bool creating; Conf_no subordinate; #if 0 /* No validator currently use these fields, so they are temporarily removed. See aux_item_add_perm() if you need to re-enable any of them. */ Aux_item_list *add_to_list; unsigned long start_looking_at; enum object_type object_type; #endif } Aux_item_validation_data; typedef Success (*Aux_item_validation_function)(Aux_item_validation_data *); typedef struct { enum aux_item_validation_type type; union { struct { char *regexp; struct re_pattern_buffer *cached_re_buf; } re; struct { Aux_item_validation_function function; } fn; } v; } Aux_item_validator; typedef struct { const char *name; Aux_item_validation_function function; } Aux_item_validator_mapping; typedef struct { const char *name; Aux_item_trigger function; } Aux_item_trigger_mapping; struct Aux_item_definition_s { char * name; unsigned long tag; Aux_item_flags clear_flags; Aux_item_flags set_flags; Bool disabled; Bool author_only; Bool supervisor_only; Bool system_only; Bool one_per_person; Bool unique_data; Bool may_not_delete; Bool owner_delete; unsigned long inherit_limit; Bool texts; short text_a; /* When can we add items of this type */ Bool confs; short conf_a; /* When can we add items of this type */ Bool letterboxes; Bool system; unsigned long num_validators; Aux_item_validator * validators; unsigned long num_delete_triggers; Aux_item_trigger * delete_triggers; unsigned long num_add_triggers; Aux_item_trigger * add_triggers; unsigned long num_undelete_triggers; Aux_item_trigger * undelete_triggers; struct Aux_item_definition_s *next; }; extern Aux_item_definition empty_aux_item_definition; /* Inerit items from parent to target. counter is a pointer to * highest_aux_item or equivalent. target_creator is the creator * of the target object (author for texts, person for persons and * conference for conferences */ void aux_inherit_items(Aux_item_list *target, const Aux_item_list *parent, unsigned long *counter, Conf_no subordinate, Text_no object_no, Text_stat *object); /* Prepare the items in list for addition to an object. creator is the * person who will add the items. The items in list will be modified. * You need to call this before sending the list to any of the other * functions. */ void prepare_aux_item_list(Aux_item_list *list, Pers_no creator); /* Get the function pointer for a named trigger */ Aux_item_trigger aux_item_find_trigger(const char *trigger_name); /* Get the function pointer for a named validation function */ Aux_item_validation_function aux_item_find_validator(const char *validator_name); /* Filter the items in ORIGINAL for sending to the person logged in on * connection CONN. On entry, RESULT should be a pointer to an empty * aux_item_list. It will be filled with copies of those items in * ORIGINAL that CONN is allowed to see. All memory allocated in this * call is allocated with tmp_alloc. */ void filter_aux_item_list(const Aux_item_list *original, Aux_item_list *result, const Connection *conn); /* Delete items_to_delete from list_to_delete_from. * list_to_delete_from and its elements may be modified. */ void delete_aux_item_list(const Number_list *items_to_delete, Aux_item_list *list_to_delete_from, enum object_type object_type, unsigned long object_no, void *object); /* Undelete items in items_to_undelete from list_to_undelete_from. * list_to_delete_from and its elements may be modified. */ void undelete_aux_item_list(const Number_list *items_to_undelete, Aux_item_list *list_to_undelete_from, enum object_type object_type, unsigned long object_no, void *object); void commit_aux_item_list(Aux_item_list *list_to_commit); /* Check if we may delete items_to_delete from list_to_delete_from * Elements in items_to_delete may be modified. Sets kom_errno, * err_stat and returns FAILURE if deletion of any single item is * not allowed */ Success check_delete_aux_item_list(const Number_list *items_to_delete, const Aux_item_list *list_to_delete_from, const Conf_no subordinate); /* Add item_list to the aux_item_list of text_s. item_creator is the * person who is adding the items. Does not check for permission first. */ void text_stat_add_aux_item_list(Text_stat *text_s, Text_no text_no, Aux_item_list *item_list, Pers_no item_creator); /* Check for permission to add items in ``list'' to aux_item_list of ``text_s''. ``creating_conn'' is the connection that gave the command that attempts to add the items. Sets kom_errno and err_stat and returns FAILURE if permission is not granted. You MUST call perpare_aux_item_list on the list before calling this! When this is called to check items when creating a text, pass NULL as ``text_s''. */ Success text_stat_check_add_aux_item_list(Text_stat *text_s, Aux_item_list *list, Connection *creating_conn); /* Add an item to ``conf''. ``conf_no'' must correspond to ``conf''. ``list'' is the list of items to add (NULL is interpreted as an empty list). ``creating_conn'' is the connection whose permissions should be used. ``creating'' should be true if the conference is being created. (The ``conf'' must be non-NULL even if the conference is being created.) */ Success conf_stat_check_add_aux_item_list(Conference *conf, Conf_no conf_no, Aux_item_list *list, Connection *creating_conn, Bool creating); void conf_stat_add_aux_item_list(Conference *conf, Conf_no conf_no, Aux_item_list *list, Pers_no creator); void system_add_aux_item_list(Info *info, Aux_item_list *item_list, Pers_no item_creator); Success system_check_add_aux_item_list(Info *info, Aux_item_list *list, Connection *creating_conn); void initialize_aux_items(char *); void free_aux_item_definitions(void); void aux_item_definition_add(Aux_item_definition *); /* Parser function from aux-item-def.y. */ extern void parse_aux_item_definitions(char *file); lyskom-server-2.1.2/src/server/cache-node.h0000664000015100472110000000653207721716126014270 /* * $Id: cache-node.h,v 0.18 2003/08/23 16:38:18 ceder Exp $ * Copyright (C) 1991, 1993-1995, 1997, 1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: cache-node.h,v 0.18 2003/08/23 16:38:18 ceder Exp $ * * cache-node.h */ typedef struct cache_node { struct { unsigned int exists : 1; unsigned int dirty : 1; /* Is *ptr modified? */ } s; void *snap_shot; /* Dirty data to be written to file B. */ /* (Dirty relative to file A). */ void *ptr; /* In-core data. */ long pos; /* Position to element in file A. */ long size; /* Size on disk. */ #ifdef FASTSAVE long saved_pos; /* Position saved in case of recover */ long saved_size; /* Size saved in case of recover */ #else long pos_b; /* Position to element in file B. */ long size_b; /* Size in file B. */ #endif struct cache_node *prev; /* Points towards most recently used. */ struct cache_node *next; /* Points towards least recently used. */ int lock_cnt; } Cache_node; extern const Cache_node EMPTY_CACHE_NODE; typedef struct cache_node_block { int next_free; Cache_node *nodes; /* Pointer to an array with mcb_size elements. */ struct cache_node_block *link; /* Points to previous block. */ } Cache_node_block; extern const Cache_node_block EMPTY_CACHE_NODE_BLOCK; typedef struct cache_node_mcb { int mcb_size; /* Number of cache_nodes in each block. */ Cache_node_block *last_block; /* The block where new cache_nodes * can be allocated. */ unsigned long hits; unsigned long misses; Cache_node *mru; Cache_node *lru; unsigned long lookup_table_size; Cache_node **lookup_table; /* Easy to implement, but memory expensive. */ } Cache_node_mcb; extern const Cache_node_mcb EMPTY_CACHE_NODE_MCB; extern void unlink_lru(Cache_node *node, Cache_node **lru, Cache_node **mru); extern Cache_node_mcb * create_cache_node_mcb(int mcb_size, int table_size); extern void destruct_cache_node(Cache_node_mcb *control, unsigned long key); extern Cache_node * get_cache_node (Cache_node_mcb *control, unsigned long key); extern void create_cache_node (Cache_node_mcb *control, unsigned long key); extern void zero_init_cache_node (Cache_node_mcb *control, unsigned long key); extern void set_mru(Cache_node_mcb *mcb, unsigned long key); extern void free_cache_node_mcb(Cache_node_mcb *control); lyskom-server-2.1.2/src/server/cache.h0000664000015100472110000001164307721716126013344 /* * $Id: cache.h,v 0.28 2003/08/23 16:38:18 ceder Exp $ * Copyright (C) 1991-1996, 1999, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * database cache header file */ extern struct matching_info *match_table; /* match_table, see build_matching_info() */ /******** initiation and shutdown of cache *******************************/ /* initiate cache (called at initiation/startup of server) */ Success init_cache(void); /* flush, shutdown cache and free all cache memory (called at shutdown) */ void free_all_cache(void); /* dump emergency files, etc, if possible */ void cache_emergency_exit(void); /******** miscellanous cache master routines *****************************/ /* end-of-atomic, may clear read entries */ void cache_limit_size(void); /* * Maybe save some part of the database. sync_part() should be called * often as long as it returns 0. If it returns anything else, there * is no need to call it again until that time has passed, but it is * harmless to call it more often than that. */ struct timeval sync_part(void); /* flush all & wait until disk is synced */ void cache_sync_all(void); /* tell cache that garb_text is in progress, ie never flush cache */ void tell_cache_garb_text(int running); /* dump cache statistics etc */ void dump_cache_stats(FILE *stat_file); void dump_cache_mem_usage(FILE *stat_file); /******** object manipulation routines ***********************************/ /* mark as changed (object is to be re-written to disk) */ void mark_person_as_changed(Pers_no pers); void mark_text_as_changed(Text_no text); void mark_conference_as_changed(Conf_no conf); /* lock (do never remove object from memory) & unlock */ void cached_lock_conf(Conf_no conf); void cached_unlock_conf(Conf_no conf); void cached_lock_person(Pers_no pers); void cached_unlock_person(Pers_no pers); /* create object (returns FALSE if person existed) */ Success cached_create_person(Pers_no pers); Conf_no cached_create_conf(String name); Text_no cached_create_text(const String message); /* get object from database */ Person *cached_get_person_stat(Pers_no person); Conference *cached_get_conf_stat(Conf_no conf); Text_stat *cached_get_text_stat(Text_no text); Small_conf *cached_get_small_conf_stat(Conf_no conf_no); /* return text. String is to be freed by caller */ String cached_get_text(Text_no text); /* remove object from database */ Success cached_delete_person(Pers_no pers); Success cached_delete_text(Text_no text); Success cached_delete_conf(Conf_no conf); /* return number of next existing object */ Pers_no traverse_person(Pers_no sead); Conf_no traverse_conference(Conf_no sead); Text_no traverse_text(Text_no sead); /* returns highest text_num +1 */ Text_no query_next_text_num(void); /* returns highest conf_no +1 */ Conf_no query_next_conf_no(void); /******** misc conference routines **************************************/ /* Change conferance name. cached_change_name(foo,EMPTY_STRING); is used when a conference is deleted. */ void cached_change_name(Conf_no conf,String new_name); /* returns TRUE when a conference exists */ Bool cached_conf_exists(Conf_no conf); /* returns conference type. conf_type is set when mark_conference_as_changed is called */ Conf_type cached_get_conf_type(Conf_no conf); /* returns supervisor of a conference. conf_type is set when mark_conference_as_changed is called */ Conf_no cached_get_conf_supervisor(Conf_no conf_no); /* Get garb_nice from smallconf */ Garb_nice cached_get_garb_nice(Conf_no conf); /* Get keep_commented from smallconf */ Garb_nice cached_get_keep_commented(Conf_no conf); /* returns conference name from smallconf */ String cached_get_name(Conf_no conf); /* returns highes text number in a certain conference */ Local_text_no cached_get_highest_local_no(Conf_no conf); /* match from name => conf_list_old */ Success cached_lookup_name(const String name,Conf_list_old *result); /* How many conferences exists? */ Conf_no cached_no_of_existing_conferences(void); lyskom-server-2.1.2/src/server/conf-file.h0000664000015100472110000000454207721716126014143 /* * $Id: conf-file.h,v 1.12 2003/08/23 16:38:18 ceder Exp $ * Copyright (C) 1994, 1998-1999, 2002-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * Read configuration files. */ #ifndef CONF_FILE_INCLUDED #define CONF_FILE_INCLUDED struct parameter { const char *name; Success (*assigner)(const char *val, const struct parameter *par); void (*freer)(const struct parameter *par); int min_assignments; int max_assignments; /* -1 == eternity */ const char *default_val; /* String, as read from the config file. */ void *value; const char *default_suffix; /* Default suffix for assigners that cares about such things. */ }; void read_config(const char *config_file, const struct parameter *par); extern Success assign_text_no (const char *val, const struct parameter *par); extern Success assign_conf_no (const char *val, const struct parameter *par); extern Success assign_int (const char *val, const struct parameter *par); extern Success assign_ulong (const char *val, const struct parameter *par); extern Success assign_uint (const char *val, const struct parameter *par); extern Success assign_string (const char *val, const struct parameter *par); extern Success assign_bool (const char *val, const struct parameter *par); extern Success assign_double (const char *val, const struct parameter *par); extern Success assign_timeval (const char *val, const struct parameter *par); extern void unassign_string(const struct parameter *par); #endif lyskom-server-2.1.2/src/server/connections.h0000664000015100472110000002763607721716126014634 /* * $Id: connections.h,v 0.77 2003/08/23 16:38:17 ceder Exp $ * Copyright (C) 1991-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: connections.h,v 0.77 2003/08/23 16:38:17 ceder Exp $ * * connections.h -- The top level of the communication packet. * * Requires kom-types.h, com.h, async.h */ #if 0 /* This comment isn't true yet. */ /* Connection establishment ======================== When a new connection is accepted, the server starts to collect some information about the client: its domainname and IDENT information. Until that information gathering is complete, the client will only be able to do its initial handshake. It will not be visible to any other client, because the information is needed by the Static-Session-Info structure. The client will, however, be noted in var/lyskomd.clients as soon as accept() returns. Once the client has performed the initial handshake (sent "A" plus the user%host hollerith string and received "LysKOM\n") the async-slow-external-system asynchronous messages will be sent to the client if an external system (currently only DNS or IDENT) is blocking the client. Until all external systems has responded (or the server has given up on them) no input from the client will be accepted once the initial handshake is performed. If the initial handshake is not completed within a few minutes (configurable via FIXME (bug 627): what?) the client will be disconnected. DNS resolution ============== If no reply from the DNS system is received for a reasonable time, or if a NXDOMAIN error is returned, the raw IP address will be used instead. IDENT checking ============== The ``Ident-authentication'' configuration parameter controls if IDENT checking is done, and what happens if the IDENT checking returns an error or a timeout. At most ``Parallell Ident connections'' IDENT requests is performed at once. If more clients are connected at once, the later clients will have to wait for the earlier IDENT requests to finish. Rationale: we reserve that many file descriptors to this task. */ #endif enum kill_state { ks_none, /* Not yet killed. */ ks_pending, /* Kill pending. */ ks_dying, /* check_kill_flg() is killing this. */ }; typedef struct connection { struct connection * prev; struct connection * next; /* The following are used by services.c (which has been split into many files such as conference.c and person.c). */ Pers_no pers_no; /* 0 if not yet logged in. */ Person * person; /* NULL if not yet logged in. */ struct timeval connect_time; /* When did the client connect? */ struct timeval login_time; /* Time of connect, login or logout */ Conf_no cwc; /* Current working conference */ String what_am_i_doing; unsigned char ena_level; /* Enable level */ String username; /* Given userid (from handshake). */ String ident_user; /* Real username (IDENT lookup) */ String client_name; /* See doc/clients.assigned */ String client_version; Session_flags flags; Bool username_valid; /* Set once username is set. Under protocol A, no async messages are sent until this bit is set. */ Bool dns_done; /* Set once DNS reverse lookup is completed. */ Bool blocked_by_dns; /* Disabled waiting for DNS reply? */ Bool want_async[ay_dummy_last]; /* Async messages to get */ /* The following are used by server/connections.c */ struct isc_scb *isc_session; String remote_ip; /* The IP address. */ char *peer; /* For dump_connections(). This holds the IP address, a space, and the port number of the peer.*/ unsigned char protocol; /* Should times be expressed in UTC or in the local timezone of the server? */ Bool use_utc; int parse_pos; int fnc_parse_pos; int array_parse_pos; int array_parse_index; int array_parse_parsed_length; int struct_parse_pos; int string_parse_pos; int hunt_parse_pos; int array_hunt_num; int array_hunt_depth; int ref_no; enum call_header function; /* Function to call. */ int function_index; /* Index of function in server tables*/ /* Gather data in these variables. */ Number_list num_list; long num0; long num1; long num2; long num3; long num4; String c_string0; /* These strings are used for strings * that are *NOT* freed by services.c. * They are freed by free_parsed() in * connections.c */ String c_string1; String string0; /* This string is used for strings that * are freed by the routines in services.c */ Misc_info_list misc_info_list; Aux_item_list aux_item_list; /* Freed by free_parsed() */ Aux_item aux_item; /* Freed by free_parsed() */ Aux_item dummy_aux_item; /* Freed by free_parsed() */ struct read_range_list read_range_list; /* Freed by free_parsed(). */ Priv_bits priv_bits; Conf_type conf_type; Membership_type membership_type; struct tm time; Info info; Personal_flags pers_flags; /* Protocol independent things. */ String unparsed; String_size first_to_parse; /* Index into unparsed. */ Bool more_to_parse; /* Any chance that there is anything left in unparsed? */ enum kill_state kill_status; /* Is this client dying? */ unsigned int penalty; /* Number of penalty points for this session. */ unsigned int penalty_generation; /* Penalties are aged. */ /* Once the penalty points are too high, the session will be disabled and put on a wait queue, which is a double linked list implemented via these fields. */ struct connection *queue_prev; struct connection *queue_next; Bool on_queue; Scheduling_info schedule; struct timeval active_time; /* Set every time the client sends user_active. */ Session_no session_no; /* A unique number. */ } Connection; /* * It is guaranteed that in the Connection struct the pers_no and person * fields are either both 0/NULL, or both non-0/non-NULL. */ /* * Data for the isc-server. */ extern struct isc_mcb *kom_server_mcb; /* * active_connection points to the info about the client who initiated this * call. This is set by connectins.c whenever a complete message is parsed * and a function in services.c is called. */ extern Connection * active_connection; /* * This enum describes the result of a function in services.c. */ enum res_type { rt_number, /* E.g. Pers_no, Conf_no, Text_no. This is somewhat special in that the function indicates an error by returning 0 and not FAILURE. */ rt_success, /* Only return a Success. */ /* Functions of the following types returns a Success _and_ data of the indicated type. The corresponding types are found in kom-types.h */ rt_person, rt_membership, rt_membership_old, rt_membership_10, rt_conf_list, rt_conf_no_list, rt_conference_old, rt_string, rt_mark_list, rt_text_stat_old, rt_who_info_list, rt_who_info_list_old, rt_info_old, rt_membership_list, rt_membership_list_old, rt_membership_list_10, rt_member_list, rt_member_list_old, rt_time_date, rt_session_info, rt_session_no, rt_text_no, rt_conf_no, rt_session_info_ident, rt_who_info_ident_list, rt_conf_z_info_list, rt_version_info, rt_uconference, rt_num_list, rt_dynamic_session_info_list, rt_static_session_info, rt_text_stat, rt_conference, rt_info, rt_l2g_iterator_as_text_list, rt_text_mapping, rt_text_mapping_reverse, rt_stats_description, rt_stats_list, rt_static_server_info, rt_scheduling_info, #ifdef DEBUG_CALLS rt_memory_info, #endif }; /* * The result from a call is stored in this union. * * The pointers in these structures are normally set to point into * data from the cache, and should thus not be free()d. In those cases * where this actually contains newly allocated memory (and it is not * allocated via tmp_alloc()) it should be free()d in prot_a_reply() in * prot-a.c. */ union result_holder { unsigned long number; Person person; Membership membership; Membership membership_10; Membership membership_old; Conf_list_old conf_list; Conf_no_list conf_no_list; Conference conference; Conference conference_old; Mark_list mark_list; String string; Text_stat text_stat; Text_stat text_stat_old; Info info; Info info_old; Who_info_list who_info_list; Who_info_list_old who_info_list_old; Membership_list membership_list; Membership_list membership_list_10; Membership_list membership_list_old; Member_list member_list; Member_list member_list_old; time_t time_date; Session_info session_info; Session_no session_no; Text_no text_no; Conf_no conf_no; Who_info_ident_list who_info_ident_list; Session_info_ident session_info_ident; Conf_z_info_list conf_z_info_list; Version_info version_info; Small_conf uconference; Number_list num_list; Dynamic_session_info_list dynamic_session_info_list; Static_session_info static_session_info; L2g_iterator l2g_iterator_as_text_list; Text_mapping text_mapping; Text_mapping_reverse text_mapping_reverse; Stats_description stats_description; Stats_list stats_list; Static_server_info static_server_info; Scheduling_info scheduling_info; #ifdef DEBUG_CALLS Memory_info memory_info; #endif }; typedef struct { enum call_header function; enum res_type result; /* The function that is used to parse args for this function: */ void (*parser)(Connection *client); } Fnc_descriptor; extern const Fnc_descriptor fnc_defs[]; extern const int num_fnc_defs; /* * This array holds number of calls to each service. It is dumped to the * log file every time the server syncs. */ extern unsigned long service_statistics[]; extern jmp_buf parse_env; extern void toploop(void); extern void dump_statistics(void); extern void logout_all_clients(void); extern void add_to_kill_list(Connection *conn); /* Functions used as ISC callbacks. */ extern void * handle_accept_event(struct isc_scb *accepting_session, struct isc_scb *new_session); /* Return true if the server is currently idle. */ extern Bool server_idle(void); /* Set the current_time global variable. */ extern void set_time(void); lyskom-server-2.1.2/src/server/end-of-atomic.h0000664000015100472110000000274407721716126014725 /* * $Id: end-of-atomic.h,v 0.7 2003/08/23 16:38:17 ceder Exp $ * Copyright (C) 1991, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: end-of-atomic.h,v 0.7 2003/08/23 16:38:17 ceder Exp $ * * end-of-atomic.c */ /* * Clean up after an atomic request. This will throw things from the * cache, free memory allocated with tmp_alloc(), and save part of the * database. The function should be called after every atomic * request, and it should also be called periodically; the caller * should wait no more than the return value before the function is * called again. */ struct timeval end_of_atomic(void); lyskom-server-2.1.2/src/server/exp.h0000664000015100472110000000212507721716126013070 /* * $Id: exp.h,v 0.5 2003/08/23 16:38:17 ceder Exp $ * Copyright (C) 1991, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: exp.h,v 0.5 2003/08/23 16:38:17 ceder Exp $ * */ #define EXPORT #define INTERNAL static lyskom-server-2.1.2/src/server/internal-connections.h0000664000015100472110000000323407721716127016433 /* * $Id: internal-connections.h,v 0.11 2003/08/23 16:38:16 ceder Exp $ * Copyright (C) 1991, 2002-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: internal-connections.h,v 0.11 2003/08/23 16:38:16 ceder Exp $ * * internal-connections.c * * Abstract routines on the data type Connection. */ extern Connection * new_client(void); extern void kill_client(Connection *cp); /* Return a Connection, or NULL if the specified session doesn't exist. */ extern Connection * get_conn_by_number (Session_no session_no); extern Session_no traverse_connections (Session_no session_no); extern void dump_allocated_connections(FILE *fp); enum ignored_conditions { ignore_dns = 1, ignore_ident = 2, }; extern Bool handshake_ok(struct connection *cptr, enum ignored_conditions ignored); lyskom-server-2.1.2/src/server/text.h0000664000015100472110000000246207721716130013257 /* * $Id: text.h,v 1.3 2003/08/23 16:38:12 ceder Exp $ * Copyright (C) 1991-1992, 1994-1995, 1998-1999, 2001, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* Delete a text from the database. Deletes all "links" to/from other objects, such as comment links, links expressed via aux-items, et c. No permission checking is performed by this function. */ extern Success do_delete_text(Text_no text_no, Text_stat *text_s); lyskom-server-2.1.2/src/server/isc-interface.h0000664000015100472110000000240007721716127015005 /* * $Id: isc-interface.h,v 0.14 2003/08/23 16:38:16 ceder Exp $ * Copyright (C) 1991-1995, 1998-1999, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: isc-interface.h,v 0.14 2003/08/23 16:38:16 ceder Exp $ * * Wrapper around to ensure that ISC_UDGTYPE is always correct. */ #define ISC_UDGTYPE struct connection #include "isc.h" extern oop_source_sys *kom_server_oop_src; lyskom-server-2.1.2/src/server/isc-malloc.h0000664000015100472110000000266407721716127014330 /* * $Id: isc-malloc.h,v 1.8 2003/08/23 16:38:16 ceder Exp $ * Copyright (C) 1991-1992, 1994-1995, 1999, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: isc-malloc.h,v 1.8 2003/08/23 16:38:16 ceder Exp $ * * Malloc wrappers for the string package. * * These functions call smalloc and also counts * how many allocated strings there are. */ extern void * isc_malloc_wrapper (size_t size); extern void isc_free_wrapper (void * ptr); extern void * isc_realloc_wrapper (void * ptr, size_t size); extern void dump_isc_alloc_counts(FILE *stat_file); lyskom-server-2.1.2/src/server/isc-parse.h0000664000015100472110000000233207721716127014163 /* * $Id: isc-parse.h,v 0.6 2003/08/23 16:38:16 ceder Exp $ * Copyright (C) 1991, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: isc-parse.h,v 0.6 2003/08/23 16:38:16 ceder Exp $ * */ #define KOM_PROTOCOL_ERR 1 #define KOM_MSG_INCOMPLETE 2 #define KOM_LOGOUT 3 int parse_char(Connection *client); int parse_nonwhite_char(Connection *client); lyskom-server-2.1.2/src/server/kom-memory.h0000664000015100472110000000776307721716127014406 /* * $Id: kom-memory.h,v 1.15 2003/08/23 16:38:16 ceder Exp $ * Copyright (C) 1991, 1993-1994, 1996-1999, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: kom-memory.h,v 1.15 2003/08/23 16:38:16 ceder Exp $ * * The time has come to get some order into this mess. * * From now on the following terminology is used: * * alloc_ smalloc() the object. Increase _cnt. * free_ sfree() the object. Decrease _cnt. * clear_ free_() any objects contained in the object, * but not the object itself. * copy_ smalloc() a new object and also smalloc() * any objects contained in it. * init_ initialize all fields in a allocated object. */ /* * Memory handling functions, grouped by data type, sorted alphabetically. */ /* Conf_type */ extern void init_conf_type(Conf_type *ct); /* Conference */ extern Conference *alloc_conference (void); extern void free_conference (Conference *c); extern void clear_conference (Conference *c); extern Conference *copy_conference (const Conference *c); extern void init_conference (Conference *c); /* Dynamic_session_info */ extern void init_dynamic_session_info (Dynamic_session_info *d); /* Mark_list */ extern void init_mark_list (Mark_list *ml); /* Member_list */ extern void init_member_list (Member_list *ml); /* Membership type */ extern void init_membership_type(Membership_type *m); /* Member */ extern void init_member(Member *mem); /* Membership */ extern void init_membership(Membership *m); /* Membership_list */ extern void init_membership_list (Membership_list *m); /* Person */ extern Person *alloc_person (void); extern void free_person (Person *p); extern void clear_person (Person *p); extern Person *copy_person (const Person *p); extern void init_person (Person *p); /* Personal_flags */ extern void init_personal_flags (Personal_flags *p); /* Priv_bits */ extern void init_priv_bits (Priv_bits *pb); /* Session_info */ extern void init_session_info (Session_info *s); /* Session_info_ident */ extern void init_session_info_ident (Session_info_ident *s); /* Static_session_info */ extern void init_static_session_info (Static_session_info *d); /* Text_stat */ extern Text_stat *alloc_text_stat (void); extern void free_text_stat (Text_stat *t); extern void clear_text_stat (Text_stat *t); extern Text_stat *copy_text_stat (const Text_stat *t); extern void init_text_stat (Text_stat *t); /* struct tm */ extern void init_struct_tm (struct tm *t); /* Who_info */ extern void init_who_info (Who_info *w); /* Who_info_ident */ extern void init_who_info_ident (Who_info_ident *w); /* Who_info_old */ extern void init_who_info_old (Who_info_old *w); /* Aux_item_list */ extern void free_aux_item_list (Aux_item_list *list); extern void init_aux_item_list (Aux_item_list *list); extern void init_aux_item_link(Aux_item_link *dest); extern void init_aux_item_flags(Aux_item_flags *dest); extern void clear_aux_item(Aux_item *item); extern void init_aux_item(Aux_item *dest); extern void copy_aux_item (Aux_item *dest, const Aux_item *src); /* * Other kind of functions */ extern void dump_alloc_counts(FILE *stat_file); lyskom-server-2.1.2/src/server/local-to-global.h0000664000015100472110000001376107721716127015255 /* * File: local_to_global.h * * Copyright 1996, 1998-1999, 2002-2003 Inge Wallin, Per Cederqvist */ #ifndef LOCAL2GLOBAL_H_INCLUDED #define LOCAL2GLOBAL_H_INCLUDED /* Set the block size. This function may be called at most once, before any other function declared in this file is called. Once the block size has been set it cannot be changed. */ void l2g_set_block_size(int sz); /* Contstructor. Take raw memory and create an empty Local_to_global mapping. */ void l2g_init(Local_to_global *l2g); /* Destructor. Frees all memory associated with ``l2g'' and destruct the object, turning it into raw memory once again. */ void l2g_destruct(Local_to_global *l2g); /* Re-initialize ``l2g''. "lg2_clear(&foo)" is equivalent to "l2g_destruct(&foo); l2g_init(&foo)" but slightly more efficient. */ void l2g_clear(Local_to_global *l2g); /* Copy ``src'' to ``dest''. Both ``src'' and ``dest'' must be constructed Local_to_global objects. This operation will ensure that they contain the same data. */ void l2g_copy(Local_to_global *dest, const Local_to_global *src); /* Append a new mapping from LNO to TNO. LNO must be higher than any LNO previously stored in the structure. Invalidates all iterators. */ void l2g_append(Local_to_global *l2g, Local_text_no lno, Text_no tno); /* Set a new mapping from LNO to TNO. This can be used for any LNO, even on that is already defined, but this may be an expensive operation. It should only be used by dbck to repair a damaged database. Invalidates all iterators. */ void l2g_expensive_set(Local_to_global *l2g, Local_text_no lno, Text_no tno); /* Delete LNO from the structure. Invalidates all iterators. */ void l2g_delete(Local_to_global *l2g, Local_text_no lno); /* Return the TNO previously stored under LNO. Returns 0 if no such LNO exists. */ Text_no l2g_lookup(const Local_to_global *l2g, Local_text_no lno); /* Returns the next local text number, or 0 if lno is larger than the largest local text number. */ Local_text_no l2g_next_key(const Local_to_global *l2g, Local_text_no lno); /* Returns the lowest local text number that has never been present in the structure. This is the same as one plus the highest local text number that is present in the structure (unless it has been deleted -- deletions do not cause this to decrease). Returns 1 if the structure has always been empty. */ Local_text_no l2g_first_appendable_key(const Local_to_global *l2g); /* Set the first the number returned by l2g_first_appendable_key. You can only set it to a higher value than it already has. This function is probably only useful when reading in a Local_to_global structure that was saved with something other than l2g_write. */ void l2g_set_first_appendable_key(Local_to_global *l2g, Local_text_no key); /* Delete global text number TNO. This function can only be called if both the local and global text numbers are monotonous series, as they are in the Person::created_text_map field. */ void l2g_delete_global_in_sorted(Local_to_global *l2g, Text_no tno); /* Dump all internal state. This is used by the test suite to peek at the internal representation. It should not be used except for such debugging purposes. */ void l2g_dump(FILE *file, const Local_to_global *l2g); /* Write an external representation of the mapping to ``file''. */ void l2g_write(FILE *file, const Local_to_global *l2g); /* Initialize the mapping from the representation found in ``file''. ``l2g'' must already be constructed. */ Success l2g_read(FILE *file, Local_to_global *l2g); /* Dump global usage statistics to ``file''. */ void dump_l2g_stats(FILE *file); /* ================================================================ */ /* * Iterator for a Local_to_global. * * Usage: * * Local_to_global l2g; * L2g_iterator l2gi; * * for (l2gi_searchall(&l2gi, &l2g); !l2gi.search_ended; l2gi_next(&l2gi)) { * use(l2gi.lno, l2gi.tno); * } * * or: * * for (l2gi_searchsome(&l2gi, &l2g, startval, endval); * !l2gi.search_ended; * l2gi_next(&l2gi)) * { * use(l2gi.lno, l2gi.tno); * } */ /* Create an iterator that will loop through all texts. */ void l2gi_searchall (L2g_iterator *l2gi, const Local_to_global *l2g); /* Create an iterator that will iterate through all existing texts with a local text number lno such that begin <= lno < end The search will be unbound if end is set to 0. */ void l2gi_searchsome(L2g_iterator *l2gi, const Local_to_global *l2g, Local_text_no begin, Local_text_no end); /* Step the iterator forward. */ void l2gi_next(L2g_iterator *l2gi); /* This can only be used on iterators created with l2gi_searchsome. Returns the value supplied to the end argument when the iterator was created. */ Local_text_no l2gi_end(const L2g_iterator *l2gi); /* This can only be used on iterators created with l2gi_searchsome. Returns the value supplied to the start argument when the iterator was created. */ Local_text_no l2gi_begin(const L2g_iterator *l2gi); /* ================================================================ */ /* * Reverse iterator for a Local_to_global. * * Usage: * * Local_to_global l2g; * L2g_reverse_iterator l2gi; * * for (l2gi_searchall_reverse(&l2gi, &l2g); // Not implemented yet. * !l2gi.search_ended; * l2gi_prev(&l2gi)) * { * use(l2gi.lno, l2gi.tno); * } * * or: * * for (l2gi_searchsome_reverse(&l2gi, &l2g, lower_limit, upper_limit); * !l2gi.search_ended; * l2gi_prev(&l2gi)) * { * use(l2gi.lno, l2gi.tno); * } */ /* Create an iterator that will iterate through all existing texts with a local text number lno such that begin <= lno < end starting at end-1 and ending at begin. */ void l2gi_searchsome_reverse(L2g_reverse_iterator *l2gi, const Local_to_global *l2g, Local_text_no begin, Local_text_no end); /* Step the iterator forward, eh, backwards, eh, towards begin. */ void l2gi_prev(L2g_reverse_iterator *l2gi); #endif /* LOCAL2GLOBAL_H_INCLUDED */ lyskom-server-2.1.2/src/server/log.h0000664000015100472110000000301707721716127013057 /* * $Id: log.h,v 0.17 2003/08/23 16:38:16 ceder Exp $ * Copyright (C) 1991, 1993-1996, 1999, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: log.h,v 0.17 2003/08/23 16:38:16 ceder Exp $ * * log.h * * File created by ceder 1990-05-25. */ #ifndef LYSKOM_H_INCLUDED #define LYSKOM_H_INCLUDED /* * Add a string to the log file. */ #if defined(HAVE_VFPRINTF) && defined(HAVE_STDARG_H) extern void kom_log (const char * format, ...) # if HAVE_ATTRIBUTE_FORMAT_PRINTF __attribute__ ((format (printf, 1, 2))) # endif ; #else /* !HAVE_VFPRINTF || !HAVE_STDARG_H*/ extern void kom_log (); #endif /* !HAVE_VFPRINTF || !HAVE_STDARG_H*/ #endif lyskom-server-2.1.2/src/server/lyskomd.h0000664000015100472110000000343607721716127013765 /* * $Id: lyskomd.h,v 0.21 2003/08/23 16:38:16 ceder Exp $ * Copyright (C) 1991-1996, 1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ #ifndef LYSKOMD_H_INCLUDED #define LYSKOMD_H_INCLUDED /* * restart_kom is used to try to recover from an impossible error. * This function is in fact never called, unless some cosmic radiation * changes some pointers or suchlike. * * The msg string is sent as a mail to kom@lysator.liu.se * (At least one member in that group should not read his mail using kom...) */ #if defined(HAVE_VFPRINTF) && defined(HAVE_STDARG_H) extern void restart_kom(const char * format, ...) # if HAVE_ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) # endif # if HAVE_ATTRIBUTE_FORMAT_PRINTF __attribute__ ((format (printf, 1, 2))) # endif ; #else extern void restart_kom() # if HAVE_ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) # endif ; #endif #endif /* LYSKOMD_H_INCLUDED */ lyskom-server-2.1.2/src/server/manipulate.h0000664000015100472110000003124707721716127014443 /* * $Id: manipulate.h,v 0.45 2003/08/23 16:38:15 ceder Exp $ * Copyright (C) 1991-1994, 1996-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: manipulate.h,v 0.45 2003/08/23 16:38:15 ceder Exp $ * * manipulate.h * * Skapad av ceder n}gon g}ng efter 1990-05-25, men f|re 1990-07-05. */ /* * Definition of macros used in services.c and manipulate.c */ /* pers_no of the connected person. (0 if not logged in) */ #define ACTPERS (active_connection->pers_no) /* person of the connected person. (NULL if not logged in) */ #define ACT_P (active_connection->person) #define CHK_CONNECTION(errortype) \ do { \ if (active_connection == NULL) \ { \ err_stat = 0; \ kom_errno = KOM_INTERNAL_ERROR; \ return errortype; \ } \ } while (0) #define CHK_BOOL(val, errortype) \ do { \ if (val != 0 && val != 1) \ { \ err_stat = 0; \ kom_errno = KOM_BAD_BOOL; \ return errortype; \ } \ } while (0) /* many functions can only be used if ACTPERS is logged in */ #define CHK_LOGIN(errortype) \ do { \ if ( !active_connection || !ACTPERS ) \ { \ err_stat = 0; \ kom_errno = KOM_LOGIN; \ return errortype; \ } \ } while (0) /* Conference 0 does never exist. */ #define CONF_ZERO(conf, errortype) \ do { \ if ( (conf) == 0 ) \ { \ err_stat = 0; \ kom_errno = KOM_CONF_ZERO; \ return errortype; \ } \ } while (0) /* Check that a conference exists */ #define CHK_EXIST(conf, errortype) \ do { \ CONF_ZERO(conf, errortype); \ if ( !cached_conf_exists( conf )) \ { \ err_stat = conf; \ kom_errno = KOM_UNDEF_CONF; \ return errortype; \ } \ } while (0) /* do a cached_get_person_stat */ #define GET_P_STAT(p_stat_p, pers_no, failure) \ do { \ if ( ((p_stat_p) = cached_get_person_stat( pers_no )) == NULL) \ { \ return (failure); \ } \ } while (0) #define VOID_GET_P_STAT(p_stat_p, pers_no) \ do { \ if ( ((p_stat_p) = cached_get_person_stat( pers_no )) == NULL) \ { \ return; \ } \ } while (0) /* do a cached_get_conf_stat */ #define GET_C_STAT(c_stat_p, conf_no, failure) \ do { \ if ( ((c_stat_p) = cached_get_conf_stat( conf_no )) == NULL) \ { \ return (failure); \ } \ } while (0) #define VOID_GET_C_STAT(c_stat_p, conf_no) \ do { \ if ( ((c_stat_p) = cached_get_conf_stat( conf_no )) == NULL) \ { \ return; \ } \ } while (0) /* do a cached_get_text_stat */ #define GET_T_STAT(t_stat_p, text_no, failure) \ do { \ if ( ((t_stat_p) = cached_get_text_stat( text_no )) == NULL) \ { \ return (failure); \ } \ } while (0) #define VOID_GET_T_STAT(t_stat_p, text_no) \ do { \ if ( ((t_stat_p) = cached_get_text_stat( text_no )) == NULL) \ { \ return; \ } \ } while (0) /* * ENA returns TRUE if ACTPERS has his privtype bit set, and has * enabled to at least req_lev. */ #define ENA(privtype, req_lev) \ (active_connection && \ active_connection->ena_level >=(req_lev) && \ (ACT_P)->privileges.privtype) #define ENA_C(conn, privtype, req_lev) \ (conn->ena_level >=(req_lev) && \ (conn)->person && \ ((conn)->person)->privileges.privtype) #define HAVE_PRIV(pers, privtype) (pers && pers->privileges.privtype) /* * Add a misc item to a text_status. * The item is put last on the list. Thus this macro should not be used * to add rec_time. * * Text_stat * text_stat_pointer Textstatus to modify * enum info_type type_of_misc Type om misc_item to add * tag_name Tagname in union info_datum * value_of_misc Value to set tag_name to. */ #define ADD_MISC(text_stat_pointer, type_of_misc, tag_name, value_of_misc) \ { \ /* Allocate space */ \ text_stat_pointer->misc_items \ = srealloc(text_stat_pointer->misc_items, \ (++(text_stat_pointer->no_of_misc)) * sizeof(Misc_info));\ \ /* Set type */ \ text_stat_pointer->misc_items[ text_stat_pointer->no_of_misc-1 ] \ .type = type_of_misc; \ \ /* Set value */ \ text_stat_pointer->misc_items[ text_stat_pointer->no_of_misc-1 ] \ .datum.tag_name = value_of_misc; \ } /* * A value of the following type are returned from access_perm(), * which is used to see how much viewer is allowed to read/modify the * data of a given conference. */ enum access { error, /* The conf doesn't exist or other error. */ none, /* A secret conference. */ read_protected, /* An rd_prot conference. */ limited, /* An open conference. */ member, /* ACTPERS is a member of the conference. */ unlimited /* ACTPERS is supervisor of the conference. */ }; /* Return the highest access level that viewer_conn has to victim, but don't bother checking for higher level of access than wanted_access. Specify as low wanted_access as possible when calling this function, since that might speed upp the processing considerably. */ extern enum access access_perm(Conf_no victim, const Connection *viewer_conn, enum access wanted_access); /* Return true if VIEWER_CONN has at least the access level WANTED_ACCESS to VICTIM. */ extern Bool has_access(Conf_no victim, const Connection *viewer_conn, enum access wanted_access); /* Return VICTIM if the user user logged in via VIEWER_CONN is allowed to see it, or 0 if it is a secret conference that the user isn't allowed to see. */ extern Conf_no filter_conf_no(Conf_no victim, const Connection *viewer_conn); /* Visibility of a membership. */ enum memb_visibility { /* No visibility at all. */ mv_none, /* The membership is visible. However, the information about read texts should be censored. */ mv_censor_unread, /* Full visibility. The unread_is_secret bit should be ignored. */ mv_full, }; /* Compute the visibility of a membership. MEMBER is a member of CONF_NO, and the membership type i TYPE. VIEWER_CONN wants to know stuff about the membership. If it is known that the person logged on at VIEWER_CONN is a supervisor of the MEMBER, IS_SUPERVISOR_OF_MEMBER should be set (for a small performance gain). Similarly for IS_SUPERVISOR_OF_CONF. */ extern enum memb_visibility membership_visible(const Connection *viewer_conn, Pers_no member, Conf_no conf_no, Membership_type type, Bool is_supervisor_of_member, Bool is_supervisor_of_conf); /* Set err_stat to CONF_NO. Set kom_errno to ERRCODE if VIEWER_CONN is allowed to know that the conference exists. Otherwise, set kom_errno to KOM_UNDEF_CONF. */ extern void set_conf_errno(const Connection *viewer_conn, Conf_no conf_no, enum kom_err errcode); /* * Functions which manipulate the CONFERENCE struct. */ extern Success chk_passwd( Password pwd, const String s ); /* * Locate the Member struct in CONF_C for person PERS_NO */ extern Member * locate_member(Pers_no pers_no, Conference * conf_c); /* * Return TRUE if viewer is a supervisor to CONF. */ Bool is_supervisor(Conf_no conf, const Connection *viewer); extern Bool is_strictly_supervisor(Conf_no conf, Pers_no viewer, const Person *viewer_p); /* May be NULL */ /* * This function is called whenever a person leaves a conf, * i e when he change_conference():s or logout():s. */ extern void leave_conf(Connection *conn); /* * Change presentation of a conference. If text_no is 0, there will be * no presentation. */ extern Success do_set_presentation(Conf_no conf_no, Conference * conf_c, Text_no text_no); /* * Change motd of a conference. If text_no is 0, there will be * no motd. */ extern Success do_set_etc_motd(Conf_no conf_no, Conference * conf_c, Text_no text_no); /* * Functions that manupulate the PERSON struct */ /* * Find the data about PERS_P:s membership in CONF_NO. * Return NULL if not found */ extern Membership * locate_membership(Conf_no conf_no, const Person *pers_p); /* * Check if any read_ranges can be extended due to deleted texts. * Returns true if any change was performed. If that happens, the * caller must call mark_person_as_changed(). */ extern Bool adjust_read(Membership *m, const Conference *conf); /* * Delete a person. (The mailbox is not deleted);. */ extern Success do_delete_pers (Pers_no pers_no); /* * Functions which work on CONFERENCES and/or PERSONS. */ /* * Add a member to a conference. All errorchecking should already * be done when this function is called. The person must not already * be a member of the conference. It is _not_ an error to make WHERE bigger * than the number of conferences the person is a member in. */ extern void do_add_member(Conf_no conf_no, /* Conference to add a new member to. */ Conference * conf_c, /* Conf. status. Must NOT be NULL. */ Pers_no pers_no, /* Person to be added. */ Person * pers_p, /* Pers. status. Must NOT be NULL. */ Pers_no added_by, /* Person doing the adding */ unsigned char priority, /* Priority to assign to this conf */ unsigned short where, /* Sequence number in the list */ Membership_type * type, /* Membership type */ Bool fake_priority ); /* * Return TRUE if NAME is a legal name. Set kom_errno otherwize. */ extern Bool legal_name( String name ); /* * Return TRUE if NAME is not already used */ extern Bool unique_name( const String name, Conf_no conf_no ); /* * Delete a member from a conference. * No checks are made on the parameters. * The dynamically allocated areas conf_c->members.members and * pers_p->confs are NOT reallocated since they will anyhow sooner or later * be flushed from core. */ extern Success do_sub_member(Conf_no conf_no, /* Conf to delete member from. */ Conference * conf_c, /* May be NULL */ Member * mbr, /* May be NULL */ Pers_no pers_no, /* Person to be deleted. */ Person * pers_p, /* May be NULL */ Membership * mship); /* Pointer to the persons membership in conf., or NULL if not known. */ /* * Functions which deal with TEXTS */ /* * Check if the person logged in on CONN is allowed to read a text. * Returns TRUE if he is allowed to read it. */ extern Bool text_read_access(const Connection *conn, Text_no text_no, const Text_stat *text_stat); /* * Check if ACTPERS has sent this text as a footnote to parent. */ extern Bool is_footn_sender(Text_stat * text_s, Text_no parent); extern void forced_leave_conf(Pers_no pers_no, Conf_no conf_no); extern void register_jubel(Pers_no pno, /* See text.c */ Text_no divis, Text_no tno, Bool public); extern void free_all_jubel(void); lyskom-server-2.1.2/src/server/minmax.h0000664000015100472110000000232207721716127013565 /* * $Id: minmax.h,v 0.5 2003/08/23 16:38:15 ceder Exp $ * Copyright (C) 1991, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: minmax.h,v 0.5 2003/08/23 16:38:15 ceder Exp $ * * I can't believe that this really doesn't exist in a standard library! */ #define min(a, b) ((a) > (b) ? (b) : (a)) #define max(a, b) ((a) > (b) ? (a) : (b)) lyskom-server-2.1.2/src/server/param.h0000664000015100472110000001055407721716127013402 /* * $Id: param.h,v 1.49 2003/08/23 16:38:15 ceder Exp $ * Copyright (C) 1994-1999, 2002-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * LysKOM parameters read from the configuration file. */ #ifndef PARAM_H_INCLUDED #define PARAM_H_INCLUDED /* See server-config.c and lyskomd.texi for more info about the fields in this structure. */ struct kom_par { char *dbase_dir; char *use_locale; Bool send_async_messages; Bool garb_enable; Bool never_save; char *logaccess_file; char *ip_client_host; /* IP to listen to (default: INADDR_ANY) */ char *ip_client_port; /* Port to listen to for clients */ Bool use_dns; double dns_log_threshold; Conf_no conf_pres_conf; Conf_no pers_pres_conf; Conf_no motd_conf; Conf_no kom_news_conf; Text_no motd_of_lyskom; char *datafile_name; char *backupfile_name; char *backupfile_name_2; char *lockfile_name; char *textfile_name; char *numberfile_name; char *numberfile_tmp_name; char *textbackupfile_name; /* Only used in dbck */ char *backup_dir; /* Only used in splitkomdb */ char *statistic_name; char *pid_name; char *memuse_name; char *logfile_name; char *connection_status_file; char *connection_status_file_tmp; char *aux_def_file; char *status_file; /* Only used in komrunning and updateLysKOM */ char *core_dir; char *nologin_file; char *lyskomd_path; char *savecore_path; struct timeval garb_busy_postponement; struct timeval garbtimeout; struct timeval synctimeout; struct timeval garb_interval; Bool permissive_sync; struct timeval sync_interval; struct timeval sync_retry_interval; struct timeval stale_timeout; int saved_items_per_call; unsigned int penalty_per_call; unsigned int penalty_per_read; unsigned int max_penalty; unsigned int low_penalty; unsigned int default_priority; unsigned int max_priority; unsigned int default_weight; unsigned int max_weight; struct timeval connect_timeout; struct timeval login_timeout; struct timeval active_timeout; int client_data_len; int conf_name_len; int pwd_len; int what_do_len; int username_len; int text_len; int aux_len; int broadcast_len; int regexp_len; int stat_name_len; int max_marks_person; int max_marks_text; int max_recipients; int max_comm; int max_foot; int max_crea_misc; int mark_as_read_chunk; int accept_async_len; int max_delete_aux; int max_add_aux; int max_read_ranges; int max_super_conf_loop; int default_nice; int default_keep_commented; int maxmsgsize; int maxqueuedsize_bytes; int maxqueuedsize; int maxdequeuelen; Bool anyone_can_create_new_persons; Bool anyone_can_create_new_confs; Bool create_person_before_login; Bool default_change_name; int cache_conferences; int cache_persons; int cache_text_stats; /* 0=never use IDENT, 1=try to use IDENT, 2=only allow login if IDENT succeeded. */ int authentication_level; Bool log_login; Bool force_iso_8859_1; int no_files; /* -1=default */ int normal_shutdown_time; /* In minutes. */ int downtime_mail_start; /* In minutes. */ int downtime_mail_end; /* In minutes */ char *sendmail_path; Bool invite_by_default; Bool secret_memberships; Bool allow_reinvite; unsigned long max_conf; unsigned long max_text; }; extern struct kom_par param; #endif lyskom-server-2.1.2/src/server/prot-a-output.h0000664000015100472110000001367007721716127015044 /* * $Id: prot-a-output.h,v 0.37 2003/08/23 16:38:15 ceder Exp $ * Copyright (C) 1991-1992, 1994-1999, 2002-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: prot-a-output.h,v 0.37 2003/08/23 16:38:15 ceder Exp $ * */ extern void prot_a_output_ul(Connection *fp, unsigned long ul); extern void prot_a_output_person(Connection *fp, Person *person); extern void prot_a_output_person_old(Connection *fp, Person *person); extern void prot_a_output_membership(Connection *fp, const Membership *mship); extern void prot_a_output_membership_10(Connection *fp, const Membership *mship); extern void prot_a_output_membership_old(Connection *fp, const Membership *mship); extern void prot_a_output_membership_list(Connection *fp, Membership_list mlist); extern void prot_a_output_membership_list_10(Connection *fp, Membership_list mlist); extern void prot_a_output_membership_list_old(Connection *fp, Membership_list mlist); extern void prot_a_output_membership_type(Connection *fp, const Membership_type type); extern void prot_a_output_conf_list(Connection *fp, Conf_list_old conf_list); extern void prot_a_output_conf_no_list(Connection *fp, Conf_no_list conf_no_list); extern void prot_a_output_conference(Connection *fp, Conference *conf_c); extern void prot_a_output_conference_old(Connection *fp, Conference *conf_c); extern void prot_a_output_uconference(Connection *fp, Small_conf *conf_c); extern void prot_a_output_mark_list(Connection *fp, Mark_list mark_list); extern void prot_a_output_aux_item_flags(Connection *fp, Aux_item_flags flags); extern void prot_a_output_aux_item(Connection *fp, Aux_item *item); extern void prot_a_output_aux_item_list(Connection *fp, Aux_item_list *aux); extern void prot_a_output_text_stat_old(Connection *fp, Text_stat *t_stat); extern void prot_a_output_text_stat(Connection *fp, Text_stat *t_stat); extern void prot_a_output_info(Connection *fp, Info *info); extern void prot_a_output_info_old(Connection *fp, Info *info); void prot_a_output_who_info(Connection *fp, Who_info *info); extern void prot_a_output_who_info_list(Connection *fp, Who_info_list info); extern void prot_a_output_who_info_ident_list(Connection *fp, Who_info_ident_list info); extern void prot_a_output_who_info_list_old(Connection *fp, Who_info_list_old info); void prot_a_output_session_info(Connection *fp, Session_info *info); void prot_a_output_session_info_ident(Connection *fp, Session_info_ident *info); extern void prot_a_output_string(Connection *fp, String str); extern void prot_a_output_priv_bits(Connection *fp, Priv_bits bits); extern void prot_a_output_personal_flags(Connection *fp, Personal_flags flags); extern void prot_a_output_conf_type(Connection *fp, Conf_type type); extern void prot_a_output_extended_conf_type(Connection *fp, Conf_type type); extern void prot_a_output_member_list(Connection *fp, Member_list m_list); extern void prot_a_output_member_list_old(Connection *fp, Member_list m_list); extern void prot_a_output_mark(Connection *fp, Mark mark); extern void prot_a_output_misc_info(Connection *fp, Misc_info misc); extern void prot_a_output_member(Connection *fp, Member member); extern void prot_a_output_member_old(Connection *fp, Member member); void prot_a_output_time(Connection *fp, time_t clk); void prot_a_output_session_no(Connection *fp, Session_no session_no); void prot_a_output_text_no(Connection *fp, Text_no text); void prot_a_output_conf_no(Connection *fp, Conf_no conf); void prot_a_output_conf_z_info_list(Connection *fp, Conf_z_info_list c_list); void prot_a_output_version_info (Connection *fp, Version_info *v_info); void prot_a_output_num_list (Connection *fp, Number_list *num_list); void prot_a_output_static_session_info (Connection *fp, Static_session_info *info); void prot_a_output_dynamic_session_info_list (Connection *fp, Dynamic_session_info_list *list); void prot_a_output_l2g_iterator_as_text_list(Connection *fp, L2g_iterator *list); void prot_a_output_text_mapping(Connection *fp, Text_mapping *result); void prot_a_output_text_mapping_reverse(Connection *fp, Text_mapping_reverse *map); void prot_a_output_stats_description(Connection *fp, Stats_description *result); void prot_a_output_stats_list(Connection *fp, const Stats_list *result); void prot_a_output_static_server_info(Connection *fp, const Static_server_info *result); void prot_a_output_scheduling_info(Connection *fp, const Scheduling_info *result); #ifdef DEBUG_CALLS void prot_a_output_memory_info(Connection *fp, Memory_info *result); #endif lyskom-server-2.1.2/src/server/prot-a-parse.h0000664000015100472110000000532107721716127014610 /* * $Id: prot-a-parse.h,v 0.23 2003/08/23 16:38:14 ceder Exp $ * Copyright (C) 1991-1992, 1994-1999, 2002-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: prot-a-parse.h,v 0.23 2003/08/23 16:38:14 ceder Exp $ * */ extern long prot_a_parse_long(Connection *client); extern void prot_a_parse_num_list(Connection *client, Number_list *res, int maxlen); extern void prot_a_parse_priv_bits(Connection *client, Priv_bits *result); extern void prot_a_parse_pers_flags(Connection *client, Personal_flags *res); extern void prot_a_parse_membership_type(Connection *client, Membership_type *res); extern void prot_a_parse_conf_type(Connection *client, Conf_type *result); extern void prot_a_parse_string(Connection *client, String *result, int maxlen); extern void prot_a_parse_aux_item_flags(Connection *client, Aux_item_flags *res); extern void prot_a_parse_aux_item(Connection *client, Aux_item *result); extern void prot_a_parse_aux_item_list(Connection *client, Aux_item_list *result, int maxlen); extern void prot_a_parse_misc_info_list(Connection *client, Misc_info_list *result, int maxlen); extern void prot_a_parse_misc_info(Connection *client, Misc_info *result); extern void prot_a_parse_read_range_list(Connection *client, struct read_range_list *res, int maxlen); extern void prot_a_parse_time_date(Connection *client, struct tm *result); extern void prot_a_parse_info(Connection *client, Info *info); extern void prot_a_hunt_nl(Connection *client); extern void prot_a_parse_skip_whitespace(Connection *client); lyskom-server-2.1.2/src/server/prot-a-send-async.h0000664000015100472110000000745007721716127015547 /* * $Id: prot-a-send-async.h,v 0.23 2003/08/23 16:38:14 ceder Exp $ * Copyright (C) 1991, 1994-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: prot-a-send-async.h,v 0.23 2003/08/23 16:38:14 ceder Exp $ * * Asynchronous messages in protocol A. */ #define ASYNC_CHECK_ACCEPT(_conn, _msg) \ { \ if (_conn->want_async[_msg] == FALSE) return; \ } void prot_a_async_new_text(Connection *cptr, Text_no text_no, Text_stat *text_s); void prot_a_async_new_text_old(Connection *cptr, Text_no text_no, Text_stat *text_s); void prot_a_async_i_am_on(Connection *cptr, Who_info info); void prot_a_async_logout(Connection *cptr, Pers_no pers_no, Session_no session_no); void prot_a_async_new_name(Connection *cptr, Conf_no conf_no, String old_name, String new_name); void prot_a_async_sync_db(Connection *cptr); void prot_a_async_forced_leave_conf(Connection *cptr, Conf_no conf_no); void prot_a_async_login(Connection *cptr, Pers_no pers_no, int session_no); void prot_a_async_rejected_connection(Connection *cptr); void prot_a_async_send_message(Connection *cptr, Conf_no recipient, Pers_no sender, String message); void prot_a_async_delete_text(Connection *cptr, Text_no text_no, Text_stat *text_s); void prot_a_async_deleted_text(Connection *cptr, Text_no text_no, Text_stat *text_s); void prot_a_async_new_recipient(Connection *cptr, Text_no text_no, Conf_no conf_no, enum info_type type); void prot_a_async_sub_recipient(Connection *cptr, Text_no text_no, Conf_no conf_no, enum info_type type); void prot_a_async_new_membership(Connection *cptr, Pers_no pers_no, Conf_no conf_no); void prot_a_async_new_user_area(Connection *cptr, Pers_no pers_no, Text_no old_user_area, Text_no new_user_area); void prot_a_async_new_presentation(Connection *cptr, Conf_no conf_no, Text_no old_presentation, Text_no new_presentation); void prot_a_async_new_motd(Connection *cptr, Conf_no conf_no, Text_no old_motd, Text_no new_motd); void prot_a_async_text_aux_changed(Connection *cptr, Text_no text_no, Aux_item_list *aux_list, unsigned long highest_old_aux); #ifdef DEBUG_CALLS void prot_a_async_garb_ended(Connection *cptr, int deleted_texts); #endif lyskom-server-2.1.2/src/server/prot-a.h0000664000015100472110000000245107721716130013473 /* * $Id: prot-a.h,v 0.13 2003/08/23 16:38:14 ceder Exp $ * Copyright (C) 1991, 1994-1995, 1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: prot-a.h,v 0.13 2003/08/23 16:38:14 ceder Exp $ * */ void prot_a_init(Connection *conn); void prot_a_destruct(Connection *conn); void prot_a_reply(Connection *client, Success status, union result_holder *result); void prot_a_parse_packet(Connection *client); lyskom-server-2.1.2/src/server/ram-output.h0000664000015100472110000000335107721716130014406 /* * $Id: ram-output.h,v 0.17 2003/08/23 16:38:14 ceder Exp $ * Copyright (C) 1991, 1993-1999, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: ram-output.h,v 0.17 2003/08/23 16:38:14 ceder Exp $ * * ram-output.c - write objects to disk. * * This is a hack. It shouldn't be used except for debugging and as a * temporary substitute for what Willf|r is (or should:-) be doing. * * Written by ceder 1990-07-13. Rewritten 1990-08-31. */ extern void foutput_info(FILE *fp, Info *info); extern void foutput_person(FILE *fp, const Person *person); extern void foutput_conference(FILE *fp, Conference *conf_c); extern void foutput_text_stat(FILE *fp, Text_stat *t_stat); /* Needed by debug code in membership.c. */ extern void foutput_membership(FILE *fp, Membership *mship); extern void set_output_format(int fmt); lyskom-server-2.1.2/src/server/ram-parse.h0000664000015100472110000000546407721716130014167 /* * $Id: ram-parse.h,v 0.14 2003/08/23 16:38:14 ceder Exp $ * Copyright (C) 1991, 1993-1995, 1997-1999, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: ram-parse.h,v 0.14 2003/08/23 16:38:14 ceder Exp $ * * ram-parse.h -- parse objects from disk file. */ extern unsigned long fparse_long(FILE *fp); extern void fskipwhite(FILE *fp); extern time_t fparse_time(FILE *fp); extern Success fparse_info(FILE *fp, Info *info); extern Success fparse_conference(FILE *fp, Conference *result); Success fparse_person(FILE *fp, Person *person); extern Success fparse_membership_list(FILE *fp, Membership_list *result); extern Success fparse_conf_list(FILE *fp, Conf_list_old *result); extern Success fparse_mark_list(FILE *fp, Mark_list *result); extern Success fparse_text_stat(FILE *fp, Text_stat *result); extern Success fparse_info(FILE *fp, Info *result); extern Success fparse_string(FILE *fp, String *result); extern Success fparse_member_list(FILE *fp, Member_list *result); extern Success fparse_member(FILE *fp, Member *result); extern Success fparse_mark(FILE *fp, Mark *result); extern Success fparse_priv_bits(FILE *fp, Priv_bits *result); extern Success fparse_personal_flags(FILE *fp, Personal_flags *result); extern Success fparse_conf_type(FILE *fp, Conf_type *result); extern Success fparse_who_info(FILE *fp, Who_info *result); extern Success fparse_who_info_list(FILE *fp, Who_info_list *result); extern Success fparse_aux_item_flags(FILE *fp, Aux_item_flags *f); extern Success fparse_aux_item_link(FILE *fp, Aux_item_link *link); extern Success fparse_aux_item(FILE *fp, Aux_item *result); extern Success fparse_aux_item_list(FILE *fp, Aux_item_list *result); extern Success fparse_misc_info(FILE *fp, Misc_info *result); extern void set_input_format(int fmt); lyskom-server-2.1.2/src/server/rfc931.h0000664000015100472110000000212407721716130013275 /* * $Id: rfc931.h,v 1.11 2003/08/23 16:38:14 ceder Exp $ * Copyright (C) 1991-1992, 1994-1995, 1998-1999, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ const char *get_real_username(struct isc_scb *scb, char *hostname); lyskom-server-2.1.2/src/server/send-async.h0000664000015100472110000000645007721716130014340 /* * $Id: send-async.h,v 0.24 2003/08/23 16:38:13 ceder Exp $ * Copyright (C) 1991, 1994-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: send-async.h,v 0.24 2003/08/23 16:38:13 ceder Exp $ * */ extern void async_new_text(Connection *cptr, Text_no text_no, Text_stat *text_s); extern void async_new_text_old(Connection *cptr, Text_no text_no, Text_stat *text_s); extern void async_i_am_on(Who_info info); extern void async_logout(Pers_no pers_no, Session_no session_no); extern void async_new_name(Conf_no conf_no, const String old_name, const String new_name); extern void async_sync_db(void); extern void async_forced_leave_conf (Connection *cptr, Conf_no conf_no); extern void async_login(Pers_no pers_no, int client_no); extern void async_rejected_connection(void); extern Success async_send_message(Pers_no recipient, Pers_no sender, String message, Bool force_message); extern Success async_send_group_message(Pers_no recipient, Conf_no group_recipient, Pers_no sender, String message, Bool force_message); extern void async_deleted_text(Connection *cptr, Text_no text_no, Text_stat *text_s); extern void async_new_recipient(struct connection *cptr, Text_no text_no, Conf_no conf_no, enum info_type type); extern void async_sub_recipient(struct connection *cptr, Text_no text_no, Conf_no conf_no, enum info_type type); void async_new_membership(struct connection *cptr, Pers_no pers_no, Conf_no conf_no); void async_new_user_area(Pers_no person, Text_no old_user_area, Text_no new_user_area); void async_new_presentation(Connection *cptr, Conf_no conf_no, Text_no old_presentation, Text_no new_presentation); void async_new_motd(Connection *cptr, Conf_no conf_no, Text_no old_motd, Text_no new_motd); void async_text_aux_changed(Connection *cptr, Text_no text_no, Aux_item_list *aux_list, unsigned long highest_old_aux); #ifdef DEBUG_CALLS void async_garb_ended(int no_deleted); #endif lyskom-server-2.1.2/src/server/server-config.h0000664000015100472110000000212007721716130015033 /* * $Id: server-config.h,v 1.5 2003/08/23 16:38:13 ceder Exp $ * Copyright (C) 1994, 1999, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ void read_configuration(const char *conf_file); void free_configuration(void); lyskom-server-2.1.2/src/server/string-malloc.h0000664000015100472110000000262107721716130015043 /* * $Id: string-malloc.h,v 0.5 2003/08/23 16:38:13 ceder Exp $ * Copyright (C) 1991, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: string-malloc.h,v 0.5 2003/08/23 16:38:13 ceder Exp $ * * Malloc wrappers for the string package. * * These functions call smalloc and also counts * how many allocated strings there are. */ extern void * string_malloc(size_t size); extern void string_free(void * ptr); extern void * string_realloc (void * ptr, size_t size); extern void dump_string_alloc_counts(FILE *stat_file); lyskom-server-2.1.2/src/server/text-garb.h0000664000015100472110000000223107721716130014162 /* * $Id: text-garb.h,v 0.6 2003/08/23 16:38:13 ceder Exp $ * Copyright (C) 1991, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * $Id: text-garb.h,v 0.6 2003/08/23 16:38:13 ceder Exp $ * */ extern void start_garb_thread(oop_source *src); extern void stop_garb_thread(oop_source *src); lyskom-server-2.1.2/src/server/version-info.h0000664000015100472110000000206507721716130014710 /* * $Id: version-info.h,v 1.5 2003/08/23 16:38:12 ceder Exp $ * Copyright (C) 1994, 1999, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ extern const Version_info_internal kom_version_info; lyskom-server-2.1.2/src/server/sigflags.h0000664000015100472110000000222407721716130014066 /* * $Id: sigflags.h,v 1.8 2003/08/23 16:38:13 ceder Exp $ * Copyright (C) 1991, 1999, 2002-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* The go_and_die flag is set by SIGTERM and shutdown_kom. It causes lyskomd to be shut down in an orderly fashion. */ extern Bool go_and_die; lyskom-server-2.1.2/src/server/trace-alloc.h0000664000015100472110000000202207721716130014451 /* * set the location of the malloc trace * Copyright (C) 1999, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ extern void trace_alloc_file(const char *); lyskom-server-2.1.2/src/server/server-time.h0000664000015100472110000000202307721716130014526 /* * The current time is kept in a global variable. * Copyright (C) 1999, 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ extern struct timeval current_time; lyskom-server-2.1.2/src/server/oop-malloc.h0000664000015100472110000000243607717413250014340 /* * Copyright (C) 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * Malloc wrappers for the liboop package. * * These functions call smalloc and also counts * how many allocated blocks there are. */ extern void * oop_malloc_wrapper (size_t size); extern void oop_free_wrapper (void * ptr); extern void * oop_realloc_wrapper (void * ptr, size_t size); extern void dump_oop_alloc_counts(FILE *stat_file); lyskom-server-2.1.2/src/server/oop-malloc.c0000664000015100472110000000344607717413250014335 /* * Copyright (C) 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * Malloc wrappers for the liboop package. * * These functions call smalloc and also counts * how many allocated blocks there are. */ #ifdef HAVE_CONFIG_H # include #endif #include #ifdef HAVE_STDDEF_H # include #endif #include #include "oop-malloc.h" #include "server/smalloc.h" static int no_of_allocated_blocks = 0; void * oop_malloc_wrapper(size_t size) { ++no_of_allocated_blocks; return smalloc (size); } void oop_free_wrapper(void * ptr) { --no_of_allocated_blocks; sfree(ptr); } void * oop_realloc_wrapper (void * ptr, size_t size) { if ( ptr == NULL ) return oop_malloc_wrapper (size); return srealloc (ptr, size); } void dump_oop_alloc_counts(FILE *stat_file) { fprintf(stat_file, "---%s:\n\tAllocated blocks by liboop: %d\n", __FILE__, no_of_allocated_blocks); } lyskom-server-2.1.2/src/server/timewrap.h0000664000015100472110000000025507704105350014116 #ifdef TIME_WITH_SYS_TIME # include # include #else # ifdef HAVE_SYS_TIME_H # include # else # include # endif #endif lyskom-server-2.1.2/src/server/stats.h0000664000015100472110000000261307717675772013454 /* * Copyright (C) 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * stats.h -- Handle statistical information, such as load averages. */ enum stat_type { STAT_RUN_QUEUE, STAT_DNS_QUEUE, STAT_IDENT_QUEUE, STAT_CLIENTS, STAT_REQUESTS, STAT_TEXTS, STAT_CONFS, /* Including letterboxes! */ STAT_PERSONS, STAT_SEND_QUEUE, STAT_RECV_QUEUE, NUM_STAT }; extern void init_stats(void); extern void update_stat(enum stat_type st, long delta); extern long read_stat_value(enum stat_type st); lyskom-server-2.1.2/src/server/stats.c0000664000015100472110000002202707717675772013450 /* * Copyright (C) 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * stats.c -- Handle statistical information, such as load averages. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include "timewrap.h" #include #include #include #include #include #include "stats.h" #include "log.h" #include "lyskomd.h" #include "kom-types.h" #include "services.h" #include "async.h" #include "com.h" #include "connections.h" #include "kom-errno.h" #include "manipulate.h" #include "server/smalloc.h" #include "timeval-util.h" #define FACT_0 (1) /* 1 second */ #define FACT_1 (15) /* 15 seconds */ #define FACT_2 ( 4 * FACT_1) /* 1 minute */ #define FACT_3 ( 5 * FACT_2) /* 5 minutes */ #define FACT_4 ( 3 * FACT_3) /* 15 minutes */ #define N_FACTS 5 #define HISTORY_LENGTH (FACT_4) enum value_type { VT_AVG, VT_ASCEND, VT_DESCEND, NUM_VT }; struct avg_status { /* When was something last added to this? */ struct timeval when; /* The current value. */ long value; /* The accumulated average value for the current second. For VT_AVG, the values for fractional seconds are accumulated here. For VT_DESCEND and VT_ASCEND, this is the same as value. */ double acc; /* A circular buffer of the acc values for the past several seconds. Use ind() to figure out which index you should use. */ float avg_history[HISTORY_LENGTH]; /* When somebody fetches an average value, it is computed. In case the value is used twice during the same second, we cache the values in avenrun. Check the avenrun_updated to see if the cached value is up-to-date. We tried to keep avenrun_updated up-to-date, but rounding errors made that hard. We could use an exponentially decaying average, but I don't like them. */ time_t avenrun_updated; double avenrun[N_FACTS]; }; static struct avg_status status[NUM_STAT][NUM_VT]; static const int factors[] = { FACT_0, FACT_1, FACT_2, FACT_3, FACT_4, }; static int ind(unsigned long sec, unsigned int offset) { int ret = (sec - offset) % HISTORY_LENGTH; assert(ret >= 0); assert(ret < HISTORY_LENGTH); return ret; } void init_stats(void) { enum stat_type st; enum value_type vt; int i; struct timeval now; assert(sizeof(factors)/sizeof(factors[0]) == N_FACTS); assert(factors[N_FACTS-1] == HISTORY_LENGTH); gettimeofday(&now, NULL); for (st = 0; st < NUM_STAT; st++) for (vt = 0; vt < NUM_VT; vt++) { status[st][vt].when = now; status[st][vt].value = 0; status[st][vt].acc = 0.0; status[st][vt].avenrun_updated = now.tv_sec; for (i = 0; i < HISTORY_LENGTH; i++) status[st][vt].avg_history[i] = 0.0; for (i = 0; i < N_FACTS; i++) status[st][vt].avenrun[i] = 0.0; } } static void update_history(struct avg_status *s, time_t end, float value) { for (; s->when.tv_sec < end; s->when.tv_sec++, s->when.tv_usec = 0) s->avg_history[ind(s->when.tv_sec, 0)] = value; } static void update_one_stat(enum stat_type st, enum value_type vt, long delta, struct timeval now) { long time_delta; int i; struct avg_status *s = &status[st][vt]; static struct timeval notified; static int logged = 0; if (timeval_less(now, s->when)) { if (!logged || !timeval_less(now, notified)) { kom_log("Time moved backward at least %g seconds." " Statistics will be wrong for that amount of time.\n", timeval_diff_d(s->when, now)); notified = s->when; logged = 1; } s->value += delta; return; } if (now.tv_sec == s->when.tv_sec) { if (vt == VT_AVG) { time_delta = now.tv_usec - s->when.tv_usec; s->acc += 1.0e-6 * (double)s->value * time_delta; s->when.tv_usec = now.tv_usec; } } else if (now.tv_sec - s->when.tv_sec <= HISTORY_LENGTH) { if (vt == VT_AVG) { time_delta = 1000000 - s->when.tv_usec; s->acc += 1.0e-6 * (double)s->value * time_delta; } else s->acc = s->value; update_history(s, s->when.tv_sec+1, s->acc); if (vt != VT_AVG) { s->acc = 0; s->value = 0; } update_history(s, now.tv_sec, s->value); assert(s->when.tv_sec == now.tv_sec); if (vt == VT_AVG) { s->acc = 1.0e-6 * (double)s->value * now.tv_usec; s->when.tv_usec = now.tv_usec; } } else { if (vt != VT_AVG) { s->acc = 0; s->value = 0; } for (i = 0; i < N_FACTS; i++) s->avenrun[i] = s->value; for (i = 0; i < HISTORY_LENGTH; i++) s->avg_history[i] = s->value; if (vt == VT_AVG) s->acc = 1.0e-6 * (double)s->value * now.tv_usec; s->when = now; s->avenrun_updated = now.tv_sec; } s->value += delta; if (s->value < 0) { kom_log("update_stat(%d, %ld): current value became negative: %ld\n", st, delta, s->value); s->value = 0; } } void update_stat(enum stat_type st, long delta) { struct timeval now; gettimeofday(&now, NULL); update_one_stat(st, VT_AVG, delta, now); if (delta >= 0) update_one_stat(st, VT_ASCEND, delta, now); if (delta <= 0) update_one_stat(st, VT_DESCEND, -delta, now); } static void check_one_stat(enum stat_type st, enum value_type vt) { struct avg_status *s; double acc; float val; int f; int i; s = &status[st][vt]; if (s->avenrun_updated == s->when.tv_sec) return; s->avenrun_updated = s->when.tv_sec; assert(factors[N_FACTS-1] == HISTORY_LENGTH); f = 0; acc = 0; for (i = 0; i < HISTORY_LENGTH; i++) { val = s->avg_history[ind(s->when.tv_sec, i+1)]; assert(val >= 0); acc += val; assert(f < N_FACTS); if (i == factors[f] - 1) { s->avenrun[f] = acc / factors[f]; f++; assert(f < N_FACTS || i + 1== HISTORY_LENGTH); } } return; } static void check_stat(enum stat_type st) { enum value_type vt; for (vt = 0; vt < NUM_VT; vt++) check_one_stat(st, vt); } static const char * name(enum stat_type st) { switch (st) { case STAT_RUN_QUEUE: return "run-queue-length"; case STAT_DNS_QUEUE: return "pending-dns"; case STAT_IDENT_QUEUE: return "pending-ident"; case STAT_CLIENTS: return "clients"; case STAT_REQUESTS: return "reqs"; case STAT_TEXTS: return "texts"; case STAT_CONFS: return "confs"; case STAT_PERSONS: return "persons"; case STAT_SEND_QUEUE: return "send-queue-bytes"; case STAT_RECV_QUEUE: return "recv-queue-bytes"; case NUM_STAT: abort(); } abort(); } long read_stat_value(enum stat_type st) { return status[st][VT_AVG].value; } extern Success get_stats_description(Stats_description *result) { enum stat_type st; int i; CHK_CONNECTION(FAILURE); result->no_of_stats = NUM_STAT; result->stat_names = tmp_alloc(NUM_STAT * sizeof(result->stat_names[0])); for (st = 0; st < NUM_STAT; st++) result->stat_names[st] = s_fcrea_str(name(st)); result->intervals.length = N_FACTS + 1; result->intervals.data = tmp_alloc( (N_FACTS + 1) * sizeof(result->intervals.data[0])); result->intervals.data[0] = 0; /* The first momentaneous value. */ for (i = 0; i < N_FACTS; i++) result->intervals.data[i+1] = factors[i]; return OK; } extern Success get_stats(const String what, Stats_list *result) { enum stat_type st; int i; CHK_CONNECTION(FAILURE); for (st = 0; st < NUM_STAT; st++) if (s_streq(what, s_fcrea_str(name(st)))) break; if (st == NUM_STAT) { kom_errno = KOM_UNDEFINED_MEASUREMENT; err_stat = 0; return FAILURE; } /* Make sure we get the curren statistics, not some old value. */ update_stat(st, 0); check_stat(st); result->no_of_stats = N_FACTS + 1; result->stats = tmp_alloc((N_FACTS + 1) * sizeof(result->stats[0])); result->stats[0].average = status[st][VT_AVG].value; result->stats[0].ascent_rate = 0; result->stats[0].descent_rate = 0; for (i = 0; i < N_FACTS; i++) { result->stats[i+1].average = status[st][VT_AVG].avenrun[i]; result->stats[i+1].ascent_rate = status[st][VT_ASCEND].avenrun[i]; result->stats[i+1].descent_rate = status[st][VT_DESCEND].avenrun[i]; } return OK; } lyskom-server-2.1.2/src/server/splitkomdb.c0000664000015100472110000001563507721716130014444 /* * splitkomdb -- Split the database for efficient incremental backups * Copyright (C) 1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #ifdef HAVE_STDLIB_H # include #endif #include "timewrap.h" #include "kom-types.h" #include "s-string.h" #include "string-malloc.h" #include "server/smalloc.h" #include "kom-config.h" #include "server-config.h" #include "param.h" #include "linkansi.h" #include "eintr.h" /* The current version of splitkomdb uses three files to store all state. You can restore the database with commands similar to these: cat $text_base $text_tail > lyskomd-texts cp $data_copy lyskomd-data Future versions of this program may use a more elaborate layout of the contents of the backup directory. That is why you can configure the location of the directory, but not the file names used within that directory. */ static const char *text_base = NULL; static const char *text_tail = NULL; static const char *data_copy = NULL; static const char *argv0; static char * create_filename(const char *suffix) { char *res = smalloc(strlen(param.backup_dir) + 1 + strlen(suffix) + 1); sprintf(res, "%s/%s", param.backup_dir, suffix); return res; } static void compute_filenames(void) { text_base = create_filename("lyskomd-texts-base.backup"); text_tail = create_filename("lyskomd-texts-tail.backup"); data_copy = create_filename("lyskomd-data.backup"); } static void safe_remove(const char *filename) { errno = 0; if (remove(filename) != 0 && errno != ENOENT) { perror(filename); exit(1); } } static void usage(const char *arg0) { fprintf(stderr, "usage: %s [-c config-file] [ -f ] [ -v ] [ -V ]\n", arg0); exit(1); } static int is_clean(FILE *fp) { return (getc(fp) == 'C' && getc(fp) == 'L' && getc(fp) == 'E' && getc(fp) == 'A' && getc(fp) == 'N'); } static void copy_file(const char *from, FILE *fromfp, const char *to) { char buf[BUFSIZ]; FILE *tofp; size_t sz; if ((tofp = i_fopen(to, "w")) == NULL) { fprintf(stderr, "%s: opening ", argv0); perror(to); exit(1); } if (setvbuf(tofp, NULL, _IONBF, 0) != 0) { perror("setvbuf"); exit(1); } while (1) { sz = fread(buf, 1, BUFSIZ, fromfp); if (ferror(fromfp)) { fprintf(stderr, "%s: error reading from ", argv0); perror(from); exit(1); } if (sz == 0) break; if (fwrite(buf, 1, sz, tofp) != sz) { fprintf(stderr, "%s: writing to ", argv0); perror(to); exit(1); } } if (ferror(tofp)) { fprintf(stderr, "%s: writing to ", argv0); perror(to); exit(1); } if (i_fclose(tofp) != 0) { fprintf(stderr, "%s: closing ", argv0); perror(to); exit(1); } } static void copy_db_file(void) { FILE *fp; const char *from; fp = i_fopen((from = param.datafile_name), "r"); if (fp == NULL || !is_clean(fp)) { if (fp != NULL) i_fclose(fp); fp = i_fopen((from = param.backupfile_name), "r"); assert(is_clean(fp)); } if (fseek(fp, 0, SEEK_SET) != 0) { perror("fseek"); exit(1); } copy_file(from, fp, data_copy); i_fclose(fp); } static int file_equal(const char *from, FILE *fromfp, const char *assumed_copy) { FILE *copyfp; int c1; int c2; if ((copyfp = i_fopen(assumed_copy, "r")) == NULL) { if (errno == ENOENT) return 0; fprintf(stderr, "%s: opening ", argv0); perror(assumed_copy); exit(1); } while (1) { if ((c1 = getc(copyfp)) == EOF) { if (ferror(copyfp)) { i_fclose(copyfp); return 0; } else { i_fclose(copyfp); return 1; } } if ((c2 = getc(fromfp)) == EOF || c1 != c2) { if (ferror(fromfp)) { fprintf(stderr, "%s: reading ", argv0); perror(from); exit(1); } i_fclose(copyfp); return 0; } } } static void copy_text_file(void) { FILE *fromfp; if ((fromfp = i_fopen(param.textfile_name, "r")) == NULL) { fprintf(stderr, "%s: opening ", argv0); perror(param.textfile_name); exit(1); } if (file_equal(param.textfile_name, fromfp, text_base)) { copy_file(param.textfile_name, fromfp, text_tail); i_fclose(fromfp); } else { safe_remove(text_base); safe_remove(text_tail); if (fseek(fromfp, 0, SEEK_SET) != 0) { perror("fseek"); exit(1); } copy_file(param.textfile_name, fromfp, text_base); } } int main (int argc, char **argv) { int i; const char *config_file = NULL; int fulldump = 0; if (getuid() == 0 || geteuid() == 0) { fprintf(stderr, "%s: this program should run as lyskom, not root\n", argv[0]); exit(1); } link_ansi(); argv0 = argv[0]; /* Initialize the string handling package. */ s_set_storage_management(string_malloc, string_realloc, string_free); /* Parse command line arguments. */ for (i = 1; i < argc && argv[i][0] == '-'; i++) { if (argv[i][1] == '\0' || argv[i][2] != '\0') usage(argv[0]); switch (argv[i][1]) { case 'c': if (config_file != NULL) { fprintf(stderr, "%s: -c may only be used once\n", argv[0]); exit(1); } if (++i >= argc) usage(argv[0]); config_file = argv[i]; break; case 'f': if (fulldump != 0) { fprintf(stderr, "%s: -f may only be used once\n", argv[0]); exit(1); } fulldump = 1; break; case 'V': case 'v': fprintf(stderr, "splitkomdb from %s-%s\n", PACKAGE, VERSION); exit(0); default: usage(argv[0]); } } if (i < argc) usage(argv[0]); /* Read in the configuration file. */ if (config_file == NULL) config_file = get_default_config_file_name(); read_configuration(config_file); free_default_config_file_name(); compute_filenames(); if (fulldump) { safe_remove(text_base); safe_remove(text_tail); safe_remove(data_copy); } copy_db_file(); copy_text_file(); exit(0); } lyskom-server-2.1.2/src/server/updateLysKOM.c0000664000015100472110000001437407721716130014614 /* * $Id: updateLysKOM.c,v 1.25 2003/08/23 16:38:12 ceder Exp $ * Copyright (C) 1994-1995, 1998-1999, 2001-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ #ifdef HAVE_CONFIG_H # include #endif #include #ifdef HAVE_STDLIB_H # include #endif #include #include #include #include #include #ifdef HAVE_STRING_H # include #else # ifdef HAVE_STRINGS_H # include # endif #endif #ifndef HAVE_STRCHR # define strchr index #endif #include "timewrap.h" #include #include "ldifftime.h" #include "pidfile.h" #include "kom-types.h" #include "s-string.h" #include "string-malloc.h" #include "server/smalloc.h" #include "kom-config.h" #include "server-config.h" #include "param.h" #include "linkansi.h" #include "eintr.h" static void usage(const char *arg0) { fprintf(stderr, "usage: %s [-c config-file] [ -v ] [ -V ]\n", arg0); exit(1); } static void checkstatus(FILE *fp, long pid, char *progname) { char lbuf[80]; struct stat sbuf; char *sendmail; FILE *sendfp; if (fstat(fileno(fp), &sbuf) < 0) { perror("updateLysKOM: stat failed"); exit(1); } if (pid != 0) { if (kill(pid, SIGTERM) != 0) { if (errno != ESRCH) { fprintf(stderr, "%s: kill(%ld, SIGTERM) failed", progname, pid); perror(""); exit(1); } } else { /* The signal got through... */ if (ldifftime(time(NULL), sbuf.st_mtime) > 60 * param.normal_shutdown_time) { /* It takes very long for lyskomd to shut down. Strange. */ fprintf(stderr, "%s: Warning: it takes lyskomd a long time to die.\n" "Consider increasing ``Normal shutdown time'' " "in the config file if you get this message often.\n", progname); exit(1); } } } if (ldifftime(time(NULL), sbuf.st_mtime) < 60 * param.downtime_mail_start) { /* NOP */ } else if (ldifftime(time(NULL), sbuf.st_mtime) < 60 * param.downtime_mail_end) { /* The first line of the file should be a mail address to send a reminder to. */ if (fgets(lbuf, sizeof(lbuf), fp) == NULL || strcmp(param.sendmail_path, ":") == 0) { fprintf(stderr, "updateLysKOM: LysKOM has been down for a short while\n"); exit(2); } if (strchr(lbuf, '\n')) *strchr(lbuf, '\n') = '\0'; sendmail = smalloc(strlen(param.sendmail_path) + 4); strcpy(sendmail, param.sendmail_path); strcat(sendmail, " -t"); sendfp = popen(sendmail, "w"); if (sendfp == NULL) { fprintf(stderr, "updateLysKOM: failed to open pipe to "); perror(sendmail); exit(2); } fprintf(sendfp, "From: %s\n", lbuf); fprintf(sendfp, "To: %s\n", lbuf); fprintf(sendfp, "Subject: lyskomd is down\n"); fprintf(sendfp, "\n"); fprintf(sendfp, "Reminder: LysKOM is still not running.\n"); fprintf(sendfp, ".\n"); fflush(sendfp); if (ferror(sendfp)) { fprintf(stderr, "writing to sendmail failed.\n"); exit(2); } if (pclose(sendfp) != 0) { perror("updateLysKOM: sending mail might have failed"); exit(2); } } else { fprintf(stderr, "updateLysKOM: LysKOM has been down for a long time\n"); exit(2); } } /* Ignore errors in this function. */ static void savecore(void) { struct stat statbuf; char *corefile; corefile = smalloc(strlen(param.core_dir) + 1 + 4 + 1); strcpy(corefile, param.core_dir); strcat(corefile, "/core"); if (stat(corefile, &statbuf) == 0 && stat(param.savecore_path, &statbuf) == 0) { system(param.savecore_path); } sfree(corefile); } int main (int argc, char **argv) { int i; FILE *fp; long pid; const char *config_file = NULL; if (getuid() == 0 || geteuid() == 0) { fprintf(stderr, "%s: this program should run as lyskom, not root\n", argv[0]); exit(1); } link_ansi(); /* Initialize the string handling package. */ s_set_storage_management(string_malloc, string_realloc, string_free); /* Parse command line arguments. */ for (i = 1; i < argc && argv[i][0] == '-'; i++) { if (argv[i][1] == '\0' || argv[i][2] != '\0') usage(argv[0]); switch (argv[i][1]) { case 'c': if (config_file != NULL) { fprintf(stderr, "%s: -c may only be used once\n", argv[0]); exit(1); } if (++i >= argc) usage(argv[0]); config_file = argv[i]; break; case 'V': case 'v': fprintf(stderr, "updateLysKOM from %s-%s\n", PACKAGE, VERSION); exit(0); default: usage(argv[0]); } } if (i < argc) usage(argv[0]); /* Read in the configuration file. */ if (config_file == NULL) config_file = get_default_config_file_name(); read_configuration(config_file); free_default_config_file_name(); pid = read_pid_file(param.pid_name, argv[0]); if (pid == 1) { fprintf(stderr, "%s: got pid %ld.\n", argv[0], pid); exit(1); } fp = i_fopen(param.status_file, "r"); if (fp != NULL) { checkstatus(fp, pid, argv[0]); i_fclose(fp); } else { errno = ESRCH; /* Set sane default if pid==0. */ if (pid == 0 || kill(pid, SIGUSR1) != 0) { if (errno != ESRCH) { fprintf(stderr, "%s: kill(%ld, SIGUSR1) failed", argv[0], pid); perror(""); exit(1); } savecore(); execl(param.lyskomd_path, "lyskomd", (char *)0); fprintf(stderr, "%s: execl() failed: ", argv[0]); perror(""); exit(1); } } exit(0); } lyskom-server-2.1.2/src/server/.cvsignore0000664000015100472110000000054307722446225014126 *.bb *.bbg *.da *.gcov .deps .gdbinit .pure Makefile Makefile.in aux-item-def-parse.c aux-item-def-parse.h aux-item-def-scan.c aux-no.h bb.out call-switch.incl com.h dbck fnc-def-init.incl fncdef-no-str-limit.txt komrunning lyskomd paths.h prot-a-is-legal-fnc.incl prot-a-parse-arg.c prot-a-parse-arg.h splitkomdb updateLysKOM version-info.c version.incl lyskom-server-2.1.2/src/server/ChangeLog.10000664000015100472110000027154006210047341014031 Sun Aug 4 03:25:18 1996 Per Cederqvist * Release 1.9.0. * dbck.c: Include if it exists. * getopt.c: Likewise. * server-config.c: Likewise. * ram-smalloc.c (srealloc): Fixed printf-style modifiers in calls to restart_kom. * connections.c (mux_handle_packet): Fixed printf-style modifiers in VBUG calls. (login_request): Likewise. (logout_request): Likewise. * Makefile.src (KOMLIBS): Link with libregex before libansi, since libregex may need memcmp from libansi. Sat Aug 3 01:46:52 1996 Per Cederqvist * fncdef.txt (who_is_on_dynamic): One more numeric argument. * session.c (who_is_on_dynamic): New argument: active_last. * simple-cache.c (get_version): Removed an unused variable. * prot-a-output.c (prot_a_output_extended_conf_type): anarchy is now named allow_anon. * prot-a-parse.c (prot_a_parse_conf_type): Likewise. * ram-output.c (foutput_conf_type): Likewise. * ram-parse.c (fparse_conf_type): Likewise. * text.c (check_anonymous_subm): Likewise. * fncdef.txt: Renamed "pepsi" to "change_conference". * session.c (change_conference): New name for former pepsi. * manipulate.h: Changed "pepsi" to "change_conference" in comments. * membership.c: Likewise. * prot-a.c (prot_a_is_legal_fnc): Changed "call_fnc_pepsi" to "call_fnc_change_conference". Fri Aug 2 01:44:11 1996 Per Cederqvist * dbck.c (delete_misc): restart_kom requires a terminating newline. (main): Likewise. * Additional idle-time refinements. * session.c (login_old): Use active_connection->flags.invisible instead of active_connection->invisible. (login): Likewise. (logout): Likewise. (pepsi): Likewise. (change_what_i_am_doing): Likewise. (who_is_on): Likewise. (who_is_on_ident): Likewise. (who_is_on_old): Likewise. (who_is_on_dynamic): Likewise. Sessions with no user are always invisible. (user_active): Set active_connection->flags.user_active_used. * connections.h (Connection): Replaced field "invisible" with "flags". * memory.c (init_dynamic_session_info): Initialize flags. * internal-connections.c (init_connection): Initialize flags. (new_client): Initialize flags. * ramkomd.c (server_init): Fixed typo introduced Jul 30: ignore SIGPIPE, not SIGHUP. * Handle idle-time. * fncdef.txt (user_active): New function. (who_is_on_dynamic): New function. (get_static_session_info): New function. * connections.h (Connection): Removed field last_request. Added field active_time. (Res_type): New values: rt_dynamic_session_info_list, rt_static_session_info. (Result_holder): New fields: dynamic_session_info_list, static_session_info. * session.c (who_is_on_dynamic): New function. (get_session_info): The idle-time is calculated using active_time instead of last_request. (get_session_info_ident): Likewise. (get_static_session_info): New function. (user_active): New function. * prot-a.c (prot_a_reply): Handle rt_dynamic_session_info_list and rt_static_session_info. (prot_a_is_legal_fnc): Added user_active, who_is_on_dynamic and get_static_session_info. * prot-a-output.c (prot_a_output_dynamic_session_info, prot_a_output_session_flags): New static functions. * prot-a-output.h, prot-a-output.c: (prot_a_output_static_session_info): New function. (prot_a_output_dynamic_session_info_list): New function. * kom-memory.h, memory.c (init_dynamic_session_info): New function. (init_static_session_info): New function. * internal-connections.c (init_connection): Set active_time to now. Don't set last_request. (new_client): Likewise. * connections.c (parse_unparsed): Don't set client->last_request. Thu Aug 1 20:23:04 1996 Per Cederqvist * Improved handling of unknown calls: the server now assumes the incoming message is terminated by a newline, and responds with error code KOM_NOT_IMPL instead of with a protocol error. * prot-a.c (prot_a_parse_packet): Set client->function to illegal_fnc if the requested function is not supported instead of raising an ISC_PROTOCOL_ERR. * prot-a-parse.h, prot-a-parse.c (prot_a_hunt_nl): New function. * fnc-def-init.awk: Output a trailing entry which uses prot_a_hunt_nl to parse when client->function is illegal_fnc. * connections.c: Include prot-a-parse.h and kom-errno.h. (call_function): Treat illegal_fnc specially: set kom_errno to KOM_NOT_IMPL and return FAILURE. * com-h.awk (enum call_header): New value: illegal_fnc (which is always one greater than the highest supported call number). * call-switch.awk: Output code that calls restart_kom if illegal_fnc is ever attempted to be called. Wed Jul 31 21:43:19 1996 Per Cederqvist * server-config.c (WHITESPACE): According to prot-A.txt, form-feed is not a valid whitespace character, so remove it. Tue Jul 30 16:31:03 1996 Per Cederqvist * ramkomd.c (server_init): Use sigaction instead of signal if available. (go_daemon): Likewise. (main): Likewise. (sighandler_hup): Don't reinstall the signal if sigaction is available. (sighandler_usr1): Likewise. (sighandler_usr2): Likewise. Mon Jul 29 10:41:41 1996 David Byers * simple-cache.c (init_cache): Call get_version with the right file name. Previously get_version was always called with the datafile name. Initialize data file version before using it. Mon Jul 29 01:30:17 1996 Per Cederqvist * Handle sysv signal semantics: * ramkomd.c (sighandler_hup): Reinstall the SIGHUP handler. (sighandler_usr2): Reinstall the SIGHUSR2 handler. * simple-cache.c (init_cache): The local loop variable 'i' must be a long, so that a Text_no fits. The local variables done, read_text_no and read_conf_no are now of type Bool (not int). The local variable c is an int, so that it can safely be compared against EOF. Call restart_kom if an unknown deletion block is found in the data file. * prot-a.c (prot_a_reply): Fixed long/int mismatch in call to mux_printf. * prot-a-output.c (prot_a_output_num_list): Removed erronous argument in call to mux_printf. * log.h (log): Tell GCC that an argument is a printf-style format string if HAVE_ATTRIBUTE_FORMAT_PRINTF is set. (logv): Likewise. * lyskomd.h (restart_kom): Likewise. * mux.h (mux_printf): Likewise. * admin.c: Fixed bogus printf-style modifiers in calls to log and/or restart_kom. * cache-node.c: Likewise. * conference.c: Likewise. * connections.c: Likewise. * dbck-cache.c: Likewise. * dbck.c: Likewise. * internal-connections.c: Likewise. * person.c: Likewise. * ram-output.c: Likewise. * ram-parse.c: Likewise. * ramkomd.c: Likewise. * simple-cache.c: Likewise. * text.c: Likewise. Sun Jul 28 14:41:13 1996 Per Cederqvist * tmp-limits.h (MAX_TEXT): Increased to 2000000. * text.c (create_text_check_misc): Return KOM_ANON_REJECTED instead of KOM_ACCESS if the conference does not accept anonymous texts. (create_text): Use FALSE instead of 0 as Bool constant. (create_anonymous_text): Use TRUE instead of 1 as Bool constant. * send-async.c, send-async.h (async_send_group_message): The force_message argument is a Bool, not a char. (async_send_message): Likewise. * connections.h (Connection::username_valid): Mention that this field is used to determine if async messages are sent. * send-async.c (async_new_text): Don't send any message unless username_valid is set. (async_i_am_on): Likewise. (async_logout): Likewise. (async_new_name): Likewise. (async_sync_db): Likewise. (async_forced_leave_conf): Likewise. (async_login): Likewise. (async_rejected_connection): Likewise. (async_send_group_message): Likewise. * prot-a.c (prot_a_parse_packet): FIXME-comment regarding this removed. * Removed an unnecessary field in Connection: * prot-a-parse.c (prot_a_parse_info): Use struct_parse_pos instead of info_parse_pos. * connections.h (Connection::info_parse_pos): Removed. * connections.c (free_parsed): Don't set info_parse_pos. * internal-connections.c (init_connection): Likewise. * Use Bool instead of int for truth values and flags: * connections.h (Connection::want_async): Now an array of Bool instead of an array of int. * internal-connections.c (init_connection): Adjust for the above. * send-async.c (async_send_group_message): Likewise. * session.c (query_async): Likewise. (accept_async): Likewise. * prot-a-send-async.h (ASYNC_CHECK_ACCEPT): Likewise. Sat Jul 27 17:26:19 1996 Per Cederqvist * text.c (check_anonymous_subm): Removed two unused arguments. All callers updated. * New rules for adding and subtracting comment links: * text.c (create_text_check_misc): Check that the author can read the text he is commenting. (add_comment): Check that the adder can read the text he is adding a comment link to. (sub_comment): The user does not have to be able to read either of the texts to remove the comment link. On the other hand, it doesn't help if he is supervisor of the author of the parent. (sub_footnote): The user does not have to be able to read either of the texts to remove the footnote link. He must be supervisor of the author of the footnote, but not necessarily the author. Sat Jul 27 13:17:05 1996 David Byers * simple-cache.c (save_one_text): Removed code that printed dollar sign at end of data file. Fri Jul 26 02:11:38 1996 Per Cederqvist * simple-cache.c (init_cache): Added a missing parameter in a log statement. Fri Jul 26 10:40:12 1996 David Byers * simple-cache.c (init_cache): Data file is now terminated by EOF, not a dollar sign. * ram-output.h: Declare foutput_conf_type_0 and foutput_conference_0. * ram-output.c (foutput_conf_type_0): New function. Outputs an old four-bit conf_type. (foutput_conference_0): New function. Outputs conference with a four_bit conf type. * dbck-cache.c (cache_sync): Fix bug that crashed the program on nonexistent texts, persons and conferences. Rewrote format-dependent code as switches rather than ifs. Output passwords to the database. Output old-type conference records in version zero files. Data file is no longer terminated by a dollar sign. (init_cache): Rewrote format-dependent code as switches rather than ifs. Data file is terminated by EOF rather than dollar. Fri Jul 26 02:11:38 1996 Per Cederqvist * Protect against too large arrays sent to accept_async: * prot-a-parse.c, prot-a-parse.h (prot_a_parse_num_list): New argument: maxlen. Rewritten. * session.c (accept_async): prot_a_parse_num_list sets data to NULL and length to a non-zero value if the client sent a too big array. Check for that condition instead of checking if the length was greater than ay_dummy_last. Set kom_errno to KOM_LONG_ARRAY instead of KOM_INDEX_OUT_OF_RANGE if the array was too big. * server-config.c (parameters): New config: "Max accept_async len". * fncdef.txt (mark_as_read): Make param.mark_as_read_chunk visible here. (create_text, create_anonymous_text): Make param.max_crea_misc visible here. (accept_async): Added param.accept_async_len. * param.h (kom_par): New field: accept_async_len. * prot-a.c (prot_a_init): Set array_parse_index. * prot-a-parse-arg-c.awk: Make prot-a-parse-arg.c include async.h. c_local_text_no_p, c_misc_info_p and num_list should be followed by a maximum array length in fncdef.txt. Use array_parse_index instead of array_parse_pos to count the array index. Added a missing newline in the generated code. * internal-connections.c (init_connection): Initialize array_parse_index. * connections.h (Connection): New field: array_parse_index. * connections.c (free_parsed): Set array_parse_index. * cache.h (match_table): Added a missing "extern". * dbck.c (kom_info): Added a missing "extern". * connections.h: Don't include async.h -- no .h file in lyskomd should include another .h file. Why? Well, mostly because that is the way it is in the rest of lyskomd. * admin.c, conference.c, connections.c, internal-connections.c, isc-parse.c, membership.c, mux-parse.c, mux.c, person.c, prot-a-output.c, prot-a-parse.c, prot-a-send-async.c, prot-a.c, ramkomd.c, regex-match.c, send-async.c, session.c, simple-cache.c, text.c: Include async.h before connections.h. Thu Jul 25 01:30:53 1996 Per Cederqvist * simple-cache.c: Include string.h. (TIMESTAMP_FORMAT): Unused define removed. (pre_sync): Removed a call to time() whose return value was never used. Wed Jul 24 18:36:17 1996 David Byers * simple-cache.c (save_one_text): Don't output an extra space after the text number. foutput_long will place the necessary space there anyway. (Top level): Include string.h for strerror, test for unistd.h. Wed Jul 24 03:05:48 1996 Per Cederqvist * dbck.c (main): Die with an error message if an unsupported output format version is requested. * dbck-cache.c (cache_sync): Don't write 'I' records in version 0 files. Ignore 'I' records in version 0 files, but warn about them. Mon Jul 22 11:38:08 1996 David Byers * ram-output.c (foutput_conf_type): Output anarchy, rsv1, rsv2 and rsv3 bits of conference type to the database file. Sun Jul 14 23:01:37 1996 Per Cederqvist * ChangeLog: Added several details in entries below that David Byers forgot to talk about. Sat Jul 13 15:55:43 1996 Per Cederqvist (ceder@lysator.liu.se) * membership.c (set_last_read): The second argument is a Local_text_no, not a Text_no. Mon Jun 10 13:38:12 1996 David Byers * prot-a.c (prot_a_reply): Handle rt_num_list. (prot_a_is_legal_fnc): Added accept_async and query_async. * prot-a-parse.c, prot-a-parse.h (prot_a_parse_num_list): New function to parse num_list data. * prot-a-parse-arg-c.awk: Handle num_list data type * admin.c (send_message): Force message to user if it has an explicit letterbox recipient or if the sender is the administrator. * send-async.c (async_new_name): Check that the connection is allowed to know about the conference that changed name. * send-async.h, send-async.c: (async_send_group_message): Allow override of preference not to receive message. (async_send_message) Option to force message to be sent to user. * fncdef.txt: Added accept_async and query_async calls. * connections.h: Added num_list to Result_holder and Res_type. * prot-a-output.c, prot-a-output.h (prot_a_output_num_list): New function. * session.c (accept_async): Added this function. * async.h: I-will-include-zis-only-vonce code added. * internal-connections.c (init_connection): Handle num_list field. Sensible initialization of the want_async field. * connections.c (free_parsed): Handle num_list field. * call-switch.awk: Handle num_list input type. * prot-a-send-async.c: Check if client wants async messages before sending them; just about all functions have been modified. * prot-a-send-async.h (ASYNC_CHECK_ACCEPT): New macro to check if connection wants the async message at all. * connections.h: (Connection): Added fields want_async and num_list. (Res_type): Added rt_num_list. (Result_holder): Added num_list. * async.h (enum Async): Added ay_dummy_last. (ASYNC_DEFAULT_MESSAGES): New define. Sun Jun 9 10:36:29 1996 David Byers * server-config.c: Added "Permissive sync" option. * param.h: Added permissive_sync. * admin.c (sync_kom): Checks that the calling session is logged in and an administrator unless the configuration file has permissive_sync on. * admin.c (set_info): New function. * fncdef.txt: Added set_info. * prot-a.c: (prot_a_is_legal_fnc): call_fnc_set_info is now a valid value. * prot-a-parse-arg-c.awk: Handle info data type. * prot-a-parse.c, prot-a-parse.h (prot_a_parse_info): New function. * dbck-cache.c (init_cache): Override database kom_info with command-line kom_info. (cache_sync): Output kom_info structure. * call-switch.awk: Handle info input type. * connections.c (free_parsed): Set info_parse_pos. * internal-connections.c (init_connection): Initialize info_parse_pos and info. * connections.h (Connection): New fields: info_parse_pos, info. * dbck.c: Initialize oformat to -1 (no explicit output format). (main): Added options to set kom-info fields (give_help): Added help for the new options. * dbck-cache.c (init_cache): If no explicit output format is given, select output format to be the same as the input format. * dbck-cache.c (init_cache): Initialize read_text_num and read_conf_num to avoid compiler warnings. * dbck.c (locate_membership): Declared non-static to avoid conflict with membership.h (locate_member): Declared non-static to avoid conflict with membership.h (top level): Include crypt.h * person.c: Guard inclusion of and with HAVE_UNISTD_H and HAVE_CRYPT_H. * tmp-limits.h (MAX_TEXT): Set to 150000. Tue Mar 12 22:40:52 1996 Per Cederqvist (ceder@lysator.liu.se) * membership.c (add_member): Log a message if somebody adds somebody else to a conference. Sun Feb 25 21:37:09 1996 Per Cederqvist (ceder@lysator.liu.se) * Makefile.src (GETOPT): New variable. (DBCK): Needs GETOPT and version-info.o. Sun Feb 25 20:53:33 1996 Per Cederqvist (ceder@lysator.liu.se) * Use GNU getopt in dbck. * dbck.c (longopts): New variable. (main): Rewrote the option-parsing loop to use GNU getopt. * Help in dbck. * dbck.c (give_help): New function. (main): Call it if -h (or --help) is given. * Reset passwords in dbck. * dbck.c (reset_pwd): New variable. (main): Set it if -P (or --clear-password) is given. (check_persons): Reset the password if the person number equals reset_pwd. * Grant permission in dbck. * dbck.c (grant_all): New variable. (main): Set it if -G (or --grant-all) is given. (check_persons): Give the person all privileges if the person number equals grant_all. * getopt.h, getopt.c, getopt1.c: New files, taken from GNU hello 1.3. Fri Feb 23 21:37:09 1996 David Byers * dbck.c (oformat, force_output): New global variables. (main): New options: 'F' (to force output) and 'o' (to select output format). Fri Feb 23 12:41:46 1996 David Byers * dbck.c, simple-cache.c: Added support for remove records. THIS SUPPORT HAS NOT BEEN TESTED AT ALL SO DON'T USE IT! Fri Dec 15 12:48:54 1995 David Byers * dbck.c, simple-cache.c: #C and #T records in database for next-free-num and next-text-num. Sun Nov 12 16:34:34 1995 David Byers * dbck.c: Option -o to select output db format * dbck-cache.c: Read/write version 0 and version 1 files * simple-cache.c: Saves and reads version one files * text.c: Anarchy bit checked for anonymous texts: (check_anonymous_subm): New static function. (create_text_check_misc): New argument: anonymous. All callers updated. Check that the conference accepts anonymous texts if the new argument is true. Wed Nov 8 21:59:22 1995 Per Cederqvist (ceder@lysator.liu.se) * Release 1.8.0. * ram-output.c (foutput_conf_type): Disable output of the new bits until the database has a version number. * dbck.c (check_misc_infos): Fixed misleading error messages. Thu Nov 2 20:58:40 1995 Per Cederqvist (ceder@lysator.liu.se) * send-async.c (async_rejected_connection): Send this message at most once per minute. * log.c (log): A pid is sometimes larger than an int, so use %ld and proper casts when printing the pid. * dbck.c (dump_text_numbers): New variable. (check_texts): Print a line for each checked text if dump_text_numbers is set. (main): Set dump_text_numbers if -t was given. Changed usage-messages to include [-t]. * cache-database.c: Include "server/smalloc.h", not "smalloc.h". * server-config.c: Likewise. * conf-file.c: Likewise. * cache.c: Likewise. * Optionally use GNU Malloc. * Makefile.src (MALLOCLIB): New variable. Use it everywhere a program is linked. (.gdbinit): Added libraries/gnumalloc. Changed libraries/libisc to libraries/libisc-new. * ram-smalloc.c: Include "malloc.h" instead of if USE_GNU_MALLOC is defined. Tue Oct 31 12:14:15 1995 David Byers * prot-a-output.c: Added UConference and extended conf-type * prot-a-parse.c: Conf-type parser accepts both extended and original conf-type * ram-parse.c: Parse extended conf-type * ram-output.c: Output extended conf-type * simple-cache.c: Access to small_conf_arr entries * Added get-uconf-stat call Let set-conf-type accept an extended conf-type. Mon Oct 23 07:52:44 1995 Per Cederqvist (ceder@lysator.liu.se) * tmp-limits.h (MAX_TEXT): Increased to 1500000. * ramkomd.c (go_daemon): Changed API. Use param.logfile_name instead of trying to calculate it from supplied parameters. All callers updated. * prot-a-parse.c (prot_a_parse_string): Check for overflow when parsing the string length. Logout the current client if the string length supplied is so large that it becomes a negative number. * mux-parse.c (mux_parse_string): Likewise, but log out the entire mux. Sat Oct 7 15:29:05 1995 Per Cederqvist (ceder@lysator.liu.se) * text-garb.c (garb_text): Don't remove any text if param.garb_enable is false. * server-config.c: (parameters): New config: "Garb". * param.h (kom_par): New field: garb_enable. Tue Sep 5 20:56:23 1995 Per Cederqvist (ceder@lysator.liu.se) * lyskomd.h (restart_kom): Tell gcc 2.7 (or newer) that restart_kom never returns. * conf-file.c (configure_line): Allow empty values. (assign_text_no, assign_conf_no, assign_int): Sanity check the argument. * updateLysKOM.c (savecore): New function. (main): Call it before starting a new lyskomd. * ramkomd.c (go_daemon): Don't go into daemon mode if in debug mode. (initialize): Fixed a printf statement. (main): chdir to param.core_dir before the action starts. * param.h (kom_par): New field: core_dir. * server-config.c (parameters): New config: "Core directory". * dbck-cache.c: Include "param.h". * server-config.c (add_prefix, param_name, check_abs_path): New static functions. (read_configuration): Check that all path names are complete paths. * Remove global file name variables, and use fields in param instead: * simple-cache.c, dbck-cache.c (datafilename): Removed. All users modified to use param.datafile_name instead. (backupfilename): Removed. All users modified to use param.backupfile_name instead. (textfilename): Removed. All users modified to use param.textfile_name instead. * dbck.c, ramkomd.c: (datafilename): Removed. All users modified to use param.datafile_name instead. (backupfilename): Removed. All users modified to use param.backupfile_name instead. (textfilename): Removed. All users modified to use param.textfile_name instead. * dbck.c (textbackupfilename): Removed. All users modified to use param.textfile_name instead. (TEXTBACKUPFILE_NAME): Removed. * ramkomd.c (statisticfile, pidfile, memusefile): Removed. All callers modified to use param.statistic_name, param.pid_name and param.memuse_name instead. * connections.c (dump_statistics): Use param.statistic_name instead of statisticfile. * text.c (find_recipient): New name for former is_recipient. New API. All callers updated. (add_recipient): Allow a recpt to be changed to a cc_recpt, and vice versa. Fri Jan 20 23:56:14 1995 Per Cederqvist (ceder@lysator.liu.se) * text.c (ok_to_create_next_text): Added a missing newline in a log message. Sun Jan 8 12:13:14 1995 Per Cederqvist (ceder@lysator.liu.se) * Release 1.7.1. Sun Jan 1 14:08:34 1995 Per Cederqvist (ceder@lysator.liu.se) * Makefile.src (KOMLIBS): New variable, holding all of the libraries included in the distribution. (LIBS): Now only holds the libraries found by Autoconf. (lyskomd, updateLysKOM, encrypt, dbck): Depend on, and link with, $(KOMLIBS). (domostlyclean): Remove $(SPECIALS). * admin.c (broadcast): The argument is a const String, not a String. * conference.c (change_name, create_conf): Likewise. * person.c (create_person): Likewise. Sat Dec 31 13:02:22 1994 Per Cederqvist (ceder@lysator.liu.se) * conference.c (lookup_z_name): New function. * fncdef.txt: Added lookup_z_name. * prot-a.c (prot_a_is_legal_fnc): call_fnc_lookup_z_name is now a valid value. * ramkomd.c (go_daemon, main): Print the full version number, not the compatibility version number, in logs. * simple-cache.c (cached_create_text): Check that writing the text do disk succeeds, and return KOM_TEMPFAIL if it doesn't. Tue Dec 27 00:35:56 1994 Per Cederqvist (ceder@lysator.liu.se) * version-info.h: New file. * version.incl: This file is now generated. It is no longer a source file, and it is no longer included in the distribution. * session.c (logout): No longer send any async_i_am_off. * send-async.h (async_send_group_message): New function. (async_i_am_off, async_broadcast): Removed. * send-async.c (async_i_am_off, async_broadcast): Removed. (async_send_group_message): New function, derived from async_send_message. (async_send_message): Now implemented in terms of async_send_group_message. * regex-match.c (lookup_regexp): Return a Conf_z_info_list instead of a Conf_no_list. New parameter: want_confs. (downgrade): New static function. (re_lookup_person, re_lookup_conf): Use downgrade to adapt to the new API of lookup_regexp. (re_z_lookup): New function. * ram-parse.h (fparse_membership): Removed from the .h-file, since it is now static. * ram-parse.c (fparse_membership): Now static. (fparse_membership, fparse_membership_list, fparse_conf_list, fparse_mark_list, fparse_text_stat, fparse_text_list, fparse_string, fparse_member_list, fparse_who_info, fparse_who_info_list, fparse_misc_info): Set kom_errno to KOM_LDB_ERR, not KOM_SERVER_IS_CRAZY. * prot-a.c (prot_a_reply): Added code for rt_conf_z_info_list and rt_version_info. (prot_a_is_legal_fnc): call_fnc_re_z_lookup and call_fnc_get_version_info are now valid values. * prot-a-send-async.c, prot-a-send-async.h (prot_a_async_i_am_off, prot_a_async_broadcast): Removed. (prot_a_async_send_message): The recipient is now a Conf_no, not necessarily a Pers_no. * prot-a-output.c (prot_a_output_conf_z_info): New static function. * prot-a-output.c, prot-a-output.h (prot_a_output_version_info, prot_a_output_conf_z_info_list): New functions. * fncdef.txt: Added re_z_lookup and get_version_info. * connections.h (Res_type): Added rt_conf_z_info_list and rt_version_info. (Result_holder): Added conf_z_info_list and version_info. * async.h (Async): Removed ay_i_am_off, ay_i_am_on_obsolete and ay_broadcast since they are no longer used. Commented out ay_conf_deleted and ay_conf_created since they are not yet used. * admin.c (get_version_info): New function. (broadcast): Rewritten in terms of send_message. (send_message): The recipient is now a Conf_no, not necessarily a Pers_no. * Makefile.src (DISKOBJS): Added version-info.o. (C_SPECIALS): Added version-info.c. (SPECIALS): Added version.incl. (version.incl): New target (version.incl is now built from ../../versions, it is no longer a source file). (version-info.c): New target (also built from ../../versions). Tue Nov 15 00:31:01 1994 Per Cederqvist (ceder@lysator.liu.se) * version.incl: Version 1.6.5. * membership.c (adjust_read): Don't follow NULL pointers. * tmp-limits.h (MAX_TEXT): Increased to 1000000. (MAX_CONF): Increased to 4765. * ramkomd.c: Include . (initialize): Fixed typo. Mon Oct 24 01:30:48 1994 Per Cederqvist (ceder@lysator.liu.se) * server-config.c (parameters): New config: "Force ISO 8859-1" and "Open files". * ramkomd.c (initialize): Use setrlimit to increase the limit on number of open file descriptors, if the config file says to do so. Moved code to calculate number of open connections here from main(). (main): Some code moved to initialize(). Sun Oct 23 16:56:30 1994 Per Cederqvist (ceder@lysator.liu.se) * ram-smalloc.c (sfree): Removed dead code. * param.h (struct kom_par): New fields: force_iso_8859_1 and no_files. * membership.c (adjust_read): Rewritten to fix an obscure bug. * conference.c (legal_name): Handle parameter "Force ISO 8859-1". Always force 8859-1 unless HAVE_LOCALE_H. * version.incl: Version 1.6.5. Sat Oct 22 13:05:54 1994 Per Cederqvist (ceder@lysator.liu.se) * membership.c (add_rec_time): Removed unused argument conf_no. The only caller updated. * simple-cache.c (cached_conf_exists): Explicitly return TRUE or FALSE, not a boolean expression, to get rid of apcc warnings. * text.c (adjust_text_list): Likewise. * ram-parse.c (fparse_misc_info): Check that the number fits in an Info_type before storing it there. * prot-a.h, prot-a.c: (prot_a_reply): Type of argument status should be Success, not Bool. * prot-a.c (prot_a_init): Initialize conn->function to call_fnc_login_old, not 0. * prot-a.c (prot_a_parse_packet): Added a cast to make apcc happy. * prot-a-parse.c (prot_a_parse_misc_info): Likewise. * connections.c (parse_forgotten, toploop): Get rid of apcc warning by not using "!" to negate a Bool. * dbck.c (adjust_text_list): Likewise. * session.c (login): Likewise. * conference.c (set_conf_type): Return FAILURE, not 0. Sat Aug 20 00:04:37 1994 Per Cederqvist (ceder@lysator.liu.se) * log.c: Include unistd.h. Thu Jun 30 01:05:09 1994 Per Cederqvist (ceder@lysator.liu.se) * version.incl: Version 1.6.4. * text.c (greater): New function. (get_last_text): Use it. Maybe it now finally works? * ramkomd.c (go_daemon): Fixed buggy call to restart_kom. * text.c (add_recipient): Check that the user is allowed to write texts in the conference, and fail with KOM_PERM otherwise. * text.c (get_last_text): Fixed a bug introduced 12 oct 1993: dates were compared backwards. Mon Jun 20 12:15:35 1994 Per Cederqvist (ceder@lysator.liu.se) * version.incl: Version 1.6.3. * simple-cache.c: Include "config.h". Sat Jun 18 20:51:32 1994 Per Cederqvist (ceder@lysator.liu.se) * version.incl: Version 1.6.2. * connections.c: Include "config.h". * dbck.c: New option: -c (Consider an unset change_name an error). (unset_change_name_is_error): New variable. (check_persons): Check change_name if unset_change_name_is_error is set. Set it if -r is given, or offer to set it if -i is given. (main): Recognize -c and set unset_change_name_is_error if given. * text.c (find_previous_text_no): Optimize the case where the requested text is larger than the highest created text. * ramkomd.c (go_daemon): Now static. * person.c (create_person): Set change_name according to param.default_change_name. Check param.anyone_can_create_new_persons and create_pers. * param.h (struct kom_par): Don't test DEBUG or DEFENSIVE_CHECKS. Always include all fields. This wastes 8 bytes, but that way there is no risk that the struct looks different in different files. * internal-connections.c, membership.c: Test NDEFENSIVE_CHECKS instead of DEFENSIVE_CHECKS. * dbck.c, connections.c, ramkomd.c, server-config.c: Test NDEBUG instead of DEBUG. * Makefile.src, Makefile.in (tags): etags no longer supports the -t flag. Use $(srcdir) for *.c and *.h. Tue Apr 5 21:14:57 1994 Per Cederqvist (ceder@lysator.liu.se) * ramkomd.c (go_daemon): Added "coming up" log message, so that the version number is written to the log file. Mon Apr 4 15:58:30 1994 Per Cederqvist (ceder@lysator.liu.se) * updateLysKOM.c (checkstatus): Don't send mail to ceder. Instead, write an error message to stderr, exit with exit status != 0, and count on cron to deliver the message to whoever should get it. * ramkomd.c (go_daemon): New function. (initialize): Call go_daemon(). * param.h (struct kom_par): Added logfile_name. * server-config.c (parameters): Added "Log file". * connections.c (dump_statistics): Use ldifftime() instead of difftime(). dbck-cache.c (cache_sync): Likewise. session.c (logout, get_session_info, get_session_info_ident): Likewise. simple-cache.c (sync_part): Likewise. text-garb.c (garb_text): Likewise. * cache-node.h (insert_mru): No longer public. Mon Mar 21 23:36:24 1994 Per Cederqvist (ceder@lysator.liu.se) * simple-cache.c (pre_sync): Destruct cache_nodes for deleted conferences, persons and texts (thus making exists_b obsolete). (throwable_p): Non-existing nodes are throwable even if they are dirty. (limit_conf, limit_pers, limit_text_stat): Throw all throwable objects, not just the first throwable object. (save_one_conf, save_one_pers, save_one_text): The fact that the node exists can be used instead of the exists_b flag. * cache-node.h (struct cache_node): Removed the now redundant exists_b flag. * cache-node.c (EMPTY_CACHE_NODE): Removed initializer for exists_b flag. Thu Mar 10 01:09:14 1994 Per Cederqvist (ceder@lysator.liu.se) * log.c (logv): New timestamp format: "YYMMDD HH:MM:SS PID" (was: "YYYY-MM-DD HH:MM:SS "). Tue Mar 8 00:30:54 1994 Per Cederqvist (ceder@lysator.liu.se) * prot-a-parse-arg-c.awk: Portability fix. * conf-file.c (read_config): Added missing newlines in format string to restart_kom. * Makefile.src (predepend): Fixed typo. * session.c (login): Set same_person before calling logout(). Mon Mar 7 22:16:05 1994 Per Cederqvist (ceder@lysator.liu.se) * server-config.c: "Text backup file" should NOT default to the same file name as "Text file". Sun Mar 6 23:05:30 1994 Per Cederqvist (ceder@lysator.liu.se) * version.incl: Version 1.6 (alpha release). * Makefile.src (LK_STD): Make `all' depend on includes and binaries. Sun Mar 6 20:53:37 1994 Per Cederqvist (ceder@lysator.liu.se) * Makefile.src (doinstall): Install $(PROGRAMS). (PROGRAMS): Added updateLysKOM. (updateLysKOM, updateLysKOM.o): New targets. * updateLysKOM.c: New file. * isc-parse.c: Use HAVE_STRINGS_H and HAVE_STRCHR. * conf-file.c: Use HAVE_STRING_H, HAVE_STRINGS_H, HAVE_STRCHR and HAVE_STDLIB_H. * cache.c: Use HAVE_STRING_H. * cache-database.c: Use HAVE_STRING_H and HAVE_STDLIB_H. Sat Mar 5 17:55:01 1994 Per Cederqvist (ceder@lysator.liu.se) * session.c (login_old, login): Added missing trailing newline in the log message added on Feb 27. (login): Don't log when a person logs in as himself. * admin.c (shutdown_kom): Log who is shutting down the server. * Makefile.src (tags, .gdbinit): User @SRCTOPDIR@, not $(TOPDIR). * conf-file.c (assign_defaults): Fixed bug in error message printing. * rfc931.c ("param.h"): Include it. * Makefile.src (SRCS, *_SRCS): Removed. No longer used. Various other fixes. * tmp-limits.h (MAX_TEXT): Increased to 750000. IÅM explosion detected. * server-config.c (DEFAULT_PREFIX): Expect that macro to be set when the file is compiled. * Makefile.src (server-config.o): Define DEFAULT_PREFIX when compiling it. Sun Feb 27 14:33:19 1994 Per Cederqvist (ceder@lysator.liu.se) * Log logins. * param.h (struct kom_par): New field: log_login. * server-config.c (parameters): Added "Log login". * session.c (login_old, login): Log successful login attempts together with username and host. * Make the use of the IDENT protocol a configurable parameter. * param.h (struct kom_par): New field: authentication_level. * server-config.c (ident_param): New function. (parameters): Added Ident-authentcation. * rfc931.c (get_real_username): Always fail, without trying to contact an IDENT server, if param.authentication_level is 0. * connections.c (login_request): Disallow connections if param.authentication_level is 2 and the IDENT lookup fails. * cache.c: Don't #define SERVER. * session.c (login): Don't update the sessions count when logging in as the same person which already is logged in. Thu Feb 24 11:31:39 1994 Per Cederqvist (ceder@lysator.liu.se) * prot-a.c: Include "kom-memory.h". * Makefile.in (doclean, dodistclean): Removed duplicate empty entries of these targets. Sun Feb 20 17:14:25 1994 Per Cederqvist (ceder@lysator.liu.se) * cache.c: Integrated into the LysKOM environment. Fixed memory handling. Still needs more work. * cache.h: Moved the comments before what they comment. * simple-cache.c (query_next_text_num): The return value is a Text_no, not an int. * membership.c, session.c, text.c: Include kom-memory.h. * cache-database.c: Include smalloc.h. Adapted to the LysKOM environment. Fold some long lines. Sun Feb 20 15:12:16 1994 Pontus Hagland (law@kajsa) * cache.h: Rewritten. (Contents should be the same) * cache.c, cache-database.c, cache-database.h: new files (cache/database) Sat Feb 19 04:36:10 1994 Per Cederqvist (ceder@lysator.liu.se) * Don't allow anybody to create jubel-texts. text.c (struct jubel): New struct. (jubel_root): New variable. (register_jubel, free_all_jubel, ok_to_create_next_text): New functions. (create_text, create_anonymous_text): Check ok_to_create_next_text(). * ramkomd.c (struct parameter, log_param): Moved to server-config.c. (init_data_base): Removed code to build an empty data base. (dump_exit_statistics): Call free_all_jubel(). * server-config.c (parameters): New file-local variable. (CONFIG_FILE): New const. (DATAFILE_NAME, BACKUPFILE_NAME, TEXTFILE_NAME, STATISTIC_NAME, PID_NAME, MEMUSE_NAME, DEFAULT_CLIENT_SERVICE, DEFAULT_MUX_SERVICE, TIMEOUT, GARBTIMEOUT, SYNCTIMEOUT, GARB_INTERVAL, SYNC_INTERVAL, SYNC_RETRY_INTERVAL, CONF_NAME_LEN, PWD_LEN, WHAT_DO_LEN, USERNAME_LEN, TEXT_LEN, BROADCAST_LEN, REGEXP_LEN, MAX_MARKS_PERSON, MAX_MARKS_TEXT, MAX_RECIPIENTS, MAX_COMM, MAX_FOOT, MAX_CREA_MISC, CACHE_CONFERENCES, CACHE_PERSONS, CACHE_TEXT_STATS, MARK_AS_READ_CHUNK, MAX_SUPER_CONF_LOOP, DEFAULT_NICE, MAXQUEUEDSIZE, MAXDEQUEUELEN): Obsoleted by parameters. Removed. (log_param, jubel, read_configuration): New file-local functions. * ram-parse.c, session.c, simple-cache.c, text.c: Use init_foo() instead fo EMPTY_FOO. * prot-a.c (prot_a_init): Use init_priv_bits() instead of DEFAULT_PRIV_BITS. Use init_conf_type() instead of NULL_CONF_TYPE. * param.h: Added lots of configuration. * membership.c (do_add_member): Use init_membership() instead of EMPTY_MEMBERSHIP. * manipulate.h (register_jubel, free_all_jubel): New functions. * lyskomd.h (num_ip_client_port, num_ip_mux_port): Removed. * kom-types.c: Removed crap. This file is now empty. * kom-memory.h, memory.c: Cleanup. Added init_* functions. * internal-connections.c (init_connection): New function. (alloc_connection): Use it, instead of the (now deleted) const EMPTY_CONNECTION. * dbck.c (main): Read configuration file, the same way that lyskomd does. * conf-file.h: (struct parameter): default_val is a char*, not void*. * conf-file.c (assign_bool, configure_line): Use strcmp, not strcasecmp (which is not portable). * admin.c, conference.c, dbck.c, disk-end-of-atomic.c, fncdef.txt, person.c, prot-a-parse-arg-c.awk, prot-a.c, session.c, simple-cache.c, text-garb.c, text.c: Use param."foo" (from param.h) instead of "FOO". * Makefile.in (DBCK): Added conf-file.o. (DBCK_SRCS): Added conf-file.c. Fri Jan 14 20:06:14 1994 Per Cederqvist (ceder@lysator.liu.se) * server-config.h: New file. Wed Jan 12 02:26:36 1994 Per Cederqvist (ceder@lysator.liu.se) * server-config.c (CONFIG_FILE): New constant. * ramkomd.c: Read configuration from a config file. (initialize): New function. (param): New variable, holding (almost) all configuration. (send_async_messages): Superseeded by param.send_async_messages. * send-async.c: Track change * ramkomd.c (parameters): New variable. (main): Only accept -d and name of config file as arguments. (num_ip_client_port, num_ip_mux_port): Superseeded by param.num_ip_client_port and param.num_ip_mux_port. * connections.c (login_request): Track change. * connections.c, dbck-cache.c, person.c, prot-a.c, text-garb.c, simple-cache.c : Fixed format strings in BUG/VBUG/TRACE2 macros. * param.h, conf-file.h, conf-file.c: New files. * Makefile.in (HDRS): Added conf-file.h and param.h. (GENOBJS): Added conf-file.o. (GEN_SRCS): Added conf-file.c. Mon Nov 22 20:03:37 1993 Per Cederqvist (ceder@lysator.liu.se) * tmp-limits.h (MAX_TEXT): Increased to 550000. (MAX_CONF): Increased to 3765. * ramkomd.c (sighandler_usr1): Re-install the signal handler when it catches a signal. * prot-a-parse-arg-c.awk: Include , and in the generated file (prot-a-parse-arg.c). Thu Oct 14 10:15:27 1993 Per Cederqvist (ceder@lysator.liu.se) * admin.c, conference.c, dbck-cache.c, internal-connections.c, membership.c, memory.c, person.c, prot-a-parse.c, ram-output.c, ram-parse.c, regex-match.c, send-async.c, session.c, simple-cache.c, text-garb.c, text.c: Include if HAVE_STDARG_H. Wed Oct 13 00:03:53 1993 Per Cederqvist (ceder@lysator.liu.se) * mux.c (mux_printf): Track the name change in isc, and call UCB_printf instead of _printf. (_printf clashed with _printf from libc on HPUX machines). * dbck-cache.c, simple-cache.c (SEEK_SET, SEEK_END): Define them, if we cannot find them in , or . * ramkomd.c (main): New option: "-llocale". Default is now to never call setlocale(). * Makefile.in (LIBS): Not all systems support the -L flag to ld, so avoid it. Give "$(LIBDIR)/libfoo.a" to ld instead of "-L$(LIBDIR) -lfoo". * log.{h,c} (log): Test HAVE_VFPRINTF, and use a substitute log function if no vfprintf is available. The substitute might even work on some architectures! * ramkomd.c (restart_kom): Likewize. * dbck.c (log, restart_kom): Ditto. Tue Oct 12 19:36:41 1993 Per Cederqvist (ceder@lysator.liu.se) * getopt.h: Removed, since it was unused. * ramkomd.c: Test HAVE_LOCALE_H. * dbck-cache.c, dbck.c, person.c, ramkomd.c: Test HAVE_STDLIB_H. * connections.c, isc-parse.c, membership.c, memory.h, mux.c, person.c, ram-parse.c, ramkomd.c: Test HAVE_STRING_H. * text.c (get_last_text): Now takes a (struct tm *) as argument, not a time_t. That way we can use localtime() (which is POSIX) instead of timelocal() (which appears to exist only on SunOS 4.x). * call-switch.awk: Don't call timelocal when creating code for a time_date. (The called function should expect a (struct tm *), not a time_t as before). Sun Oct 10 12:25:47 1993 Per Cederqvist (ceder@lysator.liu.se) * fncdef.txt: sync renamed to sync_kom, to avoid name clashes with libc. * admin.c (sync_kom): Was formerly named sync. * prot-a.c (prot_a_is_legal_fnc): call_fnc_sync is renamed to call_fnc_sync_kom. * ramkomd.c (sighandler_usr2): Removed buggy declaration of fork(). * rfc931.c (get_real_username): Test HAVE_LIBAUTHUSER instead of RFC_931. * ramkomd.c (restart_kom): Use getcwd() (which is POSIX) to get the current working directory. Fall back on getwd() if getcwd() is not available. * ramkomd.c (main): Use sysconf(_SC_OPEN_MAX) instead of getdtablesize(), if available. * server-config.c (MAX_NO_OF_CONNECTIONS): Now initialized by main() if HAVE_SYSCONF or HAVE_GETDTABLESIZE is defined. * kom-memory.h: Renamed memory.h to kom-memory.h, to avoid conflicts with . * fncdef.txt: shutdown renamed to shutdown_kom, to avoid name clashes with libc. * admin.c (shutdown_kom): Was formerly named shutdown. * prot-a.c (prot_a_is_legal_fnc): call_fnc_shutdown is renamed to call_fnc_shutdown_kom. * *.h, *.c: Replace u_ with unsigned. * *.c: POSIXized include files. * connections.h (parse_env): Always declare it, even if _JBLEN is undefined. (Not all versions of defines _JBLEN). * mux-parse.h (mux_arse_env): Likewise. * Makefile.in: Hacked to work with --srcdir. Fri Oct 8 18:41:58 1993 Per Cederqvist (ceder@lysator.liu.se) * Makefile.in (LIBS): Added -L$(LIBDIR). Thu Oct 7 22:26:52 1993 Per Cederqvist (ceder@lysator.liu.se) * missing-ansi.c, tmp-difftime.h: Removed. The contents of the files can now be found inside libraries/libansi. Tue Sep 28 00:59:41 1993 Per Cederqvist (ceder@lysator.liu.se) * rfc931.c: Don't include unless RFC_931 is defined (thanks to Bo Kullmar). Fri Aug 13 16:17:42 1993 Per Cederqvist (ceder@lysator.liu.se) * version.incl: Version 1.4.1 (not released). * simple-cache.c (sync_part): Fixed bug, introduced on 5 Aug (causing nothing to be saved automatically). * simple-cache.c (sync_state): New state: sync_idle. Documented the state machine. Thu Aug 5 01:01:44 1993 Per Cederqvist (ceder@lysator.liu.se) * version.incl: Version 1.4 (not released). * tmp-limits.h: Allow 450000 texts. * simple-cache.c (init_cache): Don't print false error messages when the -L option is not given. * simple-cache.c (sync_part): Prevent lyskomd from looping endlessly when the server is shut down, by always returning TRUE when a save cycle is finished (even if a new cycle should be initiated immediately). * conference.c (legal_name): Set kom_errno to KOM_LONG_STR or KOM_BAD_NAME if it fails. Updated all callers of legal_name to not set kom_errno. * tmp-difftime.h: New includefile, which should be removed as soon as possible (when configuration is improved). * missing-ansi.c, connections.c, text-garb.c, simple-cache.c, session.c: Include it. * fncdef.txt: Added lookup_person and lookup_conf. * conference.c (do_lookup, lookup_person, lookup_conf): New functions. * fncdef.txt: Added set_client_version, get_client_name and get_client_version. * session.c (set_client_version, get_client_name, get_client_version): New functions. * connections.h (struct connection): Added new fields named client_name and client_version. * internal-connections.c (EMPTY_CONNECTION, new_client, kill_client): Initialize/destruct the fields as appropriate. * cache.h, simple-cache.c (cached_create_text): The string is a const. * text.c (create_text, create_anonymous_text): Likewize. * It is now possible to mark texts with mark_type 0. * fncdef.txt: Renamed mark_text to mark_text_old. * fncdef.txt: Added mark_text and unmark_text. * person.c: (do_unmark_text): New function: delete a mark. * person.c: (do_mark_mark_text): Never delete a mark. All callers changed to use do_unmark_text instead where appropriate. * person.c: (mark_text, unmark_text): New functions. * person.c: (mark_text_old): Compatibility function that calls mark_text or unmark_text depending on mark_type. This will now return an error if you unmark at text that you had not marked. * prot-a.c (is_legal_fnc): Track the above changes. Mon Mar 15 02:32:16 1993 Per Cederqvist (ceder@lysator.liu.se) * version.incl: Version 1.3.3 (not released). * tmp-limits.h: Allow 399999 texts and 2965 conferences. Sun Feb 21 17:34:30 1993 Per Cederqvist (ceder@lysator.liu.se) * version.incl: Version 1.3.2 (not released). * connections.c (add_to_kill_list): Fixed a bug that caused some false warnings in the log file. * rfc931.c (get_real_username): A fake version when RFC_931 is undefined. Sun Jan 17 04:38:34 1993 Per Cederqvist (ceder@konrad) * version.incl: Version 1.3.1 (not released). Sat Jan 16 23:25:44 1993 Per Cederqvist (ceder@konrad) * *.c: Use the USE macro. * ramkomd.c (dbase_dir): This variable was only used in main, and was thus moved into main(). Sat Dec 19 01:17:41 1992 Per Cederqvist (ceder@mauritz) * version.incl: Version 1.3. * rfc931.c (get_real_username): Don't log as much as previously. * Implement regexp matching, using GNU regex 0.11. * cache.h, simple-cache.c (cached_no_of_existing_conferences, cached_get_name): New functions. * fncdef.txt (re_lookup_person, re_lookup_conf): New functions. * prot-a.c (prot_a_is_legal_fnc): They are legal. * regex-match.c: New file. * server-config.c (REGEXP_LEN): Allow 1024 bytes of regexps. * Makefile (ATOMS, ATOMS_SRCS): Include regex-match.{c,o}. Tue Dec 1 00:17:23 1992 Linus Tolke Y (linus@mauritz) * version.incl: Version 1.2.8. * simple-cache.c (cache_delete_text): Simple bug in the logging of deleting texts. Sun Nov 22 16:06:36 1992 Per Cederqvist (ceder@mauritz) * version.incl: Version 1.2.7. * Support for logging of all db accesses: * ramkomd.c (main): Added -L option. * cache.h (tell_cache_garb_text): New function. * simple-cache.c: Do the logging. * text-garb.c (garb_text): Inhibit the logging while garbing. * cache.h: Removed unused stuff. Mon Nov 2 19:18:08 1992 Per Cederqvist (ceder@mauritz) * simple-cache.c (LOGFILE): Deleted the changes from Tue Oct 27. * cache.h (MAX_CACHED_PERSONS, MAX_CACHED_WHATEVER, cached_load_names, cached_add_name): was unused, is deleted. Tue Oct 27 05:27:55 1992 Per Cederqvist (ceder@ruben) * version.incl: Version 1.2.6. * simple-cache.c (LOGFILE): If #define'd, log every usage of the database to the file whose filename LOGFILE is set to. Thu Oct 8 08:51:23 1992 Per Cederqvist (ceder@mauritz) * tmp-limits.h: Allow 333333 texts. * dbck.c (main): Fixed usage message. Wed Oct 7 00:43:03 1992 Per Cederqvist (ceder@mauritz) * text-garb.c: Added a comment that describes a design for a better way to implement garbage collection of texts. Sun Sep 6 20:30:01 1992 Per Cederqvist (ceder@robert) * version.incl: Version 1.2.5. * connections.c (toploop): Optimization: don't flush stdout unless buglevel > 0. * tmp-limits.h: Allow 33333 texts and 1999 confs. Wed Aug 12 01:38:22 1992 Per Cederqvist (ceder@robin) * version.incl: Version 1.2.4. * rfc931.c (get_real_username): Introduce 20-second timeout. Log any ident queries that takes more than 3 seconds. New argument: hostname (only used for the log). * connections.c (login_request): Send the new argument. * log.c (logv): Print the log message on a single line, with the time in the first 20 columns. (Facilitate log browsing). Wed Aug 12 00:33:55 1992 Inge Wallin (inge@lysator) * simple-cache.c (save_one_text): Write texts to file as long as they are removed. Thu Jun 11 16:28:39 1992 Per Cederqvist (ceder@lysator) * vercion.incl: Version 1.2.3. * server-config.c: Timeout set to two minutes. Cache size increased to 20 elements. * simple-cache.c (dump_cache_stats): Also report the cache sizes. * missing-ansi.c (strerror): Return a const char *,not a char *. * connections.c (login_request): Don't dump core when we can't get the name of the originating host. Wed Jun 10 03:36:30 1992 Per Cederqvist (ceder@robin) * ramkomd.c (main): Log version number and pid when starting a new server. Sun May 31 03:08:31 1992 Per Cederqvist (ceder@lysator) * version.incl: Version 1.2.2 (not released). (Note: a bug in isc-0.97 has been fixed since 1.2.1: malloc() was used instead of isc_malloc_wrapper to allocate the kom_server_mcb). * lyskomd.h (kom_server_mcb): Removed duplicate declaration (it was (and still is) also declared in connections.h). * handle-malloc-dump.el: Added (require 'elib-dll). Mon May 25 22:56:38 1992 Per Cederqvist (ceder@lysator) * ram-smalloc.c (tmp_alloc): Don't log the size of the internal table anymore. * version.incl: Version 1.2.1 (not released). * server-config.c (TIMEOUT): Increased from 100 ms to 5 seconds. With isc 0.97 that should be no problem! * connections.c (toploop): The timeout is initially zero, so that the garbing starts right away. * connections.c (login_request): Fix so that the server can tell the difference between a mux and a client (using num_ip_*_port) (The bug was introduced with the isc upgrade). * lyskomd.h (listen_client, listen_mux): No longer exported. * ramkomd.c (listen_client, listen_mux): Now static. * ramkomd.c, lyskomd.h (num_ip_client_port, num_ip_mux_port): New variables. * ramkomd.c (server_init): Really use the IscConfig struct. * ramkomd.c (server_init): Log which ports lyskomd listens to for clients and servers, and set num_ip_*_port. Sat May 23 19:57:17 1992 Per Cederqvist (ceder@robin) * text.c (add_comment, add_footnote): Disallow texts to be comments/footnotes to themselves, since that would trigger a bug (the misc-list that is created would be erronous. A proper misc-info-list handling package should be written instead. Tue May 19 01:06:50 1992 Per Cederqvist (ceder@lysator) * Makefile (tags): Search libraries/libisc-new. Mon May 18 23:27:04 1992 Per Cederqvist (ceder@lysator) * connections.h (Connection): Added the boolean field username_valid. * internal-connections.c (new_client, EMPTY_CONNECTION): Initialize it. * prot-a.c (prot_a_parse_packet): Use it to test if username is set or not (instead of just assuming that an empty username is unset). Thu Apr 16 00:46:50 1992 Per Cederqvist (ceder@lysator) * Use isc-0.97: * Makefile (LIBS): -lisc-new instead of -lold-isc. * Makefile (GENOBJS, GEN_SRCS): Include isc-malloc.[oc]. * isc-malloc.[hc]: New files. (Compare string-malloc.[hc]). * Various namechanges: ISCMCB -> IscMaster ISCECB -> IscEvent ISCSCB -> IscSession * Use isc_destroy() instead of isc_close(). * isc-interfacs.h: Include instead of . * lyskomd.h (listen_client, listen_mux): Now (IscSession *). Updated all references. * lyskomd.h (kom_server_mcb): Now declared here. * ramkomd.c ("isc-malloc.h"): Include instead of . * ramkomd.c (server_init): Use the new configuration scheme. (Needs som further investigation). * ramkomd.c (dump_exit_statistics): Don't dump_isc_message_counts() since it doesn't exist. Wed Apr 15 19:52:20 1992 Per Cederqvist (ceder@lysator) * connections.c (add_to_kill_list): Check if the connection already was on the kill-list. If so, print a diagnostic and return. Tue Apr 14 17:21:26 1992 Per Cederqvist (ceder@lysator) * Version 1.1.2 (not released). * session.c (create_oldstyle_username): New function. * session.c (pepsi, change_what_am_i_doing, who_is_on, get_session_info): Use it. (pepsi and change_what_am_i_doing used to got the username wrong in 1.1.1). Sat Apr 11 22:00:27 1992 Per Cederqvist (ceder@robin) * connections.c (check_kill_flag): Small optimization: don't call sfree when the kill_list is empty. Fri Apr 10 13:46:41 1992 Per Cederqvist (ceder@lysator) * Since lyskomd spended 25% of the time in check_kill_flag it was rewritten. Instead of having a flag in the Connection that is checked once after every atomic call a linked list of connections that shall be killed is created. * connections.h (Connection): The field kill_me deleted. * connections.[hc] (add_to_kill_list): New function. * connections.c (kill_list_size): New variables. * connections.c (check_kill_flg): Rewritten to use the kill_list. * internal-connections.c (EMPTY_CONNECTION, new_client): Don't try to initialize kill_me. * session.c (disconnect): Use add_to_kill_list() instead of kill_me. Thu Apr 9 00:15:33 1992 Per Cederqvist (ceder@lysator) * Version 1.1.1 (not released). * Lyskom used to spend 60% of the time in limit_text_stat. With the changes of today it has dropped to 0.1%. * disk-end-of-atomic.c (end_of_atomic): Call limit_cache_size only every 100 rounds. * conference.c (unique_name): Fixed bug. It was previously possible to create a conference with the same name as an already existing conference. * simple-cache.c (throwable_p): New function. * simple-cache.c (limit_pers, limit_conf, limit_text_stat): Use throwable_p, and get the condition right. Tue Apr 7 16:48:54 1992 Per Cederqvist (ceder@robin) * session.c (login_old, login): Handle visibility flag correctly when an implicit logout is performed. * prot-a-output.c (prot_a_output_who_info): Removed erroneous bugfix. Mon Apr 6 23:11:29 1992 Per Cederqvist (ceder@ruben) * session.c (who_is_on_ident): Fix malloc bug. * session.c (who_is_on, who_is_on_ident, who_is_on_old): Don't return invisible sessions. Sat Apr 4 19:24:27 1992 Per Cederqvist (ceder@lysator) * person.c (get_person_stat): It is allowed to get the person status before logging in so that it is possible to print a "last login from:" message. * ramkomd.c: Include "getopt.h", not . * person.c (create_person): The newly created person always logs in visibly. * kom-types.c (EMPTY_SESSION_INFO_IDENT, EMPTY_WHO_INFO_IDENT): New constants. * Makefile (LIBS): Use LIBRESOLV and LIBIDENT. Wed Apr 1 22:02:55 1992 Per Cederqvist (ceder@lysator) * Code to allow invisible sessions: * connections.h (Connection): New field: invisible. * session.c, fncdef.txt (login_old): New name for the function login(). * fncdef.txt (login): New function with a parameter for invisible use. * session.c, fncdef.txt (login): New function with invisibility support. * session.c (logout, pepsi, change_what_i_am_doing): Don't send asynchronous messages if the session is invisible. * Code to allow user identification using the Ident protocol (as defined in RFC 931): * connections.h (Connection): New field: ident_user. * connections.h (Res_type): New types: rt_session_info_ident and rt_who_info_ident_list. * connections.c (login_request): Set ident_user. * fncdef.txt (who_is_on_ident, get_session_info_ident): New functions that behaves like who_is_on and get_session_info, but also returns the ident name. * internal_conections.c (EMPTY_CONNECTION, new_client, kill_client): Set/free ident_user and invisible. * prot_a_output.c (prot_a_output_who_info_ident, prot_a_output_who_info_ident_list, prot_a_output_session_info_ident): New functions. * prot-a.c (reply): rt_who_info_ident_list and rt_session_info_ident: New reply types. * session.c (login_old): Generate the a proper (but not 1.1.0-compatible) string in username. * session.c (who_is_on, get_session_info): Generate username. * session.c (who_is_on_ident, get_session_info_ident): New functions. * prot-a.c (prot_a_reply): Free username when returning a session_info. It is allocated in get_session_info() in session.c. * prot-a-output.c (prot_a_output_who_info_list): Free username when returning a who_info_list. It is allocated in who_is_on() in session.c. Tue Mar 31 23:48:47 1992 Per Cederqvist (ceder@robert) * rfc931.[hc]: New file. * Makefile: (GEN_OBJS, GEN_SRCS): Use it. Tue Mar 24 18:05:18 1992 Per Cederqvist (ceder@robert) * simple-cache.c (save_one_text): Check that the entire file made it to the disk (compare wath ftell() says after fclose() and fopen()). Mon Mar 23 08:51:13 1992 Per Cederqvist (ceder@robin) * dbck.c (truncated_texts): New variable. * dbck.c (main): Increase modifications if truncated_texts is set. * dbck-cache.c (init_cache): If the database is truncated or severely damaged in the text-status part, just ignore the remaining texts (and don't fail miserably). Thu Mar 12 04:30:17 1992 Per Cederqvist (ceder@lysator) * membership.c (get_unread_confs): You must be logged in to use this call. Mon Mar 9 16:33:45 1992 Per Cederqvist (ceder@robin) * DATAFILE_NAME (server-config.c): Added a comment. Wed Feb 26 19:49:21 1992 Per Cederqvist (ceder@lysator) * various: Lint from gcc 2.0 deleted. Fri Feb 21 01:45:35 1992 Per Cederqvist (ceder@robin) * server-config.c (SYNC_TIMEOUT): Decreased from 10 millisec to 0. It takes some 2 hours for the server at Lysator to save the entire data base, and that is a bit too long... * dbck.c (main): New flag: -s. Prints some extra statistics. * dbck.c (print_statistics): New function that prints statistics about the lengths of texts. * prot-a-parse-arg-c.awk: Fixed a syntax error. (gawk could handle the file, but awk could not). Sun Jan 12 02:30:34 1992 Per Cederqvist (ceder at lysator) * prot-a-parse.[ch] (prot_a_get_token): Then function is now static. Sun Jan 5 19:10:20 1992 Per Cederqvist (ceder at lysator) * dbck.c (main): Tell the user why no compression was done if he specifies -g and there is an error in the files. * dbck.c, ramkomd.c (main): Better usage messages. * simple-cache.c (init_cache): Slightly better log error message when the text file can not be found. Wed Dec 18 00:05:43 1991 Per Cederqvist (ceder at lysator) * Version 1.0.4 was never used. Version is now 1.1.0. * fncdef.txt, prot-a.c, text.c (find_next_text_no, find_previous_text_no): New functions. Tue Dec 17 00:52:11 1991 Per Cederqvist (ceder at lysator) * prot-a-parse-arg-c.awk: Fixed bogus parsing of argument to get_last_text. * prot-a-parse.h, prot-a-parse.c (prot_a_parse_time_date): New function for get_last_text. * text.c (get_last_text): Rewrote it. Mon Dec 16 15:32:57 1991 Per Cederqvist (ceder at ruben) * conference.c (is_supervisor): New arguments: viewer and viewer_p. * membership.c (access_perm): New parameters: viewer and viewer_p. * admin.c (broadcast, send_message): Don't forget to check the length of the message. * text.c (create_text, create_anonymous_text): Fixed error in max length comparison. * All the changes below fixes one single bug. When a text is created that has both a secret and a public conference as recipient the asynchronous messages that were sent out did not filter away the secret conference. This has how been fixed. * membership.c manipulate.h (fast_access_perm): New arguments: viewer and viewer_p. * send-async.c, text.c (is_member_in_recpt): Moved from send-async.c to text.c. * send-async.h, send-async.c (async_new_text): Sends to a specified connection. * text.c (create_text, create_anonymous_text): Use send_async_new_text. * text.c (send_async_new_text): New function. * text.c (get_text_stat): Use filter_secret_info. * text.c (filter_secret_info): New function that given a text-stat and a person number yields a new text-stat that only contains tha recipients that the viewer is allowed to know about. Mon Nov 11 01:08:09 1991 Per Cederqvist (ceder at ruben) * fncdef.txt, prot-a.c, text.c: Added create_anonymous_text. Mon Nov 10 20:00:00 1991 Linus Tolke T (linus at ruben) * fncdef.txt, prot-a.c, text.c, call-switch.awk, cache.h, connections.h : Added get_last_text. Tue Oct 29 15:48:15 1991 Linus Tolke Y (linus at ruben) * prot-a-output.c, prot-a-parse.c, ram-output.c, ram-parse.c (Priv_bits): The flg7 field has change name to extern_gw. Tue Oct 29 03:52:34 1991 Per Cederqvist (ceder at robert) * Makefile (tags): tags does not depend on anything now. * Makefile (HDRS): isc.h should be isc-interface.h. See note from Sat Sep 21. * Version is now 1.0.4. * internal-connections.c (no_of_connection_attempts): Now a global variable, so that dump_allocated_connections can write it to the log files. * ramkomd.c (dump_exit_statistics): This function, which is only run when the server is brought down nicely, writes some statistics to a log file. The log file is now open in append mode (and not overwrite mode...) Mon Oct 21 23:14:22 1991 Per Cederqvist (ceder at robin) * text.c (create_text): Check that the length of the text is no greater than TEXT_LEN. Wed Sep 25 11:44:17 1991 Per Cederqvist (ceder at lysator) * person.c (do_set_passwd, chk_passwd), ram-parse.c (fparse_conference): Use string_free and not sfree to free strings that was created with s_crea_c_string. * person.c (do_set_passwd): Fixed serious bug in salt generation. Mon Sep 23 19:39:55 1991 Per Cederqvist (ceder at lysator) * text.c (sender): handle a sent_at correctly. Sat Sep 21 02:12:24 1991 Per Cederqvist (ceder at lysator) * "isc.h" is now known as "isc-interface.h" to avoid confusion with . * version.incl: Go 1.0.2. * ram-smalloc.c: Added support for memory leak finding. * trace-mem.gdb, handle-malloc-dump.el: Useful for finding memory leaks in the server. Compile ram-smalloc.c with DEBUG_MALLOC defined. * mux.c (mux_close): Fixed memory leak. * ramkomd.c (main): Print how many blocks isc allocates. * ramkomd.c: ip_client_port and ip_mux_port are local to ramkomd.c. Tue Sep 17 23:04:39 1991 Per Cederqvist (ceder at lysator) * .gdbinit: Now created by "make .gdbinit". * Removed smalloc.c that is never used. Mon Sep 16 19:27:04 1991 Per Cederqvist (ceder at lysator) * version.incl: Version 1.0! Fri Sep 13 22:20:59 1991 Per Cederqvist (ceder at lysator) * server-config.c: Det heter lyskomd-data, inte ramkomd-data (osv). F|rb{ttrade n}gra kommentarer. Thu Sep 12 01:00:13 1991 Per Cederqvist (ceder at lysator) * ramkomd.c (main): Anropa srand() om ENCRYPT_PASSWORDS {r satt, s} att vi f}r ett slumpm{ssigt fr|. * person.c (do_set_passwd, chk_passwd) Kryptera l|senord om ENCRYPT_PASSWORDS {r satt. (Inkompatibelt med gamla databasformatet). Tue Sep 10 21:58:18 1991 Per Cederqvist (ceder at robert) * conference.c (delete_conf): Om det {r en brevl}da som tas bort s} ska personen som tas bort loggas ut f|rst (inte n|dv{ndigtvis personen som tar bort en person...) Thu Sep 5 10:14:40 1991 Per Cederqvist (ceder at lysator) * cache.h, simple-cache.c, dbck-cache.c (cached_set_conf_type): borttagen. * conference.c, person.c: alla anrop till cached_set_conf_type borttagna. (Funktionen anropades bara precis efter mark_conference_as_changed. * simple-cache.c: Fixade lite stavfel. La till lite nya defensiva kontroller. * simple-cache.c (mark_conference_as_changed): Uppdatera inte bara first_local_no, utan {ven nice och type i small_conf_array varje g}ng som mark_conference_as_changed anropas. Namnet uppdateras dock inte. Det kostar nog mer {n det smakar (man m}ste reallokera en str{ng n{r man {ndrar namnet). * simple-cache.c (get_text_node, get_pers_node, get_conf_node): Returnera NULL om det s|kta numret {r st|rre {n next_free_num eller next_text_num. Defensivt ska det vara! Wed Sep 4 22:03:47 1991 Per Cederqvist (ceder at lysator) * text-garb.c (garb_text): Nollst{ll deleted_texts n{r garbningen {r klar. Sat Aug 31 22:14:30 1991 Per Cederqvist (ceder at lysator) * ramkomd.c: Inkludera alltid - gcc -M f|rs|ker inkludera den {ven om HAVE_LOCALE inte {r satt. Skicka med en tom locale.h i include/ansi f|r de som inte har locale. Fri Aug 30 05:32:13 1991 Per Cederqvist (ceder at lysator) * config.c ramkomd.c (MAX_NO_OF_CONNECTIONS): S{tt fr}n getdtablesize om det anropet finns. * limits.h heter numera tmp-limits.h (f|r att inte f|rv{xla den med ANSI-filen . Wed Aug 28 03:21:27 1991 Per Cederqvist (ceder at lysator) * dbck.c (post_check_persons): Uppdatera modifications {ven n{r man reparerar antalet skapade m|ten f|r en person. * La till RCS-Id i alla k{llkodsfiler. * prot-a-parse-arc-c.awk: "smalloc.h" heter . * dbck-cache2.c heter nu dbck-cache.c. * cache.c, end-of-atomic.c, lyskomd.c, ram-cache.c: Borttagna. Mon Aug 26 04:13:34 1991 Per Cederqvist (ceder at lysator) * simple-cache.c: Anv{nde BUFSIZ i st{llet f|r FILENAME_MAX. * #include "smalloc.h" heter nu #include Sat Aug 24 17:36:43 1991 Per Cederqvist (ceder at lysator) * simple-cache.c: Anv{nde FILENAME_MAX i st{llet f|r 1024. * limits.h (MAX_TEXT) |kade till 200003. Wed Aug 14 02:11:17 1991 Per Cederqvist (ceder at lysator) * Makefile(LIBS): La till -lresolv. * config.c(WHITESPACE): La till \r. Det g}r inte att koppla upp en telnet till server version 0.31.6. Sat May 18 04:22:06 1991 Per Cederqvist (ceder at nanny) * Installerade och startade diskomd 0.29.1. * Div. bugfixar i diskomd och simple-cache.c. Fri May 17 06:00:00 1991 Per Cederqvist (ceder at nanny) * Installerade diskomd 0.29 som ramkomd. Wed May 8 04:43:50 1991 Thomas Bellman (Bellman@nanny) * conference.c (set_super_conf): Fixed bug that made it impossible to set the super-conf to zero. Mon May 6 09:34:00 1991 Per Cederqvist (ceder at nanny) * Anv{nder funktionerna i memory.h s} l}ng m|jligt i st{llet f|r smalloc/sfree. * Nu har servern tv} kopior av namnet p} varje m|te. Dels en som alltid ligger i minnet (name_list i ramkomd, small_conf_arr i diskomd), dels en som bara {r inladdad ibland (i diskomd), conf_arr. Fri May 3 14:49:19 1991 Per Cederqvist (ceder at nanny) * 0.28 installerad. * Anv{nder traverse_connections |verallt d{r man g}r igenom alla uppkopplingar. * Ny fil: internal-connections.[hc] (i brist p} b{ttre namn). Inneh}ller new_client(), kill_client(), get_conn_by_number() och traverse_connections(). I forts{ttningen skall man inte anv{nda sig av f{ltet (Connection *)->next, utan i st{llet anv{nda traverse_connections() och get_conn_by_number(). * Nytt anrop: who_am_i som ger en Session_no. Thu May 2 17:24:50 1991 Per Cederqvist (ceder at nanny) * St{ngde av TIME_SYNC i ram-cache.c. Nu kanske n}gon orkar l{sa log-filerna igen... * Nu kollas flaggan kill_me i Connection i _alla_ uppkopplingar efter varje anrop, s} nu b|r disconnect fungera. Mon Apr 29 19:02:12 1991 Per Cederqvist (ceder at nanny) * Namnbyte i Who_info och Connection: session resp. client_no heter numera session_no. * Ett nytt asynkront meddelande: logout. (Pers_no & Session_no). * Tv} nya anrop: get_session_info och disconnect. Mon Apr 22 14:32:19 1991 Per Cederqvist (ceder at nanny) * version 0.27.2 installerad. * Nu skickas sessionsnummer med n{r man g|r 'pepsi' och 'change_what_i_am_doing'. Sat Apr 6 11:47:47 1991 Per Cederqvist (ceder at nanny) * version 0.27.1 installerad. Sun Mar 24 18:49:56 1991 Per Cederqvist (ceder at nanny) * parser.c: lookup_name(): Nu tas alla '-' bort - |kad QZ-kom-kompatibilitet! F|r tillf{llet g|rs det bara om SERVER {r definierad (f|r att inte riskera att f|rst|ra kod i klienten). Tue Mar 19 20:27:45 1991 Peter Eriksson (pen at nanny) * connections.c: logout_client() om CONN_MAGIC_FREE, skriver nu i logfilen, och g|r return omeddelbart - snabbfix f|r att servern inte ska krascha s} ofta.. * version 0.26 installerad Mon Mar 18 11:28:46 1991 Peter Eriksson (pen at nanny) * config.c: DEFAULT_CLIENT_SERVICE_NAME = lyskom-client IN_CLIENT_PORT = 4896 * version 0.24 installerad Mon Mar 18 09:12:59 1991 Peter Eriksson (pen at nanny) * connections.c: mux_handle_packet(): mux->parse.string nollst{lls nu efter att den har tilldelats till cp->hostname... * version 0.23 installerad Mon Mar 18 01:56:50 1991 Per Cederqvist (ceder at nanny) * send_message: ny funktion och asynkront meddelande. Ers{tter broadcast. Broadcast finns kvar f|r bak}tkompatibilitet. Sun Mar 17 23:49:28 1991 Per Cederqvist (ceder at nanny) * mux.c: mux_flush(): om uppkopplingen var av typ MUX_TYPE_CLIENT s} gjordes inte isc_flush. Sun Mar 17 03:50:23 1991 Peter Eriksson (pen at nanny) * connections.c: logout_client(), snabb fix f|r ett problem som medf|rde att mux_close() anropas tv} g}nger n}nstans (tror jag), och cp->mux var d} NULL andra g}ngen... * Version 0.21 installerad Sat Mar 16 00:03:29 1991 Per Cederqvist (ceder at nanny) * Simpelt mux-protokoll implementerat. * change_name(): Nu kan man byta namn fr}n "foo" till "foo". * Version 0.20 installerad Tue Mar 12 02:16:12 1991 Peter Eriksson (pen at nanny) * server version 0.19 installerad.... BUG fixad i ISCLIB som har medf|rt att en buffert vart |verskriven... * server version 0.18 installerad. (magiska nummer inf|rda {ven i Connection och Mux strukturerna) Mon Mar 11 21:23:02 1991 Peter Eriksson (pen at nanny) * ram-smalloc.c/smalloc.c: Magiskt nummer inf|rt... Mon Mar 11 19:49:10 1991 Per Cederqvist (ceder at nanny) * dbck anpassat till nya formatet. "dbck -g" garbar i text-filen. Mon Mar 11 01:48:34 1991 Peter Eriksson (pen at nanny) * 0.17 installerad och ig}ngsatt. Sun Mar 10 21:23:50 1991 Peter Eriksson (pen at nanny) * connections.c: bugfix i new_client():setup av all_conn...-listan Sat Mar 9 15:25:09 1991 Peter Eriksson (pen at nanny) * Buffring av meddelanden g|rs nu i Mux-rutinerna. Sat Mar 9 05:52:34 1991 Per Cederqvist (ceder at nanny) * 0.16 installerad och ig}ngsatt. Sat Mar 9 03:25:25 1991 Peter Eriksson (pen at nanny) * Allt f{rdigt f|r MUX-hantering. Nu fattas bara ett riktigt protokoll, samt buffring av utdata i Mux_client strukturen. Major rewrite av det mesta som hade med isc_ att g|ra. Thu Mar 7 03:16:00 1991 Peter Eriksson (pen at nanny) * Nu g}r servern genom kompilatorn, med allt fixat till ISC. Jag har dock inte provk|rt... Wed Mar 6 23:08:16 1991 Per Cederqvist (ceder at nanny) * P} grund av Isc-ombyggnaden har jag inte kunnat provk|ra. * prot-a.c: prot_a_parse_packet(): Om man skrev n}got som matchade regexpen "A[ \t\n]*\([0-9]+\)[^H].*" n{r man loggade in s} sattes username till "\1H\{\}\1". * text.c: get_text(): Nu kan man (troligtvis) h{mta en "tom" text utan att f} felet KOM_INDEX_OUT_OF_RANGE. Tue Mar 5 19:17:50 1991 Per Cederqvist (ceder at nanny) * ram-smalloc.c: rewrote tmp_alloc and free_tmp. Reason: a spurios "rm ram-smalloc.c"... Sun Mar 3 22:16:34 1991 Per Cederqvist (ceder at nanny) * isc-serverinfo.[hc]: Uppsnyggad. Anv{nder inte l{ngre n}got som {r lyskom-specifikt. F|ljd{ndringar i connections.c, dit en del saker blev flyttade. Inge hj{lpte mig v{lja vad som skulle bort. * N{r n}gon f|rs|ker logga in, men servern {r full, sker nu f|ljande: * Den som kopplar upp f}r texten "%% No connections left.\n". * Alla andra f}r det asynkrona meddelandet 11 (ay_rejected_connection) (inga argument). Sat Mar 2 18:47:37 1991 Per Cederqvist (ceder at nanny) * i_am_on_obsolete skickas inte l{ngre. * broadcast tar nu en str{ng, inte ett textnummer. Skrev broadcast och funktioner f|r det asynkrona meddelandet broadcast. Sat Mar 2 01:13:29 1991 Lars Willf|r (willfor at nanny) * Fixade en bug i set_permitted_submitters som gjorde att man inte kunde s{tta till}tna inl{ggsskrivare till 0 (vem som helst). Tue Feb 19 00:52:03 1991 Per Cederqvist (ceder at nanny) * Bytte versionsnummer till 0.13. * conference.c: set_etc_motd(): Ett |verfl|digt semikolon gjorde att det inte gick att s{tta etc_motd. Sun Feb 17 06:44:46 1991 Thomas Bellman (bellman at nanny) * isc-server.c: isc_flush(): Provar att stoppa redan n{r man n}tt upp till maxgr{nsen MAXQUEUEDSIZE, och inte v{nta tills man |verskrider den. Fri Feb 15 23:39:46 1991 Per Cederqvist (ceder at nanny) * De tv} {ndringarna nedan fungerade inte, s} jag }terst{llde allt. * Om /etc/nologin existerar skickar servern str{ngen "%% No logins allowed." vid uppkoppling. Om fildeskriptorerna {r slut skickas str{ngen "%% No connections left." * isc_getnextevent(): Nu returneras en ny uppkoppling {ven i fallet ISC_EVENT_REJECT. Anroparen m}ste nu anropa isc_logoutclient p} en s}dan uppkoppling innan isc_getnextevent anropas n{sta g}ng. Sun Feb 10 10:04:24 1991 Per Cederqvist (ceder at nanny) * convert.c och convert-cache.c konverterade databasen. Filerna f}r vara kvar ett tag till, tills vi ser att allt verkligen fungerar. * Inge och jag skrev om ram-cache.c, ram-output.c och ram-parse.c. Nu sparas textmassan i en s{rskild fil. Dessutom sparas klockslag som time_t, inte som struct tm. Dessa tv} }tg{rder ledde till _stora_ hastighetsvinster - ca en faktor 2. [ndringar i cached_delete_text(), cached_get_text(), cached_create_text(), init_cache(), fparse_text_stat(), foutput_text_stat(), foutput_time() och fparse_time(). * server/ram-output2.c heter numera server/ram-output.c * server/services.h heter numera server/internal-services.h (include/services.h {r of|r{ndrad). Fri Feb 8 20:24:59 1991 Per Cederqvist (ceder at nanny) * cache.h: Ny funktion: cached_conf_exist(Conf_no). * cache.h: cached_get_name anv{nds inte! Det {r nu borttaget. Tue Feb 5 21:17:42 1991 Per Cederqvist (ceder at nanny) * Info om hur l}ng tid de olika delarna av synkningen tog lagras om TIME_SYNC {r definierad i ram-cache.c. * Nu kan man l{sa motd_of_lyskom {ven om man inte {r inloggad. Tue Feb 5 02:58:34 1991 Peter Eriksson (pen at nanny) * isc-server.c/iscserver.h: Max queue size implementerad. Statistik / client lagras i Isc_clientinfo. Tue Feb 5 00:51:44 1991 Per Cederqvist (ceder at nanny) * db/ramkomd-logg flyttad till etc/ramkomd-logg. * etc/pid: process-id skrivs i denna fil. Fri Feb 1 23:19:04 1991 Per Cederqvist (ceder at nanny) * 0.10 installerad och startad. * get_map fungerade inte om man f|rs|kte h{mta en delmap d{r alla texter man ville ha var raderaded. 90-120 == 547689541. (unsigned). R{ttat, men fr}gan {r hur m}nga liknande buggar det finns... Tue Jan 22 10:14:28 1991 Lars Willf|r (willfor at nanny) * [ndrade lite #include-rader s} att make depend ska fungera. Kommenterade bort '#include "CloseFileDescriptors"' ur logII.c. Fri Jan 18 10:33:58 1991 Per Cederqvist (ceder at nanny) * Nytt asynkront meddelande: ay_login. S{nds n{r n}gon loggar in. Nu s{nds inte ay_i_am_on n{r man loggar in l{ngre. Thu Jan 17 14:43:14 1991 Per Cederqvist (ceder at nanny) * 0.09 installerad. * ram-cache.c: Om TIME_SYNC {r definierad loggas information om hur l}ng tid varje syncning tar. * Inge:s funktioner f|r att spara databasen n{stan dubbelt s} snabbt som vanligt testade och inlagda. Mon Jan 14 11:45:26 1991 Per Cederqvist (ceder at nanny) * forced_leave_conf(): Ny funktion som anropas n{r n}gon uttr{der ur ett m|te (av n}gon orsak). Den skickar ett asynkront meddelande till alla uppkopplingar d{r personen i fr}ga {r inloggad och ber{ttar att han inte l{ngre {r med i m|tet. Det asynkrona meddelandet heter "ay_leave_conf". Sun Jan 13 20:26:29 1991 Inge Wallin (inge at nanny) * Stoppat ner filerna ../*.h i det nyskapade directoryt ../include samt fixat samtliga h- och c-filer i serverdirectoryt att inkludera i st{llet f|r "../foo.h". Dessutom lagt till -I../include i Makefile. Sun Jan 13 11:27:31 1991 Per Cederqvist (ceder at nanny) * membership.c: get_memberhip(): Om n}gon f|rs|ker h{mta en medlemsskapslista f|r en person den {r organisat|r f|r utan att h{mta de l{sta texterna s} s{tts read_texts till NULL. Bug! Fixat. * do_delete_text(): L{nken fr}n f|rfattaren till texten (created_texts) s{tts till noll n{r texten tas bort. Fri Jan 11 13:37:00 1991 Per Cederqvist (ceder at nanny) * create_text(): Nu kan en text inte vara kommentar/fotnot till samma text mer {n en g}ng. Thu Jan 10 21:42:16 1991 Thomas Bellman (bellman at nanny) * connections.c: call_function(): Variabeln 'status' tilldelades v{rdet FALSE, fast den var av typen Success. Thu Jan 10 20:40:46 1991 Peter Eriksson (pen at nanny) * Added feature: rwhod support. (rwhod.c / connections.c) Thu Jan 10 12:40:33 1991 Per Cederqvist (ceder at nanny) * ram-output.c: foutput_membership() och ram-parse.c: fparse_membership(): Om no_of_read != 0 och read_texts == NULL s} s{tts no_of_read till 0 och ett meddelande loggas. * ram-parse.c: fparse_person(): en liten minnesl{cka tillt{ppt. L|senordet lagrades dubbelt i servern. Eftersom fparse_person bara anv{nds vid uppstart s} p}verkas inte storleken s} mycket... Wed Jan 9 16:53:56 1991 Per Cederqvist (ceder at nanny) * mark_as_read(): adjust_read anropas alltid. F|rut kunde det h{nda att read_texts blev o{ndlig om en text raderades innan man l{ste den. Nu ska det inte bli s}. (Men det finns fortfarande minst en bugg kvar n}gonstans i mark_as_read). Mon Jan 7 11:00:37 1991 Per Cederqvist (ceder at nanny) * mark_as_read(): Nu protesterar servern om man f|rs|ker markera en text med lokalt nummer 0. Mon Jan 7 09:05:24 1991 Peter Eriksson (pen at nanny) * connections.c&isc-server.c: ISC_EVENT_REJECT Sun Jan 6 16:13:49 1991 Per Cederqvist (ceder at nanny) * text-garb.c: garb_text() loggar nu hur m}nga texter den har tagit bort efter varje runda. Sun Jan 6 16:20:59 1991 Peter Eriksson (pen at nanny) * missing-ansi.c: skapade 'strerror()' connections.c: {ndrade i toploop() s} fel skrivs ut som text ist{llet f|r som siffror. isc-server.c: ditto i isc_flush(). Sat Jan 5 16:20:04 1991 Peter Eriksson (pen at nanny) * connections.c: fexists(): nollst{llning av 'errno'. skriv ut event->msg om den {r satt vid ISC_EVENT_ERROR. isc-server.c: isc_getnextevent(): s{tt isc_ei->msg till en beskrivande text vid ISC_EVENT_ERROR. Sat Jan 5 04:13:01 1991 Per Cederqvist (ceder at nanny) * La in en close i isc_logoutclient. Nu ska v{l f|rbindelserna kopplas ner ordentligt, hoppas jag. Fri Jan 4 21:14:36 1991 Per Cederqvist (ceder at nanny) * Version 0.07 tagen i drift. Fri Jan 4 20:13:40 1991 Peter Eriksson (pen at nanny) * isc-server.c: non-blocking writes och transmit queue funkar nu. Fri Jan 4 12:02:03 1991 Per Cederqvist (ceder at nanny) * create_text returnerar numera KOM_ILL_MISC om man f|rs|ker med samma mottagare mer {n en g}ng. * add_recipient klarar nu {ven av att addera en cc_recpt. Fri Jan 4 11:57:48 1991 Peter Eriksson (pen at nanny) * printf.c: Ansifikation... isc-server.c: isc_printf(), isc_putc(), isc_write() & isc_flush() anv{nder nu alla en per-klient s{ndbuffer. Dock anv{nds blocking-writes fortfarande... prot-a-*.c & ram-*.c: Anv{nder nu isc-rutinerna f|r utmatning ist{llet f|r stdio. Sun Dec 16 21:55:19 1990 Thomas Bellman (bellman at nanny) * services.c: pepsi(), change_what_i_am_doing(): Man b|r nog s{tta alla f{lt till n}got vettigt i infostrukturen som man skickar till async_i_am_on()... Speciellt str{ngar som anv{ndarnamnet. Sat Dec 15 11:04:45 1990 Per Cederqvist (ceder at nanny) * prot-a-send-async.c, async.h: i_am_on skall naturligtvis skicka en hel Who_info. Nu g|rs det. F|r att inte elisp-klienten skall sluta fungera har numera i_am_on nummer 6. Gamla i_am_on, nummer 2, finns fortfarande kvar, men kommer att tas bort om n}gon m}nad eller s} n{r alla elisp-klienter som anv{nder gamla i_am_on har f|rsvunnit. Fri Dec 14 22:15:11 1990 Per Cederqvist (ceder at nanny) * send-async.c: Nu t}l servern att det finns klienter som inte har hunnit ber{tta vilket protokoll de anv{nder. Denna bugg har orsakat ett antal omstarter... Mon Dec 10 05:32:01 1990 Thomas Bellman (bellman at nanny) * ramkomdc: chdir() till /usr/lyskom/etc innan man dumpar core. Kommer antagligen inte att funka... Mon Dec 10 05:31:33 1990 Peter Eriksson (pen at nanny) * isc-server.c: non-blocking writes. (FNDELAY). Wed Dec 5 17:44:27 1990 Per Cederqvist (ceder at nanny) * ram-cache.c: {ndrade konstanten MAX_TEXT fr}n 9999 till 15000. R{ttade en bugg i cached_create_text(). F|rut s} kollade den om next_text_num var == MAX_TEXT, och sa i s} fall ifr}n, MEN r{knade upp next_text_num. Text nummer (MAX_TEXT+1) kunde allts} skapas... Sun Dec 2 18:06:01 1990 Per Cederqvist (ceder at nanny) * ram-output.c: foutput_time() ram-parse.c: fparse_time() Tidpunkter sparas numera i GMT. P} s} s{tt slipper man ta reda p} vilken tidszon man k|r i. Thu Nov 29 14:43:27 1990 Per Cederqvist (ceder at nanny) * Jag {ndrade i typen Isc_clientinfo och tog bort en hel del som jag i st{llet la i Connection (som jag skapade). Protokoll A isolerat till typen Prot_a. Nu tror jag att allt som {r protokoll-specifikt {r isolerat, s} l}ngt det g}r. Arbetet med att implementera protokoll B b|rjar nu... Wed Nov 28 07:57:48 1990 Per Cederqvist (ceder at nanny) * [ven f|r de asynkrona meddelandena {r nu protokoll A isolerat. Tue Nov 27 14:39:12 1990 Peter Eriksson (pen at nanny) * kill -USR2 g|r fork()&abort() s} man kan f} ut en core av en exekverande server utan att d|da den. * ramkomd.c - sighandler_quit - exit(1) -> abort(). Mon Nov 26 21:15:13 1990 Per Cederqvist (ceder at nanny) * Isc_clientinfo-structuren har ett nytt f{lt: u_char protocol. * F|rberedde f|r protokoll B genom att isolera protokoll A. Nu ligger allt protkoll-A-specifikt i filerna prot-a-output.[hc], prot-a-parse-arg-[hc].awk, prot-a-parse.[hc] och prot-a.[hc]. Observera dock att jag inte {r helt klar {n: jag har inte gjort n}got }t asynkrona meddelanden. Sun Nov 25 14:17:47 1990 Peter Eriksson (pen at nanny) * isc-cache.c&prot-a-output.c: fflush()+write(fileno()) -> fwrite(). Borde snabba upp lite. Sun Nov 25 03:08:24 1990 Per Cederqvist (ceder at nanny) * services.c: mark_text(): Nu g}r det att markera texter! [ndringar i manipulate.c:text_read_access - man f}r alltid l{sa texter som man har markerat. Dessutom n}gra nya funktioner i manipulate.c f|r att hantera markeringar. * services.c: set_conf_type(): Det {r inte till}tet att ha ett m|te/en person som {r secret men inte rd_prot. Sat Nov 24 14:19:53 1990 Per Cederqvist (ceder at nanny) * kom_get_unread_confs ger vilka m|ten en viss person har ol{sta inl{gg i. Sat Nov 24 09:33:32 1990 Peter Eriksson (pen at nanny) * MAX_NO_CONNECTIONS satt till 14 om __sequent__. [14(max_no_clients)+1(portnum)+3(stdio)+1(databas)+1(reject)] * Nya kommandoradsoptioner: -D{databas-path}, -p{portnum}. * DATAFILE, BACKUPFILE -> datafile, backupfile (variabla pga support av olika databasdir). Thu Nov 22 08:06:06 1990 Peter Eriksson (pen at nanny) * Hackade in -SIGUSR1/-SIGHUP/-SIGQUIT (sync, sync&die, sync&die-fast) * MAX_NO_OF_CONNECTIONS - funktionalitet * Check av /etc/nologin f|r utesp{rr av anv{ndare Wed Nov 21 10:16:28 1990 Per Cederqvist (ceder at nanny) * end-of-atomic: Nu anropas garb-text() om servern {r idle. * ram-cache.c: traverse_text och cached_get_garb_nice skrivna. * isc-server.c: Nu anv{nds SO_DONTLINGER, SO_REUSEADDR och SO_KEEPALIVE p} socketen. * MAX_NO_OF_CONNECTIONS {r 15 om __sequent__ {r definierat, annars 32. * config.c: USERNAME_LEN {ndard fr}n 32 till 128 f|r att f} plats med ett maskinnamn ocks}. * Makefile: /bin/sed fattar inte heller \{n\}, precis som GNU-sed, s} jag skrev om Makefilen utan den. Sun Nov 11 15:36:51 1990 Per Cederqvist (ceder at nanny) * cached_set_garb_nice och cached_get_garb_nice. Fri Nov 9 14:58:54 1990 Per Cederqvist (ceder at nanny) * server/cache.c och server/flurp.c (vad {r det?): '#include "../ldb/ldb.h"' bortkommenterat f|r att kunna g|ra make depend. * Makefilen: -L bortkommenterad fr}n LIBS. Fri Nov 2 00:55:32 1990 Peter Eriksson (pen at lave) * isc_server.c: isc_gethostname() - fixade s} att den returnerade IP-nummret (som en String) som de ska enligt specen... Thu Nov 1 01:38:44 1990 Per Cederqvist (ceder at lave) * manipulate.c: do_sub_comment() och do_sub_foootnote klarade inte av att f} NULL som text-status. Det fick dom fr}n do_delete_text... * manipulate.c: do_sub_recpt(): om conf_c var NULL s} gick det }t skogen. Om conf_no inte existerade gick det }t samma h}ll. Sat Oct 20 14:35:59 1990 Per Cederqvist (ceder at lave) * Efter ett gott r}d fr}n Lars Aronsson s} har jag lagt till funktionerna get_person_stat_old, get_conf_stat_old och who_is_on_old. De har samma nummer som de gamla get_person_stat et c. P} s} s{tt {r den nya servern kompatibel med gamla klienter. * Who_info inneh}ller nu tv} nya f{lt: connection, som {r ett l|pnummer som r{knas upp med ett f|r varje ny connection till klienten, och username, som {r userid@host f|r just den h{r uppkopplingen. (Om personen samtidigt {r inloggad fr}n en annan maskin kan man inte se det med Who_info_old). * get_person_stat och get_conf_stat skall numera inte ha n}gon mask. De skickar alltid med namnet. Fri Oct 19 20:42:32 1990 Per Cederqvist (ceder at lave) * L{nkning sker nu med -lresolv, s} att servern fr}gar nameservers om namnet p} maskiner n{r den bara lyckas f} ip-nummret. Sun Oct 14 05:00:23 1990 Per Cederqvist (ceder at lave) * isc-server.c: isc_readmsg(): Det inl{sta meddelandet avslutades med ett '\0', som aldrig anv{nds i servern. Det {r ju i och f|r sig inte s} farligt, men problemet var att nollan lades utanf|r det allokerade utrymmet om det kom f|r mycket data p} en g}ng... Nu l{ggs aldrig n}gon '\0':a in. Thu Sep 13 20:38:22 1990 Per Cederqvist (ceder at laila) * isc-output.c: output_conference(): [ven conf-type |verf|rs nu. Det var aldrig meningen att ta bort den... Sat Sep 1 01:22:53 1990 Per Cederqvist (ceder at lave) * Nu fungerar {ndringarna, i alla fall delvis. Tue Aug 28 14:08:33 1990 Per Cederqvist (ceder at lave) * [ndringen av formaten f|r Text_status och tider ska vara klara nu. Sun Aug 26 16:23:40 1990 Per Cederqvist (ceder at lage) * P}b|rjade {ndring av formatet f|r |verf|ring av Text_status. I forts{ttningen kommer {ven no_of_chars att |verf|ras. * P}b|rjade {ndring av formatet f|r en time_t. I forts{ttningen kommer alla klockslag att |verf|ras som en struct tm. Serverns lokala tid kommer att |verf|ras. Just nu {r {ndringen genomf|rd p} n}gra, men inte alla st{llen. Tue Aug 21 19:46:50 1990 Per Cederqvist (ceder at lave) * get_text() tar nu h{nsyn till first_char och end_char. * get_members() testad. * Tog bort Template f|r att f|rhindra att n}gon {ndrar i den av misstag. Sun Aug 12 17:17:44 1990 Per Cederqvist (ceder at lave) * get_members() tittar ox}, men den {r inte testad. T}get g}r snart, och jag vill hinna {ta middag f|rst... Vi ses om 14 dar! * get_created_texts() tittar p} 'first' och 'len'. * En hel massa sm}buggar, bl a i mark_as_read(), r{ttade. * get_created_texts() och get_members() skrivna. Dom tittar _inte_ p} 'first' och 'no_of_*' {n. * get_membership() tittar nu p} 'first' och 'no_of_confs'. Sat Aug 11 02:13:15 1990 Per Cederqvist (ceder at lave) * services.c: create_text(): Det {r nu till}tet att ha ett loc_no som misc_item. Det ignoreras, oberoende av var det tr{ffas p}. Thu Aug 9 05:13:44 1990 Thomas Bellman (bellman at laila) * Make depend utg}r fr}n Makefile och inte fr}n Template. Man kan allts} {ndra direkt i Makefile. * get_membership() skriven, men gl|mmer titta p} parametrarna 'first' och 'no_of_confs'. Det {r inte testat heller... Sat Aug 4 01:41:41 1990 Thomas Bellman (bellman at lave) * manipulate.c: text_read_access(): Nu kan man inte l{sa texter utan att vara inloggad. ]t minstone enligt k{llkoden. Den server som k|r har fortfarande det gapande s{kerhetsh}let. Tue Jul 24 04:40:32 1990 Per Cederqvist (ceder at lave) * F|rb{ttrad felhantering n{r f|r l}nga str{ngar kommer till servern. Nu trunkerar isc-parse.c str{ngen till den maximala l{nged +1 och l}ter services.c uppt{cka att str{ngen {r f|r l}ng och protestera. F|rut skrev isc-parse.c '%% LysKOM protocol error.' och det var nog lite v{l h}rt... Mon Jul 23 23:44:49 1990 Per Cederqvist (ceder at lave) * En b{ttre version av unique_name(), som inte alltid svara TRUE, {r implementerad. * Asynkrona meddelanden {r implementerade. Fri Jul 13 00:11:48 1990 Per Cederqvist (ceder at lave) * services.h kan inte sl{ngas l{ngre. Fast nuf|rtiden s} {r den ganska liten... Wed Jun 27 07:42:59 1990 Thomas Bellman (bellman at lave) * services.h kan sl{ngas. Filen har ersatts av kom:/services.h, som numera kan anv{ndas b}de i serverdelen och klientdelen. Filerna 'services.c' och 'manipulate.c' {r {ndrade till att inkludera "../services.h" i st{llet. Flaggan SERVER definieras i Makefilen. Wed Jun 6 04:31:02 1990 Per Cederqvist (ceder at laila) * end-of-atomic.[hc]: Funktion som skall anropas efter varje atomiskt anrop. Wed May 30 18:47:42 1990 Linus Tolke (linus at lave) * cache.c rivet lite (cached_create_person, mark_conferens_as_changed.) * cache.[hc] {ndrade i definitionen av cached_lookup_name s} att den skall st{mma med -----------------------------------------\ dvs char * -> String | | Fri May 25 07:32:18 1990 Per Cederqvist (ceder at lave) | | * manipulate.[hc]: Ny fil som inneh}ller hj{lpfunktioner till | services.c. Skall endast anv{ndas av services.c. | | * log.[hc]: Funktioner f|r att skriva till log-fil. | | Wed May 23 18:30:26 1990 Per Cederqvist (ceder at lave) | | * cache.[hc], services.[hc]: Nu anv{nds String |verallt, och <--/ char * inte alls. Det {r nog mycket i cache.[hc] som inte funkar l{ngre... Tue May 22 22:01:19 1990 Per Cederqvist (ceder at laila) * 2kom/server/services.h skapad. H{r ligger saker som t ex cachen m}ste komma }t, men som klienterna inte ska komma }t. Det som bara klienterna ska komma }t ligger fortfarande i 2kom/services.h Wed May 9 21:25:13 1990 Linus Tolke (linus at laila) * Rev infinitesimalt i cache.[hc]. mark_person_as changed fungerar kanske. Tue May 8 23:19:37 1990 Per Cederqvist (ceder at lage) * Slog ihop cache.[ch] och unprot.[ch] till cache.[ch]. unprot.[ch] finns kvar ett tag till, men inneh}ller bara skr{p. Mon May 7 16:23:28 1990 Per Cederqvist (ceder at lage) * server.[hc] heter numera lyskomd.[hc] i god UNIX-anda. Sat May 5 20:53:21 1990 Per Cederqvist (ceder at lave) * unprot.[hc]: Tog bort en massa funktionsstubbar som aldrig kommer att avn{ndas. S}g till att .h och .c inneh}ller samma funktioner. unprot.c g}r nu igenom kompilatorn! Thu May 3 18:54:46 1990 Per Cederqvist (ceder at lage) * unprot.c: Jag skriver in en kommentar "/****/" f|re de funktioner som jag verkligen anv{nder. Tue Apr 24 03:34:14 1990 Per Cederqvist (ceder at lage) * smalloc.[hc]: Ny fkn srealloc. * server.h: Nytt f{lt i Connection: Person * person. Sat Apr 21 13:22:26 1990 Per Cederqvist (ceder at lave) * Ny Makefile, som regenerar sig sj{lv automagiskt. (make depend) * server.h: La till f{ltet ena_level i typen Connection. Wed Apr 18 01:35:49 1990 Per Cederqvist (ceder at lage) * services.c: get_marks har nu ingen parameter. Man kan bara titta p} sina egna markeringar. * unprot.c: Tog bort unprot_change_what_i_am_doing * Flyttade minneshanteringen till smalloc.c * cache.c: La till ett anrop: get_name. Tue Apr 17 23:54:52 1990 Per Cederqvist (ceder at lage) * services.{ch}: {ndrade anropet av create_text lyskom-server-2.1.2/src/server/Magics0000664000015100472110000000030205016043141013225 SMALLOC: alloc = 0x12FE56A0 free = 0xCA348E63 Connection: alloc = 0x18F4AE74 free = 0x67A7B144 Mux: alloc = 0x56AE17DB free = 0xF24A6BE7 ISC: alloc = 0x12F54ACE free = 0xEE47A37F lyskom-server-2.1.2/src/server/call-switch.awk0000664000015100472110000000615207721716126015045 # # $Id: call-switch.awk,v 0.24 2003/08/23 16:38:18 ceder Exp $ # Copyright (C) 1991, 1993-1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # $Id: call-switch.awk,v 0.24 2003/08/23 16:38:18 ceder Exp $ BEGIN { printf("/* Don't edit this file - it is generated automatically"); printf(" from\n call-switch.awk and fncdef.txt */\n"); printf("\tswitch(client->function)\n\t{\n"); } $1 == "#ifdef" { printf("#ifdef %s\n", $2); next; } $1 == "#endif" { printf("#endif\n"); next; } $1 != "#" && $1 != "" { printf("\tcase call_fnc_%s:\n\t ", $3); if ( $2 == "success" ) printf("status = %s(", $3); else printf("res->number = %s(", $3); num=0; string=0; c_string=0; for ( i = 4; i <= NF; i++) { if ( i != 4 ) printf(", "); if ( $i == ":" ) { printf("&res->%s", $(i+1)); break; } if ( $i == "num" ) printf("client->num%d", num++); else if ( $i == "string" ) printf("client->string%d", string++); else if ( $i == "c_string" ) printf("client->c_string%d", c_string++); else if ( $i == "priv_bits" ) printf("client->priv_bits"); else if ( $i == "conf_type" ) printf("client->conf_type"); else if ( $i == "membership_type" ) printf("&client->membership_type"); else if ( $i == "aux_item_list") printf("&client->aux_item_list"); else if ( $i == "misc_info_list") printf("&client->misc_info_list"); else if ( $i == "time_date" ) printf("&client->time"); else if ( $i == "info" ) printf("&client->info"); else if ( $i == "num_list" ) printf("&client->num_list" ); else if ( $i == "pers_flags" ) printf("client->pers_flags"); else if ( $i == "read_range_list" ) printf("&client->read_range_list"); else printf("\n#error in file server/fncdef.txt\n"); } printf(");\n"); if ( $2 == "number" ) { if ( $3 == "get_time" ) printf("\t status = OK;\n"); else printf("\t status = (res->number != 0) ? OK : FAILURE;\n"); } printf("\t break;\n\n"); } END { printf("\tcase illegal_fnc:\n"); print("\t restart_kom(\"unreachable code reached -- illegal_fnc\");"); printf("\t break;\n"); printf("\t}\n"); } lyskom-server-2.1.2/src/server/com-h.awk0000664000015100472110000000302207721716126013627 # # $Id: com-h.awk,v 0.13 2003/08/23 16:38:18 ceder Exp $ # Copyright (C) 1991, 1996, 1999, 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # $Id: com-h.awk,v 0.13 2003/08/23 16:38:18 ceder Exp $ BEGIN { printf("/*\n"); printf(" * Don't edit this file! It is generated from fncdef.txt\n"); printf(" * and com-h.awk.\n"); printf(" */\n\n"); printf("enum call_header {"); cnt = 0; } $1 == "#ifdef" { printf("\n#ifdef %s", $2); next; } $1 == "#endif" { printf("\n#endif"); next; } $1 == "#" || $1 == "" { next; } { cnt++ printf("\n call_fnc_%-20s = %d,", $3, $1); } END { printf("\n illegal_fnc = %d", -1) printf("\n};\n\n"); } lyskom-server-2.1.2/src/server/fnc-def-init.awk0000664000015100472110000000317607721716126015101 # # $Id: fnc-def-init.awk,v 0.12 2003/08/23 16:38:17 ceder Exp $ # Copyright (C) 1991, 1996, 1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # $Id: fnc-def-init.awk,v 0.12 2003/08/23 16:38:17 ceder Exp $ BEGIN { printf("/* Don't edit this file - it is generated automatically"); printf(" from\n fnc-def-init.awk and fncdef.txt */\n\n"); m = 0; } $1 == "#ifdef" { printf("#ifdef %s\n", $2); next; } $1 == "#endif" { printf("#endif\n"); next; } $1 != "#" && $1 != "" { if (m < $1) m = $1; printf(" { "); printf("%s, ", $1); if ( $(NF-1) == ":" ) printf("%7s, ", "rt_" $NF); else printf("%7s, ", "rt_" $2); printf("prot_a_parse_arg_%s },\n", $3); } END { printf(" { %d, rt_success, prot_a_hunt_nl }\n", m + 1); } lyskom-server-2.1.2/src/server/prot-a-parse-arg-c.awk0000664000015100472110000001316407721716127016136 # # $Id: prot-a-parse-arg-c.awk,v 0.31 2003/08/23 16:38:15 ceder Exp $ # Copyright (C) 1991-1994, 1996-1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # $Id: prot-a-parse-arg-c.awk,v 0.31 2003/08/23 16:38:15 ceder Exp $ BEGIN { printf("/* Don't edit this file - it is generated automatically"); printf(" from\n prot-a-parse-arg-c.awk and fncdef.txt */\n\n"); printf("#ifdef HAVE_CONFIG_H\n"); printf("# include \n"); printf("#endif\n"); printf("#include \n"); printf("#include \n"); printf("#include \n"); printf("#include \n"); printf("#include \"timewrap.h\"\n"); printf("\n"); printf("#include \"oop.h\"\n"); printf("\n"); printf("#include \"s-string.h\"\n"); printf("#include \"kom-types.h\"\n"); printf("#include \"com.h\"\n"); printf("#include \"isc-interface.h\"\n"); printf("#include \"async.h\"\n"); printf("#include \"connections.h\"\n"); printf("#include \"isc-parse.h\"\n"); printf("#include \"server/smalloc.h\"\n"); printf("#include \"prot-a.h\"\n"); printf("#include \"prot-a-parse.h\"\n"); printf("#include \"prot-a-parse-arg.h\"\n"); printf("#include \"kom-config.h\"\n"); printf("#include \"param.h\"\n\n"); } $1 == "#ifdef" { printf("#ifdef %s\n", $2); next; } $1 == "#endif" { printf("#endif\n"); next; } $1 != "#" && $1 != "" { printf("void\nprot_a_parse_arg_%s(Connection *client)\n{\n", $3); printf(" switch( client->fnc_parse_pos )\n"); printf(" {\n"); num=0; pos=0; string=0; c_string=0; for ( i = 4; i <= NF; i++) { if ( $i == ":" ) break; printf(" case %d:\n", pos); if ( $i == "num" ) printf("\tclient->num%d = prot_a_parse_long(client);\n", num++); else if ( $i == "c_string" ) printf("\tprot_a_parse_string(client, &client->c_string%d, %s);\n",\ c_string++, $(++i)); else if ( $i == "string" ) printf("\tprot_a_parse_string(client, &client->string%d, %s);\n",\ string++, $(++i)); else if ( $i == "priv_bits" ) printf("\tprot_a_parse_priv_bits(client, &client->priv_bits);\n"); else if ( $i == "conf_type" ) printf("\tprot_a_parse_conf_type(client, &client->conf_type);\n"); else if ( $i == "membership_type" ) printf("\tprot_a_parse_membership_type(client, &client->membership_type);\n"); else if ( $i == "c_misc_info_p" ) { printf("\tif ( parse_nonwhite_char(client) != '{' )\n"); printf("\t longjmp(parse_env, KOM_PROTOCOL_ERR);\n"); printf("\tif ( client->num%d > %s )\n", num-1, $(++i)); printf("\t longjmp(parse_env, KOM_PROTOCOL_ERR);\n"); printf("\n"); printf("\tclient->c_misc_info_p = "); printf("smalloc(client->num%d\n", num-1); printf("\t\t\t\t\t* sizeof(Misc_info));\n"); printf("\tclient->array_parse_index = 0;\n"); printf("\tclient->fnc_parse_pos = %d;\n", ++pos); printf(" case %d:\n", pos); printf("\twhile( client->array_parse_index < "); printf("client->num%d )\n", num-1); printf("\t{\n"); printf("\t prot_a_parse_misc_info(client,"); printf(" &client->c_misc_info_p"); printf("[ client->array_parse_index ]);\n"); printf("\t ++client->array_parse_index;\n"); printf("\t}\n"); printf("\tclient->fnc_parse_pos = %d;\n", ++pos); printf(" case %d:\n", pos); printf("\tif ( parse_nonwhite_char(client) != '}' )\n"); printf("\t longjmp(parse_env, KOM_PROTOCOL_ERR);\n"); } else if ( $i == "aux_item" ) printf("\tprot_a_parse_aux_item(client, &client->aux_item);\n"); else if ( $i == "aux_item_list" ) printf("\tprot_a_parse_aux_item_list(client, &client->aux_item_list, %s);\n", $(++i)); else if ( $i == "misc_info_list" ) printf("\tprot_a_parse_misc_info_list(client, &client->misc_info_list, %s);\n", $(++i)); else if ( $i == "time_date" ) printf("\tprot_a_parse_time_date(client, &client->time);\n"); else if ( $i == "info" ) printf("\tprot_a_parse_info(client, &client->info);\n"); else if ( $i == "num_list" ) printf("\tprot_a_parse_num_list(client, &client->num_list, %s);\n", $(++i)); else if ( $i == "pers_flags" ) printf("\tprot_a_parse_pers_flags(client, &client->pers_flags);\n"); else if ( $i == "read_range_list" ) printf("\tprot_a_parse_read_range_list(client, " \ "&client->read_range_list, %s);\n", $(++i)); else printf("#error in prot-a-parse-arg-c.awk: not ready yet.\n"); if ( i != NF && $(i+1) != ":") printf("\tclient->fnc_parse_pos = %d;\n", ++pos); } printf(" default:\n"); printf("\tclient->fnc_parse_pos = 0;\n"); printf(" }\n"); printf("}\n\n"); } END { printf("/* end of this auto generated file. */\n"); } lyskom-server-2.1.2/src/server/prot-a-parse-arg-h.awk0000664000015100472110000000273507721716127016145 # # $Id: prot-a-parse-arg-h.awk,v 0.7 2003/08/23 16:38:15 ceder Exp $ # Copyright (C) 1991, 1999, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # $Id: prot-a-parse-arg-h.awk,v 0.7 2003/08/23 16:38:15 ceder Exp $ BEGIN { printf("/* Don't edit this file - it is generated automatically"); printf(" from\n prot-a-parse-arg-h.awk and fncdef.txt */\n\n"); } $1 == "#ifdef" { printf("#ifdef %s\n", $2); next; } $1 == "#endif" { printf("#endif\n"); next; } $1 != "#" && $1 != "" { printf("void prot_a_parse_arg_%s(Connection *client);\n", $3); } END { printf("/* end of this auto generated file. */\n"); } lyskom-server-2.1.2/src/server/prot-a-is-legal-fnc.awk0000664000015100472110000000306507721716127016275 # $Id: prot-a-is-legal-fnc.awk,v 1.4 2003/08/23 16:38:15 ceder Exp $ # Copyright (C) 1991, 1993-1996, 1999, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # $Id: prot-a-is-legal-fnc.awk,v 1.4 2003/08/23 16:38:15 ceder Exp $ BEGIN { printf("/* Don't edit this file - it is generated automatically"); printf(" from\n prot-a-is-legal-fnc.awk and fncdef.txt */\n"); printf("\n"); printf("\tswitch(fnc) {\n"); cnt = 0; } $1 == "#ifdef" { printf("#ifdef %s\n", $2); next; } $1 == "#endif" { printf("#endif\n"); next; } $1 != "#" && $1 != "" { printf("\tcase call_fnc_%-20s: return %d;\n", $3, cnt++); } END { printf("\tdefault:\n"); printf("\t\treturn -1;\n"); printf("\t}\n"); } lyskom-server-2.1.2/src/server/fncdef.txt0000664000015100472110000002205007722446226014112 # # $Id: fncdef.txt,v 0.65 2003/08/25 17:13:25 ceder Exp $ # Copyright (C) 1991-1999, 2001-2003 # Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # $Id: fncdef.txt,v 0.65 2003/08/25 17:13:25 ceder Exp $ # # This file is used to describe the functions in services.c. All # functions that are reachable from the clients are listed here, together # with their argument and return types. # # NEVER alter any functions that have been in use for a while! Add # new/modified functions last on this list! # # Functions that are reachable when using protocal A: # # (Functions whose name end in _old, _older, _10, _2 and so forth # are obsolete; better versions exists.) # # # Protocol version 1 # 0 success login_old num c_string (param.pwd_len) 1 success logout 2 success change_conference num 3 success change_name num c_string (param.conf_name_len) 4 success change_what_i_am_doing string (param.what_do_len) 5 number create_person_old c_string (param.conf_name_len) c_string (param.pwd_len) 6 success get_person_stat_old num num : person 7 success set_priv_bits num priv_bits 8 success set_passwd num c_string (param.pwd_len) c_string (param.pwd_len) 9 success query_read_texts_old num num : membership_old 10 number create_conf_old c_string (param.conf_name_len) conf_type 11 success delete_conf num 12 success lookup_name c_string (param.conf_name_len) : conf_list 13 success get_conf_stat_older num num : conference_old 14 success add_member_old num num num num 15 success sub_member num num 16 success set_presentation num num 17 success set_etc_motd num num 18 success set_supervisor num num 19 success set_permitted_submitters num num 20 success set_super_conf num num 21 success set_conf_type num conf_type 22 success set_garb_nice num num 23 success get_marks : mark_list 24 success mark_text_old num num 25 success get_text num num num : string 26 success get_text_stat_old num : text_stat_old 27 success mark_as_read num num_list (param.mark_as_read_chunk) 28 number create_text_old c_string (param.text_len) misc_info_list (param.max_crea_misc) 29 success delete_text num 30 success add_recipient num num num 31 success sub_recipient num num 32 success add_comment num num 33 success sub_comment num num 34 success get_map num num num : l2g_iterator_as_text_list 35 success get_time : time_date 36 success get_info_old : info_old 37 success add_footnote num num 38 success sub_footnote num num 39 success who_is_on_old : who_info_list_old 40 success set_unread num num 41 success set_motd_of_lyskom num 42 success enable num 43 success sync_kom 44 success shutdown_kom num 45 success broadcast c_string (param.broadcast_len) 46 success get_membership_old num num num num : membership_list_old 47 success get_created_texts num num num : l2g_iterator_as_text_list 48 success get_members_old num num num : member_list_old 49 success get_person_stat num : person 50 success get_conf_stat_old num : conference_old 51 success who_is_on : who_info_list 52 success get_unread_confs num : conf_no_list 53 success send_message num c_string (param.broadcast_len) 54 success get_session_info num : session_info 55 success disconnect num 56 success who_am_i : session_no # # Protocol version 2 # 57 success set_user_area num num # # Protocol version 3 # 58 success get_last_text time_date : text_no 59 number create_anonymous_text_old c_string (param.text_len) misc_info_list (param.max_crea_misc) 60 success find_next_text_no num : text_no 61 success find_previous_text_no num : text_no # # Protocol version 4 # 62 success login num c_string (param.pwd_len) num 63 success who_is_on_ident : who_info_ident_list 64 success get_session_info_ident num : session_info_ident # # Protocol version 5 # 65 success re_lookup_person c_string (param.regexp_len) : conf_no_list 66 success re_lookup_conf c_string (param.regexp_len) : conf_no_list # # Protocol version 6 # 67 success lookup_person c_string (param.conf_name_len) : conf_no_list 68 success lookup_conf c_string (param.conf_name_len) : conf_no_list 69 success set_client_version c_string (param.client_data_len) c_string (param.client_data_len) 70 success get_client_name num : string 71 success get_client_version num : string 72 success mark_text num num 73 success unmark_text num # # Protocol version 7 # 74 success re_z_lookup c_string (param.regexp_len) num num : conf_z_info_list 75 success get_version_info : version_info 76 success lookup_z_name c_string (param.conf_name_len) num num : conf_z_info_list # # Protocol version 8 # 77 success set_last_read num num 78 success get_uconf_stat num : uconference # # Protocol version 9 # 79 success set_info info 80 success accept_async num_list (param.accept_async_len) 81 success query_async : num_list 82 success user_active 83 success who_is_on_dynamic num num num : dynamic_session_info_list 84 success get_static_session_info num : static_session_info # # Protocol version 10 # 85 success get_collate_table : string 86 number create_text c_string (param.text_len) misc_info_list (param.max_crea_misc) aux_item_list (param.max_add_aux) 87 number create_anonymous_text c_string (param.text_len) misc_info_list (param.max_crea_misc) aux_item_list (param.max_add_aux) 88 number create_conf c_string (param.conf_name_len) conf_type aux_item_list (param.max_add_aux) 89 number create_person c_string (param.conf_name_len) c_string (param.pwd_len) pers_flags aux_item_list (param.max_add_aux) 90 success get_text_stat num : text_stat 91 success get_conf_stat num : conference 92 success modify_text_info num num_list (param.max_delete_aux) aux_item_list (param.max_add_aux) 93 success modify_conf_info num num_list (param.max_delete_aux) aux_item_list (param.max_add_aux) 94 success get_info : info 95 success modify_system_info num_list (param.max_delete_aux) aux_item_list (param.max_add_aux) 96 success query_predefined_aux_items : num_list 97 success set_expire num num 98 success query_read_texts_10 num num : membership_10 99 success get_membership_10 num num num num : membership_list_10 100 success add_member num num num num membership_type 101 success get_members num num num : member_list 102 success set_membership_type num num membership_type 103 success local_to_global num num num : text_mapping 104 success map_created_texts num num num : text_mapping 105 success set_keep_commented num num 106 success set_pers_flags num pers_flags 107 success query_read_texts num num num num : membership 108 success get_membership num num num num num : membership_list 109 success mark_as_unread num num 110 success set_read_ranges num read_range_list (param.max_read_ranges) 111 success get_stats_description : stats_description 112 success get_stats c_string (param.stat_name_len) : stats_list 113 success get_boottime_info : static_server_info 114 success first_unused_conf_no : conf_no 115 success first_unused_text_no : text_no 116 success find_next_conf_no num : conf_no 117 success find_previous_conf_no num : conf_no 118 success get_scheduling num : scheduling_info 119 success set_scheduling num num num 120 success set_connection_time_format num 121 success local_to_global_reverse num num num : text_mapping_reverse 122 success map_created_texts_reverse num num num : text_mapping_reverse #ifdef DEBUG_CALLS 1000 success get_memory_info : memory_info 1001 success set_marks num num 1002 success backdate_text num num 1003 success start_garb 1004 success cache_sync_start 1005 success cache_sync_finish 1006 success dump_cfg_timevals 1007 success backdate_comment_link num num num 1008 success server_sleep num #endif lyskom-server-2.1.2/src/server/handle-malloc-dump.el0000664000015100472110000002424107721716127016114 ;;;; ;;;; $Id: handle-malloc-dump.el,v 1.12 2003/08/23 16:38:17 ceder Exp $ ;;;; Copyright (C) 1991-1995, 1999, 2003 Lysator Academic Computer Association. ;;;; ;;;; This file is part of the LysKOM server. ;;;; ;;;; LysKOM 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 1, or (at your option) ;;;; any later version. ;;;; ;;;; LysKOM 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 LysKOM; see the file COPYING. If not, write to ;;;; Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, ;;;; or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, ;;;; MA 02139, USA. ;;;; ;;;; Please report bugs at http://bugzilla.lysator.liu.se/. ;;;; ;;;; See ram-smalloc.c for instructions on how to use this file. (require 'dll) ;;; block - each block that is active is stored on a dll. The dll ;;; contains blocks. Each block consists of 'addr' - the base addr of ;;; the block - and 'marker' - a marker that points to the backtrace. ;;; Constructor: (defun create-block (addr marker) "Create a block from ADDR and MARKER." (cons 'BLOCK (vector addr marker ))) ;;; Selectors: (defun block->addr (block) "Get addr from BLOCK." (elt (cdr block) 0)) (defun block->marker (block) "Get marker from BLOCK." (elt (cdr block) 1)) ;;; Modifiers: (defun set-block->addr (block newval) "Set addr in BLOCK to NEWVAL." (aset (cdr block) 0 newval)) (defun set-block->marker (block newval) "Set marker in BLOCK to NEWVAL." (aset (cdr block) 1 newval)) ;;; Predicate: (defun block-p (object) "Return t if OBJECT is a block." (eq (car-safe object) 'BLOCK)) (defvar mstack nil "A dll that holds all currently active memory blocks.") (defvar illegal-free nil "A dll that holds all illegal free attempts.") (defun resolve-trace () "Search the current buffer, and output any erroneous mallocs/reallocs/frees to *Result*." (interactive) (setq mstack (dll-create)) (setq illegal-free (dll-create)) (goto-char (point-min)) (while (re-search-forward "^--- \\(.*\\) ---$" nil 'foo) (let* ((fn (buffer-substring (match-beginning 1) (match-end 1))) (btstart (match-end 0)) (btend (progn (re-search-forward "^==== end ====") (match-beginning 0)))) ; (message fn) (cond ((string= fn "malloc") (beginning-of-line 0) (allocate)) ((string= fn "free") (beginning-of-line 0) (free)) ((string= fn "realloc") (beginning-of-line -1) (free) (beginning-of-line 2) (allocate))))) (report-stacks)) (defun get-number () "Get the last hex-string on this line, as a string." (re-search-forward "0x[0-9a-f]*$") (buffer-substring (match-beginning 0) (match-end 0))) (defun allocate () "Add an unresolved allocation to mstack." (dll-enter-first mstack (create-block (get-number) (point)))) (defun free () "Resolve an allocation from mstack." (let ((addr (get-number)) (node (dll-nth mstack 0))) (while (and node (not (string= addr (block->addr (dll-element mstack node))))) (setq node (dll-next mstack node))) (if node (dll-delete mstack node) (dll-enter-first illegal-free (create-block addr (point)))))) (defun report-stacks () (save-window-excursion (pop-to-buffer "*Result*" t) (erase-buffer) (insert "Forgotten mallocs:\n\n")) (report-stack mstack) (save-window-excursion (pop-to-buffer "*Result*" t) (insert "\n\nIllegal frees:\n\n")) (report-stack illegal-free)) (defun report-stack (stack) (let ((gdb-buf (current-buffer)) (node (dll-nth stack 0))) (while node (goto-char (block->marker (dll-element stack node))) (re-search-backward "^---") (let* ((b (point)) (e (progn (re-search-forward "====$") (point)))) (save-excursion (set-buffer "*Result*") (insert (format "From char %d:\n" b)) (insert-buffer-substring gdb-buf (1- b) (1+ e)))) (setq node (dll-next stack node))))) ;;; Batch mode analysis (defvar gdb-tty nil) (defvar gdb-proc nil) (defvar gdb-buffer nil) (defvar lyskomd-pid nil) (defvar trace-done nil) (defun trace-collect-data (proc data) (princ data (process-mark proc))) (defun trace-expect (re) (goto-char trace-last-match) (if (re-search-forward re nil t) (progn (set-marker trace-last-match (match-end 0)) (match-beginning 0)))) (defun trace-wait-for (proc regexp) (while (null (save-excursion (set-buffer (process-buffer proc)) (trace-expect regexp))) (accept-process-output proc 1))) (defun trace-process-get-tty (proc data) (save-excursion (set-buffer (process-buffer proc)) (trace-collect-data proc data) (if (trace-expect "\\(/dev\\S-*\\)$") (progn (setq gdb-tty (match-string 1)) (message "Tracing using gdb on tty %s" gdb-tty) (set-process-filter proc nil))))) (defun trace-runtest-filter (proc data) (save-excursion (set-buffer (process-buffer proc)) (trace-collect-data proc data) (if (trace-expect "Please attach to lyskomd pid \\([0-9]+\\) and hit RETURN$") (progn (setq lyskomd-pid (string-to-int (match-string 1))) (message "Attaching to lyskomd pid %d" lyskomd-pid) (set-process-filter proc nil))))) (defun trace-runtest-sentinel (proc state) (setq trace-done t)) (defun trace-make-process-buffer (name) (let ((buf (get-buffer-create name))) (save-excursion (set-buffer buf) (erase-buffer) (make-local-variable 'trace-last-match) (setq trace-last-match (copy-marker (point-min-marker)))) buf)) (defun usage () (message "\ Usage: emacs -batch -l handle-malloc-dump.el --test arg [options] Options: --help Show this help message --tool arg Use arg as --tool argument for runtest (optional) --test arg Run the test case arg with runtest (REQUIRED) --output arg Append the results to file arg (optional) ")) (defun trace-memory () (let ((tool-to-test "lyskomd") (test-to-run nil) (output-file nil) (arg nil) (done nil) (result nil)) (while (and command-line-args-left (not done)) (setq arg (car command-line-args-left)) (cond ((string= arg "--usage") (setq command-line-args-left (cdr command-line-args-left)) (setq tool-to-test nil) (setq done t) (usage)) ((string= arg "--tool") (setq tool-to-test (car (cdr command-line-args-left))) (setq command-line-args-left (cdr (cdr command-line-args-left)))) ((string= arg "--test") (setq test-to-run (car (cdr command-line-args-left))) (setq command-line-args-left (cdr (cdr command-line-args-left)))) ((string= arg "--output") (setq output-file (car (cdr command-line-args-left))) (setq command-line-args-left (cdr (cdr command-line-args-left)))) (t (setq done t)))) (if tool-to-test (progn (if (null test-to-run) (usage) (setq result (trace-run-programs tool-to-test test-to-run)) (cond ((null output-file) (message "%s" result)) (t (let ((tmp (get-buffer-create "*tmp*"))) (set-buffer tmp) (insert result) (append-to-file (point-min) (point-max) output-file))))))))) (defun trace-run-programs (tool-to-test test-to-run) (setq lyskomd-pid nil) (setq gdb-tty nil) (setq trace-done nil) (let ((gdb-buffer (trace-make-process-buffer "*gdb*")) (runtest-buffer (trace-make-process-buffer "*runtest*"))) ;; Start gdb, load the macros, THEN find out which tty we are on ;; If we don't do it in this order, we might end up starting ;; the test case before the breakpoints are in place. Strange, ;; but true. (setq gdb-proc (start-process "gdb" gdb-buffer "gdb" "../lyskomd")) (setq gdb-buffer (get-buffer-create "*gdb*")) (set-process-filter gdb-proc 'trace-process-get-tty) (process-send-string gdb-proc "source ../trace-mem.gdb\n") (process-send-string gdb-proc "shell echo `tty`\n") (while (null gdb-tty) (accept-process-output gdb-proc)) ;; Start runtest with the selected test case. Wait until we see ;; the PID. Wait for gdb to attach to the process! (setq runtest-proc (start-process "runtest" runtest-buffer "runtest" "--srcdir=." (format "--tool=%s" tool-to-test) test-to-run "ATTACH=yes" (format "MEMTRACE=%s" gdb-tty))) (set-process-filter runtest-proc 'trace-runtest-filter) (set-process-sentinel runtest-proc 'trace-runtest-sentinel) (while (null lyskomd-pid) (accept-process-output runtest-proc)) (process-send-string gdb-proc (format "attach %s\n" lyskomd-pid)) (process-send-string gdb-proc "continue\n") (message "Waiting for gdb to resume lyskomd") (trace-wait-for gdb-proc "Continuing") ;; Start the test case, and wait for it to terminate. (message "Running test case %s" test-to-run) (process-send-string runtest-proc "\n") (while (null trace-done) (accept-process-output)) ;; Wait for all the data to be printed in the gdb buffer (trace-wait-for gdb-proc "Program exited") ;; Resolve the trace (set-process-buffer gdb-proc nil) (message "Resolving trace...") (resolve-trace) (set-buffer "*Result*") (buffer-substring))) ;; If running in batch mode, start things right away (if noninteractive (progn (message "Automatic lyskomd memory trace analysis") (trace-memory))) lyskom-server-2.1.2/src/server/trace-mem.gdb0000664000015100472110000000031205326146160014441 set height 0 break trace_smalloc commands echo --- malloc ---\n bt cont end break trace_free commands echo --- free ---\n bt cont end break trace_srealloc commands echo --- realloc ---\n bt cont end lyskom-server-2.1.2/src/server/testsuite/0000777000015100472110000000000007723710373014236 5lyskom-server-2.1.2/src/server/testsuite/l2g.0/0000777000015100472110000000000007723710367015063 5lyskom-server-2.1.2/src/server/testsuite/l2g.0/00.exp0000664000015100472110000001725407721716131015740 # Test suite for Local_to_global. # Copyright (C) 1996, 1998-1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. l2g_start l2g_send "I0" l2g_send "I1" l2g_send "D0" l2g_send "I0" l2g_send "C1 0" l2g_send "C1 0" l2g_send "C1 0" # Attempt to look up entries in an empty set. l2g_send "l 0 0" simple_expect "0" "test 0" l2g_send "l 0 1" simple_expect "0" "test 1" l2g_send "l 0 2" simple_expect "0" "test 2" l2g_send "l 0 3" simple_expect "0" "test 3" l2g_send "l 0 4" simple_expect "0" "test 4" l2g_send "l 0 5" simple_expect "0" "test 5" # Insert 3:103 l2g_send "a 0 3 103" # Look up the first few numbers in a single-valued set. l2g_send "l 0 1" simple_expect "0" "test 6" l2g_send "l 0 2" simple_expect "0" "test 7" l2g_send "l 0 3" simple_expect "103" "test 8" l2g_send "l 0 4" simple_expect "0" "test 9" l2g_send "l 0 5" simple_expect "0" "test 10" # Append 4:104, resuling in the set 3:103, 4:104 l2g_send "a 0 4 104" # Look up again. l2g_send "l 0 1" simple_expect "0" "test 11" l2g_send "l 0 2" simple_expect "0" "test 12" l2g_send "l 0 3" simple_expect "103" "test 13" l2g_send "l 0 4" simple_expect "104" "test 14" l2g_send "l 0 5" simple_expect "0" "test 15" # Append 8 more, resulting in a single full dense block. l2g_send "a 0 5 105" l2g_send "a 0 6 106" l2g_send "a 0 7 107" l2g_send "a 0 8 108" l2g_send "a 0 9 109" l2g_send "a 0 10 1010" l2g_send "a 0 11 1011" l2g_send "a 0 12 1012" l2g_send "u 0" simple_expect "Number of blocks: 1" "test 16" simple_expect "First unused: 13" "test 16b" simple_expect "0: 10 0 3 \\(dense\\) \\\[103 104 105 106 107 108 109 1010 1011 1012 \\\]" "test 17" # Append 11 more, resulting in two full dense blocks and one dense # block with a single entry. l2g_send "a 0 13 1013" l2g_send "a 0 14 1014" l2g_send "a 0 15 1015" l2g_send "a 0 16 1016" l2g_send "a 0 17 1017" l2g_send "a 0 18 1018" l2g_send "a 0 19 1019" l2g_send "a 0 20 1020" l2g_send "a 0 21 1021" l2g_send "a 0 22 1022" l2g_send "a 0 23 1023" l2g_send "l 0 1" simple_expect "0" "test 18" l2g_send "l 0 2" simple_expect "0" "test 19" l2g_send "l 0 3" simple_expect "103" "test 20" l2g_send "l 0 4" simple_expect "104" "test 21" l2g_send "l 0 5" simple_expect "105" "test 22" l2g_send "l 0 24" simple_expect "0" "test 23" l2g_send "l 0 23" simple_expect "1023" "test 24" l2g_send "l 0 22" simple_expect "1022" "test 25" l2g_send "l 0 20" simple_expect "1020" "test 26" l2g_send "d 0 20" l2g_send "l 0 20" simple_expect "0" "deletion works test 27" l2g_send "l 0 1" simple_expect "0" "test 28" l2g_send "l 0 2" simple_expect "0" "test 29" l2g_send "l 0 3" simple_expect "103" "test 30" l2g_send "l 0 4" simple_expect "104" "test 31" l2g_send "l 0 5" simple_expect "105" "test 32" l2g_send "l 0 24" simple_expect "0" "test 33" l2g_send "l 0 23" simple_expect "1023" "test 34" l2g_send "l 0 22" simple_expect "1022" "test 35" l2g_send "l 0 20" simple_expect "0" "test 36" l2g_send "l 0 21" simple_expect "1021" "test 37" l2g_send "l 0 19" simple_expect "1019" "test 38" l2g_send "d 0 19" l2g_send "l 0 18" simple_expect "1018" "test 39" l2g_send "l 0 19" simple_expect "0" "test 40" l2g_send "l 0 20" simple_expect "0" "test 41" l2g_send "l 0 21" simple_expect "1021" "test 42" proc check_state {map} { l2g_send "n $map 0" simple_expect "3" "checking index 0 in $map (test 43)" foreach n {3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 20 21 22} { l2g_send "n $map $n" simple_expect "[expr {$n + 1}]" "checking $n in $map (test 44)" } l2g_send "n $map 18" simple_expect "21" "checking 18 in $map (test 45)" l2g_send "n $map 19" simple_expect "21" "checking 19 in $map (test 46)" l2g_send "n $map 23" simple_expect "0" "checking 23 in $map (test 47)" l2g_send "n $map 24" simple_expect "0" "checking 24 in $map (test 48)" } check_state 0 l2g_send "n 1 0" simple_expect "0" "test 49" l2g_send "C1 0" check_state 1 l2g_send "d 0 14" check_state 1 l2g_send "d 1 13" l2g_send "l 0 14" simple_expect "0" "test 50" l2g_send "l 1 13" simple_expect "0" "test 51" # Test the representation. l2g_send "I2" l2g_send "u 2" simple_expect "Number of blocks: 0" "test 52" simple_expect "First unused: 1" "test 52b" l2g_send "a2 10 139" l2g_send "u 2" simple_expect "Number of blocks: 1" "test 53" simple_expect "First unused: 11" "test 53b" simple_expect "0: 1 9 10 \\(dense\\) \\\[139 \\\]" "test 54" l2g_send "a2 12 141" l2g_send "u 2" simple_expect "Number of blocks: 1" "test 55" simple_expect "First unused: 13" "test 55b" simple_expect "0: 3 8 10 \\(dense\\) \\\[139 0 141 \\\]" "test 56" l2g_send "a2 14 147" l2g_send "u 2" simple_expect "Number of blocks: 1" "test 57" simple_expect "First unused: 15" "test 57b" simple_expect "0: 5 7 10 \\(dense\\) \\\[139 0 141 0 147 \\\]" "test 58" l2g_send "a2 16 153" l2g_send "u 2" simple_expect "Number of blocks: 1" "test 59" simple_expect "First unused: 17" "test 59b" simple_expect "0: 7 6 10 \\(dense\\) \\\[139 0 141 0 147 0 153 \\\]" "test 60" l2g_send "a2 18 157" l2g_send "u 2" simple_expect "Number of blocks: 1" "test 61" simple_expect "First unused: 19" "test 61b" simple_expect "0: 9 5 10 \\(dense\\) \\\[139 0 141 0 147 0 153 0 157 \\\]" "test 62" l2g_send "a2 21 167" l2g_send "u 2" simple_expect "Number of blocks: 1" "test 63" simple_expect "First unused: 22" "test 63b" simple_expect "0: 6 4 10 \\(sparse\\) \\\[10:139 12:141 14:147 16:153 18:157 21:167 \\\]" "test 64" l2g_send "a2 28 170" l2g_send "a2 92 171" l2g_send "a2 99 172" l2g_send "a2 102 173" l2g_send "u 2" simple_expect "Number of blocks: 1" "test 65" simple_expect "First unused: 103" "test 65b" simple_expect "0: 10 0 10 \\(sparse\\) \\\[10:139 12:141 14:147 16:153 18:157 21:167 28:170 92:171 99:172 102:173 \\\]" "test 66" set block1 "" set nf 0 set zeroes 10 foreach x {{103 177} {104 178} {105 179} {106 180} {107 181} {108 182} {109 183} {110 184} {111 185} {112 186}} { l2g_send "a2 $x" append block1 "[lindex $x 1] " l2g_send "u 2" incr nf 1 incr zeroes -1 simple_expect "Number of blocks: 2" "test 67" simple_expect "First unused: [expr 1 + [lindex $x 0]]" "test 67b" simple_expect "0: 10 0 10 \\(sparse\\) \\\[10:139 12:141 14:147 16:153 18:157 21:167 28:170 92:171 99:172 102:173 \\\]" "test 68" simple_expect "1: $nf $zeroes 103 \\(dense\\) \\\[$block1\\\]" "test 69" } l2g_send "a2 113 189" l2g_send "u2" simple_expect "Number of blocks: 3" "test 70" simple_expect "First unused: 114" "test 70b" simple_expect "0: 10 0 10 \\(sparse\\) \\\[10:139 12:141 14:147 16:153 18:157 21:167 28:170 92:171 99:172 102:173 \\\]" "test 71" simple_expect "1: 10 0 103 \\(dense\\) \\\[$block1\\\]" "test 72" simple_expect "2: 1 9 113 \\(dense\\) \\\[189 \\\]" "test 73" l2g_send "l2 113" simple_expect "189" "test 74" l2g_send "l2 112" simple_expect 186 "test 75" l2g_send "l2 103" simple_expect 177 "test 76" l2g_send "l2 102" simple_expect 173 "test 77" l2g_send "l2 101" simple_expect 0 "test 78" l2g_send "D1" l2g_send "D0" l2g_send "D2" l2g_stop lyskom-server-2.1.2/src/server/testsuite/l2g.0/01.exp0000664000015100472110000001451707721716131015740 # Test suite for Local_to_global. # Copyright (C) 1996, 1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. set gnos { 125774 0 0 0 0 0 0 0 0 0 0 0 0 0 0 133120 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 149669 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 186661 0 0 0 0 0 0 191776 0 0 0 0 0 0 0 0 206984 0 0 0 209246 209676 0 0 220383 0 0 221290 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 261031 260540 0 0 0 0 0 275641 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 343330 0 0 0 0 0 0 0 0 0 0 0 0 0 0 382077 0 0 0 0 386538 0 0 0 0 0 0 0 0 0 0 0 0 403237 0 0 418462 0 0 0 438003 0 444906 449239 462189 0 495236 0 0 0 508860 0 534093 0 0 557873 0 567221 0 569719 0 0 572898 0 0 582801 0 0 589108 593683 0 0 0 630819 0 0 0 0 0 0 0 0 0 662415 666020 671541 0 0 0 0 0 680837 0 0 0 718901 0 0 722468 0 0 0 0 0 0 0 783378 784274 0 790900 0 0 0 0 806264 0 807356 0 0 841938 0 868517 0 0 0 0 0 918416 921595 0 928855 931805 0 957119 990192 0 0 0 0 1002208 0 1016709 1040762 1048418 0 0 1062992 0 0 0 0 0 0 0 0 0 0 0 0 1132441 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1299995 0 0 0 0 0 0 0 0 0 0 0 0 1301477 0 0 0 0 0 0 0 0 0 0 1305016 0 1305353 0 0 0 1306568 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1320736 1320758 0 0 0 0 0 0 0 0 0 0 0 0 1354855 1355009 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1376381 1376537 1376541 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1385636 1385671 0 0 0 0 0 0 0 1387253 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1437973 1438575 1439041 1440431 1443955 1443992 1444546 1445227 1445230 1445232 1445233 0 1445245 1445417 1445502 1445732 1450781 1452270 1452878 1453143 1453146 1453151 1453161 1454013 1454072 1454091 1454147 1459028 1461127 1465970 1468117 1474241 1474651 1474653 1474655 1477105 1477128 1477777 1478831 1478954 1479232 1479360 1479465 1480037 1480899 1484545 1484617 1484690 1484695 1486554 1486688 1488289 1492052 1492064 1492107 1499101 1499140 1499158 1499174 1499178 1499181 1499185 1499188 1499271 1499274 1506014 1506146 1506331 1506339 1506353 1506355 1506358 1506361 1506372 1506841 1506846 1511944 1512188 1513042 1516835 1516856 1516858 1516860 1516876 1516880 1516925 1516926 1516949 1516955 1517346 1517383 1517409 1517410 1517439 1517833 1517836 1517855 1517857 1517859 1517862 1517867 1517868 1517879 1517932 1517936 1517940 1517943 1517953 1517965 1517966 1517967 1517972 1517988 1518050 1518055 1518066 1518070 1518080 1518083 1518084 1518085 1518094 1518097 1518396 1518432 1518442 1518506 1518543 1518550 1518973 1519454 1519458 1519783 1520924 1520930 1520943 1520981 1521394 1522802 1522810 1522812 1526432 1526439 1526452 1526658 1526879 1526935 1526940 1526944 1527064 1527179 1527204 1527235 1527240 1527306 1528302 1528623 1528624 1530233 1530241 1530279 1530290 1530299 1530320 1530323 1531149 1531195 1531196 1531198 1531435 1531524 1531906 1532090 1532957 1533024 1533052 1533055 1533442 1534020 1534221 1534227 1535979 1536105 1536108 1537548 1537828 1537906 1538144 1538150 1538153 1539349 1539350 1539372 1539373 1539424 1539502 1539505 1539512 1539514 1539515 1541652 1541717 1542043 1542689 1542739 1542871 1542874 1542880 1543143 1543373 1543386 1543401 1543404 1543661 1543664 1543689 1544226 1544487 1544490 1544561 1544563 1544677 1544695 1544697 1544709 1545018 1545115 1545168 1545192 1545434 1545511 1545800 1545866 1546042 1546054 1546257 1548249 } l2g_start send_user "initializing\n" # 0: add each number, even when the global number is 0 l2g_send "I0" # 1: only add non-zero globals l2g_send "I1" # 2: add random number for zeroes and remove them immediately l2g_send "I2" # 2: add random number for zeroes and remove them in a separate pass l2g_send "I3" send_user "adding\n" set lno 10 foreach gno $gnos { l2g_send "a0 $lno $gno" if {$gno} { l2g_send "a1 $lno $gno" l2g_send "a2 $lno $gno" l2g_send "a3 $lno $gno" } else { l2g_send "a2 $lno 2423128" l2g_send "a3 $lno 2423129" l2g_send "l2 $lno" simple_expect 2423128 "test 7" l2g_send "d2 $lno" l2g_send "l2 $lno" simple_expect 0 "test 8" } incr lno } send_user "deleting\n" set lno 10 foreach gno $gnos { if {$gno == 0} { l2g_send "l3 $lno" simple_expect 2423129 "test 9" l2g_send "d3 $lno" l2g_send "l3 $lno" simple_expect 0 "test 10" } incr lno } send_user "checking\n" proc check {lno gno} { l2g_send "l0 $lno" simple_expect "$gno" "test 1 lookup up $lno" l2g_send "l1 $lno" simple_expect "$gno" "test 2 lookup up $lno" l2g_send "l2 $lno" simple_expect "$gno" "test 11 lookup up $lno" l2g_send "l3 $lno" simple_expect "$gno" "test 12 lookup up $lno" } foreach lno {0 1 2 3 4 5 6 7 8 9} { check $lno 0 } check 805 1548249 check 806 0 check 807 0 check 808 0 set lno 10 set plno 0 foreach gno $gnos { if {$gno} { while {$plno < $lno} { l2g_send "n0 $plno" simple_expect "$lno" "test 3 after $plno" l2g_send "n1 $plno" simple_expect "$lno" "test 4 after $plno" l2g_send "n2 $plno" simple_expect "$lno" "test 13 after $plno" l2g_send "n3 $plno" simple_expect "$lno" "test 14 after $plno" incr plno } } check $lno $gno incr lno } l2g_send "n0 $plno" simple_expect "0" "test 5 plno $plno" l2g_send "n1 $plno" simple_expect "0" "test 6 plno $plno" l2g_send "n2 $plno" simple_expect "0" "test 15 plno $plno" l2g_send "n3 $plno" simple_expect "0" "test 16 plno $plno" l2g_send "D3" l2g_send "D1" l2g_send "D0" l2g_send "D2" l2g_stop lyskom-server-2.1.2/src/server/testsuite/l2g.0/02.exp0000664000015100472110000000330007721716131015725 # Test suite for Local_to_global. # Copyright (C) 1998-1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test for a bug where find_block tested the Text_no value instead of # the Local_text_no value. The bug is now fixed. l2g_start l2g_send "I0" l2g_send "a0 700 100" l2g_send "a0 800 108" l2g_send "l0 699" simple_expect "0" "test 0" l2g_send "l0 700" simple_expect "100" "test 1" l2g_send "l0 701" simple_expect "0" "test 2" l2g_send "l0 799" simple_expect "0" "test 3" l2g_send "l0 800" simple_expect "108" "test 4" l2g_send "l0 801" simple_expect "0" "test 5" l2g_send "l0 100" simple_expect "0" "test 6" l2g_send "l0 108" simple_expect "0" "test 7" l2g_send "u0" simple_expect "Number of blocks: 1" "test 8" simple_expect "First unused: 801" "test 8b" simple_expect "0: 2 8 700 \\(sparse\\) \\\[700:100 800:108 \\\]" "test 9" l2g_send "D0" l2g_stop lyskom-server-2.1.2/src/server/testsuite/l2g.0/03.exp0000664000015100472110000000450107721716131015732 # Test suite for Local_to_global. # Copyright (C) 1998-1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check that iterators don't return a local text number that has been # deleted in a sparse block. l2g_start l2g_send "I0" l2g_send "a0 700 100" l2g_send "a0 750 103" l2g_send "a0 800 108" l2g_send "u0" simple_expect "Number of blocks: 1" "test 0" simple_expect "First unused: 801" "test 0b" simple_expect "0: 3 7 700 \\(sparse\\) \\\[700:100 750:103 800:108 \\\]" "test 1" l2g_send "d0 750" l2g_send "u0" simple_expect "Number of blocks: 1" "test 2" simple_expect "First unused: 801" "test 2b" simple_expect "0: 3 8 700 \\(sparse\\) \\\[700:100 750:0 800:108 \\\]" "test 3" l2g_send "l0 699" simple_expect "0" "test 4" l2g_send "l0 700" simple_expect "100" "test 5" l2g_send "l0 701" simple_expect "0" "test 6" l2g_send "l0 799" simple_expect "0" "test 7" l2g_send "l0 800" simple_expect "108" "test 8" l2g_send "l0 801" simple_expect "0" "test 9" l2g_send "l0 100" simple_expect "0" "test 10" l2g_send "l0 108" simple_expect "0" "test 11" l2g_send "n0 699" simple_expect "700" "test 12" l2g_send "n0 700" simple_expect "800" "test 13" l2g_send "n0 701" simple_expect "800" "test 14" l2g_send "n0 799" simple_expect "800" "test 15" l2g_send "n0 800" simple_expect "0" "test 16" l2g_send "n0 801" simple_expect "0" "test 17" l2g_send "n0 100" simple_expect "700" "test 18" l2g_send "n0 750" simple_expect "800" "test 19" l2g_send "n0 749" simple_expect "800" "test 20" l2g_send "D0" l2g_stop lyskom-server-2.1.2/src/server/testsuite/l2g.0/04.exp0000664000015100472110000000332007721716131015731 # Test suite for Local_to_global. # Copyright (C) 1998-1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check that no junk is read from a dense unfilled block. l2g_start l2g_send "I0" l2g_send "a0 10 100" l2g_send "a0 11 102" l2g_send "a0 12 104" l2g_send "a0 13 106" l2g_send "a0 14 108" l2g_send "a0 15 110" l2g_send "a0 16 112" l2g_send "a0 17 114" l2g_send "a0 18 116" # 19 not filled in. l2g_send "l0 18" simple_expect "116" "test 0" l2g_send "l0 19" simple_expect "0" "test 1" l2g_send "a0 20 118" l2g_send "l0 19" simple_expect "0" "test 2" l2g_send "l0 20" simple_expect "118" "test 3" l2g_send "u0" simple_expect "Number of blocks: 2" "test 4" simple_expect "First unused: 21" "test 4b" simple_expect "0: 9 1 10 \\(dense\\) \\\[100 102 104 106 108 110 112 114 116 \\\]" "test 5" simple_expect "1: 1 9 20 \\(dense\\) \\\[118 \\\]" "test 6" l2g_send "D0" l2g_stop lyskom-server-2.1.2/src/server/testsuite/l2g.0/05.exp0000664000015100472110000000255507721716131015743 # Test suite for Local_to_global. # Copyright (C) 1998-1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check that a sparse block is created even when the last block was a # dense block in which the last position was used. l2g_start l2g_send "I0" l2g_send "a0 90 107" l2g_send "a0 99 116" l2g_send "a0 100 117" l2g_send "u0" simple_expect "Number of blocks: 1" "test 0" simple_expect "First unused: 101" "test 0b" simple_expect "0: 3 7 90 \\(sparse\\) \\\[90:107 99:116 100:117 \\\]" "test 1" l2g_send "D0" l2g_stop lyskom-server-2.1.2/src/server/testsuite/l2g.0/06.exp0000664000015100472110000000447107721716131015743 # Test suite for Local_to_global. # Copyright (C) 1998-1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Make sure that deleting a non-existing text in a block doesn't # leave the block in an invalid state. l2g_start # Dense block. l2g_send "I0" l2g_send "a0 90 107" l2g_send "a0 91 116" l2g_send "u0" simple_expect "Number of blocks: 1" "test 0" simple_expect "First unused: 92" "test 0b" simple_expect "0: 2 8 90 \\(dense\\) \\\[107 116 \\\]" "test 1" l2g_send "d0 91" l2g_send "u0" simple_expect "Number of blocks: 1" "test 2" simple_expect "First unused: 92" "test 2b" simple_expect "0: 2 9 90 \\(dense\\) \\\[107 0 \\\]" "test 3" l2g_send "d0 91" l2g_send "u0" simple_expect "Number of blocks: 1" "test 4" simple_expect "First unused: 92" "test 4b" simple_expect "0: 2 9 90 \\(dense\\) \\\[107 0 \\\]" "test 5" # Sparse block l2g_send "I1" l2g_send "a1 90 107" l2g_send "a1 901 11116" l2g_send "u1" simple_expect "Number of blocks: 1" "test 6" simple_expect "First unused: 902" "test 6b" simple_expect "0: 2 8 90 \\(sparse\\) \\\[90:107 901:11116 \\\]" "test 7" l2g_send "d1 901" l2g_send "u1" simple_expect "Number of blocks: 1" "test 8" simple_expect "First unused: 902" "test 8b" simple_expect "0: 2 9 90 \\(sparse\\) \\\[90:107 901:0 \\\]" "test 9" l2g_send "d1 91" l2g_send "u1" simple_expect "Number of blocks: 1" "test 10" simple_expect "First unused: 902" "test 10b" simple_expect "0: 2 9 90 \\(sparse\\) \\\[90:107 901:0 \\\]" "test 11" l2g_send "D0" l2g_send "D1" l2g_stop lyskom-server-2.1.2/src/server/testsuite/l2g.0/07.exp0000664000015100472110000005460007721716131015743 # Test suite for Local_to_global. # Copyright (C) 1998-1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test that iterators don't return deleted texts, either first, last, # or in the middle, regardless of the block type. l2g_start l2g_send "I0" l2g_send "I1" l2g_send "i0" # Dense blocks. for {set i 1} {$i < 45} {incr i} { l2g_send "a0 $i [expr $i + 1000]" } l2g_send "l0 5" simple_expect "1005" "test 0" l2g_send "i0" simple_expect "1:1001" "test 1" simple_expect "2:1002" "test 2" simple_expect "3:1003" "test 3" simple_expect "4:1004" "test 4" simple_expect "5:1005" "test 5" simple_expect "6:1006" "test 6" simple_expect "7:1007" "test 7" simple_expect "8:1008" "test 8" simple_expect "9:1009" "test 9" simple_expect "10:1010" "test 10" simple_expect "11:1011" "test 11" simple_expect "12:1012" "test 12" simple_expect "13:1013" "test 13" simple_expect "14:1014" "test 14" simple_expect "15:1015" "test 15" simple_expect "16:1016" "test 16" simple_expect "17:1017" "test 17" simple_expect "18:1018" "test 18" simple_expect "19:1019" "test 19" simple_expect "20:1020" "test 20" simple_expect "21:1021" "test 21" simple_expect "22:1022" "test 22" simple_expect "23:1023" "test 23" simple_expect "24:1024" "test 24" simple_expect "25:1025" "test 25" simple_expect "26:1026" "test 26" simple_expect "27:1027" "test 27" simple_expect "28:1028" "test 28" simple_expect "29:1029" "test 29" simple_expect "30:1030" "test 30" simple_expect "31:1031" "test 31" simple_expect "32:1032" "test 32" simple_expect "33:1033" "test 33" simple_expect "34:1034" "test 34" simple_expect "35:1035" "test 35" simple_expect "36:1036" "test 36" simple_expect "37:1037" "test 37" simple_expect "38:1038" "test 38" simple_expect "39:1039" "test 39" simple_expect "40:1040" "test 40" simple_expect "41:1041" "test 41" simple_expect "42:1042" "test 42" simple_expect "43:1043" "test 43" simple_expect "44:1044" "test 44" l2g_send "i0 1 55" simple_expect "1:1001" "test 45" simple_expect "2:1002" "test 46" simple_expect "3:1003" "test 47" simple_expect "4:1004" "test 48" simple_expect "5:1005" "test 49" simple_expect "6:1006" "test 50" simple_expect "7:1007" "test 51" simple_expect "8:1008" "test 52" simple_expect "9:1009" "test 53" simple_expect "10:1010" "test 54" simple_expect "11:1011" "test 55" simple_expect "12:1012" "test 56" simple_expect "13:1013" "test 57" simple_expect "14:1014" "test 58" simple_expect "15:1015" "test 59" simple_expect "16:1016" "test 60" simple_expect "17:1017" "test 61" simple_expect "18:1018" "test 62" simple_expect "19:1019" "test 63" simple_expect "20:1020" "test 64" simple_expect "21:1021" "test 65" simple_expect "22:1022" "test 66" simple_expect "23:1023" "test 67" simple_expect "24:1024" "test 68" simple_expect "25:1025" "test 69" simple_expect "26:1026" "test 70" simple_expect "27:1027" "test 71" simple_expect "28:1028" "test 72" simple_expect "29:1029" "test 73" simple_expect "30:1030" "test 74" simple_expect "31:1031" "test 75" simple_expect "32:1032" "test 76" simple_expect "33:1033" "test 77" simple_expect "34:1034" "test 78" simple_expect "35:1035" "test 79" simple_expect "36:1036" "test 80" simple_expect "37:1037" "test 81" simple_expect "38:1038" "test 82" simple_expect "39:1039" "test 83" simple_expect "40:1040" "test 84" simple_expect "41:1041" "test 85" simple_expect "42:1042" "test 86" simple_expect "43:1043" "test 87" simple_expect "44:1044" "test 88" l2g_send "b0 1 55" simple_expect "44:1044" "test 88-2" simple_expect "43:1043" "test 87-2" simple_expect "42:1042" "test 86-2" simple_expect "41:1041" "test 85-2" simple_expect "40:1040" "test 84-2" simple_expect "39:1039" "test 83-2" simple_expect "38:1038" "test 82-2" simple_expect "37:1037" "test 81-2" simple_expect "36:1036" "test 80-2" simple_expect "35:1035" "test 79-2" simple_expect "34:1034" "test 78-2" simple_expect "33:1033" "test 77-2" simple_expect "32:1032" "test 76-2" simple_expect "31:1031" "test 75-2" simple_expect "30:1030" "test 74-2" simple_expect "29:1029" "test 73-2" simple_expect "28:1028" "test 72-2" simple_expect "27:1027" "test 71-2" simple_expect "26:1026" "test 70-2" simple_expect "25:1025" "test 69-2" simple_expect "24:1024" "test 68-2" simple_expect "23:1023" "test 67-2" simple_expect "22:1022" "test 66-2" simple_expect "21:1021" "test 65-2" simple_expect "20:1020" "test 64-2" simple_expect "19:1019" "test 63-2" simple_expect "18:1018" "test 62-2" simple_expect "17:1017" "test 61-2" simple_expect "16:1016" "test 60-2" simple_expect "15:1015" "test 59-2" simple_expect "14:1014" "test 58-2" simple_expect "13:1013" "test 57-2" simple_expect "12:1012" "test 56-2" simple_expect "11:1011" "test 55-2" simple_expect "10:1010" "test 54-2" simple_expect "9:1009" "test 53-2" simple_expect "8:1008" "test 52-2" simple_expect "7:1007" "test 51-2" simple_expect "6:1006" "test 50-2" simple_expect "5:1005" "test 49-2" simple_expect "4:1004" "test 48-2" simple_expect "3:1003" "test 47-2" simple_expect "2:1002" "test 46-2" simple_expect "1:1001" "test 45-2" l2g_send "i0 1 99" simple_expect "1:1001" "test 89" simple_expect "2:1002" "test 90" simple_expect "3:1003" "test 91" simple_expect "4:1004" "test 92" simple_expect "5:1005" "test 93" simple_expect "6:1006" "test 94" simple_expect "7:1007" "test 95" simple_expect "8:1008" "test 96" simple_expect "9:1009" "test 97" simple_expect "10:1010" "test 98" simple_expect "11:1011" "test 99" simple_expect "12:1012" "test 100" simple_expect "13:1013" "test 101" simple_expect "14:1014" "test 102" simple_expect "15:1015" "test 103" simple_expect "16:1016" "test 104" simple_expect "17:1017" "test 105" simple_expect "18:1018" "test 106" simple_expect "19:1019" "test 107" simple_expect "20:1020" "test 108" simple_expect "21:1021" "test 109" simple_expect "22:1022" "test 110" simple_expect "23:1023" "test 111" simple_expect "24:1024" "test 112" simple_expect "25:1025" "test 113" simple_expect "26:1026" "test 114" simple_expect "27:1027" "test 115" simple_expect "28:1028" "test 116" simple_expect "29:1029" "test 117" simple_expect "30:1030" "test 118" simple_expect "31:1031" "test 119" simple_expect "32:1032" "test 120" simple_expect "33:1033" "test 121" simple_expect "34:1034" "test 122" simple_expect "35:1035" "test 123" simple_expect "36:1036" "test 124" simple_expect "37:1037" "test 125" simple_expect "38:1038" "test 126" simple_expect "39:1039" "test 127" simple_expect "40:1040" "test 128" simple_expect "41:1041" "test 129" simple_expect "42:1042" "test 130" simple_expect "43:1043" "test 131" simple_expect "44:1044" "test 132" l2g_send "b0 1 99" simple_expect "44:1044" "test 132-2" simple_expect "43:1043" "test 131-2" simple_expect "42:1042" "test 130-2" simple_expect "41:1041" "test 129-2" simple_expect "40:1040" "test 128-2" simple_expect "39:1039" "test 127-2" simple_expect "38:1038" "test 126-2" simple_expect "37:1037" "test 125-2" simple_expect "36:1036" "test 124-2" simple_expect "35:1035" "test 123-2" simple_expect "34:1034" "test 122-2" simple_expect "33:1033" "test 121-2" simple_expect "32:1032" "test 120-2" simple_expect "31:1031" "test 119-2" simple_expect "30:1030" "test 118-2" simple_expect "29:1029" "test 117-2" simple_expect "28:1028" "test 116-2" simple_expect "27:1027" "test 115-2" simple_expect "26:1026" "test 114-2" simple_expect "25:1025" "test 113-2" simple_expect "24:1024" "test 112-2" simple_expect "23:1023" "test 111-2" simple_expect "22:1022" "test 110-2" simple_expect "21:1021" "test 109-2" simple_expect "20:1020" "test 108-2" simple_expect "19:1019" "test 107-2" simple_expect "18:1018" "test 106-2" simple_expect "17:1017" "test 105-2" simple_expect "16:1016" "test 104-2" simple_expect "15:1015" "test 103-2" simple_expect "14:1014" "test 102-2" simple_expect "13:1013" "test 101-2" simple_expect "12:1012" "test 100-2" simple_expect "11:1011" "test 99-2" simple_expect "10:1010" "test 98-2" simple_expect "9:1009" "test 97-2" simple_expect "8:1008" "test 96-2" simple_expect "7:1007" "test 95-2" simple_expect "6:1006" "test 94-2" simple_expect "5:1005" "test 93-2" simple_expect "4:1004" "test 92-2" simple_expect "3:1003" "test 91-2" simple_expect "2:1002" "test 90-2" simple_expect "1:1001" "test 89-2" l2g_send "i0 12 30" simple_expect "12:1012" "test 133" simple_expect "13:1013" "test 134" simple_expect "14:1014" "test 135" simple_expect "15:1015" "test 136" simple_expect "16:1016" "test 137" simple_expect "17:1017" "test 138" simple_expect "18:1018" "test 139" simple_expect "19:1019" "test 140" simple_expect "20:1020" "test 141" simple_expect "21:1021" "test 142" simple_expect "22:1022" "test 143" simple_expect "23:1023" "test 144" simple_expect "24:1024" "test 145" simple_expect "25:1025" "test 146" simple_expect "26:1026" "test 147" simple_expect "27:1027" "test 148" simple_expect "28:1028" "test 149" simple_expect "29:1029" "test 150" l2g_send "b0 12 30" simple_expect "29:1029" "test 150-2" simple_expect "28:1028" "test 149-2" simple_expect "27:1027" "test 148-2" simple_expect "26:1026" "test 147-2" simple_expect "25:1025" "test 146-2" simple_expect "24:1024" "test 145-2" simple_expect "23:1023" "test 144-2" simple_expect "22:1022" "test 143-2" simple_expect "21:1021" "test 142-2" simple_expect "20:1020" "test 141-2" simple_expect "19:1019" "test 140-2" simple_expect "18:1018" "test 139-2" simple_expect "17:1017" "test 138-2" simple_expect "16:1016" "test 137-2" simple_expect "15:1015" "test 136-2" simple_expect "14:1014" "test 135-2" simple_expect "13:1013" "test 134-2" simple_expect "12:1012" "test 133-2" l2g_send "d0 1" l2g_send "d0 11" l2g_send "d0 25" l2g_send "d0 40" l2g_send "d0 44" l2g_send "i0" simple_expect "2:1002" "test 151" simple_expect "3:1003" "test 152" simple_expect "4:1004" "test 153" simple_expect "5:1005" "test 154" simple_expect "6:1006" "test 155" simple_expect "7:1007" "test 156" simple_expect "8:1008" "test 157" simple_expect "9:1009" "test 158" simple_expect "10:1010" "test 159" simple_expect "12:1012" "test 160" simple_expect "13:1013" "test 161" simple_expect "14:1014" "test 162" simple_expect "15:1015" "test 163" simple_expect "16:1016" "test 164" simple_expect "17:1017" "test 165" simple_expect "18:1018" "test 166" simple_expect "19:1019" "test 167" simple_expect "20:1020" "test 168" simple_expect "21:1021" "test 169" simple_expect "22:1022" "test 170" simple_expect "23:1023" "test 171" simple_expect "24:1024" "test 172" simple_expect "26:1026" "test 173" simple_expect "27:1027" "test 174" simple_expect "28:1028" "test 175" simple_expect "29:1029" "test 176" simple_expect "30:1030" "test 177" simple_expect "31:1031" "test 178" simple_expect "32:1032" "test 179" simple_expect "33:1033" "test 180" simple_expect "34:1034" "test 181" simple_expect "35:1035" "test 182" simple_expect "36:1036" "test 183" simple_expect "37:1037" "test 184" simple_expect "38:1038" "test 185" simple_expect "39:1039" "test 186" simple_expect "41:1041" "test 187" simple_expect "42:1042" "test 188" simple_expect "43:1043" "test 189" l2g_send "b0 0 999" simple_expect "43:1043" "test 189-2" simple_expect "42:1042" "test 188-2" simple_expect "41:1041" "test 187-2" simple_expect "39:1039" "test 186-2" simple_expect "38:1038" "test 185-2" simple_expect "37:1037" "test 184-2" simple_expect "36:1036" "test 183-2" simple_expect "35:1035" "test 182-2" simple_expect "34:1034" "test 181-2" simple_expect "33:1033" "test 180-2" simple_expect "32:1032" "test 179-2" simple_expect "31:1031" "test 178-2" simple_expect "30:1030" "test 177-2" simple_expect "29:1029" "test 176-2" simple_expect "28:1028" "test 175-2" simple_expect "27:1027" "test 174-2" simple_expect "26:1026" "test 173-2" simple_expect "24:1024" "test 172-2" simple_expect "23:1023" "test 171-2" simple_expect "22:1022" "test 170-2" simple_expect "21:1021" "test 169-2" simple_expect "20:1020" "test 168-2" simple_expect "19:1019" "test 167-2" simple_expect "18:1018" "test 166-2" simple_expect "17:1017" "test 165-2" simple_expect "16:1016" "test 164-2" simple_expect "15:1015" "test 163-2" simple_expect "14:1014" "test 162-2" simple_expect "13:1013" "test 161-2" simple_expect "12:1012" "test 160-2" simple_expect "10:1010" "test 159-2" simple_expect "9:1009" "test 158-2" simple_expect "8:1008" "test 157-2" simple_expect "7:1007" "test 156-2" simple_expect "6:1006" "test 155-2" simple_expect "5:1005" "test 154-2" simple_expect "4:1004" "test 153-2" simple_expect "3:1003" "test 152-2" simple_expect "2:1002" "test 151-2" l2g_send "u0" simple_expect "Number of blocks: 5" "test 190" simple_expect "First unused: 45" "test 191" simple_expect "0: 10 1 1 \\(dense\\) \\\[0 1002 1003 1004 1005 1006 1007 1008 1009 1010 \\\]" "test 192" simple_expect "1: 10 1 11 \\(dense\\) \\\[0 1012 1013 1014 1015 1016 1017 1018 1019 1020 \\\]" "test 193" simple_expect "2: 10 1 21 \\(dense\\) \\\[1021 1022 1023 1024 0 1026 1027 1028 1029 1030 \\\]" "test 194" simple_expect "3: 10 1 31 \\(dense\\) \\\[1031 1032 1033 1034 1035 1036 1037 1038 1039 0 \\\]" "test 195" simple_expect "4: 4 7 41 \\(dense\\) \\\[1041 1042 1043 0 \\\]" "test 196" # Sparse blocks l2g_send "i1" # 0:0 l2g_send "a1 66 107" l2g_send "a1 109 158" l2g_send "a1 153 215" l2g_send "a1 180 240" l2g_send "a1 233 301" l2g_send "a1 278 361" l2g_send "a1 330 398" l2g_send "a1 353 455" l2g_send "a1 411 434" l2g_send "a1 448 538" # 1:0 l2g_send "a1 503 582" l2g_send "a1 514 580" l2g_send "a1 542 620" l2g_send "a1 570 658" l2g_send "a1 610 677" l2g_send "a1 659 765" l2g_send "a1 713 769" l2g_send "a1 740 808" l2g_send "a1 799 878" # 2:0 l2g_send "a1 813 908" l2g_send "a1 837 927" l2g_send "a1 876 899" l2g_send "a1 905 1000" l2g_send "a1 917 963" # 2:4 l2g_send "a1 976 1046" l2g_send "a1 994 1094" l2g_send "a1 1019 1048" l2g_send "a1 1052 1129" l2g_send "a1 1106 1198" # 2:9 l2g_send "a1 1139 1197" # 3:0 l2g_send "a1 1169 1203" l2g_send "a1 1201 1241" l2g_send "a1 1246 1336" l2g_send "a1 1300 1379" l2g_send "a1 1334 1441" l2g_send "a1 1371 1458" l2g_send "a1 1420 1443" l2g_send "a1 1475 1503" l2g_send "a1 1534 1641" l2g_send "a1 1571 1679" # 4:0 l2g_send "a1 1609 1690" l2g_send "a1 1663 1760" l2g_send "a1 1718 1763" # 4:3 l2g_send "a1 1755 1844" l2g_send "i1" simple_expect "66:107" "test 197" simple_expect "109:158" "test 198" simple_expect "153:215" "test 199" simple_expect "180:240" "test 200" simple_expect "233:301" "test 201" simple_expect "278:361" "test 202" simple_expect "330:398" "test 203" simple_expect "353:455" "test 204" simple_expect "411:434" "test 205" simple_expect "448:538" "test 206" simple_expect "503:582" "test 207" simple_expect "514:580" "test 208" simple_expect "542:620" "test 209" simple_expect "570:658" "test 210" simple_expect "610:677" "test 211" simple_expect "659:765" "test 212" simple_expect "713:769" "test 213" simple_expect "740:808" "test 214" simple_expect "799:878" "test 215" simple_expect "813:908" "test 216" simple_expect "837:927" "test 217" simple_expect "876:899" "test 218" simple_expect "905:1000" "test 219" simple_expect "917:963" "test 220" simple_expect "976:1046" "test 221" simple_expect "994:1094" "test 222" simple_expect "1019:1048" "test 223" simple_expect "1052:1129" "test 224" simple_expect "1106:1198" "test 225" simple_expect "1139:1197" "test 226" simple_expect "1169:1203" "test 227" simple_expect "1201:1241" "test 228" simple_expect "1246:1336" "test 229" simple_expect "1300:1379" "test 230" simple_expect "1334:1441" "test 231" simple_expect "1371:1458" "test 232" simple_expect "1420:1443" "test 233" simple_expect "1475:1503" "test 234" simple_expect "1534:1641" "test 235" simple_expect "1571:1679" "test 236" simple_expect "1609:1690" "test 237" simple_expect "1663:1760" "test 238" simple_expect "1718:1763" "test 239" simple_expect "1755:1844" "test 240" l2g_send "b1 50 2000" simple_expect "1755:1844" "test 240-2" simple_expect "1718:1763" "test 239-2" simple_expect "1663:1760" "test 238-2" simple_expect "1609:1690" "test 237-2" simple_expect "1571:1679" "test 236-2" simple_expect "1534:1641" "test 235-2" simple_expect "1475:1503" "test 234-2" simple_expect "1420:1443" "test 233-2" simple_expect "1371:1458" "test 232-2" simple_expect "1334:1441" "test 231-2" simple_expect "1300:1379" "test 230-2" simple_expect "1246:1336" "test 229-2" simple_expect "1201:1241" "test 228-2" simple_expect "1169:1203" "test 227-2" simple_expect "1139:1197" "test 226-2" simple_expect "1106:1198" "test 225-2" simple_expect "1052:1129" "test 224-2" simple_expect "1019:1048" "test 223-2" simple_expect "994:1094" "test 222-2" simple_expect "976:1046" "test 221-2" simple_expect "917:963" "test 220-2" simple_expect "905:1000" "test 219-2" simple_expect "876:899" "test 218-2" simple_expect "837:927" "test 217-2" simple_expect "813:908" "test 216-2" simple_expect "799:878" "test 215-2" simple_expect "740:808" "test 214-2" simple_expect "713:769" "test 213-2" simple_expect "659:765" "test 212-2" simple_expect "610:677" "test 211-2" simple_expect "570:658" "test 210-2" simple_expect "542:620" "test 209-2" simple_expect "514:580" "test 208-2" simple_expect "503:582" "test 207-2" simple_expect "448:538" "test 206-2" simple_expect "411:434" "test 205-2" simple_expect "353:455" "test 204-2" simple_expect "330:398" "test 203-2" simple_expect "278:361" "test 202-2" simple_expect "233:301" "test 201-2" simple_expect "180:240" "test 200-2" simple_expect "153:215" "test 199-2" simple_expect "109:158" "test 198-2" simple_expect "66:107" "test 197-2" l2g_send "u1" simple_expect "Number of blocks: 5" "test 241" simple_expect "First unused: 1756" "test 242" simple_expect "0: 10 0 66 \\(sparse\\) \\\[66:107 109:158 153:215 180:240 233:301 278:361 330:398 353:455 411:434 448:538 \\\]" "test 243" simple_expect "1: 10 0 503 \\(sparse\\) \\\[503:582 514:580 542:620 570:658 610:677 659:765 713:769 740:808 799:878 813:908 \\\]" "test 244" simple_expect "2: 10 0 837 \\(sparse\\) \\\[837:927 876:899 905:1000 917:963 976:1046 994:1094 1019:1048 1052:1129 1106:1198 1139:1197 \\\]" "test 245" simple_expect "3: 10 0 1169 \\(sparse\\) \\\[1169:1203 1201:1241 1246:1336 1300:1379 1334:1441 1371:1458 1420:1443 1475:1503 1534:1641 1571:1679 \\\]" "test 246" simple_expect "4: 4 6 1609 \\(sparse\\) \\\[1609:1690 1663:1760 1718:1763 1755:1844 \\\]" "test 247" l2g_send "d1 66" l2g_send "d1 503" l2g_send "d1 976" l2g_send "d1 1571" l2g_send "d1 1755" l2g_send "i1" simple_expect "109:158" "test 248" simple_expect "153:215" "test 249" simple_expect "180:240" "test 250" simple_expect "233:301" "test 251" simple_expect "278:361" "test 252" simple_expect "330:398" "test 253" simple_expect "353:455" "test 254" simple_expect "411:434" "test 255" simple_expect "448:538" "test 256" simple_expect "514:580" "test 257" simple_expect "542:620" "test 258" simple_expect "570:658" "test 259" simple_expect "610:677" "test 260" simple_expect "659:765" "test 261" simple_expect "713:769" "test 262" simple_expect "740:808" "test 263" simple_expect "799:878" "test 264" simple_expect "813:908" "test 265" simple_expect "837:927" "test 266" simple_expect "876:899" "test 267" simple_expect "905:1000" "test 268" simple_expect "917:963" "test 269" simple_expect "994:1094" "test 270" simple_expect "1019:1048" "test 271" simple_expect "1052:1129" "test 272" simple_expect "1106:1198" "test 273" simple_expect "1139:1197" "test 273b" simple_expect "1169:1203" "test 274" simple_expect "1201:1241" "test 275" simple_expect "1246:1336" "test 276" simple_expect "1300:1379" "test 277" simple_expect "1334:1441" "test 278" simple_expect "1371:1458" "test 279" simple_expect "1420:1443" "test 280" simple_expect "1475:1503" "test 281" simple_expect "1534:1641" "test 282" simple_expect "1609:1690" "test 284" simple_expect "1663:1760" "test 285" simple_expect "1718:1763" "test 286" l2g_send "b1 0 2000" simple_expect "1718:1763" "test 286-2" simple_expect "1663:1760" "test 285-2" simple_expect "1609:1690" "test 284-2" simple_expect "1534:1641" "test 282-2" simple_expect "1475:1503" "test 281-2" simple_expect "1420:1443" "test 280-2" simple_expect "1371:1458" "test 279-2" simple_expect "1334:1441" "test 278-2" simple_expect "1300:1379" "test 277-2" simple_expect "1246:1336" "test 276-2" simple_expect "1201:1241" "test 275-2" simple_expect "1169:1203" "test 274-2" simple_expect "1139:1197" "test 273b-2" simple_expect "1106:1198" "test 273-2" simple_expect "1052:1129" "test 272-2" simple_expect "1019:1048" "test 271-2" simple_expect "994:1094" "test 270-2" simple_expect "917:963" "test 269-2" simple_expect "905:1000" "test 268-2" simple_expect "876:899" "test 267-2" simple_expect "837:927" "test 266-2" simple_expect "813:908" "test 265-2" simple_expect "799:878" "test 264-2" simple_expect "740:808" "test 263-2" simple_expect "713:769" "test 262-2" simple_expect "659:765" "test 261-2" simple_expect "610:677" "test 260-2" simple_expect "570:658" "test 259-2" simple_expect "542:620" "test 258-2" simple_expect "514:580" "test 257-2" simple_expect "448:538" "test 256-2" simple_expect "411:434" "test 255-2" simple_expect "353:455" "test 254-2" simple_expect "330:398" "test 253-2" simple_expect "278:361" "test 252-2" simple_expect "233:301" "test 251-2" simple_expect "180:240" "test 250-2" simple_expect "153:215" "test 249-2" simple_expect "109:158" "test 248-2" l2g_send "u1" simple_expect "Number of blocks: 5" "test 287" simple_expect "First unused: 1756" "test 288" simple_expect "0: 10 1 66 \\(sparse\\) \\\[66:0 109:158 153:215 180:240 233:301 278:361 330:398 353:455 411:434 448:538 \\\]" "test 289" simple_expect "1: 10 1 503 \\(sparse\\) \\\[503:0 514:580 542:620 570:658 610:677 659:765 713:769 740:808 799:878 813:908 \\\]" "test 290" simple_expect "2: 10 1 837 \\(sparse\\) \\\[837:927 876:899 905:1000 917:963 976:0 994:1094 1019:1048 1052:1129 1106:1198 1139:1197 \\\]" "test 291" simple_expect "3: 10 1 1169 \\(sparse\\) \\\[1169:1203 1201:1241 1246:1336 1300:1379 1334:1441 1371:1458 1420:1443 1475:1503 1534:1641 1571:0 \\\]" "test 292" simple_expect "4: 4 7 1609 \\(sparse\\) \\\[1609:1690 1663:1760 1718:1763 1755:0 \\\]" "test 293" l2g_send "D0" l2g_send "D1" l2g_stop lyskom-server-2.1.2/src/server/testsuite/l2g.0/08.exp0000664000015100472110000000245407721716131015744 # Test suite for Local_to_global. # Copyright (C) 1998-1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test for an obscure bug that once existed in find_block_index_key, # where it would find the correct value, but return the first key # present in the sparse block even if it was a deleted one. l2g_start l2g_send "I0" l2g_send "a0 100 999" l2g_send "a0 400 9999" l2g_send "d0 100" l2g_send "n0 0" simple_expect "400" "test 0" l2g_send "D0" l2g_stop lyskom-server-2.1.2/src/server/testsuite/l2g.0/09.exp0000664000015100472110000000773107721716131015750 # Test suite for Local_to_global. # Copyright (C) 1998-1999, 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Ensure that the copy operation actually copies all relevant state. l2g_start l2g_send "I0" l2g_send "a0 10 1010" l2g_send "a0 11 1011" l2g_send "a0 12 1012" l2g_send "a0 13 1013" l2g_send "a0 14 1014" l2g_send "a0 15 1015" l2g_send "a0 16 1016" l2g_send "a0 17 1017" l2g_send "a0 18 1018" l2g_send "a0 19 1019" l2g_send "a0 25 1025" l2g_send "a0 43 1043" l2g_send "a0 98 1098" l2g_send "I1" l2g_send "C1 0" l2g_send "u0" simple_expect "Number of blocks: 2" "test 1" simple_expect "First unused: 99" "test 2" simple_expect "0: 10 0 10 \\(dense\\) \\\[1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 \\\]" "test 3" simple_expect "1: 3 7 25 \\(sparse\\) \\\[25:1025 43:1043 98:1098 \\\]" "test 4" l2g_send "u1" simple_expect "Number of blocks: 2" "test 5" simple_expect "First unused: 99" "test 6" simple_expect "0: 10 0 10 \\(dense\\) \\\[1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 \\\]" "test 7" simple_expect "1: 3 7 25 \\(sparse\\) \\\[25:1025 43:1043 98:1098 \\\]" "test 8" l2g_send "d0 98" l2g_send "D1" l2g_send "I1" l2g_send "C1 0" l2g_send "u0" simple_expect "Number of blocks: 2" "test 9" simple_expect "First unused: 99" "test 10" simple_expect "0: 10 0 10 \\(dense\\) \\\[1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 \\\]" "test 11" simple_expect "1: 3 8 25 \\(sparse\\) \\\[25:1025 43:1043 98:0 \\\]" "test 12" l2g_send "u1" simple_expect "Number of blocks: 2" "test 13" simple_expect "First unused: 99" "test 14" simple_expect "0: 10 0 10 \\(dense\\) \\\[1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 \\\]" "test 15" simple_expect "1: 2 8 25 \\(sparse\\) \\\[25:1025 43:1043 \\\]" "test 16" l2g_send "w0" simple_expect "\\\[99 10:1010,1011,1012,1013,1014,1015,1016,1017,1018,1019 25:1025 43:1043\\\]" "test 17" # FIXME (bug 217): Build something where the last entry has been deleted, l2g_send "w1" simple_expect "\\\[99 10:1010,1011,1012,1013,1014,1015,1016,1017,1018,1019 25:1025 43:1043\\\]" "test 18" l2g_send "d0 25" l2g_send "d0 43" l2g_send "C1" l2g_send "C1 0" l2g_send "u0" simple_expect "Number of blocks: 1" "test 19" simple_expect "First unused: 99" "test 20" simple_expect "0: 10 0 10 \\(dense\\) \\\[1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 \\\]" "test 21" l2g_send "u1" simple_expect "Number of blocks: 1" "test 22" simple_expect "First unused: 99" "test 23" simple_expect "0: 10 0 10 \\(dense\\) \\\[1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 \\\]" "test 24" l2g_send "w0" simple_expect "\\\[99 10:1010,1011,1012,1013,1014,1015,1016,1017,1018,1019\\\]" "test 25" l2g_send "w1" simple_expect "\\\[99 10:1010,1011,1012,1013,1014,1015,1016,1017,1018,1019\\\]" "test 26" l2g_send "I2" l2g_send "r2" send "\[118 10:1010,1011,1012,0,1014,1015,1016,1017,1018,1019 25:1025 43:1043\]\n" l2g_send "u2" simple_expect "Number of blocks: 2" "test 27" simple_expect "First unused: 118" "test 28" simple_expect "0: 10 1 10 \\(dense\\) \\\[1010 1011 1012 0 1014 1015 1016 1017 1018 1019 \\\]" "test 29" simple_expect "1: 2 8 25 \\(sparse\\) \\\[25:1025 43:1043 \\\]" "test 30" l2g_send "D0" l2g_send "D1" l2g_send "D2" l2g_stop lyskom-server-2.1.2/src/server/testsuite/l2g.0/10.exp0000664000015100472110000000351107721716131015730 # Test suite for Local_to_global. # Copyright (C) 1998-1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Ensure that iterators don't return too much when things have been deleted. l2g_start l2g_send "I0" l2g_send "a0 10 1010" l2g_send "i0" simple_expect "10:1010" "test 1" l2g_send "b0 0 200" simple_expect "10:1010" "test 1-2" l2g_send "i0 3 8" # There is nothing in the range [3..8), so no output should exist here. l2g_send "b0 3 8" # There is nothing in the range [3..8), so no output should exist here. l2g_send "a0 20 2020" l2g_send "i0" simple_expect "10:1010" "test 2" simple_expect "20:2020" "test 3" l2g_send "b0 0 21" simple_expect "20:2020" "test 3-2" simple_expect "10:1010" "test 2-2" l2g_send "i0 3 8" l2g_send "i0 3 10" l2g_send "i0 11 20" l2g_send "i0 2 12" simple_expect "10:1010" "test 4" l2g_send "b0 3 8" l2g_send "b0 3 10" l2g_send "b0 11 20" l2g_send "b0 2 12" simple_expect "10:1010" "test 5-2" l2g_send "b0 0 20" simple_expect "10:1010" "test 6" l2g_send "D0" l2g_stop lyskom-server-2.1.2/src/server/testsuite/l2g.0/11.exp0000664000015100472110000006221507721716131015737 # Test suite for Local_to_global. # Copyright (C) 1999, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check compaction of blocks. l2g_start l2g_send "I0" # Append 25 random numbers in the range 1..1000, simulating some # sparse old marked texts. l2g_send "a0 35 53428" l2g_send "a0 50 57456" l2g_send "a0 222 59570" l2g_send "a0 259 70441" l2g_send "a0 304 72037" l2g_send "a0 329 72239" l2g_send "a0 358 72910" l2g_send "a0 383 73113" l2g_send "a0 389 73612" l2g_send "a0 395 76393" l2g_send "a0 445 77697" l2g_send "a0 474 78372" l2g_send "a0 482 79436" l2g_send "a0 539 80907" l2g_send "a0 602 84499" l2g_send "a0 612 87035" l2g_send "a0 618 87514" l2g_send "a0 688 88856" l2g_send "a0 792 89215" l2g_send "a0 849 92418" l2g_send "a0 922 93794" l2g_send "a0 923 94866" l2g_send "a0 933 95724" l2g_send "a0 948 97085" l2g_send "a0 992 97960" l2g_send "w0" simple_expect "\\\[993 35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 445:77697 474:78372 482:79436 539:80907 602:84499 612:87035 618:87514 688:88856 792:89215 849:92418 922:93794,94866 933:95724 948:97085 992:97960\\\]" # Insert 25 numbers in the range 1001..1025, simulating newly created # texts. l2g_send "a0 1001 101613" l2g_send "a0 1002 102864" l2g_send "a0 1003 103254" l2g_send "a0 1004 103935" l2g_send "a0 1005 104444" l2g_send "a0 1006 105551" l2g_send "a0 1007 105859" l2g_send "a0 1008 106390" l2g_send "a0 1009 106784" l2g_send "a0 1010 107002" l2g_send "a0 1011 107212" l2g_send "a0 1012 107324" l2g_send "a0 1013 107469" l2g_send "a0 1014 107571" l2g_send "a0 1015 108471" l2g_send "a0 1016 108592" l2g_send "a0 1017 109959" l2g_send "a0 1018 111141" l2g_send "a0 1019 111225" l2g_send "a0 1020 113738" l2g_send "a0 1021 116365" l2g_send "a0 1022 117110" l2g_send "a0 1023 117278" l2g_send "a0 1024 117886" l2g_send "a0 1025 119385" l2g_send "w0" simple_expect "\\\[1026 35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 445:77697 474:78372 482:79436 539:80907 602:84499 612:87035 618:87514 688:88856 792:89215 849:92418 922:93794,94866 933:95724 948:97085 992:97960 1001:101613,102864,103254,103935,104444,105551,105859,106390,106784,107002,107212,107324,107469,107571,108471,108592,109959,111141,111225,113738,116365,117110,117278,117886,119385\\\]" # Check that we've got three sparse blocks and two dense. All of them # are optimally packed. l2g_send "u0" simple_expect "Number of blocks: 5" simple_expect "First unused: 1026" simple_expect "0: 10 0 35 \\(sparse\\) \\\[35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 \\\]" simple_expect "1: 10 0 445 \\(sparse\\) \\\[445:77697 474:78372 482:79436 539:80907 602:84499 612:87035 618:87514 688:88856 792:89215 849:92418 \\\]" simple_expect "2: 10 0 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:104444 \\\]" simple_expect "3: 10 0 1006 \\(dense\\) \\\[105551 105859 106390 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "4: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" # Remove some data from block 1 and ensure that it is not compacted # too early. l2g_send "d0 445" l2g_send "d0 849" l2g_send "d0 482" l2g_send "d0 612" l2g_send "d0 602" l2g_send "u0" simple_expect "Number of blocks: 5" simple_expect "First unused: 1026" simple_expect "0: 10 0 35 \\(sparse\\) \\\[35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 \\\]" simple_expect "1: 10 5 445 \\(sparse\\) \\\[445:0 474:78372 482:0 539:80907 602:0 612:0 618:87514 688:88856 792:89215 849:0 \\\]" simple_expect "2: 10 0 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:104444 \\\]" simple_expect "3: 10 0 1006 \\(dense\\) \\\[105551 105859 106390 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "4: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" l2g_send "w0" simple_expect "\\\[1026 35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 474:78372 539:80907 618:87514 688:88856 792:89215 922:93794,94866 933:95724 948:97085 992:97960 1001:101613,102864,103254,103935,104444,105551,105859,106390,106784,107002,107212,107324,107469,107571,108471,108592,109959,111141,111225,113738,116365,117110,117278,117886,119385\\\]" # Delete one more item and ensure that it is compacted. l2g_send "d0 539" l2g_send "u0" simple_expect "Number of blocks: 5" simple_expect "First unused: 1026" simple_expect "0: 10 0 35 \\(sparse\\) \\\[35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 \\\]" simple_expect "1: 4 6 445 \\(sparse\\) \\\[474:78372 618:87514 688:88856 792:89215 \\\]" simple_expect "2: 10 0 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:104444 \\\]" simple_expect "3: 10 0 1006 \\(dense\\) \\\[105551 105859 106390 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "4: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" l2g_send "w0" simple_expect "\\\[1026 35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 474:78372 618:87514 688:88856 792:89215 922:93794,94866 933:95724 948:97085 992:97960 1001:101613,102864,103254,103935,104444,105551,105859,106390,106784,107002,107212,107324,107469,107571,108471,108592,109959,111141,111225,113738,116365,117110,117278,117886,119385\\\]" # Check that lookup of 445..474 works properly. l2g_send "l0 444" simple_expect "0" l2g_send "l0 445" simple_expect "0" l2g_send "l0 446" simple_expect "0" l2g_send "l0 447" simple_expect "0" l2g_send "l0 472" simple_expect "0" l2g_send "l0 473" simple_expect "0" l2g_send "l0 474" simple_expect "78372" l2g_send "l0 475" simple_expect "0" # Check iterators l2g_send "i0" simple_expect "35:53428" simple_expect "50:57456" simple_expect "222:59570" simple_expect "259:70441" simple_expect "304:72037" simple_expect "329:72239" simple_expect "358:72910" simple_expect "383:73113" simple_expect "389:73612" simple_expect "395:76393" simple_expect "474:78372" simple_expect "618:87514" simple_expect "688:88856" simple_expect "792:89215" simple_expect "922:93794" simple_expect "923:94866" simple_expect "933:95724" simple_expect "948:97085" simple_expect "992:97960" simple_expect "1001:101613" simple_expect "1002:102864" simple_expect "1003:103254" simple_expect "1004:103935" simple_expect "1005:104444" simple_expect "1006:105551" simple_expect "1007:105859" simple_expect "1008:106390" simple_expect "1009:106784" simple_expect "1010:107002" simple_expect "1011:107212" simple_expect "1012:107324" simple_expect "1013:107469" simple_expect "1014:107571" simple_expect "1015:108471" simple_expect "1016:108592" simple_expect "1017:109959" simple_expect "1018:111141" simple_expect "1019:111225" simple_expect "1020:113738" simple_expect "1021:116365" simple_expect "1022:117110" simple_expect "1023:117278" simple_expect "1024:117886" simple_expect "1025:119385" l2g_send "i0 444 475" simple_expect "474:78372" l2g_send "i0 445 475" simple_expect "474:78372" l2g_send "i0 446 475" simple_expect "474:78372" l2g_send "i0 446 474" # Check reverse iterators l2g_send "b0 0 9999" simple_expect "1025:119385" simple_expect "1024:117886" simple_expect "1023:117278" simple_expect "1022:117110" simple_expect "1021:116365" simple_expect "1020:113738" simple_expect "1019:111225" simple_expect "1018:111141" simple_expect "1017:109959" simple_expect "1016:108592" simple_expect "1015:108471" simple_expect "1014:107571" simple_expect "1013:107469" simple_expect "1012:107324" simple_expect "1011:107212" simple_expect "1010:107002" simple_expect "1009:106784" simple_expect "1008:106390" simple_expect "1007:105859" simple_expect "1006:105551" simple_expect "1005:104444" simple_expect "1004:103935" simple_expect "1003:103254" simple_expect "1002:102864" simple_expect "1001:101613" simple_expect "992:97960" simple_expect "948:97085" simple_expect "933:95724" simple_expect "923:94866" simple_expect "922:93794" simple_expect "792:89215" simple_expect "688:88856" simple_expect "618:87514" simple_expect "474:78372" simple_expect "395:76393" simple_expect "389:73612" simple_expect "383:73113" simple_expect "358:72910" simple_expect "329:72239" simple_expect "304:72037" simple_expect "259:70441" simple_expect "222:59570" simple_expect "50:57456" simple_expect "35:53428" l2g_send "b0 444 475" simple_expect "474:78372" l2g_send "b0 445 475" simple_expect "474:78372" l2g_send "b0 446 475" simple_expect "474:78372" l2g_send "b0 446 474" # Remove three items from block 2 and ensure that no compaction happens. l2g_send "d0 923" l2g_send "d0 1001" l2g_send "d0 1002" l2g_send "u0" simple_expect "Number of blocks: 5" simple_expect "First unused: 1026" simple_expect "0: 10 0 35 \\(sparse\\) \\\[35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 \\\]" simple_expect "1: 4 6 445 \\(sparse\\) \\\[474:78372 618:87514 688:88856 792:89215 \\\]" simple_expect "2: 10 3 922 \\(sparse\\) \\\[922:93794 923:0 933:95724 948:97085 992:97960 1001:0 1002:0 1003:103254 1004:103935 1005:104444 \\\]" simple_expect "3: 10 0 1006 \\(dense\\) \\\[105551 105859 106390 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "4: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" l2g_send "w0" simple_expect "\\\[1026 35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 474:78372 618:87514 688:88856 792:89215 922:93794 933:95724 948:97085 992:97960 1003:103254,103935,104444,105551,105859,106390,106784,107002,107212,107324,107469,107571,108471,108592,109959,111141,111225,113738,116365,117110,117278,117886,119385\\\]" # Remove one more item from block 2 and watch it merge with block 1. l2g_send "d0 1003" l2g_send "u0" simple_expect "Number of blocks: 4" simple_expect "First unused: 1026" simple_expect "0: 10 0 35 \\(sparse\\) \\\[35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 \\\]" simple_expect "1: 10 0 445 \\(sparse\\) \\\[474:78372 618:87514 688:88856 792:89215 922:93794 933:95724 948:97085 992:97960 1004:103935 1005:104444 \\\]" simple_expect "2: 10 0 1006 \\(dense\\) \\\[105551 105859 106390 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "3: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" l2g_send "w0" simple_expect "\\\[1026 35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 474:78372 618:87514 688:88856 792:89215 922:93794 933:95724 948:97085 992:97960 1004:103935,104444,105551,105859,106390,106784,107002,107212,107324,107469,107571,108471,108592,109959,111141,111225,113738,116365,117110,117278,117886,119385\\\]" # Remove all but one item from the current block 2 (simualting a # massive garb effort). l2g_send "d0 1006" l2g_send "w0" simple_expect "\\\[1026 35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 474:78372 618:87514 688:88856 792:89215 922:93794 933:95724 948:97085 992:97960 1004:103935,104444,0,105859,106390,106784,107002,107212,107324,107469,107571,108471,108592,109959,111141,111225,113738,116365,117110,117278,117886,119385\\\]" l2g_send "d0 1007" l2g_send "w0" simple_expect "\\\[1026 35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 474:78372 618:87514 688:88856 792:89215 922:93794 933:95724 948:97085 992:97960 1004:103935,104444,0,0,106390,106784,107002,107212,107324,107469,107571,108471,108592,109959,111141,111225,113738,116365,117110,117278,117886,119385\\\]" l2g_send "d0 1008" l2g_send "w0" simple_expect "\\\[1026 35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 474:78372 618:87514 688:88856 792:89215 922:93794 933:95724 948:97085 992:97960 1004:103935,104444 1009:106784,107002,107212,107324,107469,107571,108471,108592,109959,111141,111225,113738,116365,117110,117278,117886,119385\\\]" l2g_send "d0 1009" l2g_send "w0" simple_expect "\\\[1026 35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 474:78372 618:87514 688:88856 792:89215 922:93794 933:95724 948:97085 992:97960 1004:103935,104444 1010:107002,107212,107324,107469,107571,108471,108592,109959,111141,111225,113738,116365,117110,117278,117886,119385\\\]" l2g_send "d0 1010" l2g_send "d0 1011" l2g_send "d0 1012" l2g_send "d0 1013" l2g_send "d0 1014" l2g_send "w0" simple_expect "\\\[1026 35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 474:78372 618:87514 688:88856 792:89215 922:93794 933:95724 948:97085 992:97960 1004:103935,104444 1015:108471,108592,109959,111141,111225,113738,116365,117110,117278,117886,119385\\\]" # Delete a nonexisting text that would have been present in a dense block. l2g_send "d0 1012" l2g_send "u0" simple_expect "Number of blocks: 4" simple_expect "First unused: 1026" simple_expect "0: 10 0 35 \\(sparse\\) \\\[35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 \\\]" simple_expect "1: 10 0 445 \\(sparse\\) \\\[474:78372 618:87514 688:88856 792:89215 922:93794 933:95724 948:97085 992:97960 1004:103935 1005:104444 \\\]" simple_expect "2: 10 9 1006 \\(dense\\) \\\[0 0 0 0 0 0 0 0 0 108471 \\\]" simple_expect "3: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" # Remove the last data in block 2, causing it to be removed. l2g_send "d0 1015" l2g_send "u0" simple_expect "Number of blocks: 3" simple_expect "First unused: 1026" simple_expect "0: 10 0 35 \\(sparse\\) \\\[35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 \\\]" simple_expect "1: 10 0 445 \\(sparse\\) \\\[474:78372 618:87514 688:88856 792:89215 922:93794 933:95724 948:97085 992:97960 1004:103935 1005:104444 \\\]" simple_expect "2: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" # Delete a nonexisting text that would have been present in a sparse block. l2g_send "d0 40" # Delete a nonexisting text that cannot be present. l2g_send "d0 20" l2g_send "d0 2000" # Make sure nothing bad happened. l2g_send "u0" simple_expect "Number of blocks: 3" simple_expect "First unused: 1026" simple_expect "0: 10 0 35 \\(sparse\\) \\\[35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 \\\]" simple_expect "1: 10 0 445 \\(sparse\\) \\\[474:78372 618:87514 688:88856 792:89215 922:93794 933:95724 948:97085 992:97960 1004:103935 1005:104444 \\\]" simple_expect "2: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" l2g_send "w0" simple_expect "\\\[1026 35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 474:78372 618:87514 688:88856 792:89215 922:93794 933:95724 948:97085 992:97960 1004:103935,104444 1016:108592,109959,111141,111225,113738,116365,117110,117278,117886,119385\\\]" # Insert one and a half new blocks. l2g_send "a0 1026 120115" l2g_send "a0 1027 122073" l2g_send "a0 1028 123273" l2g_send "a0 1029 125065" l2g_send "a0 1030 125444" l2g_send "a0 1031 125537" l2g_send "a0 1032 127933" l2g_send "a0 1033 128542" l2g_send "a0 1034 129196" l2g_send "a0 1035 129907" l2g_send "a0 1036 130515" l2g_send "a0 1037 131081" l2g_send "a0 1038 131308" l2g_send "a0 1039 132341" l2g_send "a0 1040 134218" l2g_send "u0" simple_expect "Number of blocks: 5" simple_expect "First unused: 1041" simple_expect "0: 10 0 35 \\(sparse\\) \\\[35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 \\\]" simple_expect "1: 10 0 445 \\(sparse\\) \\\[474:78372 618:87514 688:88856 792:89215 922:93794 933:95724 948:97085 992:97960 1004:103935 1005:104444 \\\]" simple_expect "2: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" simple_expect "3: 10 0 1026 \\(dense\\) \\\[120115 122073 123273 125065 125444 125537 127933 128542 129196 129907 \\\]" simple_expect "4: 5 5 1036 \\(dense\\) \\\[130515 131081 131308 132341 134218 \\\]" l2g_send "w0" simple_expect "\\\[1041 35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 474:78372 618:87514 688:88856 792:89215 922:93794 933:95724 948:97085 992:97960 1004:103935,104444 1016:108592,109959,111141,111225,113738,116365,117110,117278,117886,119385,120115,122073,123273,125065,125444,125537,127933,128542,129196,129907,130515,131081,131308,132341,134218\\\]" # Remove a few text from block 3 and 2, but not enough to matter. l2g_send "d0 1027" l2g_send "d0 1028" l2g_send "d0 1017" l2g_send "d0 1018" l2g_send "w0" simple_expect "\\\[1041 35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 474:78372 618:87514 688:88856 792:89215 922:93794 933:95724 948:97085 992:97960 1004:103935,104444 1016:108592,0,0,111225,113738,116365,117110,117278,117886,119385,120115,0,0,125065,125444,125537,127933,128542,129196,129907,130515,131081,131308,132341,134218\\\]" l2g_send "d0 1029" l2g_send "w0" simple_expect "\\\[1041 35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 474:78372 618:87514 688:88856 792:89215 922:93794 933:95724 948:97085 992:97960 1004:103935,104444 1016:108592,0,0,111225,113738,116365,117110,117278,117886,119385,120115 1030:125444,125537,127933,128542,129196,129907,130515,131081,131308,132341,134218\\\]" l2g_send "u0" simple_expect "Number of blocks: 5" simple_expect "First unused: 1041" simple_expect "0: 10 0 35 \\(sparse\\) \\\[35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 \\\]" simple_expect "1: 10 0 445 \\(sparse\\) \\\[474:78372 618:87514 688:88856 792:89215 922:93794 933:95724 948:97085 992:97960 1004:103935 1005:104444 \\\]" simple_expect "2: 10 2 1016 \\(dense\\) \\\[108592 0 0 111225 113738 116365 117110 117278 117886 119385 \\\]" simple_expect "3: 10 3 1026 \\(dense\\) \\\[120115 0 0 0 125444 125537 127933 128542 129196 129907 \\\]" simple_expect "4: 5 5 1036 \\(dense\\) \\\[130515 131081 131308 132341 134218 \\\]" # Remove a few more text from block 3 and 2, but still not enough to matter. l2g_send "d0 1030" l2g_send "d0 1019" l2g_send "d0 1020" l2g_send "d0 1021" l2g_send "d0 1031" l2g_send "d0 1032" l2g_send "d0 1033" l2g_send "d0 1039" l2g_send "d0 1040" l2g_send "u0" simple_expect "Number of blocks: 5" simple_expect "First unused: 1041" simple_expect "0: 10 0 35 \\(sparse\\) \\\[35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 \\\]" simple_expect "1: 10 0 445 \\(sparse\\) \\\[474:78372 618:87514 688:88856 792:89215 922:93794 933:95724 948:97085 992:97960 1004:103935 1005:104444 \\\]" simple_expect "2: 10 5 1016 \\(dense\\) \\\[108592 0 0 0 0 0 117110 117278 117886 119385 \\\]" simple_expect "3: 10 7 1026 \\(dense\\) \\\[120115 0 0 0 0 0 0 0 129196 129907 \\\]" simple_expect "4: 5 7 1036 \\(dense\\) \\\[130515 131081 131308 0 0 \\\]" # Remove an item from block 2, causing the three last blocks to # merge into one. l2g_send "d0 1016" l2g_send "u0" simple_expect "Number of blocks: 3" simple_expect "First unused: 1041" simple_expect "0: 10 0 35 \\(sparse\\) \\\[35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 \\\]" simple_expect "1: 10 0 445 \\(sparse\\) \\\[474:78372 618:87514 688:88856 792:89215 922:93794 933:95724 948:97085 992:97960 1004:103935 1005:104444 \\\]" simple_expect "2: 10 0 1016 \\(sparse\\) \\\[1022:117110 1023:117278 1024:117886 1025:119385 1026:120115 1034:129196 1035:129907 1036:130515 1037:131081 1038:131308 \\\]" l2g_send "a0 1030 33329" simple_expect "\[0-9\]\[0-9\]\[0-9\]\[0-9\]\[0-9\]\[0-9\] \[0-9\]\[0-9\]:\[0-9\]\[0-9\]:\[0-9\]\[0-9\] \[0-9\]\[0-9\]* l2g_append: won't add 33329<1030> when first_unused=1041" l2g_send "i0 0 10" simple_expect "\[0-9\]\[0-9\]\[0-9\]\[0-9\]\[0-9\]\[0-9\] \[0-9\]\[0-9\]:\[0-9\]\[0-9\]:\[0-9\]\[0-9\] \[0-9\]\[0-9\]* l2gi_searchsome\\\(0, 10\\\) called: min is 1" l2g_send "b0 0 10" l2g_send "i0 1 10" l2g_send "b0 1 10" l2g_send "i0 0 100" simple_expect "\[0-9\]\[0-9\]\[0-9\]\[0-9\]\[0-9\]\[0-9\] \[0-9\]\[0-9\]:\[0-9\]\[0-9\]:\[0-9\]\[0-9\] \[0-9\]\[0-9\]* l2gi_searchsome\\\(0, 100\\\) called: min is 1" simple_expect "35:53428" simple_expect "50:57456" l2g_send "b0 0 100" simple_expect "50:57456" simple_expect "35:53428" l2g_send "I1" # Insert 20 numbers in the range 1001..1020, simulating newly created # texts. l2g_send "a1 1001 201613" l2g_send "a1 1002 202864" l2g_send "a1 1003 203254" l2g_send "a1 1004 203935" l2g_send "a1 1005 204444" l2g_send "a1 1006 205551" l2g_send "a1 1007 205859" l2g_send "a1 1008 206390" l2g_send "a1 1009 206784" l2g_send "a1 1010 207002" l2g_send "a1 1011 207212" l2g_send "a1 1012 207324" l2g_send "a1 1013 207469" l2g_send "a1 1014 207571" l2g_send "a1 1015 208471" l2g_send "a1 1016 208592" l2g_send "a1 1017 209959" l2g_send "a1 1018 211141" l2g_send "a1 1019 211225" l2g_send "a1 1020 213738" # Delete the last texts in each block. l2g_send "d1 1010" l2g_send "d1 1020" # Test that stepping past the delete text works. l2g_send "n1 1008" simple_expect "1009" l2g_send "n1 1009" simple_expect "1011" l2g_send "n1 1010" simple_expect "1011" l2g_send "n1 1018" simple_expect "1019" l2g_send "n1 1019" simple_expect "0" l2g_send "n1 1020" simple_expect "0" l2g_send "n1 1021" simple_expect "0" l2g_send "n1 1022" simple_expect "0" l2g_send "i1 1010 1012" simple_expect "1011:207212" l2g_send "b1 1010 1012" simple_expect "1011:207212" l2g_send "i1 1020 0" l2g_send "b1 1020 0" # Trim the blocks one more from the tail. There are now two removed numbers. l2g_send "d1 1009" l2g_send "d1 1019" l2g_send "n1 1007" simple_expect "1008" l2g_send "n1 1008" simple_expect "1011" l2g_send "n1 1009" simple_expect "1011" l2g_send "n1 1010" simple_expect "1011" l2g_send "n1 1017" simple_expect "1018" l2g_send "n1 1018" simple_expect "0" l2g_send "n1 1019" simple_expect "0" l2g_send "n1 1020" simple_expect "0" l2g_send "n1 1021" simple_expect "0" l2g_send "n1 1022" simple_expect "0" l2g_send "i1 1010 1012" simple_expect "1011:207212" l2g_send "b1 1010 1012" simple_expect "1011:207212" l2g_send "i1 1020 0" l2g_send "b1 1020 0" l2g_send "i1 1009 1012" simple_expect "1011:207212" l2g_send "b1 1009 1012" simple_expect "1011:207212" l2g_send "i1 1019 0" l2g_send "b1 1019 0" # Trim the blocks one more from the tail. There are now three removed numbers. l2g_send "d1 1008" l2g_send "d1 1018" l2g_send "n1 1006" simple_expect "1007" l2g_send "n1 1007" simple_expect "1011" l2g_send "n1 1008" simple_expect "1011" l2g_send "n1 1009" simple_expect "1011" l2g_send "n1 1010" simple_expect "1011" l2g_send "n1 1017" simple_expect "0" l2g_send "n1 1018" simple_expect "0" l2g_send "n1 1019" simple_expect "0" l2g_send "n1 1020" simple_expect "0" l2g_send "n1 1021" simple_expect "0" l2g_send "n1 1022" simple_expect "0" l2g_send "i1 1010 1012" simple_expect "1011:207212" l2g_send "b1 1010 1012" simple_expect "1011:207212" l2g_send "i1 1020 0" l2g_send "b1 1020 0" l2g_send "i1 1009 1012" simple_expect "1011:207212" l2g_send "b1 1009 1012" simple_expect "1011:207212" l2g_send "i1 1019 0" l2g_send "b1 1019 0" l2g_send "i1 1008 1012" simple_expect "1011:207212" l2g_send "b1 1008 1012" simple_expect "1011:207212" l2g_send "i1 1018 0" l2g_send "b1 1018 0" # Remove the first entry in the second block l2g_send "d1 1011" l2g_send "n1 1006" simple_expect "1007" l2g_send "n1 1007" simple_expect "1012" l2g_send "n1 1008" simple_expect "1012" l2g_send "n1 1009" simple_expect "1012" l2g_send "n1 1010" simple_expect "1012" l2g_send "n1 1011" simple_expect "1012" l2g_send "i1 1010 1012" l2g_send "b1 1010 1012" l2g_send "i1 1009 1012" l2g_send "b1 1009 1012" l2g_send "i1 1008 1012" l2g_send "b1 1008 1012" l2g_send "i1 1007 1012" simple_expect "1007:205859" l2g_send "b1 1007 1012" simple_expect "1007:205859" l2g_send "i1 1008 1013" simple_expect "1012:207324" l2g_send "b1 1008 1013" simple_expect "1012:207324" # Clear 0. l2g_send "C0" l2g_send "u0" simple_expect "Number of blocks: 0" simple_expect "First unused: 1" l2g_send "D0" l2g_send "D1" l2g_stop lyskom-server-2.1.2/src/server/testsuite/l2g.0/12.exp0000664000015100472110000006620107721716131015737 # Test suite for Local_to_global. # Copyright (C) 1999, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check l2g_set_expensive. l2g_start l2g_send "I0" # Append 25 random numbers in the range 1..1000, simulating some # sparse old marked texts. l2g_send "a0 35 53428" l2g_send "a0 50 57456" l2g_send "a0 222 59570" l2g_send "a0 259 70441" l2g_send "a0 304 72037" l2g_send "a0 329 72239" l2g_send "a0 358 72910" l2g_send "a0 383 73113" l2g_send "a0 389 73612" l2g_send "a0 395 76393" l2g_send "a0 445 77697" l2g_send "a0 474 78372" l2g_send "a0 482 79436" l2g_send "a0 539 80907" l2g_send "a0 602 84499" l2g_send "a0 612 87035" l2g_send "a0 618 87514" l2g_send "a0 688 88856" l2g_send "a0 792 89215" l2g_send "a0 849 92418" l2g_send "a0 922 93794" l2g_send "a0 923 94866" l2g_send "a0 933 95724" l2g_send "a0 948 97085" l2g_send "a0 992 97960" l2g_send "w0" simple_expect "\\\[993 35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 445:77697 474:78372 482:79436 539:80907 602:84499 612:87035 618:87514 688:88856 792:89215 849:92418 922:93794,94866 933:95724 948:97085 992:97960\\\]" # Insert 25 numbers in the range 1001..1025, simulating newly created # texts. l2g_send "a0 1001 101613" l2g_send "a0 1002 102864" l2g_send "a0 1003 103254" l2g_send "a0 1004 103935" l2g_send "a0 1005 104444" l2g_send "a0 1006 105551" l2g_send "a0 1007 105859" l2g_send "a0 1008 106390" l2g_send "a0 1009 106784" l2g_send "a0 1010 107002" l2g_send "a0 1011 107212" l2g_send "a0 1012 107324" l2g_send "a0 1013 107469" l2g_send "a0 1014 107571" l2g_send "a0 1015 108471" l2g_send "a0 1016 108592" l2g_send "a0 1017 109959" l2g_send "a0 1018 111141" l2g_send "a0 1019 111225" l2g_send "a0 1020 113738" l2g_send "a0 1021 116365" l2g_send "a0 1022 117110" l2g_send "a0 1023 117278" l2g_send "a0 1024 117886" l2g_send "a0 1025 119385" l2g_send "w0" simple_expect "\\\[1026 35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 445:77697 474:78372 482:79436 539:80907 602:84499 612:87035 618:87514 688:88856 792:89215 849:92418 922:93794,94866 933:95724 948:97085 992:97960 1001:101613,102864,103254,103935,104444,105551,105859,106390,106784,107002,107212,107324,107469,107571,108471,108592,109959,111141,111225,113738,116365,117110,117278,117886,119385\\\]" # Check that we've got three sparse blocks and two dense. All of them # are optimally packed. l2g_send "u0" simple_expect "Number of blocks: 5" simple_expect "First unused: 1026" simple_expect "0: 10 0 35 \\(sparse\\) \\\[35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 \\\]" simple_expect "1: 10 0 445 \\(sparse\\) \\\[445:77697 474:78372 482:79436 539:80907 602:84499 612:87035 618:87514 688:88856 792:89215 849:92418 \\\]" simple_expect "2: 10 0 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:104444 \\\]" simple_expect "3: 10 0 1006 \\(dense\\) \\\[105551 105859 106390 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "4: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" # Remove some data. l2g_send "d0 445" l2g_send "d0 849" l2g_send "d0 482" l2g_send "d0 612" l2g_send "d0 602" l2g_send "d0 1005" # Change some settings. l2g_send "s0 445 77698" l2g_send "u0" simple_expect "Number of blocks: 5" simple_expect "First unused: 1026" simple_expect "0: 10 0 35 \\(sparse\\) \\\[35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 \\\]" simple_expect "1: 6 4 445 \\(sparse\\) \\\[445:77698 474:78372 539:80907 618:87514 688:88856 792:89215 \\\]" simple_expect "2: 10 1 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:0 \\\]" simple_expect "3: 10 0 1006 \\(dense\\) \\\[105551 105859 106390 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "4: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" l2g_send "s0 482 79932" l2g_send "u0" simple_expect "Number of blocks: 5" simple_expect "First unused: 1026" simple_expect "0: 10 0 35 \\(sparse\\) \\\[35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76393 \\\]" simple_expect "1: 7 3 445 \\(sparse\\) \\\[445:77698 474:78372 482:79932 539:80907 618:87514 688:88856 792:89215 \\\]" simple_expect "2: 10 1 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:0 \\\]" simple_expect "3: 10 0 1006 \\(dense\\) \\\[105551 105859 106390 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "4: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" l2g_send "s0 395 76394" l2g_send "u0" simple_expect "Number of blocks: 5" simple_expect "First unused: 1026" simple_expect "0: 10 0 35 \\(sparse\\) \\\[35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76394 \\\]" simple_expect "1: 7 3 445 \\(sparse\\) \\\[445:77698 474:78372 482:79932 539:80907 618:87514 688:88856 792:89215 \\\]" simple_expect "2: 10 1 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:0 \\\]" simple_expect "3: 10 0 1006 \\(dense\\) \\\[105551 105859 106390 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "4: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" l2g_send "s0 793 89216" l2g_send "u0" simple_expect "Number of blocks: 5" simple_expect "First unused: 1026" simple_expect "0: 10 0 35 \\(sparse\\) \\\[35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76394 \\\]" simple_expect "1: 8 2 445 \\(sparse\\) \\\[445:77698 474:78372 482:79932 539:80907 618:87514 688:88856 792:89215 793:89216 \\\]" simple_expect "2: 10 1 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:0 \\\]" simple_expect "3: 10 0 1006 \\(dense\\) \\\[105551 105859 106390 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "4: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" l2g_send "s0 794 89217" l2g_send "u0" simple_expect "Number of blocks: 5" simple_expect "First unused: 1026" simple_expect "0: 10 0 35 \\(sparse\\) \\\[35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76394 \\\]" simple_expect "1: 9 1 445 \\(sparse\\) \\\[445:77698 474:78372 482:79932 539:80907 618:87514 688:88856 792:89215 793:89216 794:89217 \\\]" simple_expect "2: 10 1 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:0 \\\]" simple_expect "3: 10 0 1006 \\(dense\\) \\\[105551 105859 106390 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "4: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" l2g_send "s0 795 89218" l2g_send "u0" simple_expect "Number of blocks: 5" simple_expect "First unused: 1026" simple_expect "0: 10 0 35 \\(sparse\\) \\\[35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76394 \\\]" simple_expect "1: 10 0 445 \\(sparse\\) \\\[445:77698 474:78372 482:79932 539:80907 618:87514 688:88856 792:89215 793:89216 794:89217 795:89218 \\\]" simple_expect "2: 10 1 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:0 \\\]" simple_expect "3: 10 0 1006 \\(dense\\) \\\[105551 105859 106390 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "4: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" l2g_send "s0 796 89219" l2g_send "u0" simple_expect "Number of blocks: 6" simple_expect "First unused: 1026" simple_expect "0: 10 0 35 \\(sparse\\) \\\[35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76394 \\\]" simple_expect "1: 10 0 445 \\(sparse\\) \\\[445:77698 474:78372 482:79932 539:80907 618:87514 688:88856 792:89215 793:89216 794:89217 795:89218 \\\]" simple_expect "2: 1 9 796 \\(dense\\) \\\[89219 \\\]" simple_expect "3: 10 1 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:0 \\\]" simple_expect "4: 10 0 1006 \\(dense\\) \\\[105551 105859 106390 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "5: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" l2g_send "s0 444 77690" l2g_send "u0" simple_expect "Number of blocks: 7" simple_expect "First unused: 1026" simple_expect "0: 10 0 35 \\(sparse\\) \\\[35:53428 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76394 \\\]" simple_expect "1: 1 9 444 \\(dense\\) \\\[77690 \\\]" simple_expect "2: 10 0 445 \\(sparse\\) \\\[445:77698 474:78372 482:79932 539:80907 618:87514 688:88856 792:89215 793:89216 794:89217 795:89218 \\\]" simple_expect "3: 1 9 796 \\(dense\\) \\\[89219 \\\]" simple_expect "4: 10 1 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:0 \\\]" simple_expect "5: 10 0 1006 \\(dense\\) \\\[105551 105859 106390 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "6: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" l2g_send "s0 35 53430" l2g_send "u0" simple_expect "Number of blocks: 7" simple_expect "First unused: 1026" simple_expect "0: 10 0 35 \\(sparse\\) \\\[35:53430 50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76394 \\\]" simple_expect "1: 1 9 444 \\(dense\\) \\\[77690 \\\]" simple_expect "2: 10 0 445 \\(sparse\\) \\\[445:77698 474:78372 482:79932 539:80907 618:87514 688:88856 792:89215 793:89216 794:89217 795:89218 \\\]" simple_expect "3: 1 9 796 \\(dense\\) \\\[89219 \\\]" simple_expect "4: 10 1 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:0 \\\]" simple_expect "5: 10 0 1006 \\(dense\\) \\\[105551 105859 106390 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "6: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" l2g_send "s0 35 0" l2g_send "u0" simple_expect "Number of blocks: 6" simple_expect "First unused: 1026" simple_expect "0: 10 0 35 \\(sparse\\) \\\[50:57456 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76394 444:77690 \\\]" simple_expect "1: 10 0 445 \\(sparse\\) \\\[445:77698 474:78372 482:79932 539:80907 618:87514 688:88856 792:89215 793:89216 794:89217 795:89218 \\\]" simple_expect "2: 1 9 796 \\(dense\\) \\\[89219 \\\]" simple_expect "3: 10 1 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:0 \\\]" simple_expect "4: 10 0 1006 \\(dense\\) \\\[105551 105859 106390 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "5: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" l2g_send "s0 50 0" l2g_send "u0" simple_expect "Number of blocks: 6" simple_expect "First unused: 1026" simple_expect "0: 10 1 35 \\(sparse\\) \\\[50:0 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76394 444:77690 \\\]" simple_expect "1: 10 0 445 \\(sparse\\) \\\[445:77698 474:78372 482:79932 539:80907 618:87514 688:88856 792:89215 793:89216 794:89217 795:89218 \\\]" simple_expect "2: 1 9 796 \\(dense\\) \\\[89219 \\\]" simple_expect "3: 10 1 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:0 \\\]" simple_expect "4: 10 0 1006 \\(dense\\) \\\[105551 105859 106390 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "5: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" l2g_send "s0 34 58034" l2g_send "u0" simple_expect "Number of blocks: 7" simple_expect "First unused: 1026" simple_expect "0: 1 9 34 \\(dense\\) \\\[58034 \\\]" simple_expect "1: 10 1 35 \\(sparse\\) \\\[50:0 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76394 444:77690 \\\]" simple_expect "2: 10 0 445 \\(sparse\\) \\\[445:77698 474:78372 482:79932 539:80907 618:87514 688:88856 792:89215 793:89216 794:89217 795:89218 \\\]" simple_expect "3: 1 9 796 \\(dense\\) \\\[89219 \\\]" simple_expect "4: 10 1 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:0 \\\]" simple_expect "5: 10 0 1006 \\(dense\\) \\\[105551 105859 106390 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "6: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" l2g_send "s0 35 58038" l2g_send "u0" simple_expect "Number of blocks: 7" simple_expect "First unused: 1026" simple_expect "0: 1 9 34 \\(dense\\) \\\[58034 \\\]" simple_expect "1: 10 0 35 \\(sparse\\) \\\[35:58038 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76394 444:77690 \\\]" simple_expect "2: 10 0 445 \\(sparse\\) \\\[445:77698 474:78372 482:79932 539:80907 618:87514 688:88856 792:89215 793:89216 794:89217 795:89218 \\\]" simple_expect "3: 1 9 796 \\(dense\\) \\\[89219 \\\]" simple_expect "4: 10 1 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:0 \\\]" simple_expect "5: 10 0 1006 \\(dense\\) \\\[105551 105859 106390 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "6: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" l2g_send "s0 1008 106391" l2g_send "u0" simple_expect "Number of blocks: 7" simple_expect "First unused: 1026" simple_expect "0: 1 9 34 \\(dense\\) \\\[58034 \\\]" simple_expect "1: 10 0 35 \\(sparse\\) \\\[35:58038 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76394 444:77690 \\\]" simple_expect "2: 10 0 445 \\(sparse\\) \\\[445:77698 474:78372 482:79932 539:80907 618:87514 688:88856 792:89215 793:89216 794:89217 795:89218 \\\]" simple_expect "3: 1 9 796 \\(dense\\) \\\[89219 \\\]" simple_expect "4: 10 1 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:0 \\\]" simple_expect "5: 10 0 1006 \\(dense\\) \\\[105551 105859 106391 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "6: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" l2g_send "s0 820 91032" l2g_send "u0" simple_expect "Number of blocks: 8" simple_expect "First unused: 1026" simple_expect "0: 1 9 34 \\(dense\\) \\\[58034 \\\]" simple_expect "1: 10 0 35 \\(sparse\\) \\\[35:58038 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76394 444:77690 \\\]" simple_expect "2: 10 0 445 \\(sparse\\) \\\[445:77698 474:78372 482:79932 539:80907 618:87514 688:88856 792:89215 793:89216 794:89217 795:89218 \\\]" simple_expect "3: 1 9 796 \\(dense\\) \\\[89219 \\\]" simple_expect "4: 1 9 820 \\(dense\\) \\\[91032 \\\]" simple_expect "5: 10 1 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:0 \\\]" simple_expect "6: 10 0 1006 \\(dense\\) \\\[105551 105859 106391 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "7: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" l2g_send "s0 821 91034" l2g_send "u0" simple_expect "Number of blocks: 8" simple_expect "First unused: 1026" simple_expect "0: 1 9 34 \\(dense\\) \\\[58034 \\\]" simple_expect "1: 10 0 35 \\(sparse\\) \\\[35:58038 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76394 444:77690 \\\]" simple_expect "2: 10 0 445 \\(sparse\\) \\\[445:77698 474:78372 482:79932 539:80907 618:87514 688:88856 792:89215 793:89216 794:89217 795:89218 \\\]" simple_expect "3: 1 9 796 \\(dense\\) \\\[89219 \\\]" simple_expect "4: 2 8 820 \\(dense\\) \\\[91032 91034 \\\]" simple_expect "5: 10 1 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:0 \\\]" simple_expect "6: 10 0 1006 \\(dense\\) \\\[105551 105859 106391 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "7: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" l2g_send "s0 823 91039" l2g_send "u0" simple_expect "Number of blocks: 8" simple_expect "First unused: 1026" simple_expect "0: 1 9 34 \\(dense\\) \\\[58034 \\\]" simple_expect "1: 10 0 35 \\(sparse\\) \\\[35:58038 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76394 444:77690 \\\]" simple_expect "2: 10 0 445 \\(sparse\\) \\\[445:77698 474:78372 482:79932 539:80907 618:87514 688:88856 792:89215 793:89216 794:89217 795:89218 \\\]" simple_expect "3: 1 9 796 \\(dense\\) \\\[89219 \\\]" simple_expect "4: 4 7 820 \\(dense\\) \\\[91032 91034 0 91039 \\\]" simple_expect "5: 10 1 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:0 \\\]" simple_expect "6: 10 0 1006 \\(dense\\) \\\[105551 105859 106391 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "7: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" l2g_send "s0 830 91229" l2g_send "u0" simple_expect "Number of blocks: 9" simple_expect "First unused: 1026" simple_expect "0: 1 9 34 \\(dense\\) \\\[58034 \\\]" simple_expect "1: 10 0 35 \\(sparse\\) \\\[35:58038 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76394 444:77690 \\\]" simple_expect "2: 10 0 445 \\(sparse\\) \\\[445:77698 474:78372 482:79932 539:80907 618:87514 688:88856 792:89215 793:89216 794:89217 795:89218 \\\]" simple_expect "3: 1 9 796 \\(dense\\) \\\[89219 \\\]" simple_expect "4: 4 7 820 \\(dense\\) \\\[91032 91034 0 91039 \\\]" simple_expect "5: 1 9 830 \\(dense\\) \\\[91229 \\\]" simple_expect "6: 10 1 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:0 \\\]" simple_expect "7: 10 0 1006 \\(dense\\) \\\[105551 105859 106391 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "8: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" l2g_send "s0 829 91221" l2g_send "u0" simple_expect "Number of blocks: 9" simple_expect "First unused: 1026" simple_expect "0: 1 9 34 \\(dense\\) \\\[58034 \\\]" simple_expect "1: 10 0 35 \\(sparse\\) \\\[35:58038 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76394 444:77690 \\\]" simple_expect "2: 10 0 445 \\(sparse\\) \\\[445:77698 474:78372 482:79932 539:80907 618:87514 688:88856 792:89215 793:89216 794:89217 795:89218 \\\]" simple_expect "3: 1 9 796 \\(dense\\) \\\[89219 \\\]" simple_expect "4: 10 6 820 \\(dense\\) \\\[91032 91034 0 91039 0 0 0 0 0 91221 \\\]" simple_expect "5: 1 9 830 \\(dense\\) \\\[91229 \\\]" simple_expect "6: 10 1 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:0 \\\]" simple_expect "7: 10 0 1006 \\(dense\\) \\\[105551 105859 106391 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "8: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119385 \\\]" l2g_send "s0 1025 119386" l2g_send "u0" simple_expect "Number of blocks: 9" simple_expect "First unused: 1026" simple_expect "0: 1 9 34 \\(dense\\) \\\[58034 \\\]" simple_expect "1: 10 0 35 \\(sparse\\) \\\[35:58038 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76394 444:77690 \\\]" simple_expect "2: 10 0 445 \\(sparse\\) \\\[445:77698 474:78372 482:79932 539:80907 618:87514 688:88856 792:89215 793:89216 794:89217 795:89218 \\\]" simple_expect "3: 1 9 796 \\(dense\\) \\\[89219 \\\]" simple_expect "4: 10 6 820 \\(dense\\) \\\[91032 91034 0 91039 0 0 0 0 0 91221 \\\]" simple_expect "5: 1 9 830 \\(dense\\) \\\[91229 \\\]" simple_expect "6: 10 1 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:0 \\\]" simple_expect "7: 10 0 1006 \\(dense\\) \\\[105551 105859 106391 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "8: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119386 \\\]" l2g_send "s0 1026 119389" l2g_send "u0" simple_expect "Number of blocks: 10" simple_expect "First unused: 1027" simple_expect "0: 1 9 34 \\(dense\\) \\\[58034 \\\]" simple_expect "1: 10 0 35 \\(sparse\\) \\\[35:58038 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76394 444:77690 \\\]" simple_expect "2: 10 0 445 \\(sparse\\) \\\[445:77698 474:78372 482:79932 539:80907 618:87514 688:88856 792:89215 793:89216 794:89217 795:89218 \\\]" simple_expect "3: 1 9 796 \\(dense\\) \\\[89219 \\\]" simple_expect "4: 10 6 820 \\(dense\\) \\\[91032 91034 0 91039 0 0 0 0 0 91221 \\\]" simple_expect "5: 1 9 830 \\(dense\\) \\\[91229 \\\]" simple_expect "6: 10 1 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:0 \\\]" simple_expect "7: 10 0 1006 \\(dense\\) \\\[105551 105859 106391 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "8: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119386 \\\]" simple_expect "9: 1 9 1026 \\(dense\\) \\\[119389 \\\]" l2g_send "s0 1200 119390" l2g_send "u0" simple_expect "Number of blocks: 10" simple_expect "First unused: 1201" simple_expect "0: 1 9 34 \\(dense\\) \\\[58034 \\\]" simple_expect "1: 10 0 35 \\(sparse\\) \\\[35:58038 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76394 444:77690 \\\]" simple_expect "2: 10 0 445 \\(sparse\\) \\\[445:77698 474:78372 482:79932 539:80907 618:87514 688:88856 792:89215 793:89216 794:89217 795:89218 \\\]" simple_expect "3: 1 9 796 \\(dense\\) \\\[89219 \\\]" simple_expect "4: 10 6 820 \\(dense\\) \\\[91032 91034 0 91039 0 0 0 0 0 91221 \\\]" simple_expect "5: 1 9 830 \\(dense\\) \\\[91229 \\\]" simple_expect "6: 10 1 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:0 \\\]" simple_expect "7: 10 0 1006 \\(dense\\) \\\[105551 105859 106391 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "8: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119386 \\\]" simple_expect "9: 2 8 1026 \\(sparse\\) \\\[1026:119389 1200:119390 \\\]" l2g_send "s0 1200 0" l2g_send "s0 1026 0" l2g_send "u0" simple_expect "Number of blocks: 9" simple_expect "First unused: 1201" simple_expect "0: 1 9 34 \\(dense\\) \\\[58034 \\\]" simple_expect "1: 10 0 35 \\(sparse\\) \\\[35:58038 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76394 444:77690 \\\]" simple_expect "2: 10 0 445 \\(sparse\\) \\\[445:77698 474:78372 482:79932 539:80907 618:87514 688:88856 792:89215 793:89216 794:89217 795:89218 \\\]" simple_expect "3: 1 9 796 \\(dense\\) \\\[89219 \\\]" simple_expect "4: 10 6 820 \\(dense\\) \\\[91032 91034 0 91039 0 0 0 0 0 91221 \\\]" simple_expect "5: 1 9 830 \\(dense\\) \\\[91229 \\\]" simple_expect "6: 10 1 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:0 \\\]" simple_expect "7: 10 0 1006 \\(dense\\) \\\[105551 105859 106391 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "8: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119386 \\\]" l2g_send "s0 1026 119389" l2g_send "u0" simple_expect "Number of blocks: 10" simple_expect "First unused: 1201" simple_expect "0: 1 9 34 \\(dense\\) \\\[58034 \\\]" simple_expect "1: 10 0 35 \\(sparse\\) \\\[35:58038 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76394 444:77690 \\\]" simple_expect "2: 10 0 445 \\(sparse\\) \\\[445:77698 474:78372 482:79932 539:80907 618:87514 688:88856 792:89215 793:89216 794:89217 795:89218 \\\]" simple_expect "3: 1 9 796 \\(dense\\) \\\[89219 \\\]" simple_expect "4: 10 6 820 \\(dense\\) \\\[91032 91034 0 91039 0 0 0 0 0 91221 \\\]" simple_expect "5: 1 9 830 \\(dense\\) \\\[91229 \\\]" simple_expect "6: 10 1 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:0 \\\]" simple_expect "7: 10 0 1006 \\(dense\\) \\\[105551 105859 106391 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "8: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119386 \\\]" simple_expect "9: 1 9 1026 \\(dense\\) \\\[119389 \\\]" l2g_send "s0 1126 120389" l2g_send "u0" simple_expect "Number of blocks: 11" simple_expect "First unused: 1201" simple_expect "0: 1 9 34 \\(dense\\) \\\[58034 \\\]" simple_expect "1: 10 0 35 \\(sparse\\) \\\[35:58038 222:59570 259:70441 304:72037 329:72239 358:72910 383:73113 389:73612 395:76394 444:77690 \\\]" simple_expect "2: 10 0 445 \\(sparse\\) \\\[445:77698 474:78372 482:79932 539:80907 618:87514 688:88856 792:89215 793:89216 794:89217 795:89218 \\\]" simple_expect "3: 1 9 796 \\(dense\\) \\\[89219 \\\]" simple_expect "4: 10 6 820 \\(dense\\) \\\[91032 91034 0 91039 0 0 0 0 0 91221 \\\]" simple_expect "5: 1 9 830 \\(dense\\) \\\[91229 \\\]" simple_expect "6: 10 1 922 \\(sparse\\) \\\[922:93794 923:94866 933:95724 948:97085 992:97960 1001:101613 1002:102864 1003:103254 1004:103935 1005:0 \\\]" simple_expect "7: 10 0 1006 \\(dense\\) \\\[105551 105859 106391 106784 107002 107212 107324 107469 107571 108471 \\\]" simple_expect "8: 10 0 1016 \\(dense\\) \\\[108592 109959 111141 111225 113738 116365 117110 117278 117886 119386 \\\]" simple_expect "9: 1 9 1026 \\(dense\\) \\\[119389 \\\]" simple_expect "10: 1 9 1126 \\(dense\\) \\\[120389 \\\]" # Clear 0. l2g_send "C0" l2g_send "u0" simple_expect "Number of blocks: 0" simple_expect "First unused: 1" l2g_send "D0" l2g_stop lyskom-server-2.1.2/src/server/testsuite/leaks.0/0000777000015100472110000000000007723710371015471 5lyskom-server-2.1.2/src/server/testsuite/leaks.0/leaks00.exp0000664000015100472110000000324007721716131017361 # Hunt for memory leaks. # Copyright (C) 1999, 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check for memory leaks read_versions source "$srcdir/config/leaks.exp" # ---------------------------------------------------------------------- # Test for leaks in text creation startup_leaks send "1000 86 [holl "Memory leaks suck"] 1 { 0 5 } 1 { 1000 00000000 0 [holl "Aux-items rock!"] }\n" simple_expect "=1000 1" shutdown_leaks read_usage_base startup_leaks kom_accept_async "2 { 0 15 }" for { set i 0 } { $i < 200 } { incr i 1 } { send "[expr 1000 + $i] 86 [holl "Memory leaks suck"] 1 { 0 5 } 1 { 1000 00000000 0 [holl "Aux-items rock!"] }\n" simple_expect ":16 0\[^\n\]*" simple_expect ":18 15\[^\n\]*" simple_expect "=[expr 1000 + $i] [expr 1 + $i]" } shutdown_leaks check_usage "Text creation" "leaks00" lyskom-server-2.1.2/src/server/testsuite/leaks.0/leaks01.exp0000664000015100472110000000307507721716132017371 # Hunt for memory leaks. # Copyright (C) 1999, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # ---------------------------------------------------------------------- # Test for leaks in conference creation read_versions source "$srcdir/config/leaks.exp" startup_leaks send "2000 88 [holl "Leaks Conference 2000"] 00000000 1 { 1000 00000000 0 [holl "Aux-items rock!"] }\n" simple_expect "=2000 6" shutdown_leaks read_usage_base startup_leaks for { set i 0 } { $i < 200 } { incr i 1 } { send "[expr 2000 + $i] 88 [holl "Leaks Conference [expr 2000 + $i]"] 00000000 1 { 1000 00000000 0 [holl "Aux-items rock!"] }\n" simple_expect "=[expr 2000 + $i] [expr 6 + $i]" } shutdown_leaks check_usage "Conference creation" "leaks01" lyskom-server-2.1.2/src/server/testsuite/leaks.0/leaks02.exp0000664000015100472110000000311407721716132017364 # Hunt for memory leaks. # Copyright (C) 1999, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. read_versions source "$srcdir/config/leaks.exp" # ---------------------------------------------------------------------- # Test for leaks in person creation startup_leaks send "3000 89 [holl "Leaky Memory 3000"] [holl "wossit"] 00000000 1 { 1000 00000000 0 [holl "Aux-items rock!"] }\n" simple_expect "=3000 6" shutdown_leaks read_usage_base startup_leaks for { set i 0 } { $i < 200 } { incr i 1 } { send "[expr 3000 + $i] 89 [holl "Leaky Memory [expr 3000 + $i]"] [holl "wossit"] 00000000 1 { 1000 00000000 0 [holl "Aux-items rock!"] }\n" simple_expect "=[expr 3000 + $i] [expr 6 + $i]" } shutdown_leaks check_usage "Person creation" "leaks02" lyskom-server-2.1.2/src/server/testsuite/leaks.0/leaks03.exp0000664000015100472110000000323507721716132017371 # Hunt for memory leaks. # Copyright (C) 1999, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. read_versions source "$srcdir/config/leaks.exp" # ---------------------------------------------------------------------- # Test for leaks in aux-item parsing startup_leaks send "1000 86 [holl "Parse me!"] 1 { 0 5 } 1 { 1000 00000000 0 [holl "Memory leaks blow!"] }\n" simple_expect "=1000 1" shutdown_leaks read_usage_base startup_leaks for { set i 0 } { $i < 200 } { incr i 1 } { send "[expr $i + 1000 ] 86 [holl "Parse me"] 1 { 0 5 } 4 { 1000 00000000 0 [holl "Memory leaks blow!"] 1000 00000000 0 [holl "Memory leaks blow!"] 1000 00000000 0 [holl "Memory leaks blow!"] 1000 00000000 0 [holl "Memory leaks blow!"] }\n" simple_expect "=[expr $i + 1000] [expr 1 + $i]" } shutdown_leaks check_usage "Aux-item parser" "leaks03" lyskom-server-2.1.2/src/server/testsuite/leaks.0/leaks04.exp0000664000015100472110000000320007721716132017362 # Hunt for memory leaks. # Copyright (C) 1999, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. read_versions source "$srcdir/config/leaks.exp" # ---------------------------------------------------------------------- # Test adding aux-items en masse startup_leaks send "1000 86 [holl "Sample test"] 1 { 0 5 } 0 { }\n" simple_expect "=1000 1" shutdown_leaks read_usage_base startup_leaks send "1000 86 [holl "Sample test"] 1 { 0 5 } 0 { }\n" simple_expect "=1000 1" for { set i 0 } { $i < 200 } { incr i 1 } { send "[expr $i + 1000] 92 1 0 { } 3 { 1000 00000000 0 [holl "Lost my memory blues"] 1000 00000000 0 [holl "Lost my memory blues too"] 1000 00000000 0 [holl "Lost my memory blues again"] }\n" simple_expect "=[expr $i + 1000]" } shutdown_leaks check_usage "Adding aux-items" "leaks04" lyskom-server-2.1.2/src/server/testsuite/leaks.0/leaks05.exp0000664000015100472110000000351707721716132017376 # Hunt for memory leaks. # Copyright (C) 1999, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. read_versions source "$srcdir/config/leaks.exp" # ---------------------------------------------------------------------- # Test adding and deleting aux-items en masse startup_leaks send "1000 86 [holl "Sample test"] 1 { 0 5 } 0 { }\n" simple_expect "=1000 1" shutdown_leaks read_usage_base startup_leaks send "1000 86 [holl "Sample test"] 1 { 0 5 } 0 { }\n" simple_expect "=1000 1" for { set i 0 } { $i < 200 } { incr i 1 } { send "[expr $i + 1000] 92 1 0 { } 3 { 1000 00000000 0 [holl "Lost my memory blues"] 1000 00000000 0 [holl "Lost my memory blues too"] 1000 00000000 0 [holl "Lost my memory blues again"] }\n" simple_expect "=[expr $i + 1000]" } for { set i 0 } { $i < 200 } { incr i 1 } { send "[expr $i + 2000] 92 1 3 { [expr $i * 3] [expr $i * 3 + 1] [expr $i * 3 + 2] } 0 { }\n" simple_expect "=[expr $i + 2000]" } shutdown_leaks check_usage "Adding and deleting aux-items" "leaks05" lyskom-server-2.1.2/src/server/testsuite/leaks.0/leaks06.exp0000664000015100472110000000320507721716132017371 # Hunt for memory leaks. # Copyright (C) 1999, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. read_versions source "$srcdir/config/leaks.exp" # ---------------------------------------------------------------------- # Test inheriting a pile of aux-items startup_leaks shutdown_leaks read_usage_base startup_leaks send "1000 86 [holl "Sample test"] 1 { 0 5 } 3 { 1000 01000000 0 [holl "Inherit me!"] 1000 01000000 0 [holl "Inherit me too!"] 1000 01000000 0 [holl "Inherit me three!"] }\n" simple_expect "=1000 1" for { set i 0 } { $i < 200 } { incr i 1 } { send "[expr 1000 + $i] 86 [holl "Sample test"] 2 { 0 5 2 [expr $i + 1] } 1 { 1000 00000000 0 [holl "Don't inherit me"] }\n" simple_expect "=[expr 1000 + $i] [expr 2 + $i]" } shutdown_leaks check_usage "Adding and inheriting items" "leaks06" lyskom-server-2.1.2/src/server/testsuite/leaks.0/leaks07.exp0000664000015100472110000000302307721716132017370 # Hunt for memory leaks. # Copyright (C) 1999, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check for memory leaks read_versions source "$srcdir/config/leaks.exp" # ---------------------------------------------------------------------- # Test for leaks in system aux items startup_leaks shutdown_leaks read_usage_base startup_leaks kom_enable 255 for { set i 0 } { $i < 200 } { incr i 1 } { send "[expr $i + 1000] 95 0 { } 3 { 1000 00000000 0 [holl "Lost my memory blues"] 1000 00000000 0 [holl "Lost my memory blues too"] 1000 00000000 0 [holl "Lost my memory blues again"] }\n" simple_expect "=[expr $i + 1000]" } shutdown_leaks check_usage "Adding system aux-items" leaks07 lyskom-server-2.1.2/src/server/testsuite/leaks.0/leaks08.exp0000664000015100472110000000332207721716132017373 # Hunt for memory leaks. # Copyright (C) 1999, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check for memory leaks read_versions source "$srcdir/config/leaks.exp" # ---------------------------------------------------------------------- # Test for leaks in system aux items startup_leaks shutdown_leaks read_usage_base startup_leaks kom_enable 255 for { set i 0 } { $i < 200 } { incr i 1 } { send "[expr $i + 1000] 95 0 { } 3 { 1000 00000000 0 [holl "Lost my memory blues"] 1000 00000000 0 [holl "Lost my memory blues too"] 1000 00000000 0 [holl "Lost my memory blues again"] }\n" simple_expect "=[expr $i + 1000]" } for { set i 0 } { $i < 200 } { incr i 1 } { send "[expr $i + 2000] 95 3 { [expr $i * 3] [expr $i * 3 + 1] [expr $i * 3 + 2] } 0 { }\n" simple_expect "=[expr $i + 2000]" } shutdown_leaks check_usage "Adding and removing system aux-items" leaks08 lyskom-server-2.1.2/src/server/testsuite/leaks.0/leaks09.exp0000664000015100472110000001033407721716132017375 # Hunt for memory leaks. # Copyright (C) 1999, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test for leaks when we have to truncate stuff read_versions source "$srcdir/config/leaks.exp" # ---------------------------------------------------------------------- # Test for leaks in text creation startup_leaks "" "\ Max client data length: 1 Max aux_items added per call: 1 Max aux_items deleted per call: 1 Max links per text: 1" send "1000 69 [holl "1234567890"] [holl "1234567890"]\n" simple_expect "%1000 5 1" shutdown_leaks read_usage_base startup_leaks "" "\ Max client data length: 1 Max aux_items added per call: 1 Max aux_items deleted per call: 1 Max links per text: 1" for { set i 0 } { $i < 200 } { incr i 1 } { # String truncation send "[expr 1000 + $i] 69 [holl "1234567890"] [holl "1234567890"]\n" simple_expect "%[expr 1000 + $i] 5 1" } shutdown_leaks check_usage "String truncation" "leaks09-1" startup_leaks "" "\ Max client data length: 1 Max aux_items added per call: 1 Max aux_items deleted per call: 1 Max links per text: 1" send "2000 95 0 { } 10 { 10000 00000000 0 [holl "X"] 10000 00000000 0 [holl "X"] 10000 00000000 0 [holl "X"] 10000 00000000 0 [holl "X"] 10000 00000000 0 [holl "X"] 10000 00000000 0 [holl "X"] 10000 00000000 0 [holl "X"] 10000 00000000 0 [holl "X"] 10000 00000000 0 [holl "X"] 10000 00000000 0 [holl "X"] }\n" simple_expect "%2000 46 $any_num" shutdown_leaks read_usage_base startup_leaks "" "\ Max client data length: 1 Max aux_items added per call: 1 Max aux_items deleted per call: 1 Max links per text: 1" for { set i 0 } { $i < 200 } { incr i 1 } { # Aux-item list truncation send "[expr 2000 + $i] 95 0 { } 10 { 10000 00000000 0 [holl "X"] 10000 00000000 0 [holl "X"] 10000 00000000 0 [holl "X"] 10000 00000000 0 [holl "X"] 10000 00000000 0 [holl "X"] 10000 00000000 0 [holl "X"] 10000 00000000 0 [holl "X"] 10000 00000000 0 [holl "X"] 10000 00000000 0 [holl "X"] 10000 00000000 0 [holl "X"] }\n" simple_expect "%[expr 2000 + $i] 46 $any_num" } shutdown_leaks check_usage "Aux item list truncation" "leaks09-2" startup_leaks "" "\ Max client data length: 1 Max aux_items added per call: 1 Max aux_items deleted per call: 1 Max links per text: 1" send "3000 95 10 { 1 2 3 4 5 6 7 8 9 10 } 0 { }\n" simple_expect "%3000 46 $any_num" shutdown_leaks read_usage_base startup_leaks "" "\ Max client data length: 1 Max aux_items added per call: 1 Max aux_items deleted per call: 1 Max links per text: 1" for { set i 0 } { $i < 200 } { incr i 1 } { # Num-list truncation send "[expr 3000 + $i] 95 10 { 1 2 3 4 5 6 7 8 9 10 } 0 { }\n" simple_expect "%[expr 3000 + $i] 46 $any_num" } shutdown_leaks check_usage "Number list truncation" "leaks09-3" startup_leaks "" "\ Max client data length: 1 Max aux_items added per call: 1 Max aux_items deleted per call: 1 Max links per text: 1" send "4000 86 [holl "X"] 10 { 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 } 0 { }\n" simple_expect "%4000 46 $any_num" shutdown_leaks read_usage_base startup_leaks "" "\ Max client data length: 1 Max aux_items added per call: 1 Max aux_items deleted per call: 1 Max links per text: 1" for { set i 0 } { $i < 200 } { incr i 1 } { # Misc-info-list truncation send "[expr 4000 + $i] 86 [holl "X"] 10 { 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 } 0 { }\n" simple_expect "%[expr 4000 + $i] 46 $any_num" } shutdown_leaks check_usage "Misc-info list truncation" "leaks09-4" lyskom-server-2.1.2/src/server/testsuite/leaks.0/leaks10.exp0000664000015100472110000000235007721716132017364 # Hunt for memory leaks. # Copyright (C) 1999-2000, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test for leaks in the aux-item definition parser read_versions source "$srcdir/config/leaks.exp" startup_leaks "$srcdir/leaks.0/no-aux-items.conf" shutdown_leaks read_usage_base startup_leaks "$srcdir/leaks.0/lots-aux-items.conf" shutdown_leaks check_usage "Aux item definition parser" auxp lyskom-server-2.1.2/src/server/testsuite/leaks.0/lots-aux-items.conf0000664000015100472110000002555307721716132021162 # # $Id: lots-aux-items.conf,v 1.5 2003/08/23 16:38:10 ceder Exp $ # Copyright (C) 1999, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # # Content type of a text (MIME type) # 1 : content-type (text) { author-only = true; unique = true; secret = false; hide-creator = false; dont-garb = false; inherit = false; inherit-limit = 1; validate = "^.*/.*$"; validate = existing-readable-text(); add-trigger = mark-text(); delete-trigger = unmark-text(); undelete-trigger = mark-text(); } 100 : content-type (text) { author-only = true; unique = true; secret = false; hide-creator = false; dont-garb = false; inherit = false; inherit-limit = 1; validate = "^.*/.*$"; validate = existing-readable-text(); add-trigger = mark-text(); delete-trigger = unmark-text(); undelete-trigger = mark-text(); } 101 : content-type (text) { author-only = true; unique = true; secret = false; hide-creator = false; dont-garb = false; inherit = false; inherit-limit = 1; validate = "^.*/.*$"; validate = existing-readable-text(); add-trigger = mark-text(); delete-trigger = unmark-text(); undelete-trigger = mark-text(); } 102 : content-type (text) { author-only = true; unique = true; secret = false; hide-creator = false; dont-garb = false; inherit = false; inherit-limit = 1; validate = "^.*/.*$"; validate = existing-readable-text(); add-trigger = mark-text(); delete-trigger = unmark-text(); undelete-trigger = mark-text(); } 103 : content-type (text) { author-only = true; unique = true; secret = false; hide-creator = false; dont-garb = false; inherit = false; inherit-limit = 1; validate = "^.*/.*$"; validate = existing-readable-text(); add-trigger = mark-text(); delete-trigger = unmark-text(); undelete-trigger = mark-text(); } 104 : content-type (text) { author-only = true; unique = true; secret = false; hide-creator = false; dont-garb = false; inherit = false; inherit-limit = 1; validate = "^.*/.*$"; validate = existing-readable-text(); add-trigger = mark-text(); delete-trigger = unmark-text(); undelete-trigger = mark-text(); } 105 : content-type (text) { author-only = true; unique = true; secret = false; hide-creator = false; dont-garb = false; inherit = false; inherit-limit = 1; validate = "^.*/.*$"; validate = existing-readable-text(); add-trigger = mark-text(); delete-trigger = unmark-text(); undelete-trigger = mark-text(); } 106 : content-type (text) { author-only = true; unique = true; secret = false; hide-creator = false; dont-garb = false; inherit = false; inherit-limit = 1; validate = "^.*/.*$"; validate = existing-readable-text(); add-trigger = mark-text(); delete-trigger = unmark-text(); undelete-trigger = mark-text(); } 107 : content-type (text) { author-only = true; unique = true; secret = false; hide-creator = false; dont-garb = false; inherit = false; inherit-limit = 1; validate = "^.*/.*$"; validate = existing-readable-text(); add-trigger = mark-text(); delete-trigger = unmark-text(); undelete-trigger = mark-text(); } 108 : content-type (text) { author-only = true; unique = true; secret = false; hide-creator = false; dont-garb = false; inherit = false; inherit-limit = 1; validate = "^.*/.*$"; validate = existing-readable-text(); add-trigger = mark-text(); delete-trigger = unmark-text(); undelete-trigger = mark-text(); } 109 : content-type (text) { author-only = true; unique = true; secret = false; hide-creator = false; dont-garb = false; inherit = false; inherit-limit = 1; validate = "^.*/.*$"; validate = existing-readable-text(); add-trigger = mark-text(); delete-trigger = unmark-text(); undelete-trigger = mark-text(); } # # Quick reply to a text # 2 : fast-reply (text) { secret = false; hide-creator = false; dont-garb = false; inherit = false; inherit-limit = 1; } # # Cross reference from one object to another # 3 : cross-reference (text, conference, letterbox) { dont-garb = false; inherit = false; inherit-limit = 1; validate = "^[CTP][0-9]+"; } # # Request for no comments to a text # 4 : no-comments (text) { secret = false; hide-creator = false; author-only = true; dont-garb = false; inherit = false; inherit-limit = 1; } # # Request for personal comments only # 5 : personal-comment (text) { secret = false; hide-creator = false; author-only = true; dont-garb = false; inherit = false; inherit-limit = 1; } # # Request for read confirmation # 6 : request-confirmation (text) { secret = false; unique = true; dont-garb = false; inherit = false; inherit-limit = 1; } # # Read confirmation (creator has read the text) # 7 : read-confirm (text) { secret = false; hide-creator = false; dont-garb = false; inherit = false; inherit-limit = 1; permanent = true; } # # Request redirect of texts from one conference to another or to e-mail # 8 : redirect (conference, letterbox) { dont-garb = false; supervisor-only = true; validate = "^(LysKOM|E-mail):"; } # # Graphics in compface format # 9 : x-face (conference, letterbox, server) { secret = false; hide-creator = false; supervisor-only = true; dont-garb = false; inherit = false; inherit-limit = 1; } # # Alternate name (subject or name) selected by the creator # 10 : alternate-name (text, conference, letterbox) { dont-garb = false; inherit = false; } # # PGP signature of a text (created with pgp -fsba) # 11 : pgp-signature (text) { permanent = true; hide-creator = false; dont-garb = false; inherit = false; inherit-limit = 1; } # # Public key of a person # 12 : pgp-public-key (letterbox) { author-only = true; hide-creator = false; dont-garb = false; inherit = false; inherit-limit = 1; } # # E-mail address of a person or conference # 13 : e-mail-address (conference, letterbox, server) { author-only = true; hide-creator = false; dont-garb = false; inherit = false; inherit-limit = 1; } # # FAQ in Text # 14 : faq-text (conference, server) { author-only = true; hide-creator = false; secret = false; inherit = false; inherit-limit = 1; add-trigger = link-faq(); validate = "^[0-9][0-9]*$"; validate = existing-readable-text(); } # # Name of the creating software # 15 : creating-software (text) { author-only = true; permanent = true; unique = true; hide-creator = false; dont-garb = false; inherit = false; } # # Name of actual author. # 16 : mx-author (create text) { author-only = true; unique = true; } # # From header of an imported e-mail # 17 : mx-from (text) { author-only = true; unique = false; } # # Reply-To header of an imported e-mail # 18 : mx-reply-to (text) { author-only = true; unique = false; } # # To header of an imported or to-be-exported e-mail # 19 : mx-to (text) { author-only = false; unique = false; hide-creator = false; secret = false; } # # CC header of an imported or to-be-exported e-mail # 20 : mx-cc (text) { author-only = false; unique = false; hide-creator = false; secret = false; } # # Date header of an imported e-mail # 21 : mx-date (text) { author-only = true; unique = true; inherit = false; validate = "[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]\\( [-+][0-9][0-9][0-9][0-9]\\)?"; } # # Message-ID header of an imported e-mail # 22 : mx-message-id (text) { author-only = true; unique = true; } # # In-Reply-To header of an imported e-mail # 23 : mx-in-reply-to (text) { author-only = true; unique = false; } # # All mail headers # 24 : mx-misc (text) { author-only = true; unique = true; } # # Mail filtering or something like that # Nobody quite knows how this will be used, so DON'T! # 25 : mx-allow-filter (conference, letterbox) disabled { author-only = true; unique = false; } # # Mail rejection # Nobody quite knows how this will be used, so DON'T! # 26 : mx-reject-forward (conference, letterbox) disabled { author-only = true; unique = false; } # # Notify user about comments to text # 27 : notify-comments (letterbox) { author-only = true; validate = "^[0-9]+$"; validate = existing-readable-text(); } # # Mirror of FAQ-text # 28 : faq-for-conf (text) { system-only = true; dont-garb = true; } lyskom-server-2.1.2/src/server/testsuite/leaks.0/no-aux-items.conf0000664000015100472110000000000006721243441020566 lyskom-server-2.1.2/src/server/testsuite/leaks.0/leaks99.exp0000664000015100472110000000234107721716132017405 # Hunt for memory leaks. # Copyright (C) 1999-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. read_versions source "$srcdir/config/leaks.exp" startup_leaks "" shutdown_leaks read_usage_base startup_leaks "$srcdir/leaks.0/no-aux-items.conf" shutdown_leaks read_usage_base startup_leaks "$srcdir/leaks.0/lots-aux-items.conf" shutdown_leaks check_usage "Aux item definition parser" auxp lyskom-server-2.1.2/src/server/testsuite/Makefile.am0000664000015100472110000001371407721716131016212 # $Id: Makefile.am,v 1.67 2003/08/23 16:38:12 ceder Exp $ # Copyright (C) 1998-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # include $(top_srcdir)/scripts/common.make SUBDIRS = config lyskomd.0 check_PROGRAMS = test-l2g bignum testfd test-select test-sigjmp \ timeval-overflow get-time-often check_DATA = site.exp .gdbinit valgrind.wrap ## The proper value of this depends on PROTECTED_FDS. See config/unix.exp. VALGRIND_FD = 21 EXTRA_DIST = .cvsignore \ l2g.0/00.exp l2g.0/01.exp l2g.0/02.exp l2g.0/03.exp \ l2g.0/04.exp l2g.0/05.exp l2g.0/06.exp l2g.0/07.exp \ l2g.0/08.exp l2g.0/09.exp l2g.0/10.exp l2g.0/11.exp \ l2g.0/12.exp \ leaks.0/leaks00.exp \ leaks.0/leaks01.exp \ leaks.0/leaks02.exp \ leaks.0/leaks03.exp \ leaks.0/leaks04.exp \ leaks.0/leaks05.exp \ leaks.0/leaks06.exp \ leaks.0/leaks07.exp \ leaks.0/leaks08.exp \ leaks.0/leaks09.exp \ leaks.0/leaks10.exp \ leaks.0/lots-aux-items.conf \ leaks.0/no-aux-items.conf \ locksuite.py \ lyskomd.supp \ renumber.el \ tcpconnect.py \ leaks.0/leaks99.exp MOSTLYCLEANFILES = .gdbinit site.exp *.sum *.log usage-base.tmp usage.all \ lyskomd.*.usage lyskomd.*.base *.da *.bb *.gcov *.bbg \ valgrind-*.log valgrind.log valgrind.wrap \ memory-usage-*.log mostlyclean-local: $(RM) -r -f db etc test_l2g_SOURCES = test-l2g.c test_l2g_LDADD = ../libcheck.a \ ../../libraries/libmisc/libmisc.a \ ../../libraries/libcommon/liblyskom-server.a \ ../libcheck.a \ ../../libraries/libansi/libansi.a bignum_SOURCES = bignum.c testfd_SOURCES = testfd.c timeval_overflow_SOURCES = timeval-overflow.c test_select_SOURCES = test-select.c test_select_LDADD = ../../libraries/libansi/libansi.a test_sigjmp_SOURCES = test-sigjmp.c test_sigjmp_LDADD = ../../libraries/libansi/libansi.a get_time_often_SOURCES = get-time-often.c get_time_often_LDADD = \ ../libcheck.a \ ../../libraries/libisc-new/src/libisc.a \ ../../libraries/liboop/liboop.a \ ../../libraries/adns/src/libadns.a \ ../../libraries/libmisc/libmisc.a \ ../libcheck.a ../libcheck.a: (cd .. && $(MAKE) libcheck.a) ../lyskomd: (cd .. && $(MAKE) lyskomd) AM_CPPFLAGS = -I$(srcdir)/.. \ -I../../.. \ -I$(srcdir)/../../include \ -I$(srcdir)/../../libraries/libansi \ -I$(srcdir)/../../libraries/libmisc \ -I$(srcdir)/../../libraries/libisc-new/src \ -I$(srcdir)/../../libraries/liboop \ -I$(srcdir)/../../libraries/regex \ -I$(srcdir)/../../libraries/libcommon top_srcdir = @top_srcdir@ .gdbinit: Makefile $(RM) -f .gdbinit echo dir $(top_srcdir)/src/libraries/libcommon >.gdbinit echo dir $(top_srcdir)/src/libraries/libansi >>.gdbinit echo dir $(top_srcdir)/src/libraries/libisc-new >>.gdbinit echo dir $(top_srcdir)/src/libraries/libmisc >>.gdbinit echo dir $(top_srcdir)/src/libraries/libisc-new/src >>.gdbinit echo dir $(top_srcdir)/src/libraries/liboop >>.gdbinit check: check-nondejagnu check-dejagnu check-nondejagnu: check-testfd check-test-select check-test-sigjmp check-dejagnu: check-l2g check-lyskomd check-leaks check-l2g: test-l2g site.exp valgrind.wrap runtest --tool l2g --srcdir $(srcdir) check-lyskomd: site.exp ../lyskomd valgrind.wrap bignum timeval-overflow if HAVE_PYTHON runtest --tool lyskomd --srcdir $(srcdir) \ 3<&- 4<&- 5<&- 6<&- 7<&- 8<&- 9<&- else @echo >&2 @echo WARNING: no python interpreter was found by configure, so >&2 @echo most tests could not be run. >&2 @echo >&2 endif # We need to build all test cases in lyskomd.0 before running check-lyskomd. # I have found no better way to express that check-lyskomd depends on # "make check" in lyskomd.0. check-lyskomd: check-recursive check-leaks: site.exp ../lyskomd valgrind.wrap if HAVE_PYTHON runtest --tool leaks --srcdir $(srcdir) \ 3<&- 4<&- 5<&- 6<&- 7<&- 8<&- 9<&- else @echo >&2 @echo WARNING: no python interpreter was found by configure, so >&2 @echo most tests could not be run. >&2 @echo >&2 endif check-testfd: testfd ./testfd check-test-select: test-select sleep 6|./test-select --no-sa-restart check-test-sigjmp: test-sigjmp sleep 6|./test-sigjmp sleep 6|./test-sigjmp --no-sa-restart ../../libraries/adns/client/adnshost: (cd ../../libraries/adns/client && $(MAKE) check) site.exp: Makefile ../../libraries/adns/client/adnshost $(RM) $@ $@.tmp echo "# this file is automatically generated by Makefile.am" > $@.tmp echo "set l2g ./test-l2g" >> $@.tmp echo "set top_srcdir $(top_srcdir)" >> $@.tmp if [ "$(VALGRIND)" ] ; \ then \ echo "set valgrind \"$(VALGRIND)\"" >> $@.tmp ; \ else \ echo "set valgrind \"\"" >> $@.tmp ; \ fi (../../libraries/adns/client/adnshost -i 127.0.0.1 2>/dev/null \ || echo 1.0.0.127.in-addr.arpa PTR 127.0.0.1) \ | sed -e 's/.*PTR /set lyskomd_host "/' -e 's/$$/"/' -e q >> $@.tmp echo set valgrind_fd $(VALGRIND_FD) >> $@.tmp echo set python \"$(PYTHON)\" >> $@.tmp chmod 444 $@.tmp mv $@.tmp $@ valgrind.wrap: Makefile $(RM) $@ $@.tmp echo "#!/bin/sh" > $@.tmp echo "# This file is generated by Makefile.am. Do not edit." >> $@.tmp echo 'exec $(VALGRIND_FD)>$$1' >> $@.tmp echo 'shift' >> $@.tmp echo 'echo $(VALGRIND) "$$@" >&$(VALGRIND_FD)' >> $@.tmp echo 'exec $(VALGRIND) "$$@"' >> $@.tmp chmod 555 $@.tmp mv $@.tmp $@ lyskom-server-2.1.2/src/server/testsuite/Makefile.in0000664000015100472110000006304207723707427016234 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # $Id: Makefile.am,v 1.67 2003/08/23 16:38:12 ceder Exp $ # Copyright (C) 1998-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # srcdir = @srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : top_srcdir = @top_srcdir@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEBUG_CALLS = @DEBUG_CALLS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EFENCE = @EFENCE@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FLEX = @FLEX@ HAVE_PYTHON_FALSE = @HAVE_PYTHON_FALSE@ HAVE_PYTHON_TRUE = @HAVE_PYTHON_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSURE = @INSURE@ LANGUAGE_SUFFIX = @LANGUAGE_SUFFIX@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ SED = @SED@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRACED_ALLOCATIONS = @TRACED_ALLOCATIONS@ U = @U@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ YACC = @YACC@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ RM = rm -f dbdir = $(localstatedir)/lyskomd/db exportdir = $(localstatedir)/lyskomd/exportdb SUBDIRS = config lyskomd.0 check_PROGRAMS = test-l2g bignum testfd test-select test-sigjmp \ timeval-overflow get-time-often check_DATA = site.exp .gdbinit valgrind.wrap VALGRIND_FD = 21 EXTRA_DIST = .cvsignore \ l2g.0/00.exp l2g.0/01.exp l2g.0/02.exp l2g.0/03.exp \ l2g.0/04.exp l2g.0/05.exp l2g.0/06.exp l2g.0/07.exp \ l2g.0/08.exp l2g.0/09.exp l2g.0/10.exp l2g.0/11.exp \ l2g.0/12.exp \ leaks.0/leaks00.exp \ leaks.0/leaks01.exp \ leaks.0/leaks02.exp \ leaks.0/leaks03.exp \ leaks.0/leaks04.exp \ leaks.0/leaks05.exp \ leaks.0/leaks06.exp \ leaks.0/leaks07.exp \ leaks.0/leaks08.exp \ leaks.0/leaks09.exp \ leaks.0/leaks10.exp \ leaks.0/lots-aux-items.conf \ leaks.0/no-aux-items.conf \ locksuite.py \ lyskomd.supp \ renumber.el \ tcpconnect.py \ leaks.0/leaks99.exp MOSTLYCLEANFILES = .gdbinit site.exp *.sum *.log usage-base.tmp usage.all \ lyskomd.*.usage lyskomd.*.base *.da *.bb *.gcov *.bbg \ valgrind-*.log valgrind.log valgrind.wrap \ memory-usage-*.log test_l2g_SOURCES = test-l2g.c test_l2g_LDADD = ../libcheck.a \ ../../libraries/libmisc/libmisc.a \ ../../libraries/libcommon/liblyskom-server.a \ ../libcheck.a \ ../../libraries/libansi/libansi.a bignum_SOURCES = bignum.c testfd_SOURCES = testfd.c timeval_overflow_SOURCES = timeval-overflow.c test_select_SOURCES = test-select.c test_select_LDADD = ../../libraries/libansi/libansi.a test_sigjmp_SOURCES = test-sigjmp.c test_sigjmp_LDADD = ../../libraries/libansi/libansi.a get_time_often_SOURCES = get-time-often.c get_time_often_LDADD = \ ../libcheck.a \ ../../libraries/libisc-new/src/libisc.a \ ../../libraries/liboop/liboop.a \ ../../libraries/adns/src/libadns.a \ ../../libraries/libmisc/libmisc.a \ ../libcheck.a AM_CPPFLAGS = -I$(srcdir)/.. \ -I../../.. \ -I$(srcdir)/../../include \ -I$(srcdir)/../../libraries/libansi \ -I$(srcdir)/../../libraries/libmisc \ -I$(srcdir)/../../libraries/libisc-new/src \ -I$(srcdir)/../../libraries/liboop \ -I$(srcdir)/../../libraries/regex \ -I$(srcdir)/../../libraries/libcommon subdir = src/server/testsuite ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = check_PROGRAMS = test-l2g$(EXEEXT) bignum$(EXEEXT) testfd$(EXEEXT) \ test-select$(EXEEXT) test-sigjmp$(EXEEXT) \ timeval-overflow$(EXEEXT) get-time-often$(EXEEXT) am_bignum_OBJECTS = bignum.$(OBJEXT) bignum_OBJECTS = $(am_bignum_OBJECTS) bignum_LDADD = $(LDADD) bignum_DEPENDENCIES = bignum_LDFLAGS = am_get_time_often_OBJECTS = get-time-often.$(OBJEXT) get_time_often_OBJECTS = $(am_get_time_often_OBJECTS) get_time_often_DEPENDENCIES = ../libcheck.a \ ../../libraries/libisc-new/src/libisc.a \ ../../libraries/liboop/liboop.a \ ../../libraries/adns/src/libadns.a \ ../../libraries/libmisc/libmisc.a ../libcheck.a get_time_often_LDFLAGS = am_test_l2g_OBJECTS = test-l2g.$(OBJEXT) test_l2g_OBJECTS = $(am_test_l2g_OBJECTS) test_l2g_DEPENDENCIES = ../libcheck.a ../../libraries/libmisc/libmisc.a \ ../../libraries/libcommon/liblyskom-server.a ../libcheck.a \ ../../libraries/libansi/libansi.a test_l2g_LDFLAGS = am_test_select_OBJECTS = test-select.$(OBJEXT) test_select_OBJECTS = $(am_test_select_OBJECTS) test_select_DEPENDENCIES = ../../libraries/libansi/libansi.a test_select_LDFLAGS = am_test_sigjmp_OBJECTS = test-sigjmp.$(OBJEXT) test_sigjmp_OBJECTS = $(am_test_sigjmp_OBJECTS) test_sigjmp_DEPENDENCIES = ../../libraries/libansi/libansi.a test_sigjmp_LDFLAGS = am_testfd_OBJECTS = testfd.$(OBJEXT) testfd_OBJECTS = $(am_testfd_OBJECTS) testfd_LDADD = $(LDADD) testfd_DEPENDENCIES = testfd_LDFLAGS = am_timeval_overflow_OBJECTS = timeval-overflow.$(OBJEXT) timeval_overflow_OBJECTS = $(am_timeval_overflow_OBJECTS) timeval_overflow_LDADD = $(LDADD) timeval_overflow_DEPENDENCIES = timeval_overflow_LDFLAGS = DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/scripts/depcomp am__depfiles_maybe = depfiles @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/bignum.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/get-time-often.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/test-l2g.Po ./$(DEPDIR)/test-select.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/test-sigjmp.Po ./$(DEPDIR)/testfd.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/timeval-overflow.Po COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ DIST_SOURCES = $(bignum_SOURCES) $(get_time_often_SOURCES) \ $(test_l2g_SOURCES) $(test_select_SOURCES) \ $(test_sigjmp_SOURCES) $(testfd_SOURCES) \ $(timeval_overflow_SOURCES) RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \ ps-recursive install-info-recursive uninstall-info-recursive \ all-recursive install-data-recursive install-exec-recursive \ installdirs-recursive install-recursive uninstall-recursive \ check-recursive installcheck-recursive DIST_COMMON = $(top_srcdir)/scripts/common.make Makefile.am Makefile.in DIST_SUBDIRS = $(SUBDIRS) SOURCES = $(bignum_SOURCES) $(get_time_often_SOURCES) $(test_l2g_SOURCES) $(test_select_SOURCES) $(test_sigjmp_SOURCES) $(testfd_SOURCES) $(timeval_overflow_SOURCES) all: all-recursive .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/scripts/common.make $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/server/testsuite/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) clean-checkPROGRAMS: -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS) bignum$(EXEEXT): $(bignum_OBJECTS) $(bignum_DEPENDENCIES) @rm -f bignum$(EXEEXT) $(LINK) $(bignum_LDFLAGS) $(bignum_OBJECTS) $(bignum_LDADD) $(LIBS) get-time-often$(EXEEXT): $(get_time_often_OBJECTS) $(get_time_often_DEPENDENCIES) @rm -f get-time-often$(EXEEXT) $(LINK) $(get_time_often_LDFLAGS) $(get_time_often_OBJECTS) $(get_time_often_LDADD) $(LIBS) test-l2g$(EXEEXT): $(test_l2g_OBJECTS) $(test_l2g_DEPENDENCIES) @rm -f test-l2g$(EXEEXT) $(LINK) $(test_l2g_LDFLAGS) $(test_l2g_OBJECTS) $(test_l2g_LDADD) $(LIBS) test-select$(EXEEXT): $(test_select_OBJECTS) $(test_select_DEPENDENCIES) @rm -f test-select$(EXEEXT) $(LINK) $(test_select_LDFLAGS) $(test_select_OBJECTS) $(test_select_LDADD) $(LIBS) test-sigjmp$(EXEEXT): $(test_sigjmp_OBJECTS) $(test_sigjmp_DEPENDENCIES) @rm -f test-sigjmp$(EXEEXT) $(LINK) $(test_sigjmp_LDFLAGS) $(test_sigjmp_OBJECTS) $(test_sigjmp_LDADD) $(LIBS) testfd$(EXEEXT): $(testfd_OBJECTS) $(testfd_DEPENDENCIES) @rm -f testfd$(EXEEXT) $(LINK) $(testfd_LDFLAGS) $(testfd_OBJECTS) $(testfd_LDADD) $(LIBS) timeval-overflow$(EXEEXT): $(timeval_overflow_OBJECTS) $(timeval_overflow_DEPENDENCIES) @rm -f timeval-overflow$(EXEEXT) $(LINK) $(timeval_overflow_LDFLAGS) $(timeval_overflow_OBJECTS) $(timeval_overflow_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) core *.core distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bignum.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get-time-often.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-l2g.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-select.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-sigjmp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testfd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timeval-overflow.Po@am__quote@ distclean-depend: -rm -rf ./$(DEPDIR) .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ @am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ @am__fastdepCC_TRUE@ fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< .c.obj: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ @am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ @am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ @am__fastdepCC_TRUE@ fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` uninstall-info-am: # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ETAGS = etags ETAGSFLAGS = CTAGS = ctags CTAGSFLAGS = tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if (etags --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ else \ include_option=--include; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -f $$subdir/TAGS && \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$tags$$unique" \ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = ../../.. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) $(mkinstalldirs) $(distdir)/../../../scripts $(distdir)/l2g.0 $(distdir)/leaks.0 @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d $(distdir)/$$subdir \ || mkdir $(distdir)/$$subdir \ || exit 1; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" \ distdir=../$(distdir)/$$subdir \ distdir) \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(check_DATA) check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-checkPROGRAMS clean-generic mostlyclean-am distclean: distclean-recursive distclean-am: clean-am distclean-compile distclean-depend \ distclean-generic distclean-tags dvi: dvi-recursive dvi-am: info: info-recursive info-am: install-data-am: install-exec-am: install-info: install-info-recursive install-man: installcheck-am: maintainer-clean: maintainer-clean-recursive maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-local pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-info-am uninstall-info: uninstall-info-recursive .PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \ clean-checkPROGRAMS clean-generic clean-recursive ctags \ ctags-recursive distclean distclean-compile distclean-depend \ distclean-generic distclean-recursive distclean-tags distdir \ dvi dvi-am dvi-recursive info info-am info-recursive install \ install-am install-data install-data-am install-data-recursive \ install-exec install-exec-am install-exec-recursive \ install-info install-info-am install-info-recursive install-man \ install-recursive install-strip installcheck installcheck-am \ installdirs installdirs-am installdirs-recursive \ maintainer-clean maintainer-clean-generic \ maintainer-clean-recursive mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-local mostlyclean-recursive pdf \ pdf-am pdf-recursive ps ps-am ps-recursive tags tags-recursive \ uninstall uninstall-am uninstall-info-am \ uninstall-info-recursive uninstall-recursive mostlyclean-local: $(RM) -r -f db etc ../libcheck.a: (cd .. && $(MAKE) libcheck.a) ../lyskomd: (cd .. && $(MAKE) lyskomd) .gdbinit: Makefile $(RM) -f .gdbinit echo dir $(top_srcdir)/src/libraries/libcommon >.gdbinit echo dir $(top_srcdir)/src/libraries/libansi >>.gdbinit echo dir $(top_srcdir)/src/libraries/libisc-new >>.gdbinit echo dir $(top_srcdir)/src/libraries/libmisc >>.gdbinit echo dir $(top_srcdir)/src/libraries/libisc-new/src >>.gdbinit echo dir $(top_srcdir)/src/libraries/liboop >>.gdbinit check: check-nondejagnu check-dejagnu check-nondejagnu: check-testfd check-test-select check-test-sigjmp check-dejagnu: check-l2g check-lyskomd check-leaks check-l2g: test-l2g site.exp valgrind.wrap runtest --tool l2g --srcdir $(srcdir) check-lyskomd: site.exp ../lyskomd valgrind.wrap bignum timeval-overflow @HAVE_PYTHON_TRUE@ runtest --tool lyskomd --srcdir $(srcdir) \ @HAVE_PYTHON_TRUE@ 3<&- 4<&- 5<&- 6<&- 7<&- 8<&- 9<&- @HAVE_PYTHON_FALSE@ @echo >&2 @HAVE_PYTHON_FALSE@ @echo WARNING: no python interpreter was found by configure, so >&2 @HAVE_PYTHON_FALSE@ @echo most tests could not be run. >&2 @HAVE_PYTHON_FALSE@ @echo >&2 # We need to build all test cases in lyskomd.0 before running check-lyskomd. # I have found no better way to express that check-lyskomd depends on # "make check" in lyskomd.0. check-lyskomd: check-recursive check-leaks: site.exp ../lyskomd valgrind.wrap @HAVE_PYTHON_TRUE@ runtest --tool leaks --srcdir $(srcdir) \ @HAVE_PYTHON_TRUE@ 3<&- 4<&- 5<&- 6<&- 7<&- 8<&- 9<&- @HAVE_PYTHON_FALSE@ @echo >&2 @HAVE_PYTHON_FALSE@ @echo WARNING: no python interpreter was found by configure, so >&2 @HAVE_PYTHON_FALSE@ @echo most tests could not be run. >&2 @HAVE_PYTHON_FALSE@ @echo >&2 check-testfd: testfd ./testfd check-test-select: test-select sleep 6|./test-select --no-sa-restart check-test-sigjmp: test-sigjmp sleep 6|./test-sigjmp sleep 6|./test-sigjmp --no-sa-restart ../../libraries/adns/client/adnshost: (cd ../../libraries/adns/client && $(MAKE) check) site.exp: Makefile ../../libraries/adns/client/adnshost $(RM) $@ $@.tmp echo "# this file is automatically generated by Makefile.am" > $@.tmp echo "set l2g ./test-l2g" >> $@.tmp echo "set top_srcdir $(top_srcdir)" >> $@.tmp if [ "$(VALGRIND)" ] ; \ then \ echo "set valgrind \"$(VALGRIND)\"" >> $@.tmp ; \ else \ echo "set valgrind \"\"" >> $@.tmp ; \ fi (../../libraries/adns/client/adnshost -i 127.0.0.1 2>/dev/null \ || echo 1.0.0.127.in-addr.arpa PTR 127.0.0.1) \ | sed -e 's/.*PTR /set lyskomd_host "/' -e 's/$$/"/' -e q >> $@.tmp echo set valgrind_fd $(VALGRIND_FD) >> $@.tmp echo set python \"$(PYTHON)\" >> $@.tmp chmod 444 $@.tmp mv $@.tmp $@ valgrind.wrap: Makefile $(RM) $@ $@.tmp echo "#!/bin/sh" > $@.tmp echo "# This file is generated by Makefile.am. Do not edit." >> $@.tmp echo 'exec $(VALGRIND_FD)>$$1' >> $@.tmp echo 'shift' >> $@.tmp echo 'echo $(VALGRIND) "$$@" >&$(VALGRIND_FD)' >> $@.tmp echo 'exec $(VALGRIND) "$$@"' >> $@.tmp chmod 555 $@.tmp mv $@.tmp $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/src/server/testsuite/bignum.c0000664000015100472110000000221307721716131015573 /* * Emit a very large number. * Copyright (C) 2002-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ #include #include int main(void) { #if LONG_MAX > 2147483647 printf("10000000000000000000\n"); #else printf("3000000000\n"); #endif return 0; } lyskom-server-2.1.2/src/server/testsuite/get-time-often.c0000664000015100472110000003256307717413252017154 /* * Copyright (C) 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * Issue as many get-time requests to the specified server as it can * accept. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #ifdef TIME_WITH_SYS_TIME # include # include #else # ifdef HAVE_SYS_TIME_H # include # else # include # endif #endif #include #include #include #include "oop.h" #include "s-string.h" #include "isc.h" #include "timeval-util.h" #include "getopt.h" #include "linkansi.h" #include "unused.h" #define BLOCKSIZE (65536) static long sent_writes = 0; static long sent_requests = 0; static long sent_bytes = 0; static long rcvd_reads = 0; static long rcvd_requests = 0; static long rcvd_bytes = 0; static int server; static int writing_to_server; static int reading_from_server; static long last_progress_status = 0; static int abort_pending = 0; static int do_write_only = 0; static long request_limit = -1; static oop_call_fd read_stdin; static oop_call_fd read_server; static oop_call_fd write_server; static oop_call_time report_stats; static oop_call_time report_progress; static oop_call_time end_it; static void fail(const char *reason) { fprintf(stderr, "get-time-often: "); perror(reason); exit(1); } static void start_writing(oop_source *oop) { if (!writing_to_server) { oop->on_fd(oop, server, OOP_WRITE, write_server, NULL); writing_to_server = 1; } } static void stop_writing(oop_source *oop) { if (writing_to_server) { oop->cancel_fd(oop, server, OOP_WRITE); writing_to_server = 0; } } static void start_reading(oop_source *oop) { if (!reading_from_server) { oop->on_fd(oop, server, OOP_READ, read_server, NULL); reading_from_server = 1; } } static void stop_reading(oop_source *oop) { if (reading_from_server) { oop->cancel_fd(oop, server, OOP_READ); reading_from_server = 0; } } static int tcp_connect(const char *host, const char *port) { int sock; union isc_address *ia; if ((ia = isc_mktcpaddress(host, port)) == NULL) fail("isc_mktcpaddress"); if ((sock = socket(isc_addressfamily(ia), SOCK_STREAM, 0)) < 0) fail("socket"); if (connect(sock, isc_addresspointer(ia), isc_addresssize(ia)) < 0) fail("connect"); isc_freeaddress(ia); return sock; } static void * read_stdin(oop_source *source, int fd, oop_event UNUSED(event), void *UNUSED(user)) { static char readbuf[128]; ssize_t rv; if ((rv = read(fd, readbuf, sizeof(readbuf) - 1)) < 0) { if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) fail("read(stdin)"); else rv = 0; } else if (rv == 0) { fprintf(stderr, "eof on stdin"); exit(1); } readbuf[rv] = '\0'; while (rv > 1 && (readbuf[rv-1] == '\r' || readbuf[rv-1] == '\n')) { rv--; readbuf[rv] = '\0'; } if (!strcmp(readbuf, "shutdown")) return OOP_HALT; if (!strcmp(readbuf, "ping")) { puts("pong"); fflush(stdout); return OOP_CONTINUE; } if (!strcmp(readbuf, "start-reading")) { start_reading(source); if (do_write_only) request_limit = sent_requests; puts("ok"); fflush(stdout); return OOP_CONTINUE; } fprintf(stderr, "unknown command on stdin: %s.\n", readbuf); return OOP_HALT; } static const char * parse_ok(const char *beg, const char *end) { const char *hunt; for (hunt = beg; hunt < end; hunt++) if (*hunt == '\n') return hunt + 1; return NULL; } static const char * parse_async(const char *beg, const char *end) { const char *hunt; const char *number; long len; for (hunt = beg; hunt < end; hunt++) { if (isdigit((unsigned char)*hunt)) { number = hunt; for (hunt++; hunt < end; hunt++) if (!isdigit((unsigned char)*hunt)) break; if (hunt == end) return NULL; if (*hunt == 'H') { hunt++; len = strtol(number, NULL, 10); if (len > end - hunt) return NULL; hunt += len; } else hunt--; } else if (*hunt == '\n') return hunt + 1; else { switch (*hunt) { case ' ': case '{': case '}': case '*': break; default: fprintf(stderr, "unexpected char from server in async: %c\n", *hunt); fprintf(stderr, "Current block looks like this (%d chars):\n", (int)(end - beg)); fprintf(stderr, "%.*s\n", (int)(end - beg), beg); exit(1); } } } return NULL; } static const char * parse_result(const char *beg, const char *end) { const char *next; const char *good_seqno = NULL; while (beg < end) { if (*beg == '=') { next = parse_ok(beg + 1, end); if (next != NULL) good_seqno = beg + 1; } else if (*beg == ':') next = parse_async(beg+1, end); else { fprintf(stderr, "unexpected server output: %c\n", *beg); exit(1); } if (next == NULL) break; beg = next; } if (good_seqno != NULL) rcvd_requests = strtol(good_seqno, NULL, 10); return beg; } static void * read_server(oop_source *UNUSED(source), int fd, oop_event UNUSED(event), void *UNUSED(user)) { static char readbuf[8 * BLOCKSIZE]; static char *pos = readbuf; char *end; const char *src; ssize_t rv; if ((rv = read(fd, pos, sizeof(readbuf) - (pos - readbuf))) < 0) { if ((errno == EPIPE || errno == ECONNRESET) && do_write_only) return OOP_HALT; if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) fail("read(server)"); else rv = 0; } else if (rv == 0) { if (do_write_only) return OOP_HALT; fprintf(stderr, "eof on server"); exit(1); } else { rcvd_bytes += rv; rcvd_reads++; } end = pos + rv; src = parse_result(readbuf, end); /* Move any trailing incomplete result to the head of the buffe. */ for (pos = readbuf; src < end; ) *pos++ = *src++; if (request_limit != -1 && rcvd_requests >= request_limit) { fprintf(stderr, "Only expected %ld replies, but got at least %ld.\n", request_limit, rcvd_requests); request_limit = -1; } if (writing_to_server) return OOP_CONTINUE; if (rcvd_requests < sent_requests) return OOP_CONTINUE; return OOP_HALT; } static void * write_server(oop_source *source, int fd, oop_event UNUSED(event), void *UNUSED(user)) { static char writebuf[BLOCKSIZE + 100]; static char *pos = NULL; static char *end = NULL; ssize_t rv; char *hunt; long seq = sent_requests; /* Fill the output buffer. */ if (pos == end) { pos = writebuf; while (pos < writebuf + BLOCKSIZE) pos += sprintf(pos, "%ld 35\n", seq++); end = pos; pos = writebuf; } rv = write(fd, pos, end - pos); if (rv < 0) { if ((errno == ECONNRESET || errno == EPIPE) && do_write_only) { stop_writing(source); return OOP_CONTINUE; } if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) fail("write(server)"); else rv = 0; } else if (rv == 0) { if (do_write_only) return OOP_HALT; fprintf(stderr, "eof on server (write)"); exit(1); } else { sent_bytes += rv; sent_writes++; } pos += rv; for (hunt = pos; hunt > writebuf + 1 && hunt[-1] != '\n'; hunt--); if (hunt > writebuf + 1) { for (hunt--; hunt > writebuf + 1 && hunt[-1] != '\n'; hunt--); sent_requests = strtol(hunt, NULL, 10); } return OOP_CONTINUE; } static void arm_timer(oop_source *source, time_t sec, long usec, oop_call_time *call, struct timeval *tv) { struct timeval ival; ival.tv_sec = sec; ival.tv_usec = usec; if (setup_timer(tv, ival) < 0) fprintf(stderr, "gettimeofday failed: %s\n", strerror(errno)); source->on_time(source, *tv, call, tv); } static void do_report_stats(void) { printf("%ld reqs, %ld bytes, %ld reads\n", rcvd_requests, rcvd_bytes, rcvd_reads); printf("%ld reqs, %ld bytes, %ld writes\n", sent_requests, sent_bytes, sent_writes); printf("%ld pending reqs\n\n", sent_requests - rcvd_requests); } static void * report_stats(oop_source *source, struct timeval UNUSED(tv), void *user) { do_report_stats(); arm_timer(source, 0, 100000, report_stats, user); return OOP_CONTINUE; } static void * report_progress(oop_source *source, struct timeval UNUSED(tv), void *user) { if (rcvd_requests > last_progress_status) { last_progress_status = rcvd_requests; printf("Progress: %ld pending reqs\n", sent_requests - rcvd_requests); fflush(stdout); } arm_timer(source, 2, 0, report_progress, user); return OOP_CONTINUE; } static void * end_it(oop_source *UNUSED(source), struct timeval UNUSED(tv), void *UNUSED(user)) { abort_pending = 0; return OOP_HALT; } static void * limit_it(oop_source *oop, struct timeval UNUSED(tv), void *UNUSED(user)) { stop_writing(oop); return OOP_CONTINUE; } static struct option longopts[] = { {"verbose", 0, 0, 'v'}, {"silent", 0, 0, 's'}, {"time-abort", 0, 0, 'a'}, {"time-limit", 0, 0, 'l'}, {"write-only", 0, 0, 'w'}, {"priority", 0, 0, 'p'}, {"weight", 0, 0, 'W'}, { 0, 0, 0, 0 } }; int main(int argc, char **argv) { int optc; int oldflags; ssize_t rv; oop_source_sys *sys; oop_source *oop; struct timeval progress_timer; struct timeval report_timer; struct timeval end_timer; char buf[8192]; /* What should we do? */ int do_limit_time = 0; int do_abort_time = 0; int verbose = 0; /* Alter scheduling? */ int priority = -1; int weight = -1; if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) fail("signal"); while ((optc = getopt_long(argc, argv, "W:wvalp:", longopts, (int *) 0)) != EOF) { switch (optc) { case 'v': verbose = 1; break; case 's': verbose = 0; break; case 'a': do_abort_time = 1; break; case 'l': do_limit_time = 1; break; case 'w': do_write_only = 1; break; case 'W': weight = atoi(optarg); break; case 'p': priority = atoi(optarg); break; case '?': fail("usage"); } } if (optind + 2 != argc) fail("usage"); if ((priority == -1) + (weight == -1) == 1) fail("usage"); server = tcp_connect(argv[optind], argv[optind + 1]); puts("connected"); if (write(server, "A3Hfoo\n", 7) != 7) fail("write"); if ((rv = read(server, buf, sizeof(buf))) < 0) fail("read"); if (rv == 0) { fprintf(stderr, "unexpected EOF from server"); exit(1); } if (rv != 7 || strncmp(buf, "LysKOM\n", 7) != 0) { fprintf(stderr, "Got bad handshake ``%.*s'' from the server\n", (int)rv, buf); exit(1); } puts("handshake OK"); if (priority != -1) { sprintf(buf, "1 119 0 %d %d\n", priority, weight); if (write(server, buf, strlen(buf)) != (ssize_t)strlen(buf)) fail("set-scheduling write"); if ((rv = read(server, buf, sizeof(buf))) < 0) fail("set-scheduling read"); if (rv == 0) { fprintf(stderr, "unexpected EOF from server after set-schedule\n"); exit(1); } if (rv != 3 || strncmp(buf, "=1\n", 3) != 0) { fprintf(stderr, "Got bad reply ``%.*s'' to set-schedule\n", (int)rv, buf); exit(1); } puts("set-schedule ok"); } if ((sys = oop_sys_new()) == NULL) fail("oop_sys_new"); /* Make server connection nonblocking. */ if ((oldflags = fcntl(server, F_GETFL, 0)) < 0) fail("fcntl(F_GETFL)"); if (fcntl(server, F_SETFL, oldflags|O_NONBLOCK) < 0) fail("fcntl(F_SETFL)"); oop = oop_sys_source(sys); oop->on_fd(oop, 0, OOP_READ, read_stdin, NULL); if (!do_write_only) start_reading(oop); start_writing(oop); if (verbose) arm_timer(oop, 0, 0, report_stats, &report_timer); arm_timer(oop, 0, 500000, report_progress, &progress_timer); if (do_limit_time) arm_timer(oop, 5, 0, limit_it, &end_timer); else if (do_abort_time) { abort_pending = 1; arm_timer(oop, do_write_only ? 15 : 5, 0, end_it, &end_timer); } oop_sys_run(sys); if (verbose) oop->cancel_time(oop, report_timer, report_stats, &report_timer); if (abort_pending) oop->cancel_time(oop, end_timer, end_it, &end_timer); printf("End of progress reports\n"); oop->cancel_time(oop, progress_timer, report_progress, &progress_timer); do_report_stats(); oop->cancel_fd(oop, 0, OOP_READ); stop_reading(oop); stop_writing(oop); oop_sys_delete(sys); return 0; } lyskom-server-2.1.2/src/server/testsuite/test-l2g.c0000664000015100472110000001440207721716131015756 /* * Testbench for the Local_to_global structure. * Copyright (C) 1996, 1998-1999, 2002-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ #include #include #include #include #include #include #include #include "s-string.h" #include "kom-types.h" #include "linkansi.h" #include "../local-to-global.h" #ifdef TRACED_ALLOCATIONS # include "../trace-alloc.h" #endif #define MAXMAPS 10 #define LINSIZE 1024 #define ARGS 3 /* D m destruct I m init C m clear C d s copy a m l g append d m l delete l m l lookup n m l next-key u m dump r m read s m l g expensive_set w m write i m iterate through all texts i m f e iterate through f..e-1 b m f e reverse iterate through f..e-1 q quit */ int main(void) { Local_to_global maps[MAXMAPS]; char input[LINSIZE]; int num[ARGS]; int n; int got; int ok; char *s; #ifdef TRACED_ALLOCATIONS /* We must do this before we allocate any memory... */ { char buf[1024]; char *nl; fputs("Where does the trace want to go today? [stderr]\n", stdout); fflush(stdout); if (fgets(buf, sizeof(buf), stdin) != buf) { fprintf(stderr, "unable to read trace location\n"); exit(1); } if ((nl = strchr(buf, '\n')) != NULL) *nl = '\0'; trace_alloc_file(buf); } #endif link_ansi(); l2g_set_block_size(10); printf("l2g> "); fflush(stdout); while (fgets(input, LINSIZE, stdin) != NULL) { s = strchr(input, '\n'); assert(s); *s = '\0'; if (*input == '\0') { printf("EMPTY LINE\nl2g> "); fflush(stdout); continue; } for (n = 0; n < ARGS; n++) num[n] = 0; n = 0; got = 0; for (s=input + 1; *s && *s != '\n'; ++s) { if (isdigit((int)(unsigned char)*s)) { if (n < ARGS) { got = 1; num[n] = 10*num[n] + *s - '0'; } else { printf("BAD INPUT (too many numbers)\nl2g> "); fflush(stdout); continue; } } else if (*s == ' ') { if (got) n++; got = 0; } else { printf("BAD INPUT (bad character)\nl2g> "); fflush(stdout); continue; } } if (got) n++; ok = 0; switch(*input) { case 'D': if (n == 1 && num[0] < MAXMAPS) { l2g_destruct(&maps[num[0]]); ok = 1; } break; case 'I': if (n == 1 && num[0] < MAXMAPS) { l2g_init(&maps[num[0]]); ok = 1; } break; case 'C': if (n == 1 && num[0] < MAXMAPS) { l2g_clear(&maps[num[0]]); ok = 1; } else if (n == 2 && num[0] < MAXMAPS && num[1] < MAXMAPS) { l2g_copy(&maps[num[0]], &maps[num[1]]); ok = 1; } break; case 'a': if (n == 3 && num[0] < MAXMAPS) { l2g_append(&maps[num[0]], num[1], num[2]); ok = 1; } break; case 'd': if (n == 2 && num[0] < MAXMAPS) { l2g_delete(&maps[num[0]], num[1]); ok = 1; } break; case 'l': if (n == 2 && num[0] < MAXMAPS) { printf("%lu\n", (unsigned long)l2g_lookup(&maps[num[0]], num[1])); ok = 1; } break; case 'n': if (n == 2 && num[0] < MAXMAPS) { printf("%lu\n", (unsigned long)l2g_next_key(&maps[num[0]], num[1])); ok = 1; } break; case 'i': if (n == 1 && num[0] < MAXMAPS) { L2g_iterator iter; for (l2gi_searchall(&iter, &maps[num[0]]); !iter.search_ended; l2gi_next(&iter)) printf("%lu:%lu\n", (unsigned long)iter.lno, (unsigned long)iter.tno); ok = 1; } else if (n == 3 && num[0] < MAXMAPS) { L2g_iterator iter; for (l2gi_searchsome(&iter, &maps[num[0]], num[1], num[2]); !iter.search_ended; l2gi_next(&iter)) printf("%lu:%lu\n", (unsigned long)iter.lno, (unsigned long)iter.tno); ok = 1; } break; case 'b': if (n == 1 && num[0] < MAXMAPS) { /* This is not yet implemented by local-to-global.c. */ #if 0 L2g_reverse_iterator iter; for (l2gi_searchall_reverse(&iter, &maps[num[0]]); !iter.search_ended; l2gi_prev(&iter)) printf("%lu:%lu\n", (unsigned long)iter.lno, (unsigned long)iter.tno); ok = 1; #endif } else if (n == 3 && num[0] < MAXMAPS) { L2g_reverse_iterator iter; for (l2gi_searchsome_reverse(&iter, &maps[num[0]], num[1], num[2]); !iter.search_ended; l2gi_prev(&iter)) printf("%lu:%lu\n", (unsigned long)iter.lno, (unsigned long)iter.tno); ok = 1; } break; case 'u': if (n == 1 && num[0] < MAXMAPS) { l2g_dump(stdout, &maps[num[0]]); ok = 1; } break; case 'r': if (n == 1 && num[0] < MAXMAPS) { int c; l2g_read(stdin, &maps[num[0]]); if ((c = getchar()) != '\n') { printf("BAD INPUT: got char %d instead of newline\n", c); fflush(stdout); } ok = 1; } break; case 's': if (n == 3 && num[0] < MAXMAPS) { l2g_expensive_set(&maps[num[0]], num[1], num[2]); ok = 1; } break; case 'w': if (n == 1 && num[0] < MAXMAPS) { l2g_write(stdout, &maps[num[0]]); putchar('\n'); ok = 1; } break; case 'q': printf("test-l2g quitting\n"); fflush(stdout); return 0; } if (ok == 0) { printf("BAD LINE (bad params)\nl2g> "); fflush(stdout); continue; } printf("l2g> "); fflush(stdout); } return 0; } lyskom-server-2.1.2/src/server/testsuite/test-select.c0000664000015100472110000000744007721716131016555 /* * Copyright (C) 2002-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * The lyskomd process assumes that select() returns with EINTR even * when a signal handle has been set up with SA_RESTART. This program * checks if that assumption is true or not. When started, it should * print a single line after 1 second: * * PASS: select returns EINTR * * This program will fail if input is available on stdin. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #ifdef TIME_WITH_SYS_TIME # include # include #else # ifdef HAVE_SYS_TIME_H # include # else # include # endif #endif #include #ifdef HAVE_SYS_SELECT_H # include #endif #ifdef HAVE_UNISTD_H # include /* Needed on NetBSD1.1/SPARC due to select */ #endif #ifdef HAVE_STRING_H # include /* Needed on NetBSD1.1/SPARC due to bzero */ #endif #ifdef HAVE_STRINGS_H # include /* Needed on AIX 4.2 due to bzero */ #endif #include "linkansi.h" #include "unused.h" sig_atomic_t ctr = 0; static void my_sighandler(int UNUSED(x)) { ctr++; } int main(int argc, char **argv) { fd_set r; struct timeval timeout; #ifdef HAVE_STRUCT_SIGACTION struct sigaction act; #endif int rv; int er; time_t before; time_t after; pid_t pid; int use_sa_restart = 1; if (argc == 1) use_sa_restart = 1; else if (argc == 2 && !strcmp(argv[1], "--no-sa-restart")) use_sa_restart = 0; else { fprintf(stderr, "%s: usage: %s [--no-sa-restart]\n", argv[0], argv[0]); return 1; } link_ansi(); if ((pid = fork()) < 0) { perror("fork"); return 1; } if (pid == 0) { sleep(1); kill(getppid(), SIGHUP); sleep(5); /* avoid triggering a SIGCHLD */ return 0; } #ifdef HAVE_STRUCT_SIGACTION sigemptyset(&act.sa_mask); #ifdef SA_RESTART act.sa_flags = use_sa_restart ? SA_RESTART : 0; #else act.sa_flags = 0; #endif act.sa_handler = my_sighandler; if (sigaction(SIGHUP, &act, NULL) < 0) { perror("sigaction"); return 1; } #else if (signal(SIGHUP, my_sighandler) == SIG_ERR) { perror("signal"); return 1; } #endif FD_ZERO(&r); FD_SET(0, &r); timeout.tv_sec = 5; timeout.tv_usec = 0; time(&before); rv = select(1, &r, NULL, NULL, &timeout); er = errno; time(&after); if (rv == 0) printf("select: timeout\n"); else if (rv > 0) printf("select: input available\n"); else if (er != EINTR) printf("select: fail: %s\n", strerror(er)); if (after - before < 3 && rv < 0 && er == EINTR && ctr == 1) { printf("PASS: select returns EINTR\n"); return 0; } else { printf("FAIL: select returns EINTR (got %d signals) (%d seconds)" " (retval=%d)\n", (int)ctr, (int)(after - before), (int)rv); return 1; } } lyskom-server-2.1.2/src/server/testsuite/test-sigjmp.c0000664000015100472110000000774407721716131016576 /* * Copyright (C) 2002-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * The lyskomd process assumes that select() returns with EINTR even * when a signal handle has been set up with SA_RESTART. This program * checks if that assumption is true or not. When started, it should * print a single line after 1 second: * * PASS: select returns EINTR * * This program will fail if input is available on stdin. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #ifdef TIME_WITH_SYS_TIME # include # include #else # ifdef HAVE_SYS_TIME_H # include # else # include # endif #endif #include #ifdef HAVE_SYS_SELECT_H # include #endif #ifdef HAVE_UNISTD_H # include /* Needed on NetBSD1.1/SPARC due to select */ #endif #ifdef HAVE_STRING_H # include /* Needed on NetBSD1.1/SPARC due to bzero */ #endif #ifdef HAVE_STRINGS_H # include /* Needed on AIX 4.2 due to bzero */ #endif #include #include "linkansi.h" #include "unused.h" sig_atomic_t ctr = 0; sigjmp_buf env; static void my_sighandler(int UNUSED(x)) { ctr++; siglongjmp(env, 1); } time_t before; time_t after; int main(int argc, char **argv) { fd_set r; struct timeval timeout; #ifdef HAVE_STRUCT_SIGACTION struct sigaction act; #endif volatile int rv = -2; volatile int er = -2; volatile int jumped = 0; pid_t pid; int use_sa_restart = 1; if (argc == 1) use_sa_restart = 1; else if (argc == 2 && !strcmp(argv[1], "--no-sa-restart")) use_sa_restart = 0; else { fprintf(stderr, "%s: usage: %s [--no-sa-restart]\n", argv[0], argv[0]); return 1; } link_ansi(); if ((pid = fork()) < 0) { perror("fork"); return 1; } if (pid == 0) { sleep(1); kill(getppid(), SIGHUP); sleep(5); /* avoid triggering a SIGCHLD */ return 0; } #ifdef HAVE_STRUCT_SIGACTION sigemptyset(&act.sa_mask); #ifdef SA_RESTART act.sa_flags = use_sa_restart ? SA_RESTART : 0; #else act.sa_flags = 0; #endif act.sa_handler = my_sighandler; if (sigaction(SIGHUP, &act, NULL) < 0) { perror("sigaction"); return 1; } #else if (signal(SIGHUP, my_sighandler) == SIG_ERR) { perror("signal"); return 1; } #endif FD_ZERO(&r); FD_SET(0, &r); timeout.tv_sec = 5; timeout.tv_usec = 0; time(&before); if (sigsetjmp(env, 1)) jumped = 1; else { rv = select(1, &r, NULL, NULL, &timeout); er = errno; } time(&after); if (jumped == 1) ; else if (rv == 0) printf("select: timeout\n"); else if (rv > 0) printf("select: input available\n"); else printf("select: fail: %s\n", strerror(er)); if (after - before < 3 && jumped == 1 && ctr == 1) { printf("PASS: siglongjmp breaks select\n"); return 0; } else { printf("FAIL: siglongjmp breaks select (got %d signals) (%d seconds)" " (retval=%d) (jumped=%d)\n", (int)ctr, (int)(after - before), (int)rv, jumped); return 1; } } lyskom-server-2.1.2/src/server/testsuite/testfd.c0000664000015100472110000001145007721716131015606 /* * Copyright (C) 2002-2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ /* * Test various ways of obtaining the number of available file descriptors. * Return failure if the assumptions used by lyskomd do not hold. */ #include #include #include #include #include #include #include #ifdef HAVE_SYS_RESOURCE_H # ifdef TIME_WITH_SYS_TIME # include # include # else # ifdef HAVE_SYS_TIME_H # include # else # include # endif # endif # include #else # include #endif #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_OFILE) && !defined(RLIMIT_NOFILE) # define RLIMIT_NOFILE RLIMIT_OFILE #endif #if !HAVE_RLIM_T typedef int rlim_t; #endif #define LOW_LIMIT (32) struct data { long getdtable; long openmax; long rlimmax; long rlimcur; long sysconfmax; long max_seen; }; struct all_data { struct data pre; struct data post; }; static void find_limits(const char *s, struct data *p) { long fd; long max_seen = 0; #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE) struct rlimit rlim; #endif #if HAVE_GETDTABLESIZE p->getdtable = getdtablesize(); printf("%sgetdtablesize: %ld\n", s, p->getdtable); #else printf("%sgetdtablesize: n/a\n", s); p->getdtable = 0; #endif #ifdef OPEN_MAX p->openmax = OPEN_MAX; printf("%sOPEN_MAX: %ld\n", s, p->openmax); #else printf("%sOPEN_MAX: n/a\n", s); p->openmax = 0; #endif #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE) if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) { fflush(stdout); perror("ERROR: testfd: getrlimit(RLIMIT_NOFILE) failed"); exit(1); } p->rlimmax = rlim.rlim_max; p->rlimcur = rlim.rlim_cur; printf("%sgetrlimit-current: %ld\n", s, p->rlimcur); printf("%sgetrlimit-max: %ld\n", s, p->rlimmax); #else printf("%sgetrlimit-current: n/a\n", s); printf("%sgetrlimit-max: n/a\n", s); p->rlimmax = 0; p->rlimcur = 0; #endif #if defined (HAVE_SYSCONF) p->sysconfmax = sysconf(_SC_OPEN_MAX); printf("%ssysconf: %ld\n", s, p->sysconfmax); #else printf("%ssysconf: n/a\n", s); p->sysconfmax = 0; #endif #if defined(FD_SETSIZE) printf("%sFD_SETSIZE: %ld\n", s, (long)FD_SETSIZE); #else printf("%sFD_SETSIZE: n/a\n", s); #endif while(1) { fd = open("/dev/null", O_RDONLY); if (fd < 0) break; if (fd >= max_seen) max_seen = fd + 1; } printf("%sopen: %ld\n", s, max_seen); p->max_seen = max_seen; for (fd = 10; fd < max_seen; fd++) close(fd); } int main(void) { int errs = 0; struct all_data s; #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE) struct rlimit rlim; #endif find_limits("pre-", &s.pre); #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE) if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) { fflush(stdout); perror("ERROR: testfd: post-setrlimit getrlimit failed"); exit(1); } rlim.rlim_cur = LOW_LIMIT; if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) { fflush(stdout); perror("ERROR: testfd: post-setrlimit getrlimit failed"); exit(1); } #endif find_limits("post-", &s.post); fflush(stdout); #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE) \ && !defined(HAVE_BROKEN_NOFILE) if (s.post.max_seen != 0 && s.post.max_seen != LOW_LIMIT) { fprintf(stderr, "ERROR: open-post not equal to LOW_LIMIT\n"); errs++; } #else if (s.post.getdtable != 0) { if (s.post.getdtable != s.post.max_seen) { fprintf(stderr, "ERROR: open-post not equal to getdtable-post\n"); errs++; } } else if (s.pre.openmax != 0) { if (s.pre.openmax != s.post.openmax) { fprintf(stderr, "ERROR: openmax is mutable\n"); errs++; } if (s.post.openmax != s.post.max_seen) { fprintf(stderr, "ERROR: open-post not equal to openmax\n"); errs++; } } #endif exit(!!errs); } lyskom-server-2.1.2/src/server/testsuite/timeval-overflow.c0000664000015100472110000000366107717413252017627 /* * Emit a lyskomd that causes a struct timeval to overflow. * Copyright (C) 2003 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please report bugs at http://bugzilla.lysator.liu.se/. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include "../timewrap.h" int main(void) { struct timeval tv; struct timeval next; tv.tv_sec = ~0; if (tv.tv_sec < 0) { for (next.tv_sec = 0; ; next.tv_sec = 2 * next.tv_sec + 1) { if (next.tv_sec < 0) break; tv = next; } } /* No overflow. */ printf("Garb busy postponement: %g seconds\n", (double)tv.tv_sec); /* Overflow. */ printf("Garb timeout: %g seconds\n", 1.5 * (double)tv.tv_sec); /* Overflow. */ printf("Sync timeout: %g seconds\n", 1.1 * (double)tv.tv_sec); /* Overflow. */ printf("Garb interval: %g days\n", (double)tv.tv_sec / 24.0 / 3599.0); /* No overflow. */ printf("Sync interval: %g days\n", (double)tv.tv_sec / 24.0 / 3601.0); /* Overflow. */ printf("Sync retry interval: %g us\n", 1.001e6 * tv.tv_sec); return 0; } lyskom-server-2.1.2/src/server/testsuite/.cvsignore0000664000015100472110000000055107721707034016153 *.bb *.bbg *.da *.gcov .deps .gdbinit .pure Makefile Makefile.in bb.out bignum db dbg.log etc get-time-often gmon.out l2g.log l2g.sum leaks.log leaks.sum lyskomd.*.base lyskomd.*.usage lyskomd.log lyskomd.sum memory-usage-*.log site.exp test-l2g test-select test-sigjmp testfd timeval-overflow usage-base.tmp usage.all valgrind-*.log valgrind.log valgrind.wrap lyskom-server-2.1.2/src/server/testsuite/locksuite.py0000664000015100472110000001714407721716131016533 # Lock the test suite. # Copyright (C) 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # This program is used by the test suite to ensure that only one test # is running at a time. It obtains two locks: # # - first, a socket bound to a specific port. This lock ensures # that only a single test is run on this computer. If two tests # were run at the same time, they would interfere with each other, # since static port is used by the test suite. # # - secondly, a symlink in the current working directory, that # points to the host and pid of this process. This lock ensures # that the test suite isn't used by two processes over a shared # filesystem (such as NFS). # # This process communicates with the test suite on stdin/stdout. # It understands a single command: "exit\n". It can send these # responses: # # "locking...\n": this is sent as soon as the process is started. # # "waiting: socket $USER $CWD\n": if the socket lock is already taken, # this message will be printed, with $USER replaced by the # username and $CWD with the current working directory of the # process that already holds the lock. This message may be issued # several times, but never with the same values of both $USER and # $CWD. # # "waiting: file $LOCK $HOST:$PID\n": if the symlink lock is already # taken, this message will be printed, with $LOCK replaced by the # full path to the symlink lock file, $HOST replaced by the host # name and $PID by the pid of the process holding the lock. This # message may be issued several times, but never with the same # values of bot $HOST and $PID. # # "failed: file $LOCK $HOST $PID\n": the symlink lock may be a stale # lock. If $HOST is the local host, the program can check for # stale locks and break them. However, it it is held by a remote # host, that isn't possible. After waiting an hour for a lock # that is still held by the same remote host and pid, this program # will print this message and stop trying to obtain the lock. If # this happens, the process should send the "exit\n" command. # # "locked\n": the lock has been successfully obtained. # # "queued: socket $USER $CWD\n": this is printed when the lock is # held, and another process wants it. The lock is still held. # # "bye\n": this is sent as a response to the "exit\n" command. If any # locks were held, they are now released. After printing this # response, the process will exit. import socket import select import sys import errno import string import os import select import getpass import time LOCKNAME = "locksuite.lock" __reported_queued = {} def try_socket(): s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) try: s.bind(('', 53263)) except socket.error, e: if e[0] != errno.EADDRINUSE: raise return None s.listen(3) return s def try_symlink(hostname, pid): """Try to lock the symlink. Return values: None: ok 'host:pid': the lock was already held. """ fn = "%s:%d" % (hostname, pid) while 1: try: os.symlink(fn, LOCKNAME) return None except os.error, e: if e.errno != errno.EEXIST: raise locker = None try: locker = os.readlink(LOCKNAME) except os.error, e: if e.errno != errno.ENOENT: raise if locker != None: if locker[:len(hostname)] != hostname: # Locked by a foreign host. return locker oldpid = locker[len(hostname):] if len(oldpid) < 2 or oldpid[0] != ":": # Broken lock file. Return it anyhow. return locker try: os.kill(string.atoi(oldpid[1:]), 0) # Lock owner still living. return locker except os.error, e: if e.errno == errno.EPERM: # Lock owner still living. return locker elif e.errno == errno.ESRCH: os.unlink(LOCKNAME) else: raise time.sleep(1) # Just in case... def myhostname(): host = socket.gethostname() try: fqdn = socket.gethostbyaddr(host) return fqdn[0] except socket.error: return host def my_id(): return "%s %s" % (getpass.getuser(), os.getcwd()) def poll_input(s, timeout): global __reported_queued pend = [sys.stdin] if s != None: pend.append(s) (r, w, e) = select.select(pend, [], [], timeout) if sys.stdin in r: line = sys.stdin.readline() # Ignore the result. sys.exit(0) if s in r: (other, addr) = s.accept() other.send(my_id()) their_id = other.recv(100) if not __reported_queued.has_key(their_id): print "queued: socket", their_id sys.stdout.flush() __reported_queued[their_id] = None other.close() def get_socket_lock(): reported_sockets = {} while 1: s = try_socket() if s != None: return s holder = get_holder() if holder != None and not reported_sockets.has_key(holder): print "waiting: socket", holder sys.stdout.flush() reported_sockets[holder] = None poll_input(None, 1.0) def get_holder(): s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) try: s.connect(('', 53263)) except socket.error: return None s.send(my_id()) their_id = s.recv(100) s.close() return their_id def get_link_lock(): reported_symlinks = {} start = time.time() host = myhostname() pid = os.getpid() while time.time() < start + 3600: lnk = try_symlink(host, pid) if lnk == None: return LOCKNAME if not reported_symlinks.has_key(lnk): print "waiting: file", os.path.join(os.getcwd(), LOCKNAME), lnk sys.stdout.flush() reported_symlinks[lnk] = None start = time.time() time.sleep(5) print "failed: file", os.path.join(os.getcwd(), LOCKNAME), lnk return None def main(): print "locking..." sys.stdout.flush() host = myhostname() s = None link = None try: s = get_socket_lock() link = get_link_lock() if link != None: print "locked" sys.stdout.flush() while 1: poll_input(s, 3600) finally: if s != None: s.close() if link != None: os.unlink(link) print "bye" sys.stdout.flush() if __name__ == '__main__': main() lyskom-server-2.1.2/src/server/testsuite/lyskomd.supp0000664000015100472110000001223407715662265016560 # FIXME (bug 691): our regexp matcher reads a single byte past the end # of what it is supposed to read. This is probably harmless, but not # completely understood. { regex_compile-reads-past-input-Bug-691 Memcheck:Addr1 fun:regex_compile fun:re_compile_pattern fun:lookup_regexp } ##----------------------------------------------------------------------## # getprotobyname() under glibc-2.3.1 apparently triggers several # leaks. These are harmless, since they are only triggered during # initialization. { adns-getprotobyname-dl-reloc-leak Memcheck:Cond fun:elf_dynamic_do_rela.8 fun:_dl_relocate_object_internal fun:dl_open_worker fun:_dl_catch_error_internal fun:__GI__dl_open fun:do_dlopen fun:_dl_catch_error_internal fun:dlerror_run fun:__libc_dlopen fun:__nss_lookup_function fun:__nss_lookup fun:__GI___nss_protocols_lookup fun:getprotobyname_r@@GLIBC_2.1.2 fun:getprotobyname fun:init_finish fun:adns_init } { adns-getprotobyname-dl-leak Memcheck:Leak fun:malloc fun:_dl_map_object_deps_internal fun:dl_open_worker fun:_dl_catch_error_internal fun:__GI__dl_open fun:do_dlopen fun:_dl_catch_error_internal fun:dlerror_run fun:__libc_dlopen fun:__nss_lookup_function fun:__nss_lookup fun:__GI___nss_protocols_lookup fun:getprotobyname_r@@GLIBC_2.1.2 fun:getprotobyname fun:init_finish fun:adns_init } { adns-getprotobyname-nss-lookup-leak Memcheck:Leak fun:malloc fun:__nss_lookup_function fun:__nss_lookup fun:__GI___nss_protocols_lookup fun:getprotobyname_r@@GLIBC_2.1.2 fun:getprotobyname fun:init_finish fun:adns_init } { adns-getprotobyname-nss-tsearch-leak Memcheck:Leak fun:malloc fun:__tsearch fun:__nss_lookup_function fun:__nss_lookup fun:__GI___nss_protocols_lookup fun:getprotobyname_r@@GLIBC_2.1.2 fun:getprotobyname fun:init_finish fun:adns_init } { adns-getprotobyname-nss-dl-leak Memcheck:Leak fun:malloc fun:_dl_new_object fun:_dl_map_object_from_fd fun:_dl_map_object_internal fun:dl_open_worker fun:_dl_catch_error_internal fun:__GI__dl_open fun:do_dlopen fun:_dl_catch_error_internal fun:dlerror_run fun:__libc_dlopen fun:__nss_lookup_function fun:__nss_lookup fun:__GI___nss_protocols_lookup fun:getprotobyname_r@@GLIBC_2.1.2 fun:getprotobyname fun:init_finish fun:adns_init } { adns-getprotobyname-nss-dl-leak-2 Memcheck:Leak fun:malloc fun:_dl_map_object_internal fun:dl_open_worker fun:_dl_catch_error_internal fun:__GI__dl_open fun:do_dlopen fun:_dl_catch_error_internal fun:dlerror_run fun:__libc_dlopen fun:__nss_lookup_function fun:__nss_lookup fun:__GI___nss_protocols_lookup fun:getprotobyname_r@@GLIBC_2.1.2 fun:getprotobyname fun:init_finish } { adns-getprotobyname-nss-parse-leak Memcheck:Leak fun:malloc fun:nss_parse_service_list fun:__GI___nss_database_lookup fun:__GI___nss_protocols_lookup fun:getprotobyname_r@@GLIBC_2.1.2 fun:getprotobyname fun:init_finish fun:adns_init } { adns-getprotobyname-nss-dl-versions-leak Memcheck:Leak fun:calloc fun:_dl_check_map_versions_internal fun:dl_open_worker fun:_dl_catch_error_internal fun:__GI__dl_open fun:do_dlopen fun:_dl_catch_error_internal fun:dlerror_run fun:__libc_dlopen fun:__nss_lookup_function fun:__nss_lookup fun:__GI___nss_protocols_lookup fun:getprotobyname_r@@GLIBC_2.1.2 fun:getprotobyname fun:init_finish fun:adns_init } { adns-getprotobyname-nss-dl-fromfd-leak Memcheck:Leak fun:calloc fun:_dl_new_object fun:_dl_map_object_from_fd fun:_dl_map_object_internal fun:dl_open_worker fun:_dl_catch_error_internal fun:__GI__dl_open fun:do_dlopen fun:_dl_catch_error_internal fun:dlerror_run fun:__libc_dlopen fun:__nss_lookup_function fun:__nss_lookup fun:__GI___nss_protocols_lookup fun:getprotobyname_r@@GLIBC_2.1.2 fun:getprotobyname fun:init_finish fun:adns_init } ##----------------------------------------------------------------------## # fopen() under glibc-2.3.1 apparently triggers a leaks. It seems to # happen only once, during initialization, and is probably no real # leak at all. { i_fopen Memcheck:Leak fun:malloc fun:__fopen_internal fun:_IO_fopen@@GLIBC_2.1 fun:i_fopen fun:init_cache } ##----------------------------------------------------------------------## # flex-2.5.4a seems to not delete the current buffer once it is done. # This only leaks a single block, however. { aid_lexer Memcheck:Leak fun:malloc fun:yy_flex_alloc fun:yy_create_buffer fun:aid_lex fun:aid_parse fun:parse_aux_item_definitions fun:initialize_aux_items fun:initialize } ##----------------------------------------------------------------------## # There is a memory leak in the regex parser when a broken regexp # is supplied. FIXME (bug 689): more info is present in Bugzilla. { regex-Bug-689 Memcheck:Leak fun:malloc fun:regex_compile fun:re_compile_pattern fun:lookup_regexp fun:re_z_lookup fun:call_function fun:parse_unparsed } lyskom-server-2.1.2/src/server/testsuite/renumber.el0000664000015100472110000000417407721716131016317 ;;; Renumber Protocol A test cases. ;; Copyright (C) 1998, 2002-2003 Lysator Academic Computer Association. ;; ;; This file is part of the LysKOM server. ;; ;; LysKOM 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 1, or (at your option) ;; any later version. ;; ;; LysKOM 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 LysKOM; see the file COPYING. If not, write to ;; Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, ;; or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, ;; MA 02139, USA. ;; ;; Please report bugs at http://bugzilla.lysator.liu.se/. ;;;###autoload (defun renumber-lyskom-send-simple-expect () (interactive) (goto-char (point-min)) (let ((ref-nr 999) (case-fold-search nil)) (while (re-search-forward "^send \"\\([0-9]+\\) " nil t) (setq ref-nr (+ 1 ref-nr)) (replace-match (format "%d" ref-nr) t t nil 1) (let ((pos (point)) (limit (re-search-forward "^\\(send\\)\\|\\(talk_to\\)" nil t))) (goto-char pos) (while (re-search-forward "^\\(simple\\|extracting\\|good_bad\\)_expect \"[%=]\\([0-9]+\\)" limit t) (replace-match (format "%d" ref-nr) t t nil 2)))))) ;;;###autoload (defun renumber-lyskom-send-simple-expect-indented () (interactive) (goto-char (point-min)) (let ((ref-nr 1999) (case-fold-search nil)) (while (re-search-forward "^ send \"\\([0-9]+\\) " nil t) (setq ref-nr (+ 1 ref-nr)) (replace-match (format "%d" ref-nr) t t nil 1) (let ((pos (point)) (limit (re-search-forward "^ \\(send\\)\\|\\(talk_to\\)" nil t))) (goto-char pos) (while (re-search-forward "^ \\(simple\\|extracting\\|good_bad\\)_expect \"[%=]\\([0-9]+\\)" limit t) (replace-match (format "%d" ref-nr) t t nil 2)))))) lyskom-server-2.1.2/src/server/testsuite/tcpconnect.py0000664000015100472110000000506007721716131016663 # Connect the test suite to a TCP port. # Copyright (C) 1998-1999, 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. import socket import select import sys import string s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) host=sys.argv[1] port=string.atoi(sys.argv[2]) pfx = "" metapfx = "" if len(sys.argv) > 3: pfx = sys.argv[3] + ": " metapfx = sys.argv[3] + "meta: " print metapfx + "Connecting to", host, port sys.stdout.flush() s.connect((host, port)) print metapfx + "Connected" sys.stdout.flush() needpfx = 1 fdset = [s, sys.stdin] while 1: (i, o, e) = select.select(fdset, [], []) if s in i: try: d = s.recv(512) except socket.error: d = "" if d == "": if needpfx == 0: print if pfx == "": sys.exit(0) else: print metapfx + "EOF on socket" sys.stdout.flush() sys.stdin.readline() sys.exit(0) line = "" if needpfx: line = pfx needpfx = 0 if d[-1] == '\n': d = d[:-1] needpfx = 1 line = line + string.replace(d, "\n", "\n" + pfx) if needpfx == 1: line = line + "\n" sys.stdout.write(line) sys.stdout.flush() if sys.stdin in i: d = sys.stdin.readline() if d == "": print metapfx + "EOF on stdin" sys.exit(1) elif d == "#suspend socket\n": fdset = [sys.stdin] print metapfx + "suspended" sys.stdout.flush() elif d == "#resume socket\n": fdset = [s, sys.stdin] print metapfx + "resumed" sys.stdout.flush() elif d == "#hose socket\n": s.send(string.zfill(0, 2000)) elif d[:6] == "#nocr ": s.send(d[6:-1]) else: s.send(d) lyskom-server-2.1.2/src/server/testsuite/config/0000777000015100472110000000000007723710372015502 5lyskom-server-2.1.2/src/server/testsuite/config/Makefile.am0000664000015100472110000000214407721716131017452 # $Id: Makefile.am,v 1.11 2003/08/23 16:38:12 ceder Exp $ # Copyright (C) 1998-1999, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # include $(top_srcdir)/scripts/common.make EXTRA_DIST = .cvsignore unix.exp prot-a.exp leaks.exp MOSTLYCLEANFILES = lyskomd-config lyskom-server-2.1.2/src/server/testsuite/config/Makefile.in0000664000015100472110000002253307723707427017501 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # $Id: Makefile.am,v 1.11 2003/08/23 16:38:12 ceder Exp $ # Copyright (C) 1998-1999, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../../../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEBUG_CALLS = @DEBUG_CALLS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EFENCE = @EFENCE@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FLEX = @FLEX@ HAVE_PYTHON_FALSE = @HAVE_PYTHON_FALSE@ HAVE_PYTHON_TRUE = @HAVE_PYTHON_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSURE = @INSURE@ LANGUAGE_SUFFIX = @LANGUAGE_SUFFIX@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ SED = @SED@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRACED_ALLOCATIONS = @TRACED_ALLOCATIONS@ U = @U@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ YACC = @YACC@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ RM = rm -f dbdir = $(localstatedir)/lyskomd/db exportdir = $(localstatedir)/lyskomd/exportdb EXTRA_DIST = .cvsignore unix.exp prot-a.exp leaks.exp MOSTLYCLEANFILES = lyskomd-config subdir = src/server/testsuite/config ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = DIST_SOURCES = DIST_COMMON = $(top_srcdir)/scripts/common.make Makefile.am Makefile.in all: all-am .SUFFIXES: $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/scripts/common.make $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/server/testsuite/config/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) uninstall-info-am: tags: TAGS TAGS: ctags: CTAGS CTAGS: DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = ../../../.. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) $(mkinstalldirs) $(distdir)/../../../../scripts @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am info info-am install \ install-am install-data install-data-am install-exec \ install-exec-am install-info install-info-am install-man \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \ uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/src/server/testsuite/config/.cvsignore0000664000015100472110000000006107634725271017422 Makefile Makefile.in localcfg.exp lyskomd-config lyskom-server-2.1.2/src/server/testsuite/config/unix.exp0000664000015100472110000011035207723506147017126 # The values in this file can be overridden by creating localcfg.exp # and setting them there. This is useful if you are working against # the CVS repository and make a purely local change (such as setting # the timeout value to a low value). # Set this to 1 to cause the test suite to wait while you attach to # the process that is being tested. if { ![info exists ATTACH] } { set ATTACH no } if { ![info exists MEMTRACE] } { set MEMTRACE /dev/null } if { ![info exists DBCK_MEMTRACE] } { set DBCK_MEMTRACE /dev/null } if { ![info exists EFENCE] } { set EFENCE 0 } # The attach option if { $ATTACH == "yes" } { set attach 1 } else { set attach 0 } # Set this to 1 if test-l2g was linked with Electric Fence. if { $EFENCE == "yes" } { set efence 1 } else { set efence 0 } # Set MEMTRACE to the file where the trace should be sent. # This is typically the tty where you are running the attached gdb. # Some of the machines we run the Xenofarm tests on are really, really # slow, so we have to increase the timeout. set timeout [expr {3 * $timeout + 2}] # Set the timeout value to something small for quicker testing, if you # have a fast enough machine. #set timeout 5 # This constant is also defined in src/include/kom-config.h. # It also affects VALGRIND_FD in ../Makefile.am. set PROTECTED_FDS [expr 13 + 9] # The file descriptor used for valgrind support. We use the # last of the protected FD:s. If this changes, you must # change VALGRIND_FD in ../Makefile.am. if {$valgrind_fd != $PROTECTED_FDS - 1} { error "Mismatch between valgrind_fd ($valgrind_fd) and PROTECTED_FDS ($PROTECTED_FDS)" } set valgrind_fd [expr $PROTECTED_FDS - 1] # Some useful constants. set nl "\r?\n" set any "\[ -ÿ\]" set deep_any "\\\[ -ÿ\\\]" set hollerith "\[0-9\]*H$any*" set any_time "\[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]*" # 1970-01-01 GMT, but with some fuzziness to allow for local time zones. set epoch_time "0 0 \[0-9\]* (1|31) (0|11) (70|69) (4|3) (0|364) \[01\]" set any_num "\[0-9\]\[0-9\]*" set any_float "\[0-9\]\[-0-9e.+\]*" # FIXME (bug 1069): Why doesn't this work? # set any_float "\[0-9\]\[0-9\]*(\\.\[0-9\]*)?(e(+|-)\[0-9\]\[0-9\]\[0-9\]*" # The port that is used for Protocol A connections by the test suite. set clientport 53262 set aux_item_default_conf_file "$top_srcdir/run-support/aux-items.conf" # Fix the tty settings for minimum impact on the data flow. set stty_init "-echo -onlcr -istrip -isig erase '^-' kill '^-' werase '^-'" # State variables. set line_leader "" set meta_line_leader "" # valgrind support set valgrindix 0 # Save all broken memory-usage files. set memix 0 # Recursive lock count. set lock_count 0 proc efence_blurb {} { global efence if {$efence} { simple_expect "" "efence blank line" simple_expect " Electric Fence .* Copyright .* Bruce Perens." \ "efence init" } } proc obtain_lock {} { global lock_count global nl global spawn_id global lock_id global any global srcdir global python if {$lock_count == 0} { set redo 1 while {$redo} { spawn $python $srcdir/locksuite.py set lock_id $spawn_id expect { -re "^locking...$nl" { exp_continue } -re "^waiting: socket (.*)$nl" { warning "Test suite locked by socket $expect_out(1,string)" 0 exp_continue } -re "^waiting: file (.*)$nl" { warning "Test suite locked by file $expect_out(1,string)" 0 exp_continue } -re "^failed: file ($any*) (\[^ :\]*):(\[0-9\]*)$nl" { warning "failed to obtain lock due to $expect_out(1,string)" warning "removing stale lock $expect_out(1,string)" system "rm $expect_out(1,string)" send "exit\n" expect bye expect eof wait } -re "^locked$nl" { set redo 0 } timeout { exp_continue } eof { fail "obtaining lock failed" wait set redo 0 } } } } set lock_count [expr {$lock_count + 1}] } proc release_lock {} { global lock_count global nl global spawn_id global lock_id if {$lock_count == 1} { set spawn_id $lock_id send "exit\n" expect { -re "queued: socket (.*)$nl" { warning "Test suite blocked for $expect_out(1,string)" 0 exp_continue } -re "bye$nl" } expect eof wait } if {$lock_count < 1} { error "lock already unlocked" } else { set lock_count [expr {$lock_count - 1}] } } proc l2g_start {} { global spawn_id global l2g global efence global l2g_id global deep_any global nl global expect_active global expect_always global test global MEMTRACE global valgrind global valgrind_fd obtain_lock if {$valgrind != ""} { spawn ./valgrind.wrap valgrind-l2g.log --suppressions=lyskomd.supp --num-callers=40 --leak-check=yes --logfile-fd=$valgrind_fd --show-reachable=yes $l2g } else { spawn $l2g } set l2g_id $spawn_id set expect_active($l2g_id) \ " -i $l2g_id eof { fail \"\$test (eof on l2g)\"; wait } -re \"^($deep_any*)$nl\" { fail \"\$test (unexpected line '\$expect_out(1,string)')\" } -re \"($deep_any*)l2g> \" { fail \"\$test (unexpected incomplete line '\$expect_out(1,string)')\" } timeout { fail \"\$test (timeout on l2g)\" }" set expect_always($l2g_id) \ " -i $l2g_id full_buffer { fail \"\$test (full_buffer on l2g)\" }" talk_to l2g set test "starting l2g" expect { -re "^Where does the trace want to go today. .stderr.$nl" { pass "Tracing is activated ($MEMTRACE)" send "$MEMTRACE\n" exp_continue } -re "^l2g> " { pass "$test" } } unset test send "\n" simple_expect "^EMPTY LINE" "noop command" if {$efence} { l2g_send "I9" l2g_send "a9 3 17" efence_blurb } } proc l2g_stop {} { global spawn_id l2g_send "q" simple_expect "test-l2g quitting" wait close check_valgrind valgrind-l2g.log 1 1 {} release_lock } proc l2g_send {str} { unanchored_expect "^l2g> " "prompt before $str" verbose "sending $str" send "$str\n" } proc fix_expect_after {} { global expect_always global expect_active global spawn_id set stmt "expect_after" foreach k [array names expect_always] { set stmt "$stmt $expect_always($k)" } if {[info exists spawn_id] && [info exists expect_active($spawn_id)]} { set stmt "$stmt $expect_active($spawn_id)" } verbose "evaluating $stmt" 2 eval $stmt } proc simple_expect {regex {testname ""} {is_meta ""}} { global test global any global nl global line_leader global meta_line_leader global verbose if { $verbose } { puts -nonewline "." flush stdout } if {$is_meta == "meta"} { set ll $meta_line_leader } else { set ll $line_leader } set test $testname if {$test == ""} { set test "looking for $regex" } if {[regexp "^(\[=%\])(\[0-9\]*)(( )(..*))?$" "$regex" all a refno]} { # This looks like a protocol A reply. expect { -re "^$ll$regex$nl" {pass "$test"} -re "^$ll=$refno$nl" {fail "$test (unexpected reply =$refno)"} -re "^${ll}(\[=%\]$refno $any*)$nl" { fail "$test (unexpected reply $expect_out(1,string))" } timeout {fail "$test (timeout)"} eof {fail "$test (eof)"; wait} full_buffer {fail "$test (full_buffer)"} } } else { expect { -re "^$ll$regex$nl" {pass "$test"} timeout {fail "$test (timeout)"} eof {fail "$test (eof)"; wait} full_buffer {fail "$test (full_buffer)"} } } unset test } proc lyskomd_expect {regex} { global current_talk_what global current_talk_nr set what $current_talk_what set nr $current_talk_nr talk_to lyskomd simple_expect "$regex" talk_to $what $nr } proc client_expect {nr regex} { global current_talk_what global current_talk_nr set oldwhat $current_talk_what set oldnr $current_talk_nr talk_to client $nr simple_expect "$regex" talk_to $oldwhat $oldnr } proc client_good_bad_expect {nr good_regex bad_regex {xreason ""}} { global current_talk_what global current_talk_nr set oldwhat $current_talk_what set oldnr $current_talk_nr talk_to client $nr good_bad_expect "$good_regex" "$bad_regex" "$xreason" talk_to $oldwhat $oldnr } proc good_bad_expect {good_regex bad_regex {xreason ""}} { global test global any global nl global line_leader global meta_line_leader global verbose if { $verbose } { puts -nonewline "." flush stdout } set ll $line_leader if {![regexp "^(\[=%\])(\[0-9\]*)(( )(..*))?$" "$good_regex" all first refno]} { fail "$test (broken good regex)" unset test return } set rest "[string range "$bad_regex" 1 end]" if {$rest != ""} { set rest " $rest" } set bad_regex "[string range "$bad_regex" 0 0]$refno$rest" set test "looking for $good_regex (or $bad_regex)" expect { -re "^${ll}($good_regex)$nl" { if {$xreason != ""} { setup_xfail "*-*-*" "$xreason" } pass "$test (got $expect_out(1,string))" } -re "^$ll$bad_regex$nl" { if {$xreason != ""} { setup_xfail "*-*-*" "$xreason" } fail "$test (bad regex matches)" } -re "^${ll}(\[=%\]$refno $any*)$nl" { fail "$test (unexpected reply $expect_out(1,string))" } timeout {fail "$test (timeout)"} eof {fail "$test (eof)"; wait} full_buffer {fail "$test (full_buffer)"} } unset test } proc client_extracting_expect {nr regex var grp} { global current_talk_what global current_talk_nr set oldwhat $current_talk_what set oldnr $current_talk_nr talk_to client $nr extracting_expect "$regex" $var $grp talk_to $oldwhat $oldnr } proc extracting_expect {regex var grp} { global test global any global nl global line_leader global $var global verbose set test "looking for $regex" if { $verbose } { puts -nonewline "." flush stdout } set $var "" expect { -re "^$line_leader$regex$nl" { set $var $expect_out($grp,string) pass "$test (extracted $expect_out($grp,string))" } timeout {fail "$test (timeout)"} eof {fail "$test (eof)"; wait} full_buffer {fail "$test (full_buffer)"} } unset test } proc unanchored_expect {regex testname} { global test global any global nl global verbose set test $testname if { $verbose } { puts -nonewline "." flush stdout } expect { -re "$regex" {pass "$test"} timeout {fail "$test (timeout)"} full_buffer {fail "$test (full_buffer)"} eof {fail "$test (eof)"; wait} -re "($any*)$nl" { fail "$test (unexpected line '$expect_out(1,string)' waiting for '$regex')" exp_continue } -re "($any*)l2g> " { fail "$test (unexpected incomplete line '$expect_out(1,string)' waiting for '$regex')" } } unset test } proc spawn_lyskomd {logfile arg} { global valgrind global spawn_id global valgrind_fd set cmd "spawn" if {$valgrind != ""} { set cmd "$cmd ./valgrind.wrap" set cmd "$cmd $logfile" # set cmd "$cmd -v" set cmd "$cmd --num-callers=40" set cmd "$cmd --suppressions=lyskomd.supp" set cmd "$cmd --leak-check=yes" set cmd "$cmd --logfile-fd=$valgrind_fd" set cmd "$cmd --show-reachable=yes" } set cmd "$cmd ../lyskomd" if { $arg == "" } { set cmd "$cmd -f config/lyskomd-config" } else { set cmd "$cmd $arg" } set pid [eval $cmd] return $pid } proc unpack_db {basename} { global srcdir # Check that we are in in the correct directory before removing # directories... set f [open "../lyskomd" "r"] close $f system "rm -rf db etc" system "mkdir db etc" system "cp $srcdir/lyskomd.0/$basename.data db/lyskomd-data" system "cp $srcdir/lyskomd.0/$basename.texts db/lyskomd-texts" system "chmod 644 db/lyskomd-data db/lyskomd-texts" if {[file exists "$srcdir/lyskomd.0/$basename.nr"]} { system "cp $srcdir/lyskomd.0/$basename.nr db/number.txt" system "chmod 644 db/number.txt" } } proc lyskomd_start {{aux_item_conf_file ""} \ {extra_config ""} \ {base_config ""} \ {args ""} \ {db_suffix ""} \ {log_messages {}} \ {init_db 1} \ {want_stale 0} \ {confs 6} \ {texts 1} \ {nogarb 0} \ {db_messages {}}} { global spawn_id global server_id global test global deep_any global nl global attach global timeout global expect_active global expect_always global clientport global aux_item_default_conf_file global lyskomd_pid global top_srcdir global debug_calls global mem_trace global MEMTRACE global line_leader global any obtain_lock if { $aux_item_conf_file == "" } { set aux_item_conf_file $aux_item_default_conf_file } # Check that we are in in the correct directory before removing # directories... set f [open "../lyskomd" "r"] close $f if {$init_db} { system "rm -rf db etc" system "mkdir db etc" system "cp $top_srcdir/db-crypt/db/lyskomd-data$db_suffix db/lyskomd-data" system "cp $top_srcdir/db-crypt/db/lyskomd-texts db/" system "cp $top_srcdir/db-crypt/db/number.txt db/" system "chmod 644 db/lyskomd-data db/lyskomd-texts db/number.txt" } set cf [open "config/lyskomd-config" "w"] puts $cf "Client port: $clientport" puts $cf "Prefix: [pwd]" # FIXME (bug 1088): For now, we continue to use the pre-2.1.0 file names. puts $cf "Data file: db/lyskomd-data" puts $cf "Backup file: db/lyskomd-backup" puts $cf "Backup file 2: db/lyskomd-backup-prev" puts $cf "Lock file: db/lyskomd-lock" puts $cf "Text file: db/lyskomd-texts" puts $cf "Number file: db/number.txt" puts $cf "Number temp file: db/number.tmp" puts $cf "Text backup file: db/lyskomd-texts-backup" puts $cf "Backup export directory: exportdb" puts $cf "Log file: etc/server-log" if {[regexp -nocase "Log statistics:" $extra_config] == 0 && [regexp -nocase "Log statistics:" $base_config] == 0} { puts $cf "Log statistics: etc/lyskomd-log" } puts $cf "Pid file: etc/pid" puts $cf "Memory usage file: etc/memory-usage" puts $cf "Status file: etc/status" puts $cf "Connection status file: etc/connections.txt" puts $cf "Connection status temp file: etc/connections.tmp" puts $cf "Core directory: cores" if { $base_config == "" } { if { [regexp -nocase "Max conferences:" $extra_config] == 0 } { puts $cf "Max conferences: 2000" } if { [regexp -nocase "Max texts:" $extra_config] == 0 } { puts $cf "Max texts: 20000" } if { [regexp -nocase "DNS log threshold:" $extra_config] == 0 } { puts $cf "DNS log threshold: 3600" } if { [regexp -nocase "Sync interval:" $extra_config] == 0 } { puts $cf "Sync interval: 1 day" } if { [regexp -nocase "Connect timeout:" $extra_config] == 0 } { puts $cf "Connect timeout: 1 day" } if { [regexp -nocase "Login timeout:" $extra_config] == 0 } { puts $cf "Login timeout: 1 day" } puts $cf "Aux-item definition file: $aux_item_conf_file" } else { puts $cf $base_config } puts $cf $extra_config close $cf set pid [spawn_lyskomd valgrind-lyskomd.log $args] set lyskomd_pid $pid set server_id $spawn_id set expect_active($server_id) \ " -i $server_id -re \"($deep_any*)$nl\" { fail \"\$test (unexpected line from lyskomd: \$expect_out(1,string))\"; exp_continue } -i $server_id eof { fail \"\$test (eof on lyskomd)\"; wait } timeout { fail \"\$test (timeout on lyskomd)\" }" set expect_always($server_id) \ " -i $server_id full_buffer { fail \"\$test (full_buffer on lyskomd)\" } -i $server_id eof { fail \"\$test (eof on lyskomd)\" }" talk_to lyskomd set test "server started" set t $timeout set timeout [expr {2 * $timeout}] set debug_calls 0 set mem_trace 0 set unattached $attach expect { -re "^Where does the trace want to go today. .stderr." { pass "Tracing is activated ($MEMTRACE)" if {$unattached} { send_user "Please attach to lyskomd pid $pid and hit RETURN\n" set timeout 3600 set t 3600 expect_user { -re . } send_user "Continuing with timeout set to $timeout\n" set unattached 0 } send "$MEMTRACE\n" set mem_trace 1 exp_continue } -re "^${line_leader}... Version $any* .process $any*. started.$nl" { } timeout {fail "$test (timeout)"} full_buffer {fail "$test (full_buffer)"} eof {fail "$test (eof)"; wait} } set stale 0 set test "Lock created" expect { -re "^${line_leader}WARNING: This server was compiled with --with-debug-calls\\.$nl" { expect -re "^${line_leader}It isn.t safe to use in a production environment.$nl" pass "debug calls are enabled" set debug_calls 1 exp_continue } -re "^${line_leader}Removed stale lock file left by ($any*):($any*).$nl" { if {$stale == 1} { fail "$test (more than one stale lock file removed)" } elseif {$want_stale == 0} { fail "$test (lyskomd removed a stale lock file)" } set stale 1 exp_continue } -re "^${line_leader}Created lock ($any*)$nl" { pass "$test (lock file $expect_out(1,string)" } timeout {fail "$test (timeout)"} full_buffer {fail "$test (full_buffer)"} eof {fail "$test (eof)"; wait} } set timeout $t if {$stale == 0 && $want_stale == 1} { fail "$test (no stale lock file removed)" } unset test simple_expect "Listening for clients on $clientport." simple_expect "Database = [pwd]/db/lyskomd-data" simple_expect "Backup = [pwd]/db/lyskomd-backup" simple_expect "2nd Backup = [pwd]/db/lyskomd-backup-prev" simple_expect "Lock File = [pwd]/db/lyskomd-lock" simple_expect "MSG: init_cache: using datafile." simple_expect "Database saved on $any*" foreach dbmsg $db_messages { simple_expect "$dbmsg" } simple_expect "Read $confs confs/persons and $texts texts" foreach logmsg $log_messages { simple_expect "$logmsg" } if {$nogarb == 0} { simple_expect "MSG: garb started." simple_expect "MSG: garb ready. 0 texts deleted." } if {$unattached} { send_user "Please attach to lyskomd process $pid and press RETURN\n" set timeout 3600 expect_user { -re . } send_user "Continuing with timeout set to $timeout\n" } } proc lyskomd_fail_start {log_messages {aux_item_conf_file "" } {extra_config ""} {base_config ""} {args ""}} { global spawn_id global server_id global test global deep_any global any global nl global line_leader global timeout global expect_active global expect_always global clientport global aux_item_default_conf_file global lyskomd_pid global top_srcdir global MEMTRACE global debug_calls obtain_lock if { $aux_item_conf_file == "" } { set aux_item_conf_file $aux_item_default_conf_file } # Check that we are in in the correct directory before removing # directories... set f [open "../lyskomd" "r"] close $f system "rm -rf db etc" system "mkdir db etc" system "cp $top_srcdir/db-crypt/db/lyskomd-data db/" system "cp $top_srcdir/db-crypt/db/lyskomd-texts db/" system "cp $top_srcdir/db-crypt/db/number.txt db/" set cf [open "config/lyskomd-config" "w"] puts $cf "Client port: $clientport" if { $base_config == "" } { puts $cf "Max conferences: 2000" puts $cf "Max texts: 2000" puts $cf "Prefix: [pwd]" puts $cf "Aux-item definition file: $aux_item_conf_file" } else { puts $cf $base_config } puts $cf $extra_config close $cf set pid [spawn_lyskomd valgrind-lyskomdfail.log $args] set lyskomd_pid $pid set server_id $spawn_id set expect_active($server_id) \ " -i $server_id -re \"($deep_any*)$nl\" { fail \"\$test (unexpected line from lyskomd: \$expect_out(1,string))\"; exp_continue } -i $server_id eof { fail \"\$test (eof on lyskomd)\"; wait } timeout { fail \"\$test (timeout on lyskomd)\" }" set expect_always($server_id) \ " -i $server_id full_buffer { fail \"\$test (full_buffer on lyskomd)\" } -i $server_id eof { fail \"\$test (eof on lyskomd)\" }" talk_to lyskomd set test "server start failed" set t $timeout set timeout [expr {2 * $timeout}] expect { -re "^Where does the trace want to go today. .stderr." { pass "Tracing is activated ($MEMTRACE)" send "$MEMTRACE\n" exp_continue } -re "^${line_leader}... Version $any* .process $any*. started.$nl" { } timeout {fail "$test (timeout)" } full_buffer {fail "$test (full_buffer)" } eof {fail "$test (eof)"; wait} } set debug_calls 0 expect { -re "^${line_leader}WARNING: This server was compiled with --with-debug-calls\\.$nl" { expect -re "^${line_leader}It isn.t safe to use in a production environment.$nl" pass "debug calls are enabled" set debug_calls 1 exp_continue } -notransfer -re "^${line_leader}." } foreach logmsg $log_messages { simple_expect "$logmsg" } simple_expect "Previous message is fatal. Will dump core now." simple_expect "Search for the core in [pwd]" set timeout $t set test "server died" expect { timeout { fail "$test (timeout)" } eof { pass "$test"; wait } } check_valgrind valgrind-lyskomdfail.log 0 0 {} release_lock } proc check_memory_usage {} { global memix set allocated_strings 0 set allocated_blocks 0 set f [ open "etc/memory-usage" ] while { [ gets $f line] >= 0 } { if { [regexp "Allocated blocks .grand total." $line] } { set allocated_blocks [lindex "$line" [expr [llength "$line"] - 1]] } elseif { [regexp "Allocated strings" $line] } { set allocated_strings [lindex "$line" [expr [llength "$line"] - 1]] } } close $f if { $allocated_blocks != 0 } { while {[file exists "memory-usage-$memix.log"]} { set memix [expr $memix + 1] } set saved "memory-usage-$memix.log" system "mv etc/memory-usage $saved" fail "Allocated blocks on exit (see $saved)" } else { pass "Allocated blocks on exit" } if { $allocated_strings != 0 } { fail "Allocated strings on exit" } else { pass "Allocated strings on exit" } } proc parse_valgrind_leak {f} { if {[gets $f line] < 0} { fail "valgrind EOF in leak summary" return 999 } if {[regexp ": *\[0-9\]* bytes in (\[0-9\]*) block" "$line" all blocks]} { return $blocks } fail "valgrind leak report parse error" return 998 } proc check_valgrind {logfile need_leaks need_errs expected_leaks} { # The "expected_leaks" argument should be a such as: # # {"Bug 99 & Bug 93" 4 3 9 11} # # that indicates that due to Bug 99 and Bug 93 there will be 4 # definite leaks, 3 possible leaks, 9 still reachable blocks, and # 11 suppressed leaks. global valgrindix global valgrind global test if {$valgrind == ""} { return } set errfound 0 set memfound 0 set errcount 0 set leakcount 0 # Rename the file. $saved holds the new name. while {[file exists "valgrind-$valgrindix.log"]} { set valgrindix [expr $valgrindix + 1] } set saved "valgrind-$valgrindix.log" system "mv $logfile $saved" # Should the log file be kept? set keep 0 set f [open $saved] while {[gets $f line] >= 0} { if {[regexp "ERROR SUMMARY: (\[0-9\]*) errors" $line match errs]} { if {$errfound} { fail "check_valgrind logic error due to $saved" set keep 1 } else { set errfound 1 set errcount $errs } } if {[regexp "LEAK SUMMARY:" $line]} { set memfound 1 set definite [parse_valgrind_leak $f] set possible [parse_valgrind_leak $f] set reachable [parse_valgrind_leak $f] set suppressed [parse_valgrind_leak $f] if {$expected_leaks != {}} { set xreason [lindex $expected_leaks 0] set exp_def [lindex $expected_leaks 1] set exp_pos [lindex $expected_leaks 2] set exp_rea [lindex $expected_leaks 3] set exp_sup [lindex $expected_leaks 4] setup_xfail "*-*-*" $xreason if {$exp_def == $definite && $exp_pos == $possible && $exp_rea == $reachable && $exp_sup == $suppressed} { fail "memory leaks: $definite definite, $possible possible" set definite 0 set possible 0 set reachable 0 set suppressed 0 } else { pass "wrong memory leak count found" } } set leakcount [expr $definite + $possible + $reachable] # Ignore up to 25 suppressed blocks. if {$suppressed > 25} { set leakcount "$suppressed" } } if {[regexp "No malloc'd blocks -- no leaks are possible" $line]} { set memfound 1 } } close $f if {$errfound == 0 && $need_errs == 1} { fail "no error summary in valgrind output $saved" set keep 1 } if {$memfound == 0 && $need_leaks == 1} { fail "no malloc summary in valgrind output $saved" set keep 1 } if {$errcount == 0} { pass "valgrind found no errors" } else { fail "valgrind found $errcount error(s). See $saved." set keep 1 } if {$leakcount == 0} { pass "valgrind found no leaks" } else { if {$definite} { fail "valgrind found $definite definite leaks. See $saved." set keep 1 } if {$possible} { fail "valgrind found $possible possible leaks. See $saved." set keep 1 } if {$reachable} { fail "valgrind found $reachable reachable blocks. See $saved." set keep 1 } if {$suppressed} { fail "valgrind found $suppressed suppressed blocks. See $saved." set keep 1 } } if {$keep == 0} { system rm $saved } } proc lyskomd_death {{expected_leaks {}} {reason 5}} { # See check_valgrind for a description of "expected_leaks". global spawn_id global server_id global test global any global nl global expect_active global expect_always talk_to lyskomd if {$reason == "signal"} { simple_expect "Signal TERM received. Shutting down server." } elseif {$reason == "sighup"} { simple_expect "Signal HUP received. Shutting down server. Please use SIGTERM instead." } elseif {$reason == "sigint"} { simple_expect "Signal INT received. Shutting down server. Please use SIGTERM instead." } elseif {$reason == "restart_kom"} { simple_expect "Search for the core in $any*" } else { simple_expect "shutdown initiated by person $reason $any*" } if {$reason != "restart_kom"} { simple_expect "../lyskomd terminated normally." simple_expect "Press enter to terminate lyskomd" send "\n" } set test "server died" expect { timeout { fail "$test (timeout)" } eof { pass "$test"; wait } } unset expect_active($server_id) unset expect_always($server_id) unset spawn_id fix_expect_after if {$reason != "restart_kom"} { system "cat etc/memory-usage >> usage.all" check_memory_usage check_valgrind valgrind-lyskomd.log 1 1 $expected_leaks } dbck_run release_lock } proc kill_lyskomd {} { global lyskomd_pid global test global spawn_id global expect_active global expect_always global server_id talk_to lyskomd system "kill -KILL $lyskomd_pid" set test "server died" expect { timeout { fail "$test (timeout)" } eof { pass "$test"; wait } } unset expect_active($server_id) unset expect_always($server_id) unset spawn_id fix_expect_after release_lock } proc dbck_run {{extra_lines {}}} { global nl global any global test global any_num global DBCK_MEMTRACE global valgrind global spawn_id global valgrind_fd if {$valgrind != ""} { spawn ./valgrind.wrap valgrind-dbck.log --suppressions=lyskomd.supp --num-callers=40 --logfile-fd=$valgrind_fd --show-reachable=yes ../dbck -d config/lyskomd-config } else { spawn ../dbck -d config/lyskomd-config } set test "dbck started" expect_after { timeout { fail "$test (timeout)" } eof { fail "$test (eof)" } } expect { -re "^Where does the trace want to go today. .stderr.$nl" { pass "Tracing is activated ($DBCK_MEMTRACE)" send "$DBCK_MEMTRACE\n" exp_continue } -re "^MSG: init_cache: using datafile\.$nl" { pass "$test" } } foreach line $extra_lines { set test "dbck sent extra line $line" expect { -re "^$line$nl" { pass "$test" } } } set test "dbck sent second line" expect { -re "^Read $any_num confs/persons and $any_num texts, eof at $any_num$nl" { pass "$test" } } set test "dbck sent final line" expect { -re "^Press enter to terminate dbck$nl" { pass "$test" } -re "^($any*)$nl" { fail "$test (unexpected line: $expect_out(1,string))" exp_continue } } send "\n" set test "dbck died" expect { eof { pass "$test"; wait } } unset test check_valgrind valgrind-dbck.log 0 1 {} } proc client_start {nr} { global client_id global clientport global spawn_id global test global nl global expect_always global expect_active global srcdir global deep_any global python spawn $python $srcdir/tcpconnect.py localhost $clientport MRK:client$nr set client_id($nr) $spawn_id set expect_active($client_id($nr)) " -i $client_id($nr) -re \"($deep_any*)$nl\" { fail \"\$test (unexpected line \$expect_out(1,string))\"; exp_continue } timeout { fail \"\$test (timeout on client $nr)\" }" set expect_always($client_id($nr)) \ " -i $client_id($nr) full_buffer { fail \"\$test (full_buffer on client$nr)\" } " talk_to client $nr simple_expect "Connecting to localhost $clientport" \ "client connects" meta simple_expect "Connected" "client connected" meta } proc client_start_fail {nr {response ""}} { global client_id global clientport global spawn_id global test global nl global expect_always global expect_active global srcdir global deep_any global python obtain_lock spawn $python $srcdir/tcpconnect.py localhost $clientport MRK:client$nr set client_id($nr) $spawn_id set expect_active($client_id($nr)) " -i $client_id($nr) -re \"($deep_any*)$nl\" { fail \"\$test (unexpected line \$expect_out(1,string))\"; exp_continue } timeout { fail \"\$test (timeout on client $nr)\" }" set expect_always($client_id($nr)) \ " -i $client_id($nr) eof { fail \"\$test (eof on client$nr)\" } -i $client_id($nr) full_buffer { fail \"\$test (full_buffer on client$nr)\" } " talk_to client $nr simple_expect "Connecting to localhost $clientport" \ "client connects" meta simple_expect "Connected" "client connected" meta if { $response != "" } { simple_expect "$response" } simple_expect "EOF on socket" "client $nr got EOF from server" meta send "die\n" set test "client $nr closes pty" expect { eof { pass "$test"; wait } } unset test unset expect_active($client_id($nr)) unset expect_always($client_id($nr)) unset spawn_id fix_expect_after release_lock } proc kill_client {nr} { global client_id global expect_always global expect_active global timeout global line_leader global test global any global nl set old_timeout $timeout set timeout 0 talk_to client $nr set test "looking for stray output before killing client $nr" set ok 1 expect { -re "^${line_leader}($any*)$nl" { fail "$test (got $expect_out(1,string))" set ok 0 exp_continue } -re "^${line_leader}($any*)" { fail "$test (got $expect_out(1,string)) (no end-of-line)" set ok 0 exp_continue } -re "($any$any*)" { fail "$test (got $expect_out(1,string)) (bad line-leader)" set ok 0 exp_continue } timeout { if {$ok} { pass "$test" } } eof { fail "$test (eof on client)" } } unset test set timeout $old_timeout close -i $client_id($nr) wait -i $client_id($nr) unset expect_active($client_id($nr)) unset expect_always($client_id($nr)) fix_expect_after } proc suspend_client {} { global current_talk_nr send "\#suspend socket\n" simple_expect "suspended" "client $current_talk_nr suspended" meta } proc hose_client {} { send "\#hose socket\n" } proc resume_client {} { global current_talk_nr send "\#resume socket\n" simple_expect "resumed" "client $current_talk_nr resumed" meta } proc client_death {nr} { global client_id global spawn_id global test global expect_always global expect_active talk_to client $nr simple_expect "EOF on socket" "client $nr got EOF from server" meta send "die\n" set test "client $nr closes pty" expect { eof { pass "$test"; wait } } unset test unset expect_active($client_id($nr)) unset expect_always($client_id($nr)) unset spawn_id fix_expect_after } proc get_time_client_start {nr args} { global get_time_client_id global clientport global spawn_id global test global nl global expect_always global expect_active global deep_any set cmd "spawn ./get-time-often --silent" foreach a $args { set cmd "$cmd $a" } set cmd "$cmd localhost $clientport" eval $cmd set get_time_client_id($nr) $spawn_id set expect_active($get_time_client_id($nr)) " -i $get_time_client_id($nr) -re \"($deep_any*)$nl\" { fail \"\$test (unexpected line \$expect_out(1,string))\"; exp_continue } timeout { fail \"\$test (timeout on get_time_client $nr)\" }" set expect_always($get_time_client_id($nr)) \ " -i $get_time_client_id($nr) full_buffer { fail \"\$test (full_buffer on get_time_client $nr)\" } " talk_to get_time_client $nr simple_expect "connected" simple_expect "handshake OK" } proc get_time_client_death {nr} { global get_time_client_id global spawn_id global test global expect_always global expect_active talk_to get_time_client $nr set test "get_time_client $nr closes pty" expect { eof { pass "$test"; wait } } unset test unset expect_active($get_time_client_id($nr)) unset expect_always($get_time_client_id($nr)) unset spawn_id fix_expect_after } proc talk_to {what {nr ""}} { global spawn_id global server_id global client_id global get_time_client_id global l2g_id global line_leader global meta_line_leader global current_talk_what global current_talk_nr global any_num set line_leader "" set meta_line_leader "" switch $what { lyskomd { set spawn_id $server_id set line_leader "\[0-9\]\[0-9\]\[0-9\]\[0-9\]\[0-9\]\[0-9\] \[0-9\]\[0-9\]:\[0-9\]\[0-9\]:\[0-9\]\[0-9\] $any_num " } client { set spawn_id $client_id($nr) set line_leader "MRK:client$nr" } get_time_client { set spawn_id $get_time_client_id($nr) } l2g { set spawn_id $l2g_id } default { error "attempting to talk to $what" } } set current_talk_what $what set current_talk_nr $nr if {$line_leader != "" && $what != "lyskomd"} { set meta_line_leader "${line_leader}meta: " set line_leader "${line_leader}: " } verbose "TALKING TO $spawn_id $what $nr" fix_expect_after } proc holl {str} { return "[string length $str]H$str" } proc idholl {str} { global lyskomd_host; return [holl "$str@$lyskomd_host"] } proc read_versions {} { # Read $top_srcdir/versions and store the versions in global variables. global top_srcdir global protocol_a_level global server_software global server_version global server_compat_version set f [open "$top_srcdir/versions"] while {[gets $f line] >= 0} { if {[lindex $line 0] == "PROTOCOL-A-LEVEL:"} { set protocol_a_level [lindex $line 1] } elseif {[lindex $line 0] == "SERVER-SOFTWARE:"} { set server_software [lindex $line 1] } elseif {[lindex $line 0] == "SERVER-VERSION:"} { set server_version [lindex $line 1] } elseif {[lindex $line 0] == "SERVER-COMPAT-VERSION:"} { set server_compat_version [lindex $line 1] } } close $f } proc dump_statistics {} { global lyskomd_pid system "kill -USR1 $lyskomd_pid" } # If you want to override the timeout or some other values, you # can do so by creating "localcfg.exp" in the build tree. if {[file exists "config/localcfg.exp"]} { source "config/localcfg.exp" } lyskom-server-2.1.2/src/server/testsuite/config/prot-a.exp0000664000015100472110000001523307721716131017341 # Test suite for lyskomd. # Copyright (C) 1998-1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Functions to make protocol A a little simpler # set ref_no 0 proc kom_next_call {} { global ref_no set ref_no [expr $ref_no + 1] } proc cres { result dflt} { global ref_no if { $result == "" } { return $dflt } else { return [eval concat "$result"] } } proc kom_connect { user {result ""} {testname ""}} { global ref_no send "A[holl $user]\n" set result [cres $result "LysKOM"] simple_expect $result $testname } proc kom_accept_async { str {result ""} {testname ""}} { global ref_no kom_next_call send "$ref_no 80 $str\n" set result [cres $result "=$ref_no"] simple_expect $result $testname } proc kom_create_person { name password flags aux {result ""} {testname ""}} { global ref_no global any_num global pers_no kom_next_call send "$ref_no 89 [holl "$name"] [holl "$password"] $flags $aux\n" set result [cres $result "=$ref_no ($any_num)" ] extracting_expect $result pers_no 1 return $pers_no } proc kom_logout {{result ""} {testname ""}} { global ref_no kom_next_call send "$ref_no 1\n" set result [cres $result "=$ref_no"] simple_expect $result $testname } proc kom_login_old {person password {result ""} {testname ""}} { global ref_no kom_next_call send "$ref_no 0 $person [holl "$password"]\n" set result [cres $result "=$ref_no"] simple_expect $result $testname } proc kom_login {person password invisible {result ""} {testname ""}} { global ref_no kom_next_call send "$ref_no 62 $person [holl "$password"] $invisible\n" set result [cres $result "=$ref_no"] simple_expect $result $testname } proc kom_create_conference { name type aux {result ""} {testname ""}} { global ref_no global any_num global conf_no kom_next_call send "$ref_no 88 [holl "$name"] $type $aux\n" set result [cres $result "=$ref_no ($any_num)"] extracting_expect $result conf_no 1 return $conf_no } proc kom_enable { value {result ""} {testname ""} } { global ref_no kom_next_call send "$ref_no 42 $value\n" set result [cres $result "=$ref_no"] simple_expect $result $testname } proc kom_set_supervisor { conf admin {result ""} {testname ""} } { global ref_no kom_next_call send "$ref_no 18 $conf $admin\n" set result [cres $result "=$ref_no"] simple_expect $result $testname } proc kom_set_permitted_submitters { conf permitted {result ""} {testname ""}} { global ref_no kom_next_call send "$ref_no 19 $conf $permitted\n" set result [cres $result "=$ref_no"] simple_expect $result $testname } proc kom_set_super_conf { conf super {result ""} {testname ""}} { global ref_no kom_next_call send "$ref_no 20 $conf $super\n" set result [cres $result "=$ref_no"] simple_expect $result $testname } proc kom_add_member { conf pers prio where type {result ""} {testname ""}} { global ref_no kom_next_call send "$ref_no 100 $conf $pers $prio $where $type\n" set result [cres $result "=$ref_no"] simple_expect $result $testname } proc kom_mark_text { text mark { result "" } { testname "" }} { global ref_no kom_next_call send "$ref_no 72 $text $mark\n" set result [cres $result "=$ref_no"] simple_expect $result $testname } proc kom_sub_recipient { text recpt { result "" } { testname "" }} { global ref_no kom_next_call send "$ref_no 31 $text $recpt\n" set result [cres $result "=$ref_no"] simple_expect $result $testname } proc kom_set_conf_type { conf type { result "" } { testname "" }} { global ref_no kom_next_call send "$ref_no 21 $conf $type\n" set result [cres $result "=$ref_no"] simple_expect $result $testname } proc kom_change_conference { conf { result "" } { testname "" }} { global ref_no kom_next_call send "$ref_no 2 $conf\n" set result [cres $result "=$ref_no"] simple_expect $result $testname } proc kom_set_priv_bits { pers bits { result "" } { testname "" }} { global ref_no kom_next_call send "$ref_no 7 $pers $bits\n" set result [cres $result "=$ref_no"] simple_expect $result $testname } proc kom_set_user_area { pers text { result "" } { testname "" } } { global ref_no; kom_next_call send "$ref_no 57 $pers $text\n" set result [cres $result "=$ref_no"] simple_expect $result $testname } proc kom_create_text_simple { text recpt { result "" } { testname "" } } { global ref_no; global any_num; global text_no; kom_next_call send "$ref_no 86 [holl "$text"] 1 { 0 $recpt } 0 { }\n" set result [cres $result "=$ref_no ($any_num)"] extracting_expect $result text_no 1 return $text_no } proc kom_shutdown_server { { result "" } { testname "" } } { global ref_no; kom_next_call send "$ref_no 44 0\n" set result [cres $result "=$ref_no"] simple_expect $result $testname } proc kom_lookup_z_name { name want_pers want_conf { result "" } { testname "" } } { global ref_no; kom_next_call send "$ref_no 76 [holl "$name"] $want_pers $want_conf\n" set result [cres $result "=$ref_no"] simple_expect $result $testname } proc kom_delete_conf { conf_no { result "" } { testname "" } } { global ref_no; kom_next_call send "$ref_no 11 $conf_no\n" set result [cres $result "=$ref_no"] simple_expect $result $testname } proc kom_delete_text { text_no { result "" } { testname "" } } { global ref_no; kom_next_call send "$ref_no 29 $text_no\n" set result [cres $result "=$ref_no"] simple_expect $result $testname } proc kom_ping_server { } { global ref_no global any_time kom_next_call send "$ref_no 35\n" simple_expect "=$ref_no $any_time" } lyskom-server-2.1.2/src/server/testsuite/config/leaks.exp0000664000015100472110000000612007721716131017231 # Test suite for lyskomd. # Copyright (C) 1998-2001, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Common code for leaks checking source "$srcdir/config/prot-a.exp" set blocks_base 0 set strings_base 0 set blocks_usage 0 set strings_usage 0 proc startup_leaks {{aux "def_val"} { config "" }} { global srcdir if {"$aux" == "def_val"} { set aux $srcdir/lyskomd.0/aux-items.conf } lyskomd_start "$aux" "$config" client_start 0 talk_to client 0 send "A[holl "DejaGnu Leaks Test"]\n" simple_expect "LysKOM" kom_accept_async "0 { }" kom_login 5 "gazonk" 0 } proc shutdown_leaks {} { kom_logout kom_login 5 "gazonk" 0 kom_enable 255 send "9999 44 0\n" simple_expect "=9999" client_death 0 lyskomd_death } proc read_memory_file {} { set allocated_strings 0 set allocated_blocks 0 set f [ open "etc/memory-usage" ] while { [ gets $f line] >= 0 } { if { [regexp "Allocated blocks .grand total." $line] } { set allocated_blocks [lindex "$line" [expr [llength "$line"] - 1]] } elseif { [regexp "Allocated strings" $line] } { set allocated_strings [lindex "$line" [expr [llength "$line"] - 1]] } } close $f return "$allocated_blocks $allocated_strings" } proc read_usage_base {} { global blocks_base global strings_base set val [read_memory_file] set blocks_base [lindex $val 0] set strings_base [lindex $val 1] save_memory_file "usage-base.tmp" } proc check_usage {test id} { global blocks_usage global strings_usage global blocks_base global strings_base set val [read_memory_file] set blocks_usage [lindex $val 0] set strings_usage [lindex $val 1] set succeed 1 if { [expr $strings_usage != $strings_base] } { fail "$test (strings) See lyskomd.$id.\{usage,base\}" set succeed 0 } if { [expr $blocks_usage != $blocks_base] } { fail "$test (blocks) See lyskomd.$id.\{base,usage\}" set succeed 0 } if { $succeed } { pass "$test" } else { save_memory_file "lyskomd.$id.usage" system "cp usage-base.tmp lyskomd.$id.base" } } proc save_memory_file {target} { system "cp etc/memory-usage $target" } lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/0000777000015100472110000000000007723710417016055 5lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/Makefile.am0000664000015100472110000000563507723506631020041 # $Id: Makefile.am,v 1.43 2003/08/28 23:14:07 ceder Exp $ # Copyright (C) 2000-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # include $(top_srcdir)/scripts/common.make MOSTLYCLEANFILES = aux-items-18.conf \ aux-items-35.conf \ aux-items-46.conf check_DATA = $(srcdir)/15.exp $(srcdir)/19.exp $(srcdir)/15.exp: $(srcdir)/gen-15.py $(RM) $@ $@.tmp if HAVE_PYTHON $(PYTHON) $^ > $@.tmp else echo 'unsupported "15.exp needs python"' > $@.tmp endif chmod 444 $@.tmp mv -f $@.tmp $@ $(srcdir)/19.exp: $(srcdir)/gen-19.py $(RM) $@ $@.tmp if HAVE_PYTHON $(PYTHON) $^ > $@.tmp else echo 'unsupported "19.exp needs python"' > $@.tmp endif chmod 444 $@.tmp mv -f $@.tmp $@ EXTRA_DIST = .cvsignore \ 00.exp \ 01.exp \ 02.exp \ 03.exp \ 04.exp \ 05.exp \ 06.exp \ 07.exp \ 08.exp \ 09.exp \ 10.exp \ 11.exp \ 12.exp \ 13.exp \ 14.exp \ 15.exp \ 16.exp \ 17.exp \ 18.exp \ 19.exp \ 20.exp \ 21.exp \ 22.exp \ 23.exp \ 24.exp \ 25.exp \ 26.exp \ 27.exp \ 28.exp \ 29.exp \ 30.exp \ 31.exp \ 32.exp \ 33.exp \ 34.exp \ 35.exp \ 36.exp \ 37.exp \ 38.exp \ 39.exp \ 40.exp \ 41.exp \ 42.exp \ 43.exp \ 44.exp \ 45.exp \ 46.exp \ 47.exp \ 48.exp \ 49.exp \ admin-cov.exp \ aux-items-bad.conf \ aux-items-cov.exp \ aux-items.conf \ aux-items.cov \ aux-items.leaks \ broken-aux-items.conf \ bug-1121.data \ bug-1121.exp \ bug-1121.texts \ bug-145.exp \ bug-225.exp \ bug-349.exp \ bug-37-2.exp \ bug-37-3.exp \ bug-37-4.exp \ bug-37.exp \ bug-38.exp \ bug-48.exp \ bug-52.data \ bug-52.exp \ bug-52.texts \ bug-572.exp \ bug-598-2.exp \ bug-598.exp \ bug-612.exp \ bug-810.exp \ bug-877.exp \ bug-84.exp \ cache-node-cov.exp \ conf-file-cov.exp \ conference-cov.exp \ connections-cov.exp \ disk-end-of-atomic-cov.exp \ gen-15.py \ gen-19.py \ internal-connections-cov.exp \ isc-parse-cov.exp \ log-cov.exp \ membership-cov.exp \ memory-cov.exp \ null.exp \ person-cov.exp \ prot-a-parse-cov.exp \ prot-a-send-async-cov.exp \ regexp-match-cov.exp \ send-async-cov.exp \ session-cov.exp \ summarize.sh \ text-cov.exp lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/Makefile.in0000664000015100472110000002633007723707427020053 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # $Id: Makefile.am,v 1.43 2003/08/28 23:14:07 ceder Exp $ # Copyright (C) 2000-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../../../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEBUG_CALLS = @DEBUG_CALLS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EFENCE = @EFENCE@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FLEX = @FLEX@ HAVE_PYTHON_FALSE = @HAVE_PYTHON_FALSE@ HAVE_PYTHON_TRUE = @HAVE_PYTHON_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSURE = @INSURE@ LANGUAGE_SUFFIX = @LANGUAGE_SUFFIX@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ SED = @SED@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRACED_ALLOCATIONS = @TRACED_ALLOCATIONS@ U = @U@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ YACC = @YACC@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ RM = rm -f dbdir = $(localstatedir)/lyskomd/db exportdir = $(localstatedir)/lyskomd/exportdb MOSTLYCLEANFILES = aux-items-18.conf \ aux-items-35.conf \ aux-items-46.conf check_DATA = $(srcdir)/15.exp $(srcdir)/19.exp EXTRA_DIST = .cvsignore \ 00.exp \ 01.exp \ 02.exp \ 03.exp \ 04.exp \ 05.exp \ 06.exp \ 07.exp \ 08.exp \ 09.exp \ 10.exp \ 11.exp \ 12.exp \ 13.exp \ 14.exp \ 15.exp \ 16.exp \ 17.exp \ 18.exp \ 19.exp \ 20.exp \ 21.exp \ 22.exp \ 23.exp \ 24.exp \ 25.exp \ 26.exp \ 27.exp \ 28.exp \ 29.exp \ 30.exp \ 31.exp \ 32.exp \ 33.exp \ 34.exp \ 35.exp \ 36.exp \ 37.exp \ 38.exp \ 39.exp \ 40.exp \ 41.exp \ 42.exp \ 43.exp \ 44.exp \ 45.exp \ 46.exp \ 47.exp \ 48.exp \ 49.exp \ admin-cov.exp \ aux-items-bad.conf \ aux-items-cov.exp \ aux-items.conf \ aux-items.cov \ aux-items.leaks \ broken-aux-items.conf \ bug-1121.data \ bug-1121.exp \ bug-1121.texts \ bug-145.exp \ bug-225.exp \ bug-349.exp \ bug-37-2.exp \ bug-37-3.exp \ bug-37-4.exp \ bug-37.exp \ bug-38.exp \ bug-48.exp \ bug-52.data \ bug-52.exp \ bug-52.texts \ bug-572.exp \ bug-598-2.exp \ bug-598.exp \ bug-612.exp \ bug-810.exp \ bug-877.exp \ bug-84.exp \ cache-node-cov.exp \ conf-file-cov.exp \ conference-cov.exp \ connections-cov.exp \ disk-end-of-atomic-cov.exp \ gen-15.py \ gen-19.py \ internal-connections-cov.exp \ isc-parse-cov.exp \ log-cov.exp \ membership-cov.exp \ memory-cov.exp \ null.exp \ person-cov.exp \ prot-a-parse-cov.exp \ prot-a-send-async-cov.exp \ regexp-match-cov.exp \ send-async-cov.exp \ session-cov.exp \ summarize.sh \ text-cov.exp subdir = src/server/testsuite/lyskomd.0 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = DIST_SOURCES = DIST_COMMON = $(top_srcdir)/scripts/common.make Makefile.am Makefile.in all: all-am .SUFFIXES: $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/scripts/common.make $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/server/testsuite/lyskomd.0/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) uninstall-info-am: tags: TAGS TAGS: ctags: CTAGS CTAGS: DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = ../../../.. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) $(mkinstalldirs) $(distdir)/../../../../scripts @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_DATA) check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am info info-am install \ install-am install-data install-data-am install-exec \ install-exec-am install-info install-info-am install-man \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \ uninstall-info-am $(srcdir)/15.exp: $(srcdir)/gen-15.py $(RM) $@ $@.tmp @HAVE_PYTHON_TRUE@ $(PYTHON) $^ > $@.tmp @HAVE_PYTHON_FALSE@ echo 'unsupported "15.exp needs python"' > $@.tmp chmod 444 $@.tmp mv -f $@.tmp $@ $(srcdir)/19.exp: $(srcdir)/gen-19.py $(RM) $@ $@.tmp @HAVE_PYTHON_TRUE@ $(PYTHON) $^ > $@.tmp @HAVE_PYTHON_FALSE@ echo 'unsupported "19.exp needs python"' > $@.tmp chmod 444 $@.tmp mv -f $@.tmp $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/.cvsignore0000664000015100472110000000013107721707035017766 15.exp 19.exp Makefile Makefile.in aux-items-18.conf aux-items-35.conf aux-items-46.conf lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/00.exp0000664000015100472110000010574007721716132016735 # Test suite for lyskomd. # Copyright (C) 1998-1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test get_map and local_to_global. # Test get_created_texts and map_created_texts. # Test local_to_global_reverse and map_created_texts_reverse. # As a side effect a lot of other things are also tested. # The following texts are created by this test case: # # Author Text_no Recipients # 5 1 1<1> # 5 2 2<1> # 5 3 1<2> 3<1> # 6 4 1<3> # 6 5 1<4> # 5 6 1<5> # 5 7 1<6> # 5 8 1<7> # 5 9 1<8> # 5 10 1<9> # 6 11 1<10> # 6 12 1<11> # 6 13 1<11> lyskomd_start client_start 0 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" "connected" # Log in send "1000 0 5 [holl gazonk]\n" simple_expect ":2 9 5 1" "0=login-old caused a login async msg" simple_expect "=1000" "0=login-old succeeded" # Become a member of conference 1 using 14=add-member-old send "1001 14 1 5 100 1\n" simple_expect "=1001" "14=add-member-old succeeded" # Get the map using 34=get-map and 103=local-to-global # Also test 121=local-to-global-reverse, in indented lines. send "1002 34 1 0 50\n" simple_expect "=1002 1 0 \\*" "empty map (old-style 0)" send "1003 103 1 0 50\n" simple_expect "%1003 17 0" "empty map (new-style 0)" send "2000 121 1 0 50\n" simple_expect "=2000 1 1 0 0 0 \\*" send "1004 34 1 1 50\n" simple_expect "%1004 16 1" "empty map (old-style 1)" send "1005 103 1 1 50\n" simple_expect "%1005 16 1" "empty map (new-style 1)" send "2001 121 1 1 50\n" simple_expect "=2001 1 1 0 0 0 \\*" send "1006 34 1 2 50\n" simple_expect "%1006 16 2" "empty map (old-style 2)" send "1007 103 1 2 50\n" simple_expect "%1007 16 2" "empty map (new-style 2)" send "2002 121 1 2 50\n" simple_expect "=2002 1 1 0 0 0 \\*" # Create a text send "1008 28 [holl text0001] 1 { 0 1 }\n" simple_expect ":16 0 1 $any_time 5 0 8 0 2 { 0 1 6 1 }" "async text 1 created" simple_expect "=1008 1" "text 1 created" # Get the map using 34=get-map and 103=local-to-global send "1009 34 1 0 50\n" simple_expect "=1009 1 1 { 1 }" "one map (old-style 0)" send "1010 103 1 0 50\n" simple_expect "%1010 17 0" "one map (new-style 0)" send "2003 121 1 0 50\n" simple_expect "=2003 1 2 0 1 1 1 { 1 }" send "1011 34 1 1 50\n" simple_expect "=1011 1 1 { 1 }" "one map (old-style)" send "1012 103 1 1 50\n" simple_expect "=1012 1 2 0 1 1 1 { 1 }" "one map (new-style)" send "2004 121 1 1 50\n" simple_expect "=2004 1 1 0 0 0 \\*" send "1013 34 1 2 50\n" simple_expect "%1013 16 2" "one map (old-style 2)" send "1014 103 1 2 50\n" simple_expect "%1014 16 2" "one map (new-style 2)" send "2005 121 1 2 50\n" simple_expect "=2005 1 2 0 1 1 1 { 1 }" # Create yet another text in a conference we are not subscribed to. # Make sure that no async message arrives. send "1015 28 [holl text002] 1 { 0 2 }\n" simple_expect "=1015 2" "text 2 created" # Create text 3. Make sure that loc_no is ignored. send "1016 28 [holl text0003] 4 { 0 1 6 99 1 3 6 32 }\n" simple_expect ":16 0 3 $any_time 5 0 8 0 4 { 0 1 6 2 1 3 6 1 }" \ "async text 3 created" simple_expect "=1016 3" "text 3 created" # Get the map using 34=get-map and 103=local-to-global send "1017 34 1 0 50\n" simple_expect "=1017 1 2 { 1 3 }" "one map (old-style 0)" send "1018 103 1 0 50\n" simple_expect "%1018 17 0" "one map (new-style 0)" send "2006 121 1 0 50\n" simple_expect "=2006 1 3 0 1 1 2 { 1 3 }" send "1019 34 1 1 50\n" simple_expect "=1019 1 2 { 1 3 }" "one map (old-style)" send "1020 103 1 1 50\n" simple_expect "=1020 1 3 0 1 1 2 { 1 3 }" "one map (new-style)" send "2007 121 1 1 50\n" simple_expect "=2007 1 1 0 0 0 \\*" send "1021 34 1 3 50\n" simple_expect "%1021 16 3" "one map (old-style 3)" send "1022 103 1 3 50\n" simple_expect "%1022 16 3" "one map (new-style 3)" send "2008 121 1 3 50\n" simple_expect "=2008 1 3 0 1 1 2 { 1 3 }" send "1023 34 1 2 50\n" simple_expect "=1023 2 1 { 3 }" "one map (old-style 2)" send "1024 103 1 2 50\n" simple_expect "=1024 2 3 0 1 2 1 { 3 }" "one map (new-style 2)" send "2009 121 1 2 50\n" simple_expect "=2009 1 2 0 1 1 1 { 1 }" send "1025 34 1 1 2\n" simple_expect "=1025 1 2 { 1 3 }" "one map (old-style)" send "1026 103 1 1 2\n" simple_expect "=1026 1 3 0 1 1 2 { 1 3 }" "one map (new-style)" send "2010 121 1 3 2\n" simple_expect "=2010 1 3 0 1 1 2 { 1 3 }" send "1027 34 1 1 1\n" simple_expect "=1027 1 1 { 1 }" "one map (old-style)" send "1028 103 1 1 1\n" simple_expect "=1028 1 2 1 1 1 1 { 1 }" "one map (new-style)" send "2011 121 1 3 1\n" simple_expect "=2011 2 3 1 1 2 1 { 3 }" send "1029 34 1 1 0\n" simple_expect "=1029 1 0 \\*" "one map (old-style)" send "1030 103 1 1 0\n" simple_expect "=1030 1 1 1 0 0 \\*" "one map (new-style)" send "2012 121 1 3 0\n" simple_expect "=2012 3 3 1 0 0 \\*" # Connect a second client that is aux-info-aware client_start 1 talk_to client 1 send "A3Hbar\n" simple_expect "LysKOM" "connected" # Enable new-style async messages. send "1031 81\n" simple_expect "=1031 8 { 0 5 7 8 9 11 12 13 }" "the default list of async messages" send "1032 80 10 { 5 6 8 9 11 12 13 14 15 9999 }\n" simple_expect "%1032 50 9999" "async-message 9999 does not exist" send "1033 81\n" simple_expect "=1033 9 { 5 6 8 9 11 12 13 14 15 }" "the failed call succeeded" send "1034 80 10 { 5 6 8 9 11 12 7 13 14 15 }\n" simple_expect "=1034" "setting wanted async" send "1035 81\n" simple_expect "=1035 10 { 5 6 7 8 9 11 12 13 14 15 }" "setting async" # Create the person "Eskil Block, FOA" # lookup send "1036 76 [holl "Eskil Block, FOA"] 0 1\n" simple_expect "=1036 0 \\*" "No Eskil Block yet" send "1037 89 [holl "Eskil Block, FOA"] [holl "liksE"] 00000000 2 { 9 00000000 1 [holl "simulated compface data"] 12 00000000 1 [holl "simulated pgp public key"] }\n" simple_expect "=1037 6" "created Eskil, got 6" send "2013 62 6 [holl "liksE"] 0\n" simple_expect ":2 9 6 2" "Eskil logged in (async c1)" simple_expect "=2013" talk_to client 0 simple_expect ":2 9 6 2" "Eskil logged in (async c0)" talk_to client 1 # Check that Eskil is a member of his letterbox and nothing else. send "1038 99 6 0 9 0\n" simple_expect "=1038 1 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 }" "Eskil is a member of his letterbox (only)" # Eskil joins conf 1 and creates a text. send "1039 2 1\n" simple_expect "%1039 13 1" "Eskil not member yet; thus cannot change conference" send "1040 100 1 6 100 0 00000000\n" simple_expect "=1040" "Eskil joins ok" send "1041 2 1\n" simple_expect ":5 6 6 1 2 [holl ""] [idholl "bar"]" simple_expect "=1041" "Eskil member; thus can change conference" send "1042 86 [holl "text0004"] 1 { 0 1 } 0 { }\n" simple_expect ":18 15 4 $any_time 6 0 8 0 2 { 0 1 6 3 } 0 \\*" "async to c1" simple_expect "=1042 4" "Eskil created text 4" talk_to client 0 simple_expect ":16 0 4 $any_time 6 0 8 0 2 { 0 1 6 3 }" "async to c0" send "1043 34 1 0 50\n" simple_expect "=1043 1 3 { 1 3 4 }" "one map (old-style 0)" send "1044 103 1 0 50\n" simple_expect "%1044 17 0" "one map (new-style 0)" send "2014 121 1 0 50\n" simple_expect "=2014 1 4 0 1 1 3 { 1 3 4 }" send "1045 34 1 1 50\n" simple_expect "=1045 1 3 { 1 3 4 }" "one map (old-style)" send "1046 103 1 1 50\n" simple_expect "=1046 1 4 0 1 1 3 { 1 3 4 }" "one map (new-style)" send "2015 121 1 1 50\n" simple_expect "=2015 1 1 0 0 0 \\*" send "1047 34 1 4 50\n" simple_expect "%1047 16 4" "one map (old-style 3)" send "1048 103 1 4 50\n" simple_expect "%1048 16 4" "one map (new-style 3)" send "2016 121 1 4 50\n" simple_expect "=2016 1 4 0 1 1 3 { 1 3 4 }" send "1049 34 1 2 50\n" simple_expect "=1049 2 2 { 3 4 }" "one map (old-style 2)" send "1050 103 1 2 50\n" simple_expect "=1050 2 4 0 1 2 2 { 3 4 }" "one map (new-style 2)" send "2017 121 1 3 50\n" simple_expect "=2017 1 3 0 1 1 2 { 1 3 }" send "2018 121 1 2 50\n" simple_expect "=2018 1 2 0 1 1 1 { 1 }" send "1051 34 1 1 2\n" simple_expect "=1051 1 2 { 1 3 }" "one map (old-style)" send "1052 103 1 1 2\n" simple_expect "=1052 1 3 1 1 1 2 { 1 3 }" "one map (new-style)" send "2019 121 1 3 2\n" simple_expect "=2019 1 3 0 1 1 2 { 1 3 }" send "2020 121 1 4 2\n" simple_expect "=2020 2 4 1 1 2 2 { 3 4 }" send "1053 34 1 1 1\n" simple_expect "=1053 1 1 { 1 }" "one map (old-style)" send "1054 103 1 1 1\n" simple_expect "=1054 1 2 1 1 1 1 { 1 }" "one map (new-style)" send "2021 121 1 4 1\n" simple_expect "=2021 3 4 1 1 3 1 { 4 }" send "2022 121 1 3 1\n" simple_expect "=2022 2 3 1 1 2 1 { 3 }" send "2023 121 1 2 1\n" simple_expect "=2023 1 2 0 1 1 1 { 1 }" send "2024 121 1 1 1\n" simple_expect "=2024 1 1 0 0 0 \\*" send "2025 121 1 0 1\n" simple_expect "=2025 3 4 1 1 3 1 { 4 }" send "1055 34 1 3 0\n" simple_expect "=1055 3 0 \\*" "one map (old-style)" send "1056 103 1 3 0\n" simple_expect "=1056 3 3 1 0 0 \\*" "one map (new-style)" send "2026 121 1 1 0\n" simple_expect "=2026 1 1 0 0 0 \\*" send "2027 121 1 4 0\n" simple_expect "=2027 4 4 1 0 0 \\*" send "2028 121 1 0 0\n" simple_expect "=2028 4 4 1 0 0 \\*" talk_to client 1 send "1057 86 [holl "text0005 failed attempt"] 1 { 0 1 } 1 { 9 00000000 1 [holl "simulated compface data"] }\n" simple_expect "%1057 49 0" "not allowed to add compface to texts" send "1058 86 [holl "text0005"] 1 { 0 1 } 1 { 1 00000000 1 [holl "text/plain"] }\n" simple_expect ":18 15 5 $any_time 6 0 8 0 2 { 0 1 6 4 } 1 { 1 1 6 $any_time 00000000 1 [holl "text/plain"] }" "async to c1" simple_expect "=1058 5" "Eskil created text 5" talk_to client 0 simple_expect ":16 0 5 $any_time 6 0 8 0 2 { 0 1 6 4 }" "async to c0" # Create some more texts send "1059 28 [holl text0006] 1 { 0 1 }\n" simple_expect ":16 0 6 $any_time 5 0 8 0 2 { 0 1 6 5 }" "async text 6 created" simple_expect "=1059 6" talk_to client 1 simple_expect ":18 15 6 $any_time 5 0 8 0 2 { 0 1 6 5 } 0 \\*" "async to c1" talk_to client 0 send "1060 28 [holl text0007] 1 { 0 1 }\n" simple_expect ":16 0 7 $any_time 5 0 8 0 2 { 0 1 6 6 }" "async text 7 created" simple_expect "=1060 7" talk_to client 1 simple_expect ":18 15 7 $any_time 5 0 8 0 2 { 0 1 6 6 } 0 \\*" "async to c1" talk_to client 0 send "1061 28 [holl text0008] 1 { 0 1 }\n" simple_expect ":16 0 8 $any_time 5 0 8 0 2 { 0 1 6 7 }" "async text 8 created" simple_expect "=1061 8" talk_to client 1 simple_expect ":18 15 8 $any_time 5 0 8 0 2 { 0 1 6 7 } 0 \\*" "async to c1" talk_to client 0 send "1062 28 [holl text0009] 1 { 0 1 }\n" simple_expect ":16 0 9 $any_time 5 0 8 0 2 { 0 1 6 8 }" "async text 9 created" simple_expect "=1062 9" talk_to client 1 simple_expect ":18 15 9 $any_time 5 0 8 0 2 { 0 1 6 8 } 0 \\*" "async to c1" talk_to client 0 send "1063 28 [holl text0010] 1 { 0 1 }\n" simple_expect ":16 0 10 $any_time 5 0 8 0 2 { 0 1 6 9 }" "async text 10 created" simple_expect "=1063 10" talk_to client 1 simple_expect ":18 15 10 $any_time 5 0 8 0 2 { 0 1 6 9 } 0 \\*" "async to c1" # We now have 9 texts in conference 1. Check get_map. send "1064 34 1 0 50\n" simple_expect "=1064 1 9 { 1 3 4 5 6 7 8 9 10 }" send "1065 34 1 1 50\n" simple_expect "=1065 1 9 { 1 3 4 5 6 7 8 9 10 }" send "1066 34 1 2 50\n" simple_expect "=1066 2 8 { 3 4 5 6 7 8 9 10 }" send "1067 34 1 3 50\n" simple_expect "=1067 3 7 { 4 5 6 7 8 9 10 }" send "1068 34 1 4 50\n" simple_expect "=1068 4 6 { 5 6 7 8 9 10 }" send "1069 34 1 5 50\n" simple_expect "=1069 5 5 { 6 7 8 9 10 }" send "1070 34 1 6 50\n" simple_expect "=1070 6 4 { 7 8 9 10 }" send "1071 34 1 7 50\n" simple_expect "=1071 7 3 { 8 9 10 }" send "1072 34 1 8 50\n" simple_expect "=1072 8 2 { 9 10 }" send "1073 34 1 9 50\n" simple_expect "=1073 9 1 { 10 }" send "1074 34 1 10 50\n" simple_expect "%1074 16 10" send "1075 34 1 0 11\n" simple_expect "=1075 1 9 { 1 3 4 5 6 7 8 9 10 }" send "1076 34 1 0 10\n" simple_expect "=1076 1 9 { 1 3 4 5 6 7 8 9 10 }" send "1077 34 1 0 9\n" simple_expect "=1077 1 8 { 1 3 4 5 6 7 8 9 }" send "1078 34 1 1 10\n" simple_expect "=1078 1 9 { 1 3 4 5 6 7 8 9 10 }" send "1079 34 1 1 9\n" simple_expect "=1079 1 9 { 1 3 4 5 6 7 8 9 10 }" send "1080 34 1 1 8\n" simple_expect "=1080 1 8 { 1 3 4 5 6 7 8 9 }" send "1081 34 1 8 2\n" simple_expect "=1081 8 2 { 9 10 }" send "1082 34 1 9 1\n" simple_expect "=1082 9 1 { 10 }" # Check local_to_global send "1083 103 1 0 50\n" simple_expect "%1083 17 0" send "1084 103 1 1 50\n" simple_expect "=1084 1 10 0 1 1 9 { 1 3 4 5 6 7 8 9 10 }" send "1085 103 1 2 50\n" simple_expect "=1085 2 10 0 1 2 8 { 3 4 5 6 7 8 9 10 }" send "1086 103 1 3 50\n" simple_expect "=1086 3 10 0 1 3 7 { 4 5 6 7 8 9 10 }" send "1087 103 1 4 50\n" simple_expect "=1087 4 10 0 1 4 6 { 5 6 7 8 9 10 }" send "1088 103 1 5 50\n" simple_expect "=1088 5 10 0 1 5 5 { 6 7 8 9 10 }" send "1089 103 1 6 50\n" simple_expect "=1089 6 10 0 1 6 4 { 7 8 9 10 }" send "1090 103 1 7 50\n" simple_expect "=1090 7 10 0 1 7 3 { 8 9 10 }" send "1091 103 1 8 50\n" simple_expect "=1091 8 10 0 1 8 2 { 9 10 }" send "1092 103 1 9 50\n" simple_expect "=1092 9 10 0 1 9 1 { 10 }" send "1093 103 1 10 50\n" simple_expect "%1093 16 10" send "1094 103 1 0 11\n" simple_expect "%1094 17 0" send "1095 103 1 0 10\n" simple_expect "%1095 17 0" send "1096 103 1 0 9\n" simple_expect "%1096 17 0" send "1097 103 1 1 10\n" simple_expect "=1097 1 10 0 1 1 9 { 1 3 4 5 6 7 8 9 10 }" send "1098 103 1 1 9\n" simple_expect "=1098 1 10 0 1 1 9 { 1 3 4 5 6 7 8 9 10 }" send "1099 103 1 1 8\n" simple_expect "=1099 1 9 1 1 1 8 { 1 3 4 5 6 7 8 9 }" send "1100 103 1 3 5\n" simple_expect "=1100 3 8 1 1 3 5 { 4 5 6 7 8 }" send "1101 103 1 8 2\n" simple_expect "=1101 8 10 0 1 8 2 { 9 10 }" send "1102 103 1 9 1\n" simple_expect "=1102 9 10 0 1 9 1 { 10 }" # Check local_to_global_reverse send "2029 121 1 0 50\n" simple_expect "=2029 1 10 0 1 1 9 { 1 3 4 5 6 7 8 9 10 }" send "2030 121 1 12 50\n" simple_expect "=2030 1 10 0 1 1 9 { 1 3 4 5 6 7 8 9 10 }" send "2031 121 1 11 50\n" simple_expect "=2031 1 10 0 1 1 9 { 1 3 4 5 6 7 8 9 10 }" send "2032 121 1 10 50\n" simple_expect "=2032 1 10 0 1 1 9 { 1 3 4 5 6 7 8 9 10 }" send "2033 121 1 9 50\n" simple_expect "=2033 1 9 0 1 1 8 { 1 3 4 5 6 7 8 9 }" send "2034 121 1 8 50\n" simple_expect "=2034 1 8 0 1 1 7 { 1 3 4 5 6 7 8 }" send "2035 121 1 7 50\n" simple_expect "=2035 1 7 0 1 1 6 { 1 3 4 5 6 7 }" send "2036 121 1 6 50\n" simple_expect "=2036 1 6 0 1 1 5 { 1 3 4 5 6 }" send "2037 121 1 5 50\n" simple_expect "=2037 1 5 0 1 1 4 { 1 3 4 5 }" send "2038 121 1 4 50\n" simple_expect "=2038 1 4 0 1 1 3 { 1 3 4 }" send "2039 121 1 3 50\n" simple_expect "=2039 1 3 0 1 1 2 { 1 3 }" send "2040 121 1 2 50\n" simple_expect "=2040 1 2 0 1 1 1 { 1 }" send "2041 121 1 1 50\n" simple_expect "=2041 1 1 0 0 0 \\*" send "2042 121 1 12 10\n" simple_expect "=2042 1 10 0 1 1 9 { 1 3 4 5 6 7 8 9 10 }" send "2043 121 1 12 9\n" simple_expect "=2043 1 10 0 1 1 9 { 1 3 4 5 6 7 8 9 10 }" send "2044 121 1 12 8\n" simple_expect "=2044 2 10 1 1 2 8 { 3 4 5 6 7 8 9 10 }" send "2045 121 1 11 8\n" simple_expect "=2045 2 10 1 1 2 8 { 3 4 5 6 7 8 9 10 }" send "2046 121 1 10 8\n" simple_expect "=2046 2 10 1 1 2 8 { 3 4 5 6 7 8 9 10 }" send "2047 121 1 10 5\n" simple_expect "=2047 5 10 1 1 5 5 { 6 7 8 9 10 }" send "2048 121 1 10 4\n" simple_expect "=2048 6 10 1 1 6 4 { 7 8 9 10 }" send "2049 121 1 10 2\n" simple_expect "=2049 8 10 1 1 8 2 { 9 10 }" send "2050 121 1 10 1\n" simple_expect "=2050 9 10 1 1 9 1 { 10 }" # Remove a few texts to provoke sparse maps. send "1103 29 4\n" simple_expect ":18 14 4 $any_time 6 0 8 0 2 { 0 1 6 3 } 0 \\*" simple_expect "=1103" send "1104 31 5 1\n" simple_expect "=1104" # Now, these local text numbers exist: # lno: 1 2 . . 5 6 7 8 9 # tno: 1 3 . . 6 7 8 9 10 send "1105 34 1 1 50\n" simple_expect "=1105 1 9 { 1 3 0 0 6 7 8 9 10 }" send "1106 34 1 2 50\n" simple_expect "=1106 2 8 { 3 0 0 6 7 8 9 10 }" send "1107 34 1 3 50\n" simple_expect "=1107 3 7 { 0 0 6 7 8 9 10 }" send "1108 34 1 4 50\n" simple_expect "=1108 4 6 { 0 6 7 8 9 10 }" send "1109 34 1 5 50\n" simple_expect "=1109 5 5 { 6 7 8 9 10 }" send "1110 34 1 6 50\n" simple_expect "=1110 6 4 { 7 8 9 10 }" send "1111 103 1 3 1\n" simple_expect "=1111 3 6 1 1 5 1 { 6 }" send "1112 103 1 4 1\n" simple_expect "=1112 4 6 1 1 5 1 { 6 }" send "1113 103 1 5 1\n" simple_expect "=1113 5 6 1 1 5 1 { 6 }" send "1114 103 1 2 1\n" simple_expect "=1114 2 3 1 1 2 1 { 3 }" send "1115 103 1 2 2\n" simple_expect "=1115 2 6 1 0 2 { 2 3 5 6 }" send "1116 103 1 2 3\n" simple_expect "=1116 2 7 1 1 2 5 { 3 0 0 6 7 }" send "2051 121 1 0 50\n" simple_expect "=2051 1 10 0 1 1 9 { 1 3 0 0 6 7 8 9 10 }" send "2052 121 1 7 1\n" simple_expect "=2052 6 7 1 1 6 1 { 7 }" send "2053 121 1 6 1\n" simple_expect "=2053 5 6 1 1 5 1 { 6 }" send "2054 121 1 5 1\n" simple_expect "=2054 2 5 1 1 2 1 { 3 }" send "2055 121 1 4 1\n" simple_expect "=2055 2 4 1 1 2 1 { 3 }" send "2056 121 1 3 1\n" simple_expect "=2056 2 3 1 1 2 1 { 3 }" send "2057 121 1 2 1\n" simple_expect "=2057 1 2 0 1 1 1 { 1 }" send "2058 121 1 6 2\n" simple_expect "=2058 2 6 1 0 2 { 2 3 5 6 }" send "2059 121 1 6 3\n" simple_expect "=2059 1 6 0 1 1 5 { 1 3 0 0 6 }" send "2060 121 1 7 3\n" simple_expect "=2060 2 7 1 1 2 5 { 3 0 0 6 7 }" # Texts written by person 5: # ano: 1 2 3 4 5 6 7 8 # tno: 1 2 3 6 7 8 9 10 # Texts written by person 6: # ano: . 2 # tno: . 5 send "1117 47 5 1 50\n" simple_expect "=1117 1 8 { 1 2 3 6 7 8 9 10 }" send "1118 47 5 1 8\n" simple_expect "=1118 1 8 { 1 2 3 6 7 8 9 10 }" send "1119 47 5 1 7\n" simple_expect "=1119 1 7 { 1 2 3 6 7 8 9 }" send "1120 47 5 1 6\n" simple_expect "=1120 1 6 { 1 2 3 6 7 8 }" send "1121 47 5 1 1\n" simple_expect "=1121 1 1 { 1 }" send "1122 47 5 0 1\n" simple_expect "=1122 1 1 { 1 }" send "1123 47 5 0 2\n" simple_expect "=1123 1 2 { 1 2 }" send "1124 47 5 5 3\n" simple_expect "=1124 5 3 { 7 8 9 }" send "1125 47 5 5 4\n" simple_expect "=1125 5 4 { 7 8 9 10 }" send "1126 47 5 5 5\n" simple_expect "=1126 5 4 { 7 8 9 10 }" send "1127 47 5 8 4\n" simple_expect "=1127 8 1 { 10 }" send "1128 47 5 9 4\n" simple_expect "%1128 16 9" send "1129 47 5 10 4\n" simple_expect "%1129 16 10" send "1130 47 6 1 10\n" simple_expect "=1130 2 1 { 5 }" send "1131 104 5 1 50\n" simple_expect "=1131 1 9 0 1 1 8 { 1 2 3 6 7 8 9 10 }" send "1132 104 5 1 9\n" simple_expect "=1132 1 9 0 1 1 8 { 1 2 3 6 7 8 9 10 }" send "1133 104 5 1 8\n" simple_expect "=1133 1 9 0 1 1 8 { 1 2 3 6 7 8 9 10 }" send "1134 104 5 1 7\n" simple_expect "=1134 1 8 1 1 1 7 { 1 2 3 6 7 8 9 }" send "1135 104 5 1 6\n" simple_expect "=1135 1 7 1 1 1 6 { 1 2 3 6 7 8 }" send "1136 104 5 1 2\n" simple_expect "=1136 1 3 1 1 1 2 { 1 2 }" send "1137 104 5 1 1\n" simple_expect "=1137 1 2 1 1 1 1 { 1 }" send "1138 104 5 1 0\n" simple_expect "=1138 1 1 1 0 0 \\*" send "1139 104 5 0 0\n" simple_expect "%1139 17 0" send "1140 104 5 0 1\n" simple_expect "%1140 17 0" send "1141 104 5 0 50\n" simple_expect "%1141 17 0" send "1142 104 6 1 10\n" simple_expect "=1142 1 3 0 1 2 1 { 5 }" send "2061 122 5 0 50\n" simple_expect "=2061 1 9 0 1 1 8 { 1 2 3 6 7 8 9 10 }" send "2062 122 5 10 50\n" simple_expect "=2062 1 9 0 1 1 8 { 1 2 3 6 7 8 9 10 }" send "2063 122 5 10 50\n" simple_expect "=2063 1 9 0 1 1 8 { 1 2 3 6 7 8 9 10 }" send "2064 122 5 9 50\n" simple_expect "=2064 1 9 0 1 1 8 { 1 2 3 6 7 8 9 10 }" send "2065 122 5 8 50\n" simple_expect "=2065 1 8 0 1 1 7 { 1 2 3 6 7 8 9 }" send "2066 122 5 2 50\n" simple_expect "=2066 1 2 0 1 1 1 { 1 }" send "2067 122 5 8 7\n" simple_expect "=2067 1 8 0 1 1 7 { 1 2 3 6 7 8 9 }" send "2068 122 5 8 6\n" simple_expect "=2068 2 8 1 1 2 6 { 2 3 6 7 8 9 }" send "2069 122 5 8 0\n" simple_expect "=2069 8 8 1 0 0 \\*" # Remove some more talk_to client 0 send "1143 29 6\n" simple_expect "=1143" send "1144 29 7\n" simple_expect "=1144" send "1145 29 8\n" simple_expect "=1145" send "1146 29 9\n" simple_expect "=1146" talk_to client 1 simple_expect ":18 14 6 $any_time 5 0 8 0 2 { 0 1 6 5 } 0 \\*" simple_expect ":18 14 7 $any_time 5 0 8 0 2 { 0 1 6 6 } 0 \\*" simple_expect ":18 14 8 $any_time 5 0 8 0 2 { 0 1 6 7 } 0 \\*" simple_expect ":18 14 9 $any_time 5 0 8 0 2 { 0 1 6 8 } 0 \\*" # Now, these local text numbers exist: # lno: 1 2 . . . . . . 9 # tno: 1 3 . . . . . . 10 send "1147 103 1 1 2\n" simple_expect "=1147 1 3 1 1 1 2 { 1 3 }" send "1148 103 1 2 2\n" simple_expect "=1148 2 10 0 0 2 { 2 3 9 10 }" send "1149 103 1 2 3\n" simple_expect "=1149 2 10 0 0 2 { 2 3 9 10 }" send "1150 103 1 1 3\n" simple_expect "=1150 1 10 0 0 3 { 1 1 2 3 9 10 }" send "1151 103 1 1 4\n" simple_expect "=1151 1 10 0 0 3 { 1 1 2 3 9 10 }" send "1152 103 1 1 50\n" simple_expect "=1152 1 10 0 0 3 { 1 1 2 3 9 10 }" send "1153 103 1 6 50\n" simple_expect "=1153 6 10 0 1 9 1 { 10 }" send "1154 34 1 6 50\n" simple_expect "=1154 6 4 { 0 0 0 10 }" send "1155 34 1 1 50\n" simple_expect "=1155 1 9 { 1 3 0 0 0 0 0 0 10 }" send "2070 121 1 3 2\n" simple_expect "=2070 1 3 0 1 1 2 { 1 3 }" send "2071 121 1 4 2\n" simple_expect "=2071 1 4 0 1 1 2 { 1 3 }" send "2072 121 1 8 2\n" simple_expect "=2072 1 8 0 1 1 2 { 1 3 }" send "2073 121 1 9 2\n" simple_expect "=2073 1 9 0 1 1 2 { 1 3 }" send "2074 121 1 10 2\n" simple_expect "=2074 2 10 1 0 2 { 2 3 9 10 }" send "2075 121 1 10 3\n" simple_expect "=2075 1 10 0 0 3 { 1 1 2 3 9 10 }" send "2076 121 1 10 50\n" simple_expect "=2076 1 10 0 0 3 { 1 1 2 3 9 10 }" send "2077 121 1 40 50\n" simple_expect "=2077 1 10 0 0 3 { 1 1 2 3 9 10 }" send "2078 121 1 0 50\n" simple_expect "=2078 1 10 0 0 3 { 1 1 2 3 9 10 }" send "2079 121 1 6 50\n" simple_expect "=2079 1 6 0 1 1 2 { 1 3 }" # Test the limit on no_of_texts send "1156 103 1 3 256\n" simple_expect "%1156 46 255" send "1157 103 1 3 255\n" simple_expect "=1157 3 10 0 1 9 1 { 10 }" send "2080 121 1 0 256\n" simple_expect "%2080 46 255" send "2081 121 1 0 255\n" simple_expect "=2081 1 10 0 0 3 { 1 1 2 3 9 10 }" # Test to get the map from a conference we are not a member of send "1158 34 3 1 10\n" simple_expect "=1158 1 1 { 3 }" send "1159 103 3 1 10\n" simple_expect "=1159 1 2 0 1 1 1 { 3 }" send "2082 121 3 0 10\n" simple_expect "=2082 1 2 0 1 1 1 { 3 }" # Texts written by person 5: # ano: 1 2 3 . . . . 8 # tno: 1 2 3 . . . . 10 # Texts written by person 6: # ano: . 2 # tno: . 5 send "1160 104 5 1 3\n" simple_expect "=1160 1 4 1 1 1 3 { 1 2 3 }" send "1161 104 5 2 2\n" simple_expect "=1161 2 4 1 1 2 2 { 2 3 }" send "1162 104 5 1 4\n" simple_expect "=1162 1 9 0 0 4 { 1 1 2 2 3 3 8 10 }" send "1163 104 5 4 50\n" simple_expect "=1163 4 9 0 1 8 1 { 10 }" send "1164 104 5 1 50\n" simple_expect "=1164 1 9 0 0 4 { 1 1 2 2 3 3 8 10 }" send "1165 104 5 3 50\n" simple_expect "=1165 3 9 0 0 2 { 3 3 8 10 }" send "1166 104 5 3 2\n" simple_expect "=1166 3 9 0 0 2 { 3 3 8 10 }" send "1167 104 5 3 1\n" simple_expect "=1167 3 4 1 1 3 1 { 3 }" send "2083 122 5 4 3\n" simple_expect "=2083 1 4 0 1 1 3 { 1 2 3 }" send "2084 122 5 10 1\n" simple_expect "=2084 8 9 1 1 8 1 { 10 }" send "2085 122 5 9 1\n" simple_expect "=2085 8 9 1 1 8 1 { 10 }" send "2086 122 5 8 1\n" simple_expect "=2086 3 8 1 1 3 1 { 3 }" send "2087 122 5 10 2\n" simple_expect "=2087 3 9 1 0 2 { 3 3 8 10 }" send "2088 122 5 10 3\n" simple_expect "=2088 2 9 1 0 3 { 2 2 3 3 8 10 }" send "2089 122 5 10 4\n" simple_expect "=2089 1 9 0 0 4 { 1 1 2 2 3 3 8 10 }" send "2090 122 5 10 5\n" simple_expect "=2090 1 9 0 0 4 { 1 1 2 2 3 3 8 10 }" send "2091 122 5 10 50\n" simple_expect "=2091 1 9 0 0 4 { 1 1 2 2 3 3 8 10 }" send "2092 122 5 10 255\n" simple_expect "=2092 1 9 0 0 4 { 1 1 2 2 3 3 8 10 }" send "2093 122 5 10 256\n" simple_expect "%2093 46 255" send "2094 122 5 9 255\n" simple_expect "=2094 1 9 0 0 4 { 1 1 2 2 3 3 8 10 }" send "2095 122 5 8 255\n" simple_expect "=2095 1 8 0 1 1 3 { 1 2 3 }" send "1168 47 5 1 3\n" simple_expect "=1168 1 3 { 1 2 3 }" send "1169 47 5 1 4\n" simple_expect "=1169 1 4 { 1 2 3 0 }" send "1170 47 5 1 5\n" simple_expect "=1170 1 5 { 1 2 3 0 0 }" send "1171 47 5 1 6\n" simple_expect "=1171 1 6 { 1 2 3 0 0 0 }" send "1172 47 5 1 7\n" simple_expect "=1172 1 7 { 1 2 3 0 0 0 0 }" send "1173 47 5 1 8\n" simple_expect "=1173 1 8 { 1 2 3 0 0 0 0 10 }" send "1174 47 5 1 9\n" simple_expect "=1174 1 8 { 1 2 3 0 0 0 0 10 }" send "1175 47 5 2 6\n" simple_expect "=1175 2 6 { 2 3 0 0 0 0 }" send "1176 47 5 2 7\n" simple_expect "=1176 2 7 { 2 3 0 0 0 0 10 }" send "1177 47 5 3 7\n" simple_expect "=1177 3 6 { 3 0 0 0 0 10 }" send "1178 47 5 4 7\n" simple_expect "=1178 4 5 { 0 0 0 0 10 }" send "1179 47 5 5 4\n" simple_expect "=1179 5 4 { 0 0 0 10 }" send "1180 47 5 7 4\n" simple_expect "=1180 7 2 { 0 10 }" send "1181 47 5 8 4\n" simple_expect "=1181 8 1 { 10 }" send "1182 104 6 1 50\n" simple_expect "=1182 1 3 0 1 2 1 { 5 }" send "2096 122 6 0 50\n" simple_expect "=2096 2 3 0 1 2 1 { 5 }" send "1183 47 6 1 50\n" simple_expect "=1183 2 1 { 5 }" # Test what happens when the oldest texts are removed and there exists # a few more texts. talk_to client 0 send "1184 29 1\n" simple_expect "=1184" send "1185 29 3\n" simple_expect "=1185" talk_to client 1 simple_expect ":18 14 1 $any_time 5 0 8 0 2 { 0 1 6 1 } 0 \\*" simple_expect ":18 14 3 $any_time 5 0 8 0 4 { 0 1 6 2 1 3 6 1 } 0 \\*" send "1186 86 [holl "text0011"] 1 { 0 1 } 0 { }\n" simple_expect ":18 15 11 $any_time 6 0 8 0 2 { 0 1 6 10 } 0 \\*" "async to c1" simple_expect "=1186 11" "Eskil created text 11" send "1187 86 [holl "text0012"] 1 { 0 1 } 0 { }\n" simple_expect ":18 15 12 $any_time 6 0 8 0 2 { 0 1 6 11 } 0 \\*" "async to c1" simple_expect "=1187 12" "Eskil created text 12" send "1188 86 [holl "text0013"] 1 { 0 1 } 0 { }\n" simple_expect ":18 15 13 $any_time 6 0 8 0 2 { 0 1 6 12 } 0 \\*" "async to c1" simple_expect "=1188 13" "Eskil created text 13" talk_to client 0 simple_expect ":16 0 11 $any_time 6 0 8 0 2 { 0 1 6 10 }" "async to c0" simple_expect ":16 0 12 $any_time 6 0 8 0 2 { 0 1 6 11 }" "async to c0" simple_expect ":16 0 13 $any_time 6 0 8 0 2 { 0 1 6 12 }" "async to c0" talk_to client 1 send "1189 29 11\n" simple_expect ":18 14 11 $any_time 6 0 8 0 2 { 0 1 6 10 } 0 \\*" simple_expect "=1189" # Now, these local text numbers exist: # lno: 9 . 11 12 # tno: 10 . 12 13 send "1190 34 1 0 1\n" simple_expect "=1190 9 0 \\*" send "1191 34 1 1 1\n" simple_expect "=1191 9 0 \\*" send "1192 34 1 1 8\n" simple_expect "=1192 9 0 \\*" send "1193 34 1 1 9\n" simple_expect "=1193 9 1 { 10 }" send "1194 34 1 1 10\n" simple_expect "=1194 9 2 { 10 0 }" send "1195 34 1 1 11\n" simple_expect "=1195 9 3 { 10 0 12 }" send "1196 34 1 1 12\n" simple_expect "=1196 9 4 { 10 0 12 13 }" send "1197 34 1 1 13\n" simple_expect "=1197 9 4 { 10 0 12 13 }" send "1198 34 1 9 13\n" simple_expect "=1198 9 4 { 10 0 12 13 }" # Test to get the map from a completely empty conference # Text 5 was a member of this conference. send "1199 34 3 1 10\n" simple_expect "=1199 2 0 \\*" send "1200 103 3 1 10\n" simple_expect "=1200 1 2 0 0 0 \\*" send "2097 121 3 0 10\n" simple_expect "=2097 2 2 0 0 0 \\*" send "2098 121 3 400 10\n" simple_expect "=2098 2 2 0 0 0 \\*" send "2099 121 3 3 10\n" simple_expect "=2099 2 2 0 0 0 \\*" send "2100 121 3 2 10\n" simple_expect "=2100 2 2 0 0 0 \\*" send "2101 121 3 1 10\n" simple_expect "=2101 1 1 0 0 0 \\*" # Texts written by person 5: # ano: . 2 . . . . . 8 # tno: . 2 . . . . . 10 # Texts written by person 6: # ano: . 2 . 4 5 # tno: . 5 . 12 13 send "1201 104 5 1 50\n" simple_expect "=1201 1 9 0 0 2 { 2 2 8 10 }" send "1202 104 5 1 2\n" simple_expect "=1202 1 9 0 0 2 { 2 2 8 10 }" send "1203 104 5 8 50\n" simple_expect "=1203 8 9 0 1 8 1 { 10 }" send "1204 104 5 9 50\n" simple_expect "%1204 16 9" send "1205 104 5 1 1\n" simple_expect "=1205 1 3 1 1 2 1 { 2 }" send "2102 122 5 0 50\n" simple_expect "=2102 2 9 0 0 2 { 2 2 8 10 }" send "2103 122 5 0 2\n" simple_expect "=2103 2 9 0 0 2 { 2 2 8 10 }" send "2104 122 5 3 50\n" simple_expect "=2104 2 3 0 1 2 1 { 2 }" send "2105 122 5 25 1\n" simple_expect "=2105 8 9 1 1 8 1 { 10 }" send "2106 122 5 2 50\n" simple_expect "=2106 2 2 0 0 0 \\*" send "1206 104 6 1 1\n" simple_expect "=1206 1 3 1 1 2 1 { 5 }" send "1207 104 6 1 2\n" simple_expect "=1207 1 5 1 1 2 3 { 5 0 12 }" send "1208 104 6 1 3\n" simple_expect "=1208 1 6 0 1 2 4 { 5 0 12 13 }" send "2107 122 6 9 1\n" simple_expect "=2107 5 6 1 1 5 1 { 13 }" send "2108 122 6 9 2\n" simple_expect "=2108 4 6 1 1 4 2 { 12 13 }" send "2109 122 6 9 3\n" simple_expect "=2109 2 6 0 1 2 4 { 5 0 12 13 }" send "2110 122 6 9 50\n" simple_expect "=2110 2 6 0 1 2 4 { 5 0 12 13 }" send "2111 122 6 0 1\n" simple_expect "=2111 5 6 1 1 5 1 { 13 }" send "2112 122 6 0 2\n" simple_expect "=2112 4 6 1 1 4 2 { 12 13 }" send "2113 122 6 0 3\n" simple_expect "=2113 2 6 0 1 2 4 { 5 0 12 13 }" send "2114 122 6 0 4\n" simple_expect "=2114 2 6 0 1 2 4 { 5 0 12 13 }" send "2115 122 6 0 50\n" simple_expect "=2115 2 6 0 1 2 4 { 5 0 12 13 }" send "1209 104 6 2 1\n" simple_expect "=1209 2 3 1 1 2 1 { 5 }" send "1210 104 6 2 2\n" simple_expect "=1210 2 5 1 1 2 3 { 5 0 12 }" send "1211 104 6 2 3\n" simple_expect "=1211 2 6 0 1 2 4 { 5 0 12 13 }" send "2116 122 6 5 1\n" simple_expect "=2116 4 5 1 1 4 1 { 12 }" send "2117 122 6 5 2\n" simple_expect "=2117 2 5 0 1 2 3 { 5 0 12 }" send "2118 122 6 5 3\n" simple_expect "=2118 2 5 0 1 2 3 { 5 0 12 }" send "1212 104 6 3 1\n" simple_expect "=1212 3 5 1 1 4 1 { 12 }" send "1213 104 6 3 2\n" simple_expect "=1213 3 6 0 1 4 2 { 12 13 }" send "1214 104 6 3 3\n" simple_expect "=1214 3 6 0 1 4 2 { 12 13 }" send "2119 122 6 4 1\n" simple_expect "=2119 2 4 0 1 2 1 { 5 }" send "2120 122 6 4 2\n" simple_expect "=2120 2 4 0 1 2 1 { 5 }" send "2121 122 6 4 40\n" simple_expect "=2121 2 4 0 1 2 1 { 5 }" send "1215 104 6 4 1\n" simple_expect "=1215 4 5 1 1 4 1 { 12 }" send "1216 104 6 4 2\n" simple_expect "=1216 4 6 0 1 4 2 { 12 13 }" send "1217 104 6 4 3\n" simple_expect "=1217 4 6 0 1 4 2 { 12 13 }" send "2122 122 6 3 40\n" simple_expect "=2122 2 3 0 1 2 1 { 5 }" send "1218 47 5 0 7\n" simple_expect "=1218 2 7 { 2 0 0 0 0 0 10 }" send "1219 47 5 1 7\n" simple_expect "=1219 2 7 { 2 0 0 0 0 0 10 }" send "1220 47 5 2 7\n" simple_expect "=1220 2 7 { 2 0 0 0 0 0 10 }" send "1221 47 5 3 7\n" simple_expect "=1221 3 6 { 0 0 0 0 0 10 }" send "1222 47 5 1 6\n" simple_expect "=1222 2 6 { 2 0 0 0 0 0 }" send "1223 47 5 2 8\n" simple_expect "=1223 2 7 { 2 0 0 0 0 0 10 }" send "1224 47 5 3 8\n" simple_expect "=1224 3 6 { 0 0 0 0 0 10 }" send "1225 47 5 2 50\n" simple_expect "=1225 2 7 { 2 0 0 0 0 0 10 }" send "1226 47 5 3 50\n" simple_expect "=1226 3 6 { 0 0 0 0 0 10 }" send "1227 47 6 1 2\n" simple_expect "=1227 2 2 { 5 0 }" send "1228 47 6 1 1\n" simple_expect "=1228 2 1 { 5 }" send "1229 47 6 3 4\n" simple_expect "=1229 3 3 { 0 12 13 }" send "1230 47 6 3 2\n" simple_expect "=1230 3 2 { 0 12 }" send "1231 47 6 3 1\n" simple_expect "=1231 3 1 { 0 }" send "1232 47 6 4 1\n" simple_expect "=1232 4 1 { 12 }" send "1233 47 6 4 4\n" simple_expect "=1233 4 2 { 12 13 }" send "1234 47 6 4 2\n" simple_expect "=1234 4 2 { 12 13 }" send "1235 47 6 4 1\n" simple_expect "=1235 4 1 { 12 }" send "1236 47 6 5 1\n" simple_expect "=1236 5 1 { 13 }" send "1237 47 6 5 50\n" simple_expect "=1237 5 1 { 13 }" send "1238 47 6 6 1\n" simple_expect "%1238 16 6" # Delete text 5 send "1239 29 5\n" # No async message, since there are no members of the text. # simple_expect ":18 14 5 $any_time 6 0 8 0 0 \\* 1 { 1 1 6 $any_time 00000000 1 [holl "text/plain"] }" simple_expect "=1239" # Texts written by person 5: # ano: . 2 . . . . . 8 # tno: . 2 . . . . . 10 # Texts written by person 6: # ano: . . . 4 5 # tno: . . . 12 13 send "1240 104 6 1 2\n" simple_expect "=1240 1 6 0 1 4 2 { 12 13 }" send "1241 104 6 1 1\n" simple_expect "=1241 1 5 1 1 4 1 { 12 }" send "2123 122 6 6 2\n" simple_expect "=2123 4 6 0 1 4 2 { 12 13 }" send "2124 122 6 6 1\n" simple_expect "=2124 5 6 1 1 5 1 { 13 }" send "2125 122 6 0 2\n" simple_expect "=2125 4 6 0 1 4 2 { 12 13 }" send "2126 122 6 0 1\n" simple_expect "=2126 5 6 1 1 5 1 { 13 }" send "1242 47 6 1 2\n" simple_expect "=1242 4 2 { 12 13 }" send "1243 47 6 1 1\n" simple_expect "=1243 4 1 { 12 }" # Delete all remaining texts that person 5 have created. talk_to client 0 send "1244 29 2\n" simple_expect "=1244" send "1245 29 10\n" simple_expect "=1245" talk_to client 1 # Text 2 is sent to conference 2, so we get no async message about it. simple_expect ":18 14 10 $any_time 5 0 8 0 2 { 0 1 6 9 } 0 \\*" # Texts written by person 5: # ano: . . . . . . . . (9) # tno: . . . . . . . . # Texts written by person 6: # ano: . . . 4 5 # tno: . . . 12 13 send "1246 104 5 1 2\n" simple_expect "=1246 1 9 0 0 0 \\*" send "1247 104 5 1 1\n" simple_expect "=1247 1 9 0 0 0 \\*" send "1248 104 5 1 50\n" simple_expect "=1248 1 9 0 0 0 \\*" send "1249 104 5 7 1\n" simple_expect "=1249 7 9 0 0 0 \\*" send "1250 104 5 8 1\n" simple_expect "=1250 8 9 0 0 0 \\*" send "1251 104 5 8 2\n" simple_expect "=1251 8 9 0 0 0 \\*" send "1252 104 5 9 1\n" simple_expect "%1252 16 9" send "2127 122 5 0 50\n" simple_expect "=2127 9 9 0 0 0 \\*" send "2128 122 5 9 50\n" simple_expect "=2128 9 9 0 0 0 \\*" send "2129 122 5 10 50\n" simple_expect "=2129 9 9 0 0 0 \\*" send "2130 122 5 8 50\n" simple_expect "=2130 8 8 0 0 0 \\*" send "2131 122 5 2 50\n" simple_expect "=2131 2 2 0 0 0 \\*" send "2132 122 5 1 50\n" simple_expect "=2132 1 1 0 0 0 \\*" send "2133 122 5 0 1\n" simple_expect "=2133 9 9 0 0 0 \\*" send "2134 122 5 9 1\n" simple_expect "=2134 9 9 0 0 0 \\*" send "2135 122 5 10 1\n" simple_expect "=2135 9 9 0 0 0 \\*" send "2136 122 5 8 1\n" simple_expect "=2136 8 8 0 0 0 \\*" send "2137 122 5 2 1\n" simple_expect "=2137 2 2 0 0 0 \\*" send "2138 122 5 1 1\n" simple_expect "=2138 1 1 0 0 0 \\*" send "1253 47 5 1 2\n" simple_expect "=1253 9 0 \\*" send "1254 47 5 7 2\n" simple_expect "=1254 9 0 \\*" send "1255 47 5 7 1\n" simple_expect "=1255 9 0 \\*" send "1256 47 5 8 1\n" simple_expect "=1256 9 0 \\*" send "1257 47 5 0 50\n" simple_expect "=1257 9 0 \\*" send "1258 47 5 1 50\n" simple_expect "=1258 9 0 \\*" send "1259 47 5 9 50\n" simple_expect "%1259 16 9*" # Shut down the server. talk_to client 0 send "1260 42 255\n" simple_expect "=1260" "42=enable succeeded" send "1261 44 0\n" simple_expect "=1261" "44=shutdown-kom succeeded" client_death 0 client_death 1 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/01.exp0000664000015100472110000004676007721716132016744 # Test suite for lyskomd. # Copyright (C) 1998-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check that all functions do the right thing when invoked before the # user logs in. read_versions lyskomd_start client_start 0 talk_to client 0 send "A\n" send "[holl "DejaGnu test suite"]\n" simple_expect "LysKOM" "connected" send "1000 62 5 [holl "bogus"] 0\n" simple_expect "%1000 4 5" send "1001 62 4 [holl "nono"] 0\n" simple_expect "%1001 10 4" send "1002 62 6 [holl "nono"] 0\n" simple_expect "%1002 10 6" send "1003 62 60 [holl "nono"] 0\n" simple_expect "%1003 10 60" send "1004 62 0 [holl "zero"] 0\n" simple_expect "%1004 8 0" # Turn of async messages send "1005 80 0 { }\n" simple_expect "=1005" # Test that most calls fail when the user isn't logged in. # 0:login-old may succeed # 1:logout always succeeds send "1006 1\n" simple_expect "=1006" "logout" # 2:change-conference send "1007 2 4\n" simple_expect "%1007 6 0" "change-conference" # 3:change-name send "1008 3 1 [holl "new name"]\n" simple_expect "%1008 6 0" "change-name" # 4:change-what-i-am-doing send "1009 4 [holl "testing lyskomd"]\n" simple_expect "=1009" "change-what-i-am-doing" # 5:create-person-old send "1010 5 [holl "new person"] [holl "mypasswd"]\n" simple_expect "=1010 6" "create-person-old" send "1011 39\n" simple_expect "=1011 1 { 6 0 [holl ""] }" "create-person-old" send "1012 1\n" simple_expect "=1012" "create-person-old" # 6:get-person-stat-old send "1013 6 6 1\n" simple_expect "%1013 6 0" "get-person-stat-old" # 7:set-priv-bits send "1014 7 6 0000000000000000\n" simple_expect "%1014 6 0" "set-priv-bits" # 8:set-passwd send "1015 8 5 [holl "old"] [holl "new"]\n" simple_expect "%1015 6 0" "set-passwd" # 9:query-read-texts-old send "1016 9 6 6\n" simple_expect "=1016 $any_time 6 255 0 0 \\*" "query-read-texts-old" # 10:create-conf-old send "1017 10 [holl "no way"] 0000\n" simple_expect "%1017 6 0" "create-conf-old" # 11:delete-conf send "1018 11 1\n" simple_expect "%1018 6 0" "delete-conf" # 12:lookup-name send "1019 12 [holl "pres"]\n" simple_expect "=1019 2 { 1 2 } { 0000 0000 }" "lookup-name" send "1020 12 [holl "xyzzy does not exist"]\n" simple_expect "=1020 0 \\* \\*" "lookup-name" # 13:get-conf-stat-older send "1021 13 1 0\n" simple_expect "=1021 0H 0000 $any_time $any_time 0 0 0 0 0 0 77 0 1 0" "get-conf-stat-older" send "1022 13 1 1\n" simple_expect "=1022 [holl "Presentation .av nya. möten"] 0000 $any_time $any_time 0 0 0 0 0 0 77 0 1 0" "get-conf-stat-older" # 14:add-member-old send "1023 14 4 5 255 1\n" simple_expect "%1023 6 0" "add-member-old" # 15:sub-member send "1024 15 4 5\n" simple_expect "%1024 6 0" "sub-member" # 16:set-presentation send "1025 16 4 1\n" simple_expect "%1025 6 0" "set-presentation" # 17:set-etc-motd send "1026 17 4 1\n" simple_expect "%1026 6 0" "set-etc-motd" # 18:set-supervisor send "1027 18 4 1\n" simple_expect "%1027 6 0" "set-supervisor" # 19:set-permitted-submitters send "1028 19 4 1\n" simple_expect "%1028 6 0" "set-permitted-submitters" # 20:set-super-conf send "1029 20 4 1\n" simple_expect "%1029 6 0" "set-super-conf" # 21:set-conf-type send "1030 21 4 0000\n" simple_expect "%1030 6 0" "set-conf-type" send "1031 21 4 00000000\n" simple_expect "%1031 6 0" "set-conf-type" # 22:set-garb-nice send "1032 22 4 17\n" simple_expect "%1032 6 0" "set-garb-nice" # 23:get-marks send "1033 23\n" simple_expect "%1033 6 0" "get-marks" # 24:mark-text-old send "1034 24 1 243\n" simple_expect "%1034 6 0" "mark-text-old" # 25:get-text send "1035 25 1 0 999\n" simple_expect "%1035 14 1" "get-text" # 26:get-text-stat-old send "1036 26 1\n" simple_expect "%1036 14 1" "get-text-stat-old" # 27:mark-as-read send "1037 27 3 1 { 1 }\n" simple_expect "%1037 6 0" "mark-as-read" # 28:create-text-old send "1038 28 [holl "A sample text"] 1 { 0 2 }\n" simple_expect "%1038 6 0" "create-text-old" # 29:delete-text send "1039 29 1\n" simple_expect "%1039 6 0" "delete-text" # 30:add-recipient send "1040 30 1 4 0\n" simple_expect "%1040 6 0" "add-recipient" # 31:sub-recipient send "1041 31 1 4\n" simple_expect "%1041 6 0" "sub-recipient" # 32:add-comment send "1042 32 2 1\n" simple_expect "%1042 6 0" "add-comment" # 33:sub-comment send "1043 33 2 1\n" simple_expect "%1043 6 0" "sub-comment" # 34:get-map send "1044 34 1 0 99\n" simple_expect "%1044 6 0" "get-map" # 35:get-time send "1045 35\n" simple_expect "=1045 $any_time" "get-time" # 36:get-info-old send "1046 36\n" simple_expect "=1046 $server_compat_version 1 2 3 4 0" "get-info-old" # 37:add-footnote send "1047 37 1 2\n" simple_expect "%1047 6 0" "add-footnote" # 38:sub-footnote send "1048 38 1 2\n" simple_expect "%1048 6 0" "sub-footnote" # 39:who-is-on-old send "1049 39\n" simple_expect "=1049 0 \\*" "who-is-on-old" # 40:set-unread send "1050 40 1 3\n" simple_expect "%1050 6 0" "set-unread" # 41:set-motd-of-lyskom send "1051 41 1\n" simple_expect "%1051 6 0" "set-motd-of-lyskom" # 42:enable send "1052 42 255\n" simple_expect "%1052 6 0" "enable" # 43:sync-kom send "1053 43\n" simple_expect "%1053 6 0" "sync-kom" # 44:shutdown-kom send "1054 44 2\n" simple_expect "%1054 6 0" "shutdown-kom" # 45:broadcast send "1055 45 [holl "broadcast-message"]\n" simple_expect "%1055 6 0" "broadcast" # 46:get-membership-old send "1056 46 5 1 3 1\n" simple_expect "%1056 6 0" "get-membership-old" # 47:get-created-texts send "1057 47 5 1 3\n" simple_expect "%1057 6 0" "get-created-text" # 48:get-members-old send "1058 48 5 0 1\n" simple_expect "=1058 1 { 5 }" "get-members-old" send "1059 48 5 0 2\n" simple_expect "=1059 1 { 5 }" "get-members-old" send "1060 48 5 0 10\n" simple_expect "=1060 1 { 5 }" "get-members-old" send "1061 49 5\n" simple_expect "=1061 [holl "X.unknown.@localhost"] 1111111111111111 00000000 $any_time 0 482 4 0 0 0 0 0 0 1 0 0 1" "get-members-old" # 50:get-conf-stat-old send "1062 50 1\n" simple_expect "=1062 [holl "Presentation .av nya. möten"] 0000 $any_time $any_time 0 0 0 0 0 0 77 0 1 0" "get-conf-stat-old" # 51:who-is-on send "1063 51\n" simple_expect "=1063 0 \\*" "who-is-on" # 52:get-unread-confs send "1064 52 5\n" simple_expect "%1064 6 0" "get-unread-confs" # 53:send-message send "1065 53 1 [holl "holler"]\n" simple_expect "%1065 6 0" "send-message" # 54:get-session-info send "1066 54 1\n" simple_expect "%1066 6 0" "get-session-info" # 55:disconnect send "1067 55 2\n" simple_expect "%1067 6 0" "disconnect" # 56:who-am-i send "1068 56\n" simple_expect "=1068 1" "who-am-i" # 57:set-user-area send "1069 57 5 2\n" simple_expect "%1069 6 0" "set-user-area" # 58:get-last-text send "1070 58 0 0 12 1 0 90 0 0 0\n" simple_expect "%1070 6 0" "get-last-text" # 59:create-anonymous-text-old send "1071 59 [holl "anon-txt"] 1 { 0 2 }\n" simple_expect "%1071 6 0" "create-anonymous-text-old" # 60:find-next-text-no send "1072 60 0\n" simple_expect "%1072 6 0" "find-next-text-no" send "1073 60 1\n" simple_expect "%1073 6 0" "find-next-text-no" send "1074 60 3\n" simple_expect "%1074 6 0" "find-next-text-no" # 61:find-previous-text-no send "1075 61 18\n" simple_expect "%1075 6 0" "find-previous-text-no" # 62:login send "1076 62 0 [holl "broken"] 1\n" simple_expect "%1076 8 0" "login" # 63:who-is-on-ident send "1077 63\n" simple_expect "=1077 0 \\*" "who-is-on-ident" # 64:get-session-info-ident send "1078 64 1\n" simple_expect "%1078 6 0" "get-session-info-ident" # 65:re-lookup-person send "1079 65 [holl "."]\n" simple_expect "=1079 2 { 5 6 }" "re-lookup-person" # 66:re-lookup-conf send "1080 66 [holl "Pre.*m.*"]\n" simple_expect "=1080 2 { 1 2 }" "re-lookup-conf" # 67:lookup-person send "1081 67 [holl "ad"]\n" simple_expect "=1081 1 { 5 }" "lookup-person" # 68:lookup-conf send "1082 68 [holl "n o lys"]\n" simple_expect "=1082 1 { 4 }" "lookup-conf" # 69:set-client-version send "1083 69 [holl "DejaGnu"] [holl "1.3"]\n" simple_expect "=1083" "set-client-version" # 70:get-client-name send "1084 70 1\n" simple_expect "%1084 6 0" "get-client-name" # 71:get-client-version send "1085 71 1\n" simple_expect "%1085 6 0" "get-clien-version" # 72:mark-text send "1086 72 1 239\n" simple_expect "%1086 6 0" "mark-text" # 73:unmark-text send "1087 73 1\n" simple_expect "%1087 6 0" "unmark-text" # 74:re-z-lookup send "1088 74 [holl "LysKOM"] 1 1\n" simple_expect "=1088 2 { [holl "Nyheter om LysKOM"] 0000 4 [holl "Administratör .för. LysKOM"] 1001 5 }" "re-z-lookup" # 75:get-version-info send "1089 75\n" simple_expect "=1089 $protocol_a_level [holl "$server_software"] [holl "$server_version"]" "get-version-info" # 76:lookup-z-name send "1090 76 [holl "pre m"] 1 1\n" simple_expect "=1090 2 { [holl "Presentation .av nya. möten"] 0000 1 [holl "Presentation .av nya. medlemmar"] 0000 2 }" "lookup-z-name" # 77:set-last-read send "1091 77 3 4\n" simple_expect "%1091 6 0" "set-last-read" # 78:get-uconf-stat send "1092 78 3\n" simple_expect "=1092 [holl "Lappar .på. dörren"] 00001000 0 77" "get-uconf-stat" # 79:set-info send "1093 79 10901 1 2 3 4 1080\n" simple_expect "%1093 6 0" "set-info" # 80:accept-async send "1094 80 0 { }\n" simple_expect "=1094" "accept-async" # 81:query-async send "1095 81\n" simple_expect "=1095 0 \\*" "query-async" # 82:user-active send "1096 82\n" simple_expect "=1096" "user-active" # 83:who-is-on-dynamic send "1097 83 1 1 0\n" simple_expect "=1097 1 { 1 0 0 $any_num 11000000 [holl ""] }" "who-is-on-dynamic" # 84:get-static-session-info send "1098 84 1\n" simple_expect "%1098 6 0" "get-static-session-info" # 85:get-collate-table send "1099 85\n" unanchored_expect "^MRK:client0: =1099 256H" "get-collate-table start" unanchored_expect "$nl" "get-collate-table newline before digits" # NOTE: Comment out the next two lines if runtest seems to hang. # NOTE: But also notify ceder of the versions of dejagnu, TCL and expect # NOTE: that you are using, and try to upgrade to current versions first. unanchored_expect "0123456789" "get-collate-table digits" unanchored_expect "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "get-collate-table upper" unanchored_expect "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "get-collate-table lower" unanchored_expect "\377$nl" "collate end" # 86:create-text send "1100 86 [holl "some text"] 1 { 0 4 } 0 { }\n" simple_expect "%1100 6 0" "create-text" # 87:create-anonymous-text send "1101 87 [holl "some text"] 1 { 0 4 } 0 { }\n" simple_expect "%1101 6 0" "create-anonymous-text" # 88:create-conf send "1102 88 [holl "new conf"] 0000 0 { }\n" simple_expect "%1102 6 0" "create-conf" send "1103 88 [holl "new conf"] 00000000 0 { }\n" simple_expect "%1103 6 0" "create-conf" # 89:create-person send "1104 89 [holl "new 89 person"] [holl "89pwd"] 00000000 0 { }\n" simple_expect "=1104 7" "create-person" send "101105 62 7 [holl "89pwd"] 0\n" simple_expect "=101105" send "1105 83 1 1 0\n" simple_expect "=1105 1 { 1 7 0 $any_num 01000000 [holl ""] }" "create-person" send "1106 1\n" simple_expect "=1106" "create-person" send "1107 83 1 1 0\n" simple_expect "=1107 1 { 1 0 0 $any_num 11000000 [holl ""] }" "create-person" # 90:get-text-stat send "1108 90 1\n" simple_expect "%1108 14 1" "get-text-stat" # 91:get-conf-stat send "1109 91 1\n" simple_expect "=1109 [holl "Presentation .av nya. möten"] 00001000 $any_time $any_time 0 0 0 0 0 0 77 77 0 1 0 0 0 \\*" "get-conf-stat" # 92:modify-text-info send "1110 92 1 0 { } 0 { }\n" simple_expect "%1110 6 0" "modify-text-info" # 93:modify-conf-info send "1111 93 1 0 { } 0 { }\n" simple_expect "%1111 6 0" "modify-conf-info" # 94:get-info send "1112 94\n" simple_expect "=1112 $server_compat_version 1 2 3 4 0 0 \\*" "get-info" # 95:modify-system-info send "1113 95 0 { } 0 { }\n" simple_expect "%1113 6 0" "modify-system-info" # 96:query-predefined-aux-items send "1114 96\n" simple_expect "=1114 40 { 10104 10103 10102 10101 10100 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 }" "query-predefined-aux-items" # 97:set-expire send "1115 97 1 76\n" simple_expect "%1115 6 0" "set-expire" # 98:query-read-texts-10 send "1116 98 6 6\n" simple_expect "=1116 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000" "query-read-texts-10" # 99:get-membership-10 send "1117 99 6 0 10 1\n" simple_expect "%1117 6 0" "get-membership-10" # 100:add-member send "1118 100 5 3 250 1 00000000\n" simple_expect "%1118 6 0" "add-member" # 101:get-members send "1119 101 5 0 10\n" simple_expect "=1119 1 { 5 5 $any_time 00000000 }" "get-members" # 102:set-membership-type send "1120 102 5 5 01000000\n" simple_expect "%1120 6 0" "set-membership-type" # 103:local-to-global send "1121 103 1 1 20\n" simple_expect "%1121 6 0" "local-to-global" # 104:map_created_texts send "1122 104 5 1 20\n" simple_expect "%1122 6 0" "map-created-texts" # 105:set-keep-commented send "1123 105 1 99\n" simple_expect "%1123 6 0" "set-keep-commented" # 106:set-pers-flags send "1124 106 5 10101010\n" simple_expect "%1124 6 0" "set-pers-flags" # 107:query-read-texts send "1125 107 6 6 1 0\n" simple_expect "=1125 0 $any_time 6 255 0 \\* 6 $any_time 00000000" "query-read-texts" # 108:get-membership send "1126 108 6 0 10 1 0\n" simple_expect "%1126 6 0" "get-membership" # 109:mark-as-unread send "1127 109 6 1\n" simple_expect "%1127 6 0" "mark-as-unread" # 110:set-read-ranges send "1128 110 6 0 { }\n" simple_expect "%1128 6 0" "mark-as-unread" send "1129 110 6 1 { 1 2 }\n" simple_expect "%1129 6 0" "mark-as-unread" send "1130 110 6 2 { 1 1 3 3 }\n" simple_expect "%1130 6 0" "mark-as-unread" send "1131 110 6 1 { 3 1 }\n" simple_expect "%1131 55 0" "mark-as-unread" send "1132 110 6 2 { 1 3 3 3 }\n" simple_expect "%1132 56 1" "mark-as-unread" send "1133 110 6 2 { 0 1 3 3 }\n" simple_expect "%1133 17 0" "mark-as-unread" send "1134 110 6 2 { 1 1 3 2 }\n" simple_expect "%1134 55 1" "mark-as-unread" # 111:get-stats-description send "1135 111\n" simple_expect "=1135 10 { [holl "run-queue-length"] [holl "pending-dns"] [holl "pending-ident"] [holl "clients"] [holl "reqs"] [holl "texts"] [holl "confs"] [holl "persons"] [holl "send-queue-bytes"] [holl "recv-queue-bytes"] } 6 { 0 1 15 60 300 900 }" # 112:get-stats send "1136 112 [holl "run-queue-length"]\n" simple_expect "=1136 6 { 0 0 0 $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float }" send "1137 112 [holl "pending-dns"]\n" simple_expect "=1137 6 { 0 0 0 $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float }" send "1138 112 [holl "pending-ident"]\n" simple_expect "=1138 6 { 0 0 0 $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float }" send "1139 112 [holl "clients"]\n" simple_expect "=1139 6 { 1 0 0 $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float }" send "1140 112 [holl "reqs"]\n" simple_expect "=1140 6 { 1 0 0 $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float }" send "1141 112 [holl "texts"]\n" simple_expect "=1141 6 { 0 0 0 $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float }" send "1142 112 [holl "confs"]\n" simple_expect "=1142 6 { 7 0 0 $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float }" send "1143 112 [holl "persons"]\n" simple_expect "=1143 6 { 3 0 0 $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float }" send "1144 112 [holl "send-queue-bytes"]\n" simple_expect "=1144 6 { $any_num 0 0 $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float }" send "1145 112 [holl "recv-queue-bytes"]\n" simple_expect "=1145 6 { $any_num 0 0 $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float }" # Non-existing stuff. send "1146 112 [holl "no-such-thing"]\n" simple_expect "%1146 57 0" # 113:get-boottime-info send "1147 113\n" simple_expect "=1147 $any_time $any_time [holl "clean"] 0 0 5 1 5" # 114:first-unused-conf-no send "1148 114\n" simple_expect "=1148 8" # 115:first-unused-text-no send "1149 115\n" simple_expect "=1149 1" # 116:find-next-conf-no send "1150 116 0\n" simple_expect "%1150 6 0" send "1151 116 1\n" simple_expect "%1151 6 0" send "1152 116 2\n" simple_expect "%1152 6 0" send "1153 116 200\n" simple_expect "%1153 6 0" # 117:find-previous-conf-no send "1154 117 0\n" simple_expect "%1154 6 0" send "1155 117 1\n" simple_expect "%1155 6 0" send "1156 117 2\n" simple_expect "%1156 6 0" send "1157 117 200\n" simple_expect "%1157 6 0" # 118:get-scheduling send "1158 118 0\n" simple_expect "=1158 0 20" send "1159 118 1\n" simple_expect "=1159 0 20" send "1160 118 2\n" simple_expect "%1160 6 0" # 119:set-scheduling send "1161 119 0 0 1\n" simple_expect "=1161" send "1162 119 2 0 1\n" simple_expect "%1162 6 0" send "1163 119 1 0 1\n" simple_expect "=1163" send "1164 119 1 1 1\n" simple_expect "%1164 19 0" send "1165 119 1 0 0\n" simple_expect "%1165 60 0" send "1166 119 1 0 101\n" simple_expect "%1166 59 100" # 120:set-connection-time-format send "1167 120 1\n" simple_expect "=1167" send "1168 120 2\n" simple_expect "%1168 61 0" send "1169 120 0\n" simple_expect "=1169" # 121:local-to-global-reverse send "1170 121 1 1 20\n" simple_expect "%1170 6 0" # 122:map-created-texts-reverse send "1171 122 5 1 20\n" simple_expect "%1171 6 0" # 123:does not exist (change this when you add a call) send "1172 123\n" simple_expect "%1172 2 0" # finally, check that 55=disconnect actually works without logging in. send "1173 55 1\n" simple_expect "=1173" "disconnect (no login)" client_death 0 client_start 0 talk_to client 0 send "A\n" send "[holl "DejaGnu test suite"]\n" simple_expect "LysKOM" "connected" # Turn of async messages send "1174 80 0 { }\n" simple_expect "=1174" # Log in send "1175 62 5 [holl "gazonk"] 0\n" simple_expect "=1175" send "1176 9 5 5\n" simple_expect "=1176 $any_time 5 255 0 0 \\*" send "1177 27 5 0 { }\n" simple_expect "=1177" send "1178 9 5 5\n" simple_expect "=1178 $any_time 5 255 0 0 \\*" send "1179 6 6 1\n" simple_expect "=1179 [idholl "DejaGnu test suite.unknown."] 0000010000000000 00000000 $any_time 0 $any_num 1 0 0 0 0 0 0 1 0 0 1" send "1180 6 6 0\n" simple_expect "=1180 0H 0000010000000000 00000000 $any_time 0 $any_num 1 0 0 0 0 0 0 1 0 0 1" talk_to client 0 send "1181 42 255\n" simple_expect "=1181" "42=enable succeeded" send "1182 44 0\n" simple_expect "=1182" "44=shutdown-kom succeeded" client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/02.exp0000664000015100472110000001723707721716132016742 # Test suite for lyskomd. # Copyright (C) 1998-1999, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check that get-text, get-text-stat-old and get-text-stat don't leak # information to clients that are not logged in. lyskomd_start client_start 0 talk_to client 0 send "A\n" send "[holl "DejaGnu test suite"]\n" simple_expect "LysKOM" "connected" # Log in as the administrator and create a few texts. send "1000 0 5 [holl gazonk]\n" simple_expect ":2 9 5 1" simple_expect "=1000" send "1001 88 [holl "Secret Conf"] 10100000 0 { }\n" simple_expect "=1001 6" send "1002 86 [holl "Text in Secret Conf"] 1 { 0 6 } 0 { }\n" simple_expect "=1002 1" send "1003 86 [holl "Text in news conference"] 1 { 0 4 } 0 { }\n" simple_expect "=1003 2" send "1004 86 [holl "Deleted text"] 1 { 0 4 } 0 { }\n" simple_expect "=1004 3" send "1005 29 3\n" simple_expect "=1005" send "1006 86 [holl "Solipsist Nation"] 0 { } 0 { }\n" simple_expect "=1006 4" send "1007 86 [holl "Message of the day"] 1 { 0 4 } 0 { }\n" simple_expect "=1007 5" send "1008 41 5\n" simple_expect "%1008 12 0" send "1009 42 255\n" simple_expect "=1009" send "1010 41 5\n" simple_expect "=1010" send "1011 42 0\n" simple_expect "=1011" send "1012 41 5\n" simple_expect "%1012 12 0" send "1013 86 [holl "Mixed-mode text"] 2 { 0 4 0 6 } 1 { 15 00000000 0 [holl "DejaGnu"] }\n" simple_expect "=1013 6" # Check that the administrator can retrieve the texts. send "1014 25 0 0 999\n" simple_expect "%1014 15 0" send "1015 26 0\n" simple_expect "%1015 15 0" send "1016 90 0\n" simple_expect "%1016 15 0" send "1017 25 1 0 999\n" simple_expect "=1017 [holl "Text in Secret Conf"]" send "1018 26 1\n" simple_expect "=1018 $any_time 5 0 19 0 2 { 0 6 6 1 }" send "1019 90 1\n" simple_expect "=1019 $any_time 5 0 19 0 2 { 0 6 6 1 } 0 \\*" send "1020 25 2 1 10\n" simple_expect "=1020 [holl "ext in new"]" send "1021 26 2\n" simple_expect "=1021 $any_time 5 0 23 0 2 { 0 4 6 1 }" send "1022 90 2\n" simple_expect "=1022 $any_time 5 0 23 0 2 { 0 4 6 1 } 0 \\*" send "1023 25 3 0 999\n" simple_expect "%1023 14 3" send "1024 26 3\n" simple_expect "%1024 14 3" send "1025 90 3\n" simple_expect "%1025 14 3" send "1026 25 4 5 11\n" simple_expect "=1026 [holl "sist Na"]" send "1027 26 4\n" simple_expect "=1027 $any_time 5 0 16 0 0 \\*" send "1028 90 4\n" simple_expect "=1028 $any_time 5 0 16 0 0 \\* 0 \\*" send "1029 25 5 0 17\n" simple_expect "=1029 [holl "Message of the day"]" send "1030 26 5\n" # Implementation detail: the text is marked since it is the message of the day. simple_expect "=1030 $any_time 5 0 18 1 2 { 0 4 6 3 }" send "1031 90 5\n" # Implementation detail: the text is marked since it is the message of the day. simple_expect "=1031 $any_time 5 0 18 1 2 { 0 4 6 3 } 0 \\*" send "1032 25 5 0 16\n" simple_expect "=1032 [holl "Message of the da"]" send "1033 25 5 1 16\n" simple_expect "=1033 [holl "essage of the da"]" send "1034 25 5 3 15\n" simple_expect "=1034 [holl "sage of the d"]" send "1035 25 5 3 1540\n" simple_expect "=1035 [holl "sage of the day"]" send "1036 25 6 0 110\n" simple_expect "=1036 [holl "Mixed-mode text"]" send "1037 26 6\n" simple_expect "=1037 $any_time 5 0 15 0 4 { 0 4 6 4 0 6 6 2 }" send "1038 90 6\n" simple_expect "=1038 $any_time 5 0 15 0 4 { 0 4 6 4 0 6 6 2 } 1 { 1 15 5 $any_time 00000000 0 [holl "DejaGnu"] }" # Check what a session that isn't logged in can retrieve. client_start 1 talk_to client 1 send "A3Hfoo\n" simple_expect "LysKOM" "connected" send "1039 25 0 0 999\n" simple_expect "%1039 15 0" send "1040 26 0\n" simple_expect "%1040 15 0" send "1041 90 0\n" simple_expect "%1041 15 0" send "1042 25 1 0 999\n" simple_expect "%1042 14 1" send "1043 26 1\n" simple_expect "%1043 14 1" send "1044 90 1\n" simple_expect "%1044 14 1" send "1045 25 2 1 10\n" simple_expect "%1045 14 2" send "1046 26 2\n" simple_expect "%1046 14 2" send "1047 90 2\n" simple_expect "%1047 14 2" send "1048 25 3 0 999\n" simple_expect "%1048 14 3" send "1049 26 3\n" simple_expect "%1049 14 3" send "1050 90 3\n" simple_expect "%1050 14 3" send "1051 25 4 5 11\n" simple_expect "%1051 14 4" send "1052 26 4\n" simple_expect "%1052 14 4" send "1053 90 4\n" simple_expect "%1053 14 4" send "1054 25 5 0 17\n" simple_expect "=1054 [holl "Message of the day"]" send "1055 26 5\n" # Implementation detail: the text is marked since it is the message of the day. simple_expect "=1055 $any_time 5 0 18 1 2 { 0 4 6 3 }" send "1056 90 5\n" # Implementation detail: the text is marked since it is the message of the day. simple_expect "=1056 $any_time 5 0 18 1 2 { 0 4 6 3 } 0 \\*" send "1057 25 6 0 110\n" simple_expect "%1057 14 6" send "1058 26 6\n" simple_expect "%1058 14 6" send "1059 90 6\n" simple_expect "%1059 14 6" # Create an unprivileged person, and try to re-fetch all texts send "1060 56\n" simple_expect "=1060 2" send "1061 83 1 1 0\n" simple_expect "=1061 2 { 2 0 0 $any_num 10000000 0H 1 5 0 $any_num 00000000 0H }" send "1062 89 [holl "John Doe"] [holl "letmein"] 00000000 0 { }\n" simple_expect "=1062 7" send "1062 62 7 [holl "letmein"] 0\n" simple_expect ":2 9 7 2" simple_expect "=1062" talk_to client 0 simple_expect ":2 9 7 2" "client 0 also got :2 9 7 2 message" talk_to client 1 send "1063 83 1 1 0\n" simple_expect "=1063 2 { 2 7 0 $any_num 00000000 0H 1 5 0 $any_num 00000000 0H }" send "1064 25 0 0 999\n" simple_expect "%1064 15 0" send "1065 26 0\n" simple_expect "%1065 15 0" send "1066 90 0\n" simple_expect "%1066 15 0" send "1067 25 1 0 999\n" simple_expect "%1067 14 1" send "1068 26 1\n" simple_expect "%1068 14 1" send "1069 90 1\n" simple_expect "%1069 14 1" send "1070 25 2 1 10\n" simple_expect "=1070 [holl "ext in new"]" send "1071 26 2\n" simple_expect "=1071 $any_time 5 0 23 0 2 { 0 4 6 1 }" send "1072 90 2\n" simple_expect "=1072 $any_time 5 0 23 0 2 { 0 4 6 1 } 0 \\*" send "1073 25 3 0 999\n" simple_expect "%1073 14 3" send "1074 26 3\n" simple_expect "%1074 14 3" send "1075 90 3\n" simple_expect "%1075 14 3" send "1076 25 4 5 11\n" simple_expect "%1076 14 4" send "1077 26 4\n" simple_expect "%1077 14 4" send "1078 90 4\n" simple_expect "%1078 14 4" send "1079 25 5 0 17\n" simple_expect "=1079 [holl "Message of the day"]" send "1080 26 5\n" # Implementation detail: the text is marked since it is the message of the day. simple_expect "=1080 $any_time 5 0 18 1 2 { 0 4 6 3 }" send "1081 90 5\n" # Implementation detail: the text is marked since it is the message of the day. simple_expect "=1081 $any_time 5 0 18 1 2 { 0 4 6 3 } 0 \\*" send "1082 25 6 0 110\n" simple_expect "=1082 [holl "Mixed-mode text"]" send "1083 26 6\n" simple_expect "=1083 $any_time 5 0 15 0 2 { 0 4 6 4 }" send "1084 90 6\n" simple_expect "=1084 $any_time 5 0 15 0 2 { 0 4 6 4 } 1 { 1 15 5 $any_time 00000000 0 [holl "DejaGnu"] }" talk_to client 0 send "1085 42 255\n" simple_expect "=1085" "42=enable succeeded" send "1086 44 0\n" simple_expect "=1086" "44=shutdown-kom succeeded" client_death 0 client_death 1 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/03.exp0000664000015100472110000015767607721716132016757 # Test suite for lyskomd. # Copyright (C) 1998-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check that all functions do the right thing in their most normal use. # # The following objects are created in this test case: # Conferences # 7 "(So called) Christian Music", later "PRIMa musik" # 9 "Temporary Sancturay" (immediately deleted) # 10 "aux in general" (created at call 88) # 11 "aux non anon" (created at call 88) # Persons # 6 "Per Cederqvist" # Member of 7. # 8 "Kelly Talisman" (all available aux-infos are set) # Member of 7. # 12 "aux person" # Texts # 1 "Old-style text 1" 0 7 6 1 # 2 "Old-style text 2" 0 7 6 2 (deleted at call 28) # 3 "Old-style text 3" 0 7 6 3 (; 0 2 6 1 during 29..31) # 4 "New-style text 4" 0 7 6 4; 15 6 6 1 # 5 "New-style text 5" 0 7 6 5; 15 6 6 2 # 6 "New-style text 6" 0 7 6 6; 15 8 6 1 # 7 "New-style text 7" 0 1 6 1; 15 8 6 2 # 8 "Anon text 8" 0 1 6 2 # 9 "aux-style text 9" 0 7 6 7 # 10 "aux-style anon 10" 0 7 6 7 (FAQ for conf 10 and 11 after call 88) # Sessions # 1 logged in as person 6; default asyncs; does not use user_active # or set_client_version or any other new and fancy stuff. # (This is client 0) # 2 logged in as person 8; all available asyncs; uses user_active; # calls set_client_version("dgt03", "sc 1"). # (This is client 1) # 3 logged in as person 8 for brief moments. Logged in invisibly # as person 5 from the testing of call 8 and onwards. # Default asyncs; does not us user_active or set_client_version. # (This is client 2) # 4 logged in invisibly as person 5 from call 79. # Default asyncs; does not us user_active or set_client_version. # (This is client 2) read_versions lyskomd_start # Preamble: create a "typical database" containing some persons and # texts created with traditional calls, and some created using newer # calls. # Client 0 is traditional. Let it start the race. client_start 0 talk_to client 0 send "A[holl "ceder@gratia"]\n" simple_expect "LysKOM" "connected" send "1000 12 [holl "Per Cederqvist"]\n" simple_expect "=1000 0 \\* \\*" # This test was written while listening to Talitha, so it seemed proper # to use her name as password. send "1001 5 [holl "Per Cederqvist"] [holl "Talitha"]\n" simple_expect ":2 9 6 1" simple_expect "=1001 6" # Create a conference send "1002 10 [holl "(So called) Christian Music"] 0000\n" simple_expect "=1002 7" send "1003 2 7\n" simple_expect "%1003 13 7" send "1004 14 7 6 100 1\n" simple_expect "=1004" send "1005 2 7\n" simple_expect "=1005" send "1006 28 [holl "Old-style text 1"] 1 { 0 7 }\n" extracting_expect ":16 0 1 ($any_time) 6 0 16 0 2 { 0 7 6 1 }" time_1 1 simple_expect "=1006 1" set post_1 $time_1 while {"$post_1" == "$time_1"} { sleep 0.1 send "999 35\n" extracting_expect "=999 ($any_time)" post_1 1 } send "1007 28 [holl "Old-style text 2"] 2 { 0 7 6 99 }\n" extracting_expect ":16 0 2 ($any_time) 6 0 16 0 2 { 0 7 6 2 }" time_2 1 simple_expect "=1007 2" set post_2 $time_2 while {"$post_2" == "$time_2"} { sleep 0.1 send "999 35\n" extracting_expect "=999 ($any_time)" post_2 1 } send "1008 28 [holl "Old-style text 3"] 1 { 0 7 }\n" extracting_expect ":16 0 3 ($any_time) 6 0 16 0 2 { 0 7 6 3 }" time_3 1 simple_expect "=1008 3" # Client 1 is contemporary. Let it use all the latest fancy stuff. client_start 1 talk_to client 1 send "A[holl "ic@gratia"]\n" simple_expect "LysKOM" "client 1 connected" send "1009 69 [holl "dgt03"] [holl "sc 1"]\n" simple_expect "=1009" # This test is written on the assumption that the server knows about # exactly these aux-items. It shouldn't be hard to fix the test suite # when more items are added. send "1010 96\n" simple_expect "=1010 40 { 10104 10103 10102 10101 10100 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 }" send "1011 82\n" simple_expect "=1011" send "1012 35\n" extracting_expect "=1012 ($any_time)" user_active_0 1 send "1013 81\n" simple_expect "=1013 8 { 0 5 7 8 9 11 12 13 }" # Check that the server returns "long-array" if a too long # array is passed to the accept-async. # The next line is split in two to avoid filling the pty buffer. send "1014 80 129 { 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81\n" send "82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 }\n" simple_expect "%1014 46 0" # The above request should not have modified the list of accepted asyncs. send "1015 81\n" simple_expect "=1015 8 { 0 5 7 8 9 11 12 13 }" # This array isn't too long, but it contains illegal aux-items. send "1016 80 128 { 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81\n" send "82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 129 }\n" simple_expect "%1016 50 1" # Make sure all legal aux-items were added to the list of accepted asyncs. send "1017 81\n" simple_expect "=1017 18 { 0 5 6 7 8 9 11 12 13 14 15 16 17 18 19 20 21 22 }" send "1018 80 127 { 0 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82\n" send "83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 129 }\n" simple_expect "%1018 50 2" send "1019 80 126 { 0 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82\n" send "83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 129 }\n" simple_expect "%1019 50 3" send "1020 81\n" simple_expect "=1020 18 { 0 5 6 7 8 9 11 12 13 14 15 16 17 18 19 20 21 22 }" send "1021 80 126 { 0 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83\n" send "84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 3923 }\n" simple_expect "%1021 50 4" send "1022 81\n" simple_expect "=1022 18 { 0 5 6 7 8 9 11 12 13 14 15 16 17 18 19 20 21 22 }" send "1023 80 125 { 128 127 126 125 124 123 122 121 120 119 118 117 116 115 114 113 112 111 110 109 108 107 106 105 104 103 102 101 100 99 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70 69 68 67 66 65 64 63 62 61 60\n" send "59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 0 }\n" simple_expect "%1023 50 128" send "1024 80 124 { 0 5 6 7 8 9 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85\n" send "86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 }\n" simple_expect "%1024 50 23" send "1025 81\n" simple_expect "=1025 18 { 0 5 6 7 8 9 11 12 13 14 15 16 17 18 19 20 21 22 }" send "1026 80 12 { 0 5 6 7 8 9 10 11 12 13 14 15 }\n" simple_expect "%1026 50 10" send "1027 80 11 { 0 5 6 7 8 9 11 12 13 14 15 }\n" simple_expect "=1027" send "1028 81\n" simple_expect "=1028 11 { 0 5 6 7 8 9 11 12 13 14 15 }" # AUXITEM: All aux-items that can be set on letterboxes should be set # on person 8, unless the aux-item has semantics that would interfere # with the tests below. Some items must be added once the person is created. # Do that below. send "1029 89 [holl "Kelly Talisman"] [holl "the stars"] 00000000 10 { 3 00000000 0 [holl "C6 My Creator"] 3 00000000 0 [holl "C7 Slightly offensive name, huh"] 8 00000000 0 [holl "E-mail:kelly@hotbox.com"] 9 00000000 0 [holl "compface must die"] 10 00000000 0\n" send "[holl "Air"] 12 00000000 0 [holl "PGP public key"] 13 00000000 0 [holl "kelly@hotbox.com"] 30 00000000 0 [holl "2 text/plain"] 30 00000000 0 [holl "2 x-kom/basic"] 33 00000000 1 1H0 }\n" simple_expect "=1029 8" send "1030 62 8 [holl "the stars"] 0\n" simple_expect ":2 9 8 2" simple_expect "=1030" talk_to client 0 simple_expect ":2 9 8 2" talk_to client 1 # AUXITEM: Add items that cannot be added at the time of creation. # (indent to avoid renumbering) if {1} { send "990 93 8 0 { } 1 { 14 00000000 0 [holl "3"] }\n" simple_expect "=990" } send "1031 86 [holl "New-style text 4"] 2 { 0 7 15 6 } 0 { }\n" # No async message; person 8 isn't a member of the conferences this # text goes to. simple_expect "=1031 4" talk_to client 0 simple_expect ":16 0 4 $any_time 8 0 16 0 4 { 0 7 6 4 1 6 6 1 }" talk_to client 1 # Join conference 7. send "1032 100 7 8 100 0 00000000\n" simple_expect "=1032" send "1033 86 [holl "New-style text 5"] 2 { 0 7 15 6 } 0 { }\n" simple_expect ":16 0 5 $any_time 8 0 16 0 4 { 0 7 6 5 1 6 6 2 }" simple_expect ":18 15 5 $any_time 8 0 16 0 4 { 0 7 6 5 15 6 6 2 } 0 \\*" simple_expect "=1033 5" talk_to client 0 simple_expect ":16 0 5 $any_time 8 0 16 0 4 { 0 7 6 5 1 6 6 2 }" talk_to client 1 send "1034 86 [holl "New-style text 6"] 2 { 0 7 15 8 } 0 { }\n" simple_expect ":16 0 6 $any_time 8 0 16 0 4 { 0 7 6 6 1 8 6 1 }" simple_expect ":18 15 6 $any_time 8 0 16 0 4 { 0 7 6 6 15 8 6 1 } 0 \\*" simple_expect "=1034 6" talk_to client 0 simple_expect ":16 0 6 $any_time 8 0 16 0 2 { 0 7 6 6 }" talk_to client 1 send "1035 86 [holl "New-style text 7"] 2 { 0 1 15 8 } 0 { }\n" extracting_expect ":16 0 7 ($any_time) 8 0 16 0 4 { 0 1 6 1 1 8 6 2 }" time_7 1 simple_expect ":18 15 7 $time_7 8 0 16 0 4 { 0 1 6 1 15 8 6 2 } 0 \\*" simple_expect "=1035 7" talk_to client 0 # No async for client 0 at this point. send "1036 35\n" simple_expect "=1036 $any_time" talk_to client 1 # test call 0 (login) client_start 2 talk_to client 2 send "A[holl "Foo"]\n" simple_expect "LysKOM" "client 2 connected" send "1037 0 3 [holl "gazonk"]\n" simple_expect "%1037 10 3" send "1038 0 8 [holl "gazonk"]\n" simple_expect "%1038 4 8" talk_to client 0 send "1039 35\n" simple_expect "=1039 $any_time" talk_to client 1 send "1040 35\n" simple_expect "=1040 $any_time" talk_to client 2 send "1041 0 8 [holl "the stars"]\n" simple_expect ":2 9 8 3" simple_expect "=1041" talk_to client 0 simple_expect ":2 9 8 3" talk_to client 1 simple_expect ":2 9 8 3" # test call 1 (logout) talk_to client 2 send "1042 1\n" simple_expect ":2 13 8 3" simple_expect "=1042" talk_to client 0 simple_expect ":2 13 8 3" talk_to client 1 simple_expect ":2 13 8 3" # test call 2 (change-conference) talk_to client 0 send "1043 2 2\n" simple_expect "%1043 13 2" send "1044 2 34\n" simple_expect "%1044 9 34" # This session has already changed conference to 7 in the preamble above. # Check that the failed attempts didn't change that. send "1045 83 1 0 0\n" simple_expect "=1045 2 { 2 8 0 $any_num 01000000 0H 1 6 7 $any_num 00000000 0H }" # Check that we can leave all conferences. send "1046 2 0\n" simple_expect "=1046" talk_to client 1 simple_expect ":5 6 6 0 1 [holl ""] [idholl "ceder@gratia"]" talk_to client 0 send "1047 83 1 0 0\n" simple_expect "=1047 2 { 2 8 0 $any_num 01000000 0H 1 6 0 $any_num 00000000 0H }" # Go to the letterbox and stay there send "1048 2 6\n" simple_expect "=1048" talk_to client 1 simple_expect ":5 6 6 6 1 [holl ""] [idholl "ceder@gratia"]" talk_to client 0 send "1049 83 1 0 0\n" simple_expect "=1049 2 { 2 8 0 $any_num 01000000 0H 1 6 6 $any_num 00000000 0H }" # test call 3 (change-name) talk_to client 0 send "1050 3 7 [holl "Per Cederqvist"]\n" simple_expect "%1050 20 0" send "1051 3 7 [holl "PRIMa musik"]\n" simple_expect ":3 5 7 [holl ".So called. Christian Music"] [holl "PRIMa musik"]" simple_expect "=1051" talk_to client 1 simple_expect ":3 5 7 [holl ".So called. Christian Music"] [holl "PRIMa musik"]" talk_to client 2 simple_expect ":3 5 7 [holl ".So called. Christian Music"] [holl "PRIMa musik"]" # test call 4 (change-what-i-am-doing) talk_to client 0 send "1052 4 [holl "Running a test suite"]\n" simple_expect "=1052" talk_to client 1 simple_expect ":5 6 6 6 1 [holl "Running a test suite"] [idholl "ceder@gratia"]" send "1053 4 [holl "Accepting i-am-on"]\n" simple_expect ":5 6 8 0 2 [holl "Accepting i-am-on"] [idholl "ic@gratia"]" simple_expect "=1053" # call 5 (create-person-old) is tested above. # test call 6 (get-person-stat-old) send "1054 6 0 0\n" simple_expect "%1054 8 0" send "1055 6 3 0\n" simple_expect "%1055 10 3" send "1056 6 10 0\n" simple_expect "%1056 10 10" send "1057 6 6 0\n" simple_expect "=1057 [holl ""] 0000010000000000 00000000 $any_time 0 0 1 0 48 0 0 0 1 1 3 0 2" send "1058 6 6 1\n" simple_expect "=1058 [idholl "ceder@gratia.unknown."] 0000010000000000 00000000 $any_time 0 0 1 0 48 0 0 0 1 1 3 0 2" send "1059 6 6 2\n" simple_expect "=1059 [holl ""] 0000010000000000 00000000 $any_time 0 0 1 0 48 0 0 0 1 1 3 0 2" send "1060 6 6 3\n" simple_expect "=1060 [idholl "ceder@gratia.unknown."] 0000010000000000 00000000 $any_time 0 0 1 0 48 0 0 0 1 1 3 0 2" send "1061 6 6 32770\n" simple_expect "=1061 [holl ""] 0000010000000000 00000000 $any_time 0 0 1 0 48 0 0 0 1 1 3 0 2" send "1062 6 6 32771\n" simple_expect "=1062 [idholl "ceder@gratia.unknown."] 0000010000000000 00000000 $any_time 0 0 1 0 48 0 0 0 1 1 3 0 2" # test call 7 (set-priv-bits) send "1063 7 8 0000000000000000\n" simple_expect "%1063 12 0" talk_to client 2 send "1064 62 5 [holl "gazonk"] 1\n" simple_expect "=1064" send "1065 7 8 0000000000000000\n" simple_expect "%1065 12 0" send "1066 42 255\n" simple_expect "=1066" send "1067 6 8 0\n" simple_expect "=1067 [holl ""] 0000010000000000 00000000 $any_time 0 $any_num 2 0 64 0 0 0 0 1 4 0 2" send "1068 7 8 0000000000000000\n" simple_expect "=1068" send "1069 6 8 0\n" simple_expect "=1069 [holl ""] 0000000000000000 00000000 $any_time 0 $any_num 2 0 64 0 0 0 0 1 4 0 2" send "1070 7 8 1111111111111111\n" simple_expect "=1070" send "1071 6 8 0\n" simple_expect "=1071 [holl ""] 1111111111111111 00000000 $any_time 0 $any_num 2 0 64 0 0 0 0 1 4 0 2" send "1072 7 8 0000010000000000\n" simple_expect "=1072" send "1073 6 8 0\n" simple_expect "=1073 [holl ""] 0000010000000000 00000000 $any_time 0 $any_num 2 0 64 0 0 0 0 1 4 0 2" # test call 8 (set-passwd) send "1074 8 5 [holl "foo"] [holl "bar"]\n" simple_expect "%1074 4 5" send "1075 8 5 [holl "gazonk"] [holl "bar"]\n" simple_expect "=1075" send "1076 1\n" simple_expect "=1076" send "1077 62 5 [holl "gazonk"] 1\n" simple_expect "%1077 4 5" send "1078 62 5 [holl "bar"] 1\n" simple_expect "=1078" # test call 9 (query-read-texts-old) talk_to client 0 send "1079 9 6 7\n" simple_expect "=1079 $any_time 7 100 0 0 \\*" # test call 10 (create-conf-old) send "1080 78 9\n" simple_expect "%1080 9 9" send "1081 10 [holl "Temporary Sanctuary"] 1010\n" simple_expect "=1081 9" send "1082 78 9\n" simple_expect "=1082 [holl "Temporary Sanctuary"] 10101000 0 77" # test call 11 (delete-conf) send "1083 11 9\n" simple_expect "=1083" send "1084 78 9\n" simple_expect "%1084 9 9" # test call 12 (lookup-name) send "1085 12 [holl "p"]\n" simple_expect "=1085 4 { 1 2 6 7 } { 0000 0000 1001 0000 }" send "1086 12 [holl "p c"]\n" simple_expect "=1086 1 { 6 } { 1001 }" send "1087 12 [holl "xyzzy"]\n" simple_expect "=1087 0 \\* \\*" send "1088 12 [holl ""]\n" simple_expect "=1088 8 { 1 2 3 4 5 6 7 8 } { 0000 0000 0000 0000 1001 1001 0000 1001 }" send "1089 76 [holl ""] 1 1\n" simple_expect "=1089 8 { [holl "Presentation .av nya. möten"] 0000 1 [holl "Presentation .av nya. medlemmar"] 0000 2 [holl "Lappar .på. dörren"] 0000 3 [holl "Nyheter om LysKOM"] 0000 4 [holl "Administratör .för. LysKOM"] 1001 5 [holl "Per Cederqvist"] 1001 6 [holl "PRIMa musik"] 0000 7 [holl "Kelly Talisman"] 1001 8 }" # test call 13 (get-conf-stat-older) send "1090 13 3 0\n" simple_expect "=1090 [holl ""] 0000 $any_time $any_time 0 0 0 0 0 0 77 0 1 0" send "1091 13 3 1\n" simple_expect "=1091 [holl "Lappar .på. dörren"] 0000 $any_time $any_time 0 0 0 0 0 0 77 0 1 0" # test call 14 (add-member-old) send "1092 14 3 6 90 2\n" simple_expect "=1092" send "1093 13 3 1\n" simple_expect "=1093 [holl "Lappar .på. dörren"] 0000 $any_time $any_time 0 0 0 0 0 0 77 1 1 0" # test call 15 (sub-member) send "1094 15 3 6\n" simple_expect ":1 8 3" simple_expect "=1094" send "1095 15 3 6\n" simple_expect "%1095 13 3" # test call 16 (set-presentation) send "1096 16 7 3\n" simple_expect "=1096" # We check the result under call 50 below. # test call 17 (set-etc-motd) send "1097 17 7 2\n" simple_expect "=1097" # We check the result under call 50 below. # test call 18 (set-supervisor) send "1098 18 7 7\n" simple_expect "=1098" # We check the result under call 50 below. # test call 19 (set-permitted-submitters) send "1099 19 7 8\n" simple_expect "=1099" # We check the result under call 50 below. # test call 20 (set-super-conf) send "1100 20 7 4\n" simple_expect "=1100" # We check the result under call 50 below. # test call 21 (set-conf-type) send "1101 21 7 0100\n" simple_expect "=1101" send "1102 21 7 01001000\n" simple_expect "=1102" # We check the result under call 50 below. # test call 22 (set-garb-nice) send "1103 22 7 144\n" simple_expect "=1103" # We check the result under call 50 below. # test call 23 (get-marks) and call 24 (mark-text-old) send "1104 24 2 15\n" simple_expect "=1104" send "1105 23\n" simple_expect "=1105 1 { 2 15 }" send "1106 24 2 28\n" simple_expect "=1106" send "1107 23\n" simple_expect "=1107 1 { 2 28 }" send "1108 24 3 9\n" simple_expect "=1108" send "1109 23\n" simple_expect "=1109 2 { 2 28 3 9 }" send "1110 24 2 0\n" simple_expect "=1110" send "1111 23\n" simple_expect "=1111 1 { 3 9 }" send "1112 24 3 0\n" simple_expect "=1112" send "1113 23\n" simple_expect "=1113 0 \\*" # call 25 is tested extensively in 02.exp # This is approximately halfway between the call to user-active and # the use where we want two seconds to have passed. Wait for one tick. send "1114 35\n" extracting_expect "=1114 ($any_time)" user_active_1 1 while {"$user_active_1" == "$user_active_0"} { sleep 0.1 send "999 35\n" extracting_expect "=999 ($any_time)" user_active_1 1 } # test call 26 (get-text-stat-old) send "1115 26 1\n" simple_expect "=1115 $any_time 6 0 16 0 2 { 0 7 6 1 }" # test call 27 (mark-as-read) and 40 (set-unread) send "1116 9 6 7\n" simple_expect "=1116 $any_time 7 100 0 0 \\*" send "1117 27 7 1 { 2 }\n" simple_expect "=1117" send "1118 9 6 7\n" simple_expect "=1118 $any_time 7 100 0 1 { 2 }" send "1119 27 7 1 { 2 }\n" simple_expect "=1119" send "1120 46 6 1 1 1\n" simple_expect "=1120 1 { $any_time 7 100 0 1 { 2 } }" send "1121 27 7 1 { 4 }\n" simple_expect "=1121" send "1122 9 6 7\n" simple_expect "=1122 $any_time 7 100 0 2 { 2 4 }" send "1123 27 7 1 { 5 }\n" simple_expect "=1123" send "1124 9 6 7\n" simple_expect "=1124 $any_time 7 100 0 3 { 2 4 5 }" send "1125 27 7 1 { 6 }\n" simple_expect "=1125" send "1126 9 6 7\n" simple_expect "=1126 $any_time 7 100 0 4 { 2 4 5 6 }" send "1127 27 7 1 { 1 }\n" simple_expect "=1127" send "1128 9 6 7\n" simple_expect "=1128 $any_time 7 100 2 3 { 4 5 6 }" send "1129 27 7 1 { 7 }\n" simple_expect "%1129 16 0" send "1130 9 6 7\n" simple_expect "=1130 $any_time 7 100 2 3 { 4 5 6 }" send "1131 27 7 1 { 3 }\n" simple_expect "=1131" send "1132 9 6 7\n" simple_expect "=1132 $any_time 7 100 6 0 \\*" send "1133 40 7 6\n" simple_expect "=1133" send "1134 9 6 7\n" simple_expect "=1134 $any_time 7 100 0 0 \\*" send "1135 27 7 6 { 1 2 3 4 5 6 }\n" simple_expect "=1135" send "1136 9 6 7\n" simple_expect "=1136 $any_time 7 100 6 0 \\*" send "1137 40 7 6\n" simple_expect "=1137" send "1138 9 6 7\n" simple_expect "=1138 $any_time 7 100 0 0 \\*" send "1139 27 7 6 { 6 5 4 3 2 1 }\n" simple_expect "=1139" send "1140 9 6 7\n" simple_expect "=1140 $any_time 7 100 6 0 \\*" send "1141 40 7 6\n" simple_expect "=1141" send "1142 9 6 7\n" simple_expect "=1142 $any_time 7 100 0 0 \\*" send "1143 27 7 6 { 1 3 5 2 4 6 }\n" simple_expect "=1143" send "1144 9 6 7\n" simple_expect "=1144 $any_time 7 100 6 0 \\*" send "1145 40 7 6\n" simple_expect "=1145" send "1146 9 6 7\n" simple_expect "=1146 $any_time 7 100 0 0 \\*" send "1147 27 7 6 { 2 4 6 1 3 5 }\n" simple_expect "=1147" send "1148 9 6 7\n" simple_expect "=1148 $any_time 7 100 6 0 \\*" send "1149 40 7 6\n" simple_expect "=1149" send "1150 9 6 7\n" simple_expect "=1150 $any_time 7 100 0 0 \\*" send "1151 27 7 1 { 1 }\n" simple_expect "=1151" send "1152 9 6 7\n" simple_expect "=1152 $any_time 7 100 1 0 \\*" send "1153 27 7 1 { 1 }\n" simple_expect "=1153" send "1154 9 6 7\n" simple_expect "=1154 $any_time 7 100 1 0 \\*" send "1155 27 7 1 { 2 }\n" simple_expect "=1155" send "1156 9 6 7\n" simple_expect "=1156 $any_time 7 100 2 0 \\*" send "1157 27 7 1 { 3 }\n" simple_expect "=1157" send "1158 9 6 7\n" simple_expect "=1158 $any_time 7 100 3 0 \\*" send "1159 27 7 1 { 4 }\n" simple_expect "=1159" send "1160 9 6 7\n" simple_expect "=1160 $any_time 7 100 4 0 \\*" send "1161 27 7 1 { 5 }\n" simple_expect "=1161" send "1162 9 6 7\n" simple_expect "=1162 $any_time 7 100 5 0 \\*" send "1163 27 7 1 { 6 }\n" simple_expect "=1163" send "1164 9 6 7\n" simple_expect "=1164 $any_time 7 100 6 0 \\*" send "1165 40 7 5\n" simple_expect "=1165" send "1166 9 6 7\n" simple_expect "=1166 $any_time 7 100 1 0 \\*" send "1167 40 7 2\n" simple_expect "=1167" send "1168 9 6 7\n" simple_expect "=1168 $any_time 7 100 4 0 \\*" send "1169 40 7 1\n" simple_expect "=1169" send "1170 9 6 7\n" simple_expect "=1170 $any_time 7 100 5 0 \\*" send "1171 40 7 0\n" simple_expect "=1171" send "1172 9 6 7\n" simple_expect "=1172 $any_time 7 100 6 0 \\*" # call 28 is tested above # test call 29 (delete-text) # (First, check that get_last_text gives a proper result before the # text is deleted.) send "1173 58 $time_3\n" simple_expect "=1173 2" send "1174 98 6 7\n" simple_expect "=1174 1 $any_time 7 100 6 0 \\* 6 $any_time 00000000" send "1175 29 2\n" # No new'n'fancy async message here. simple_expect "=1175" talk_to client 1 # The text is marked since it is motd of conference 7. simple_expect ":18 14 2 $any_time 6 0 16 1 2 { 0 7 6 2 } 0 \\*" talk_to client 0 # Test that mark-as-read of local text number 1 steps past local text # 2 when it doesn't exist. send "1176 40 7 6\n" simple_expect "=1176" send "1177 9 6 7\n" simple_expect "=1177 $any_time 7 100 0 0 \\*" send "1178 27 7 1 { 1 }\n" simple_expect "=1178" send "1179 9 6 7\n" simple_expect "=1179 $any_time 7 100 2 0 \\*" # test call 30 (add-recipient) send "1180 30 3 2 0\n" simple_expect "=1180" send "1181 26 3\n" # This is marked since text 3 is presentation of conf 7. simple_expect "=1181 $any_time 6 0 16 1 5 { 0 7 6 3 0 2 6 1 9 $any_time }" # test call 31 (sub-recipient) send "1182 31 3 2\n" simple_expect "=1182" send "1183 26 3\n" # This is marked since text 3 is presentation of conf 7. simple_expect "=1183 $any_time 6 0 16 1 2 { 0 7 6 3 }" # test call 32 (add-comment) send "1184 32 3 1\n" simple_expect "=1184" send "1185 26 3\n" # This is marked since text 3 is presentation of conf 7. simple_expect "=1185 $any_time 6 0 16 1 4 { 0 7 6 3 2 1 9 $any_time }" send "1186 26 1\n" simple_expect "=1186 $any_time 6 0 16 0 3 { 0 7 6 1 3 3 }" # test call 33 (sub-comment) send "1187 33 3 1\n" simple_expect "=1187" send "1188 26 3\n" # This is marked since text 3 is presentation of conf 7. simple_expect "=1188 $any_time 6 0 16 1 2 { 0 7 6 3 }" send "1189 26 1\n" simple_expect "=1189 $any_time 6 0 16 0 2 { 0 7 6 1 }" # test call 34 (get-map) send "1190 34 7 1 50\n" simple_expect "=1190 1 6 { 1 0 3 4 5 6 }" # test call 35 (get-time) send "1191 35\n" simple_expect "=1191 $any_time" # test call 36 (get-info-old) send "1192 36\n" simple_expect "=1192 $server_compat_version 1 2 3 4 0" # test call 37 (add-footnote) send "1193 37 3 1\n" simple_expect "=1193" send "1194 26 3\n" # This is marked since text 3 is presentation of conf 7. simple_expect "=1194 $any_time 6 0 16 1 4 { 0 7 6 3 4 1 9 $any_time }" send "1195 26 1\n" simple_expect "=1195 $any_time 6 0 16 0 3 { 0 7 6 1 5 3 }" # test call 38 (sub-footnote) send "1196 38 3 1\n" simple_expect "=1196" send "1197 26 3\n" # This is marked since text 3 is presentation of conf 7. simple_expect "=1197 $any_time 6 0 16 1 2 { 0 7 6 3 }" send "1198 26 1\n" simple_expect "=1198 $any_time 6 0 16 0 2 { 0 7 6 1 }" # test call 39 (who-is-on-old) send "1199 39\n" simple_expect "=1199 2 { 8 0 [holl "Accepting i-am-on"] 6 6 [holl "Running a test suite"] }" # call 40 (set-unread) is tested above # test call 41 (set-motd-of-lyskom) talk_to client 2 send "1200 42 255\n" simple_expect "=1200" send "1201 41 7\n" simple_expect "=1201" send "1202 42 0\n" simple_expect "=1202" send "1203 36\n" simple_expect "=1203 $server_compat_version 1 2 3 4 7" # call 42 (enable) is tested above # test call 43 (sync-kom) send "1204 43\n" simple_expect "%1204 12 0" send "1205 42 255\n" simple_expect "=1205" send "1206 43\n" simple_expect ":0 7" simple_expect ":0 7" simple_expect "=1206" talk_to client 0 simple_expect ":0 7" simple_expect ":0 7" talk_to client 1 simple_expect ":0 7" simple_expect ":0 7" talk_to client 2 send "1207 42 0\n" simple_expect "=1207" # test call 44 (shutdown-kom) is tested below # test call 45 (broadcast) send "1208 45 [holl "a broadcast message"]\n" simple_expect ":3 12 0 5 [holl "a broadcast message"]" simple_expect "=1208" talk_to client 1 simple_expect ":3 12 0 5 [holl "a broadcast message"]" talk_to client 0 simple_expect ":3 12 0 5 [holl "a broadcast message"]" # test call 46 (get-membership-old) send "1209 46 6 0 100 1\n" simple_expect "=1209 2 { $any_time 6 255 0 0 \\* $any_time 7 100 2 0 \\* }" # test call 47 (get-created-texts) send "1210 47 6 1 100\n" simple_expect "=1210 1 3 { 1 0 3 }" # test call 48 (get-members-old) send "1211 48 7 0 100\n" simple_expect "=1211 2 { 6 8 }" # test call 49 (get-person-stat) send "1212 49 6\n" simple_expect "=1212 [idholl "ceder@gratia.unknown."] 0000010000000000 00000000 $any_time 0 0 1 0 48 0 0 0 2 1 3 0 2" # test call 50 (get-conf-stat-old) send "1213 50 7\n" simple_expect "=1213 [holl "PRIMa musik"] 0100 $any_time $any_time 6 3 7 8 4 2 144 2 1 6" # test call 51 (who-is-on) send "1214 51\n" simple_expect "=1214 2 { 8 0 2 [holl "Accepting i-am-on"] [idholl "ic@gratia"] 6 6 1 [holl "Running a test suite"] [idholl "ceder@gratia"] }" # test call 52 (get-unread-confs) send "1215 52 6\n" simple_expect "=1215 2 { 6 7 }" # test call 53 (send-message) send "1216 53 8 [holl "hullo eight"]\n" simple_expect "=1216" talk_to client 1 simple_expect ":3 12 8 6 [holl "hullo eight"]" talk_to client 0 send "1217 53 7 [holl "seven"]\n" simple_expect ":3 12 7 6 [holl "seven"]" simple_expect "=1217" talk_to client 1 simple_expect ":3 12 7 6 [holl "seven"]" talk_to client 0 send "1218 53 0 [holl "all"]\n" simple_expect ":3 12 0 6 [holl "all"]" simple_expect "=1218" talk_to client 1 simple_expect ":3 12 0 6 [holl "all"]" talk_to client 2 simple_expect ":3 12 0 6 [holl "all"]" talk_to client 0 # test call 54 (get-session-info) send "1219 54 2\n" simple_expect "=1219 8 0 2 [holl "Accepting i-am-on"] [idholl "ic@gratia"] $any_num $any_time" # test call 55 (disconnect) talk_to client 2 send "1220 55 3\n" simple_expect "=1220" client_death 2 # test call 56 (who-am-i) talk_to client 0 send "1221 56\n" simple_expect "=1221 1" # test call 57 (set-user-area) send "1222 57 6 3\n" simple_expect "=1222" send "1223 49 6\n" simple_expect "=1223 [idholl "ceder@gratia.unknown."] 0000010000000000 00000000 $any_time 3 0 1 0 48 0 0 0 2 1 3 0 2" # test call 58 (get-last-text) send "1224 58 0 0 0 1 0 98 0 0 0\n" simple_expect "=1224 0" send "1225 35\n" extracting_expect "=1225 ($any_time)" post_7 1 while {"$post_7" == "$time_7"} { sleep 0.1 send "999 35\n" extracting_expect "=999 ($any_time)" post_7 1 } send "1226 58 $time_1\n" simple_expect "=1226 0" send "1227 58 $time_2\n" simple_expect "=1227 1" send "1228 58 $time_3\n" simple_expect "=1228 1" send "1229 58 $post_7\n" simple_expect "=1229 7" # test call 59 (create-anonymous-text-old) send "1230 59 [holl "Anon text 8"] 1 { 0 2 }\n" simple_expect "=1230 8" # check that the number of created texts/bytes does not increase send "1231 49 6\n" simple_expect "=1231 [idholl "ceder@gratia.unknown."] 0000010000000000 00000000 $any_time 3 0 1 0 48 0 0 0 2 1 3 0 2" # test call 60 (find-next-text-no) send "1232 60 0\n" simple_expect "=1232 1" send "1233 60 1\n" simple_expect "=1233 3" send "1234 60 2\n" simple_expect "=1234 3" send "1235 60 3\n" simple_expect "=1235 4" send "1236 60 4\n" simple_expect "=1236 5" send "1237 60 5\n" simple_expect "=1237 6" send "1238 60 6\n" simple_expect "=1238 7" send "1239 60 7\n" simple_expect "=1239 8" send "1240 60 8\n" simple_expect "%1240 14 8" # test call 61 (find-previous-text-no) send "1241 61 0\n" simple_expect "%1241 14 0" send "1242 61 1\n" simple_expect "%1242 14 1" send "1243 61 2\n" simple_expect "=1243 1" send "1244 61 3\n" simple_expect "=1244 1" send "1245 61 4\n" simple_expect "=1245 3" send "1246 61 5\n" simple_expect "=1246 4" send "1247 61 6\n" simple_expect "=1247 5" send "1248 61 7\n" simple_expect "=1248 6" send "1249 61 8\n" simple_expect "=1249 7" send "1250 61 9\n" simple_expect "=1250 8" send "1251 61 10\n" simple_expect "=1251 8" send "1252 61 1000\n" simple_expect "=1252 8" # call 62 is tested above # test call 63 (who-is-on-ident) send "1253 63\n" simple_expect "=1253 2 { 8 0 2 [holl "Accepting i-am-on"] [holl "ic@gratia"] [holl "$lyskomd_host"] [holl "unknown"] 6 6 1 [holl "Running a test suite"] [holl "ceder@gratia"] [holl "$lyskomd_host"] [holl "unknown"] }" # test call 64 (get-session-info-ident) send "1254 64 2\n" simple_expect "=1254 8 0 2 [holl "Accepting i-am-on"] [holl "ic@gratia"] [holl "$lyskomd_host"] [holl "unknown"] $any_num $any_time" # test call 65 (re-lookup-person) send "1255 65 [holl "nya"]\n" simple_expect "=1255 0 \\*" send "1256 65 [holl "el*y"]\n" simple_expect "=1256 1 { 8 }" # test call 66 (re-lookup-conf) send "1257 66 [holl "nya"]\n" simple_expect "=1257 2 { 1 2 }" # test call 67 (lookup-person) send "1258 67 [holl "k t"]\n" simple_expect "=1258 1 { 8 }" # test call 68 (lookup-conf) send "1259 68 [holl "p m"]\n" simple_expect "=1259 3 { 1 2 7 }" # test call 69 (set-client-version) talk_to client 1 send "1260 69 [holl "i changed my mind"] [holl "99.9"]\n" simple_expect "%1260 41 0" talk_to client 0 # test call 70 (get-client-name) send "1261 70 2\n" simple_expect "=1261 [holl "dgt03"]" # test call 71 (get-client-version) send "1262 71 2\n" simple_expect "=1262 [holl "sc 1"]" # test call 72 (mark-text) send "1263 72 1 92\n" simple_expect "=1263" send "1264 72 3 0\n" simple_expect "=1264" send "1265 72 4 91\n" simple_expect "=1265" send "1266 72 4 98\n" simple_expect "=1266" send "1267 23\n" simple_expect "=1267 3 { 1 92 3 0 4 98 }" # test call 73 (unmark-text) send "1268 73 4\n" simple_expect "=1268" send "1269 73 1\n" simple_expect "=1269" send "1270 23\n" simple_expect "=1270 1 { 3 0 }" send "1271 73 1\n" simple_expect "%1271 44 1" send "1272 23\n" simple_expect "=1272 1 { 3 0 }" send "1273 73 3\n" simple_expect "=1273" send "1274 23\n" simple_expect "=1274 0 \\*" # test call 74 (re-z-lookup) send "1275 74 [holl "P.*r"] 1 1\n" simple_expect "=1275 3 { [holl "Presentation .av nya. möten"] 0000 1 [holl "Presentation .av nya. medlemmar"] 0000 2 [holl "Per Cederqvist"] 1001 6 }" send "1276 74 [holl "P.*r"] 0 1\n" simple_expect "=1276 2 { [holl "Presentation .av nya. möten"] 0000 1 [holl "Presentation .av nya. medlemmar"] 0000 2 }" send "1277 74 [holl "P.*r"] 1 0\n" simple_expect "=1277 1 { [holl "Per Cederqvist"] 1001 6 }" # This is a meaningless combination, so test it. send "1278 74 [holl "P.*r"] 0 0\n" simple_expect "=1278 0 \\*" # test call 75 (get-version-info) send "1279 75\n" simple_expect "=1279 $protocol_a_level [holl "$server_software"] [holl "$server_version"]" # test call 76 (lookup-z-name) send "1280 76 [holl "P r"] 1 1\n" simple_expect "=1280 0 \\*" send "1281 76 [holl "P"] 1 1\n" simple_expect "=1281 4 { [holl "Presentation .av nya. möten"] 0000 1 [holl "Presentation .av nya. medlemmar"] 0000 2 [holl "Per Cederqvist"] 1001 6 [holl "PRIMa musik"] 0100 7 }" send "1282 76 [holl "P"] 0 1\n" simple_expect "=1282 3 { [holl "Presentation .av nya. möten"] 0000 1 [holl "Presentation .av nya. medlemmar"] 0000 2 [holl "PRIMa musik"] 0100 7 }" send "1283 76 [holl "P"] 1 0\n" simple_expect "=1283 1 { [holl "Per Cederqvist"] 1001 6 }" send "1284 76 [holl "P"] 0 0\n" simple_expect "=1284 0 \\*" # test call 77 (set-last-read) send "1285 77 7 0\n" simple_expect "=1285" send "1286 9 6 7\n" simple_expect "=1286 $any_time 7 100 0 0 \\*" send "1287 77 7 1\n" simple_expect "=1287" send "1288 9 6 7\n" simple_expect "=1288 $any_time 7 100 2 0 \\*" # Local text number 2 no longer exists send "1289 77 7 2\n" simple_expect "=1289" send "1290 9 6 7\n" simple_expect "=1290 $any_time 7 100 2 0 \\*" send "1291 77 7 4\n" simple_expect "=1291" send "1292 9 6 7\n" simple_expect "=1292 $any_time 7 100 4 0 \\*" send "1293 77 7 5\n" simple_expect "=1293" send "1294 9 6 7\n" simple_expect "=1294 $any_time 7 100 5 0 \\*" send "1295 77 7 6\n" simple_expect "=1295" send "1296 9 6 7\n" simple_expect "=1296 $any_time 7 100 6 0 \\*" # Check what happens when we try to set last-text-read to a local text # number that doesn't yet exist. send "1297 77 7 7\n" simple_expect "=1297" send "1298 9 6 7\n" simple_expect "=1298 $any_time 7 100 6 0 \\*" # test call 78 (get-uconf-stat) send "1299 78 7\n" simple_expect "=1299 [holl "PRIMa musik"] 01001000 6 144" # test call 79 (set-info) client_start 2 send "A3Hfoo\n" simple_expect "LysKOM" send "1300 62 5 [holl "bar"] 1\n" simple_expect "=1300" send "1301 42 255\n" simple_expect "=1301" send "1302 79 32 7 1 2 8 3\n" simple_expect "=1302" send "1303 94\n" simple_expect "=1303 $server_compat_version 7 1 2 8 3 0 \\*" send "1304 36\n" simple_expect "=1304 $server_compat_version 7 1 2 8 3" send "1305 79 $server_compat_version 1 2 3 4 0\n" simple_expect "=1305" send "1306 94\n" simple_expect "=1306 $server_compat_version 1 2 3 4 0 0 \\*" send "1307 36\n" simple_expect "=1307 $server_compat_version 1 2 3 4 0" send "1308 79 $server_compat_version 4 3 2 1 2\n" simple_expect "%1308 14 2" send "1309 36\n" simple_expect "=1309 $server_compat_version 1 2 3 4 0" send "1310 79 $server_compat_version 1 2 3 9 0\n" simple_expect "%1310 9 9" send "1311 36\n" simple_expect "=1311 $server_compat_version 1 2 3 4 0" talk_to client 1 # call 80 is tested during startup of client 1. # call 81 is tested during startup of client 1. # test call 82 (user-active) and call 83 (who-is-on-dynamic) # Wait for the second tick. send "1312 35\n" extracting_expect "=1312 ($any_time)" user_active_2 1 while {"$user_active_2" == "$user_active_1"} { sleep 0.1 send "999 35\n" extracting_expect "=999 ($any_time)" user_active_2 1 } # Stupid me. We have to wait for a third tick as well, # since we test that *more* than two seconds has passed. # Maybe we should move the waits for the two previous ticks # earlier in the test. send "101313 35\n" extracting_expect "=101313 ($any_time)" user_active_3 1 while {"$user_active_3" == "$user_active_2"} { sleep 0.1 send "999 35\n" extracting_expect "=999 ($any_time)" user_active_3 1 } send "1313 83 1 1 0\n" simple_expect "=1313 3 { 4 5 0 $any_num 10000000 [holl ""] 2 8 0 $any_num 01000000 [holl "Accepting i-am-on"] 1 6 6 $any_num 00000000 [holl "Running a test suite"] }" send "1314 83 1 1 2\n" simple_expect "=1314 2 { 4 5 0 $any_num 10000000 [holl ""] 1 6 6 $any_num 00000000 [holl "Running a test suite"] }" send "1315 83 1 0 2\n" simple_expect "=1315 1 { 1 6 6 $any_num 00000000 [holl "Running a test suite"] }" send "1316 83 0 1 2\n" simple_expect "=1316 1 { 4 5 0 $any_num 10000000 [holl ""] }" send "1317 83 0 0 2\n" simple_expect "=1317 0 \\*" send "1318 83 0 0 0\n" simple_expect "=1318 0 \\*" send "1319 82\n" simple_expect "=1319" send "1320 83 1 1 2\n" simple_expect "=1320 3 { 4 5 0 $any_num 10000000 [holl ""] 2 8 0 $any_num 01000000 [holl "Accepting i-am-on"] 1 6 6 $any_num 00000000 [holl "Running a test suite"] }" send "1321 83 1 1 2\n" simple_expect "=1321 3 { 4 5 0 $any_num 10000000 [holl ""] 2 8 0 $any_num 01000000 [holl "Accepting i-am-on"] 1 6 6 $any_num 00000000 [holl "Running a test suite"] }" # This test is timing sensitive. It will fail if the server is extremely slow. send "1322 83 1 0 2\n" simple_expect "=1322 2 { 2 8 0 $any_num 01000000 [holl "Accepting i-am-on"] 1 6 6 $any_num 00000000 [holl "Running a test suite"] }" # test call 84 (get-static-session-info) send "1323 84 2\n" simple_expect "=1323 [holl "ic@gratia"] [holl "$lyskomd_host"] [holl "unknown"] $any_time" # test call 85 (get-collate-table) send "1324 85\n" unanchored_expect "^MRK:client1: =1324 256H" "collate-table start" unanchored_expect "$nl" "get-collate-table newline before digits" # NOTE: Comment out the next two lines if runtest seems to hang. # NOTE: But also notify ceder of the versions of dejagnu, TCL and expect # NOTE: that you are using, and try to upgrade to current versions first. unanchored_expect "0123456789" "collate digits" unanchored_expect "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "collate upper" unanchored_expect "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "collate lower" unanchored_expect "\377$nl" "collate end" # test call 86 (create-text) send "1325 86 [holl "aux-style text 9"] 2 { 0 7 6 7 } 1 { 1 11111111 7 [holl "text/plain"] }\n" extracting_expect ":16 0 9 ($any_time) 8 0 16 0 2 { 0 7 6 7 }" time_9 1 # The last three bits in aux-flags had no defined meaning when this # test was written. simple_expect ":18 15 9 $time_9 8 0 16 0 2 { 0 7 6 7 } 1 { 1 1 8 $time_9 00000111 1 [holl "text/plain"] }" simple_expect "=1325 9" talk_to client 0 simple_expect ":16 0 9 $time_9 8 0 16 0 2 { 0 7 6 7 }" talk_to client 1 # test call 87 (create-anonymous-text) send "1326 87 [holl "aux-style anon 10"] 2 { 0 7 6 7 } 1 { 1 11111111 7 [holl "text/plain"] }\n" extracting_expect ":16 0 10 ($any_time) 0 0 17 0 2 { 0 7 6 8 }" time_10 1 # The last three bits in aux-flags had no defined meaning when this # test was written. simple_expect ":18 15 10 $time_10 0 0 17 0 2 { 0 7 6 8 } 1 { 1 1 0 $time_10 00000111 1 [holl "text/plain"] }" simple_expect "=1326 10" talk_to client 0 simple_expect ":16 0 10 $time_10 0 0 17 0 2 { 0 7 6 8 }" talk_to client 1 # test call 88 (create-conf) send "1327 88 [holl "aux in general"] 0100 1 { 14 00000000 1 [holl "10"] }\n" simple_expect "=1327 10" send "1328 88 [holl "aux non anon"] 01000000 1 { 14 00000000 1 [holl "10"] }\n" simple_expect "=1328 11" # test call 89 (create-person) send "1329 89 [holl "aux person"] [holl "secret"] 00000000 1 { 12 00000000 1 [holl "public"] }\n" simple_expect "=1329 12" # test call 90 (get-text-stat) send "1330 90 10\n" # Text 10 should have two extra aux-items since it is the FAQ of conferences 10 and 11. simple_expect "=1330 $time_10 0 0 17 0 2 { 0 7 6 8 } 3 { 1 1 0 $time_10 00000111 1 [holl "text/plain"] 2 28 8 $any_time 00001000 0 2H10 3 28 8 $any_time 00001000 0 2H11 }" # test call 91 (get-conf-stat) send "1331 91 10\n" extracting_expect "=1331 [holl "aux in general"] 01001000 ($any_time) $any_time 8 0 8 0 8 0 77 77 0 1 0 0 1 { 1 14 8 $any_time 00000000 1 [holl "10"] }" time_c_10 1 send "1332 91 10\n" simple_expect "=1332 [holl "aux in general"] 01001000 $time_c_10 $time_c_10 8 0 8 0 8 0 77 77 0 1 0 0 1 { 1 14 8 $time_c_10 00000000 1 [holl "10"] }" # test call 92 (modify-text-info) # Add a short notice. send "1333 92 3 0 { } 1 { 2 00000000 1 [holl "Du har fel"] }\n" simple_expect "=1333" send "1334 90 3\n" # This text is marked twice: user area of person 6, presentation for 7. simple_expect "=1334 $time_3 6 0 16 2 2 { 0 7 6 3 } 2 { 1 28 8 $any_time 00001000 0 [holl "8"] 2 2 8 $any_time 00000000 1 [holl "Du har fel"] }" # Remove it. send "1335 92 3 1 { 2 } 0 { }\n" simple_expect "=1335" send "1336 90 3\n" # This text is marked twice: user area of person 6, presentation for 7. simple_expect "=1336 $time_3 6 0 16 2 2 { 0 7 6 3 } 1 { 1 28 8 $any_time 00001000 0 [holl "8"] }" # Add a couple of more comments send "1337 92 3 0 { } 2 { 2 00000000 1 [holl "Du har massor fel"] 2 00000000 1 [holl "Du har felast av alla"] }\n" simple_expect "=1337" send "1338 90 3\n" # This text is marked twice: user area of person 6, presentation for 7. simple_expect "=1338 $time_3 6 0 16 2 2 { 0 7 6 3 } 3 { 1 28 8 $any_time 00001000 0 [holl "8"] 3 2 8 $any_time 00000000 1 [holl "Du har massor fel"] 4 2 8 $any_time 00000000 1 [holl "Du har felast av alla"] }" # test call 93 (modify-conf-info) send "1339 91 8\n" extracting_expect "=1339 [holl "Kelly Talisman"] 10011000 ($any_time) $any_time 8 0 8 0 0 0 77 77 1 1 2 0 11 { 1 3 8 $any_time 00000000 1 [holl "C6 My Creator"] 2 3 8 $any_time 00000000 1 [holl "C7 Slightly offensive name, huh"] 3 8 8 $any_time 00000000 1 [holl "E-mail:kelly@hotbox.com"] 4 9 8 $any_time 00000000 1 [holl "compface must die"] 5 10 8 $any_time 00000000 0 [holl "Air"] 6 12 8 $any_time 00000000 1 [holl "PGP public key"] 7 13 8 $any_time 00000000 1 [holl "kelly@hotbox.com"] 8 30 8 $any_time 00000000 0 [holl "2 text/plain"] 9 30 8 $any_time 00000000 0 [holl "2 x-kom/basic"] 10 33 8 $any_time 00000000 1 [holl "0"] 11 14 8 $any_time 00000000 1 [holl "3"] }" time_c_8 1 send "1340 91 8\n" simple_expect "=1340 [holl "Kelly Talisman"] 10011000 $time_c_8 $time_7 8 0 8 0 0 0 77 77 1 1 2 0 11 { 1 3 8 $time_c_8 00000000 1 [holl "C6 My Creator"] 2 3 8 $time_c_8 00000000 1 [holl "C7 Slightly offensive name, huh"] 3 8 8 $time_c_8 00000000 1 [holl "E-mail:kelly@hotbox.com"] 4 9 8 $time_c_8 00000000 1 [holl "compface must die"] 5 10 8 $time_c_8 00000000 0 [holl "Air"] 6 12 8 $time_c_8 00000000 1 [holl "PGP public key"] 7 13 8 $time_c_8 00000000 1 [holl "kelly@hotbox.com"] 8 30 8 $time_c_8 00000000 0 [holl "2 text/plain"] 9 30 8 $time_c_8 00000000 0 [holl "2 x-kom/basic"] 10 33 8 $any_time 00000000 1 [holl "0"] 11 14 8 $any_time 00000000 1 [holl "3"] }" send "1341 93 8 2 { 7 1 } 1 { 13 00000000 1 [holl "kelly@lysator.liu.se"] }\n" simple_expect "=1341" send "1342 91 8\n" simple_expect "=1342 [holl "Kelly Talisman"] 10011000 $time_c_8 $time_7 8 0 8 0 0 0 77 77 1 1 2 0 10 { 2 3 8 $time_c_8 00000000 1 [holl "C7 Slightly offensive name, huh"] 3 8 8 $time_c_8 00000000 1 [holl "E-mail:kelly@hotbox.com"] 4 9 8 $time_c_8 00000000 1 [holl "compface must die"] 5 10 8 $time_c_8 00000000 0 [holl "Air"] 6 12 8 $time_c_8 00000000 1 [holl "PGP public key"] 8 30 8 $time_c_8 00000000 0 [holl "2 text/plain"] 9 30 8 $time_c_8 00000000 0 [holl "2 x-kom/basic"] 10 33 8 $any_time 00000000 1 [holl "0"] 11 14 8 $any_time 00000000 1 [holl "3"] 12 13 8 $any_time 00000000 1 [holl "kelly@lysator.liu.se"] }" # test call 94 (get-info) send "1343 94\n" simple_expect "=1343 $server_compat_version 1 2 3 4 0 0 \\*" # test call 95 (modify-system-info) talk_to client 2 send "1344 95 0 { } 2 { 9 00000000 1 [holl "compface must die"] 13 00000000 1 [holl "maint@kom"] }\n" simple_expect "=1344" # Attempt to set a nonexisting text as faq for the server. send "1345 95 0 { } 1 { 14 00000000 1 [holl "999"] }\n" simple_expect "%1345 48 0" send "1346 94\n" simple_expect "=1346 $server_compat_version 1 2 3 4 0 2 { 1 9 5 $any_time 00000000 1 [holl "compface must die"] 2 13 5 $any_time 00000000 1 [holl "maint@kom"] }" send "1347 95 1 { 2 } 0 { }\n" simple_expect "=1347" send "1348 94\n" simple_expect "=1348 $server_compat_version 1 2 3 4 0 1 { 1 9 5 $any_time 00000000 1 [holl "compface must die"] }" # test call 96 (query-predefined-aux-items) talk_to client 1 send "1349 96\n" simple_expect "=1349 40 { 10104 10103 10102 10101 10100 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 }" # test call 97 (set-expire) send "1350 97 10 7123123\n" simple_expect "=1350" send "1351 91 10\n" simple_expect "=1351 [holl "aux in general"] 01001000 $time_c_10 $time_c_10 8 0 8 0 8 0 77 77 0 1 0 7123123 1 { 1 14 8 $time_c_10 00000000 1 [holl "10"] }" # test call 98 (query-read-texts-10) send "1352 98 6 7\n" simple_expect "=1352 1 $any_time 7 100 6 0 \\* 6 $any_time 00000000" send "1353 98 6 6\n" simple_expect "=1353 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000" # test call 99 (get-membership-10) send "1354 99 6 0 100 1\n" simple_expect "=1354 2 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 7 100 6 0 \\* 6 $any_time 00000000 }" send "1355 99 6 0 100 0\n" simple_expect "=1355 2 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 7 100 6 0 \\* 6 $any_time 00000000 }" # test call 100 (add-member) tested more in 05.exp send "1356 100 10 6 123 0 10000000\n" lyskomd_expect "Person 6 added to conference 10 by 8." simple_expect "=1356" send "1357 99 6 0 100 0\n" simple_expect "=1357 3 { 0 $any_time 10 123 0 0 \\* 8 $any_time 10000000 1 $any_time 6 255 0 0 \\* 6 $any_time 00000000 2 $any_time 7 100 6 0 \\* 6 $any_time 00000000 }" # test call 101 (get-members) tested more in 05.exp send "1358 101 10 0 100\n" simple_expect "=1358 1 { 6 8 $any_time 10000000 }" # test call 102 (set-membership-type) tested more in 05.exp send "1359 62 6 [holl "Talitha"] 0\n" simple_expect ":2 13 8 2" simple_expect ":2 9 6 2" simple_expect "=1359" send "1360 102 6 10 00000000\n" simple_expect "=1360" send "1361 101 10 0 100\n" simple_expect "=1361 1 { 6 8 $any_time 00000000 }" send "1362 99 6 0 100 0\n" simple_expect "=1362 3 { 0 $any_time 10 123 0 0 \\* 8 $any_time 00000000 1 $any_time 6 255 0 0 \\* 6 $any_time 00000000 2 $any_time 7 100 6 0 \\* 6 $any_time 00000000 }" # Finish testing membership stuff send "1363 62 8 [holl "the stars"] 0\n" simple_expect ":2 13 6 2" simple_expect ":2 9 8 2" simple_expect "=1363" talk_to client 0 simple_expect ":2 13 8 2" simple_expect ":2 9 6 2" simple_expect ":2 13 6 2" simple_expect ":2 9 8 2" talk_to client 2 simple_expect ":2 13 8 2" simple_expect ":2 9 6 2" simple_expect ":2 13 6 2" simple_expect ":2 9 8 2" talk_to client 1 # test call 103 (local-to-global) send "1364 103 7 1 50\n" simple_expect "=1364 1 9 0 1 1 8 { 1 0 3 4 5 6 9 10 }" send "1365 34 7 1 50\n" simple_expect "=1365 1 8 { 1 0 3 4 5 6 9 10 }" # test call 104 (map-created-texts) send "1366 47 6 1 100\n" simple_expect "=1366 1 3 { 1 0 3 }" send "1367 104 6 1 100\n" simple_expect "=1367 1 4 0 1 1 3 { 1 0 3 }" # test call 105 (set-keep-commented) send "1368 105 10 99\n" simple_expect "=1368" send "1369 91 10\n" simple_expect "=1369 [holl "aux in general"] 01001000 $time_c_10 $time_c_10 8 0 8 0 8 0 77 99 1 1 0 7123123 1 { 1 14 8 $time_c_10 00000000 1 [holl "10"] }" # test call 106 (set-pers-flags) send "1370 106 8 01011010\n" simple_expect "=1370" send "1371 49 8\n" simple_expect "=1371 [idholl "ic@gratia.unknown."] 0000010000000000 01011010 $any_time 0 $any_num 3 0 80 0 0 1 2 1 5 0 2" # test call 107 (query-read-texts) send "1372 107 6 7 1 1\n" simple_expect "=1372 2 $any_time 7 100 1 { 1 6 } 6 $any_time 00000000" send "1373 107 6 6 1 1\n" simple_expect "=1373 1 $any_time 6 255 0 \\* 6 $any_time 00000000" # test call 108 (get-membership) send "1374 108 6 0 100 1 1\n" simple_expect "=1374 3 { 0 $any_time 10 123 0 \\* 8 $any_time 00000000 1 $any_time 6 255 0 \\* 6 $any_time 00000000 2 $any_time 7 100 1 { 1 6 } 6 $any_time 00000000 }" send "1375 108 6 0 100 0 1\n" simple_expect "=1375 3 { 0 $any_time 10 123 0 \\* 8 $any_time 00000000 1 $any_time 6 255 0 \\* 6 $any_time 00000000 2 $any_time 7 100 1 \\* 6 $any_time 00000000 }" # test call 109 (mark-as-unread) talk_to client 0 send "1376 109 7 4\n" simple_expect "=1376" send "1377 108 6 0 100 1 0\n" simple_expect "=1377 3 { 0 $any_time 10 123 0 \\* 8 $any_time 00000000 1 $any_time 6 255 0 \\* 6 $any_time 00000000 2 $any_time 7 100 2 { 1 3 5 6 } 6 $any_time 00000000 }" # test call 110 (set-read-ranges) send "1378 110 7 0 { }\n" simple_expect "=1378" send "1379 108 6 0 100 1 0\n" simple_expect "=1379 3 { 0 $any_time 10 123 0 \\* 8 $any_time 00000000 1 $any_time 6 255 0 \\* 6 $any_time 00000000 2 $any_time 7 100 0 \\* 6 $any_time 00000000 }" send "1380 110 7 3 { 1 1 3 4 6 6 }\n" simple_expect "=1380" send "1381 108 6 0 100 1 0\n" simple_expect "=1381 3 { 0 $any_time 10 123 0 \\* 8 $any_time 00000000 1 $any_time 6 255 0 \\* 6 $any_time 00000000 2 $any_time 7 100 2 { 1 4 6 6 } 6 $any_time 00000000 }" # test call 111 (get-stats-description) send "1382 111\n" simple_expect "=1382 10 { [holl "run-queue-length"] [holl "pending-dns"] [holl "pending-ident"] [holl "clients"] [holl "reqs"] [holl "texts"] [holl "confs"] [holl "persons"] [holl "send-queue-bytes"] [holl "recv-queue-bytes"] } 6 { 0 1 15 60 300 900 }" # test call 112 (get-stats) send "1383 112 [holl "run-queue-length"]\n" simple_expect "=1383 6 { 0 0 0 $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float }" send "1384 112 [holl "pending-dns"]\n" simple_expect "=1384 6 { 0 0 0 $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float }" send "1385 112 [holl "pending-ident"]\n" simple_expect "=1385 6 { 0 0 0 $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float }" send "1386 112 [holl "clients"]\n" simple_expect "=1386 6 { 3 0 0 $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float }" send "1387 112 [holl "reqs"]\n" simple_expect "=1387 6 { 1 0 0 $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float }" send "1388 112 [holl "texts"]\n" simple_expect "=1388 6 { 9 0 0 $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float }" send "1389 112 [holl "confs"]\n" simple_expect "=1389 6 { 11 0 0 $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float }" send "1390 112 [holl "persons"]\n" simple_expect "=1390 6 { 4 0 0 $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float }" send "1391 112 [holl "send-queue-bytes"]\n" simple_expect "=1391 6 { $any_num 0 0 $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float }" send "1392 112 [holl "recv-queue-bytes"]\n" simple_expect "=1392 6 { $any_num 0 0 $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float }" # Non-existing stuff. send "1393 112 [holl "no-such-thing"]\n" simple_expect "%1393 57 0" talk_to client 1 # test call 113 (get-boottime-info) send "1394 113\n" simple_expect "=1394 $any_time $any_time [holl "clean"] 0 0 5 1 5" # test call 114 (first-unused-conf-no) send "1395 114\n" simple_expect "=1395 13" # test call 115 (first-unused-text-no) send "1396 115\n" simple_expect "=1396 11" # test call 116 (find-next-conf-no) send "1397 116 0\n" simple_expect "=1397 1" send "1398 116 1\n" simple_expect "=1398 2" send "1399 116 2\n" simple_expect "=1399 3" send "1400 116 6\n" simple_expect "=1400 7" send "1401 116 7\n" simple_expect "=1401 8" send "1402 116 8\n" simple_expect "=1402 10" send "1403 116 9\n" simple_expect "=1403 10" send "1404 116 200\n" simple_expect "%1404 9 200" # 117:find-previous-conf-no send "1405 117 0\n" simple_expect "%1405 9 0" send "1406 117 1\n" simple_expect "%1406 9 1" send "1407 117 2\n" simple_expect "=1407 1" send "1408 117 200\n" simple_expect "=1408 12" send "1409 117 11\n" simple_expect "=1409 10" send "1410 117 10\n" simple_expect "=1410 8" send "1411 117 9\n" simple_expect "=1411 8" send "1412 117 8\n" simple_expect "=1412 7" # 118:get-scheduling send "1413 118 0\n" simple_expect "=1413 0 20" send "1414 118 1\n" simple_expect "=1414 0 20" send "1415 118 2\n" simple_expect "=1415 0 20" send "1416 118 3\n" simple_expect "%1416 42 3" send "1417 118 4\n" simple_expect "=1417 0 20" send "1418 118 5\n" simple_expect "%1418 42 5" # 119:set-scheduling send "1419 56\n" simple_expect "=1419 2" send "1420 119 0 0 1\n" simple_expect "=1420" send "1421 119 1 0 1\n" simple_expect "%1421 11 1" send "1422 119 2 0 1\n" simple_expect "=1422" send "1423 119 2 1 1\n" simple_expect "%1423 19 0" send "1424 119 2 0 0\n" simple_expect "%1424 60 0" send "1425 119 2 0 101\n" simple_expect "%1425 59 100" send "1426 119 3 0 1\n" simple_expect "%1426 42 3" # 120:set-connection-time-format send "1427 120 1\n" simple_expect "=1427" send "1428 120 2\n" simple_expect "%1428 61 0" send "1429 120 0\n" simple_expect "=1429" # 121:local-to-global-reverse send "1430 34 7 1 50\n" simple_expect "=1430 1 8 { 1 0 3 4 5 6 9 10 }" send "1431 121 7 0 50\n" simple_expect "=1431 1 9 0 1 1 8 { 1 0 3 4 5 6 9 10 }" send "1432 121 7 10 50\n" simple_expect "=1432 1 9 0 1 1 8 { 1 0 3 4 5 6 9 10 }" # 122:map-created-texts-reverse send "1433 47 6 1 100\n" simple_expect "=1433 1 3 { 1 0 3 }" send "1434 122 6 0 100\n" simple_expect "=1434 1 4 0 1 1 3 { 1 0 3 }" send "1435 122 6 4 100\n" simple_expect "=1435 1 4 0 1 1 3 { 1 0 3 }" # There is no call 122--yet. send "1436 123 1 2 3 4 1 32 { 2 }\n" simple_expect "%1436 2 0" # There is no call 124--yet. send "1437 124\n" simple_expect "%1437 2 0" # There is no call 125--yet. send "1438 125\n" simple_expect "%1438 2 0" # There is no call 126--yet. send "1439 126\n" simple_expect "%1439 2 0" # Test creation of a person with a faq-text aux-item. This should fail # when you are not logged on. talk_to client 2 send "1440 1\n" simple_expect "=1440" send "1441 89 [holl "Kelly Talisman II"] [holl "the stars"] 00000000 11 { 3 00000000 0 [holl "C6 My Creator"] 3 00000000 0 [holl "C7 Slightly offensive name, huh"] 8 00000000 0 [holl "E-mail:kelly@hotbox.com"] 9 00000000 0 [holl "compface must die"] 10 00000000 0\n" send "[holl "Air"] 12 00000000 0 [holl "PGP public key"] 13 00000000 0 [holl "kelly@hotbox.com"] 30 00000000 0 [holl "2 text/plain"] 30 00000000 0 [holl "2 x-kom/basic"] 33 00000000 1 1H0 14 00000000 0 [holl "3"] }\n" simple_expect "%1441 48 10" # Disconnect all but the first session talk_to client 2 send "1442 55 4\n" simple_expect "=1442" client_death 2 talk_to client 1 send "1443 55 2\n" simple_expect "=1443" simple_expect ":2 13 8 2" client_death 1 # Shut everything down talk_to client 0 simple_expect ":2 13 8 2" send "1444 62 5 [holl "bar"] 0\n" simple_expect ":2 13 6 1" simple_expect ":2 9 5 1" simple_expect "=1444" send "1445 42 255\n" simple_expect "=1445" "42=enable succeeded" send "1446 43\n" simple_expect ":0 7" simple_expect ":0 7" simple_expect "=1446" talk_to client 0 send "1447 44 0\n" simple_expect "=1447" "44=shutdown-kom succeeded" client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/04.exp0000664000015100472110000010770007721716132016737 # Test suite for lyskomd. # Copyright (C) 1998-2000, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test of aux-item functonality # # It's assumed that person 5 is privileged and has # the password "gazonk" read_versions source "$srcdir/config/prot-a.exp" lyskomd_start "$srcdir/lyskomd.0/aux-items.conf" client_start 0 talk_to client 0 kom_connect "DejaGnu test suite" "" "AIX: Client connected" kom_accept_async "0 { }" "" "AIX: Accept-async" set pers_6 [ kom_create_person "User 1" "pw1" "00000000" "0 { }" "" "AIX: Create P6" ] kom_login 6 "pw1" 0 set pers_7 [ kom_create_person "User 2" "pw2" "00000000" "0 { }" "" "AIX: Create P7" ] kom_logout "" "AIX: Logout P7" set pers_8 [ kom_create_person "User 3" "pw3" "00000000" "0 { }" "" "AIX: Create P8" ] kom_login 8 "pw3" 0 kom_login 7 "pw2" 0 "" "AIX: Login P7" set conf_9 [ kom_create_conference "Conference 9" "00001000" "0 { }" "" "AIX: Create C9" ] # ============================================================ # Basic checks on texts # send "1000 86 [holl "Text 1"] 1 { 0 9 } 3 { 1000 01000000 2 [holl "A1"] 1001 00100000 0 [holl "A2" ] 1002 00010000 0 [holl "A3"] }\n" simple_expect "=1000 1" "AI Create text with items" # Create a comment send "1001 86 [holl "Text 2"] 2 { 0 9 2 1 } 0 { }\n" simple_expect "=1001 2" "AI Create comment without items" # Create a second comment send "1002 86 [holl "Text 3"] 2 { 0 9 2 2 } 0 { }\n" simple_expect "=1002 3" "AI Create comment without items" # Check that secret items can be read by creator # Check that hide-author item can be read by creator" send "2000 90 1\n" simple_expect "=2000 $any_time 7 0 6 0 3 { 0 9 6 1 3 2 } 3 { 1 1000 7 $any_time 01000000 2 [holl "A1"] 2 1001 7 $any_time 00100000 0 [holl "A2"] 3 1002 7 $any_time 00010000 0 [holl "A3"] }" "AIT: Permissions when seen by creator" # Check that inheritance works send "2001 90 2\n" simple_expect "=2001 $any_time 7 0 6 0 4 { 0 9 6 2 2 1 3 3 } 1 { 1 1000 7 $any_time 01000000 1 [holl "A1"] }" "AIT: Inheritance works" # Check that inherit-limit works send "2002 90 3\n" simple_expect "=2002 $any_time 7 0 6 0 3 { 0 9 6 3 2 2 } 0 \\*" "AIT: Inherit limit works" # Add one item send "2003 92 3 0 { } 1 { 1010 00000000 0 [holl "D1"] }\n" simple_expect "=2003" "AIT: Add one item to text (add)" send "2004 90 3\n" simple_expect "=2004 $any_time 7 0 6 0 3 { 0 9 6 3 2 2 } 1 { 1 1010 7 $any_time 00000000 0 [holl "D1"] }" "AIT: Add one item to text (read)" # Add three items at once send "2005 92 3 0 { } 3 { 1011 00000000 0 [holl "D2"] 1012 00000000 0 [holl "D3"] 1013 00000000 0 [holl "D4"] }\n" simple_expect "=2005" "AIT: Add three items to text (add)" send "2006 90 3\n" simple_expect "=2006 $any_time 7 0 6 0 3 { 0 9 6 3 2 2 } 4 { 1 1010 7 $any_time 00000000 0 [holl "D1"] 2 1011 7 $any_time 00000000 0 [holl "D2"] 3 1012 7 $any_time 00000000 0 [holl "D3"] 4 1013 7 $any_time 00000000 0 [holl "D4"] }" "AIT: Add three items to text (read)" # Creator deleting an item send "2007 92 3 1 { 1 } 0 { }\n" simple_expect "=2007" "AIT: Creator deleting item (delete)" send "2008 90 3\n" simple_expect "=2008 $any_time 7 0 6 0 3 { 0 9 6 3 2 2 } 3 { 2 1011 7 $any_time 00000000 0 [holl "D2"] 3 1012 7 $any_time 00000000 0 [holl "D3"] 4 1013 7 $any_time 00000000 0 [holl "D4"] }" "AIT: Creator deleting item (read)" # Creator deleting three items at once send "2009 92 3 3 { 2 3 4 } 0 { }\n" simple_expect "=2009" "AIT: Creator deleting three items (delete)" send "2010 90 3\n" simple_expect "=2010 $any_time 7 0 6 0 3 { 0 9 6 3 2 2 } 0 \\*" "aux-items: three items can be deleted" "AIT: Creator deleting three items (read)" # Creator attempting to delete a non-existant item send "2011 92 3 1 { 1 } 0 { }\n" simple_expect "%2011 49 0" "AIT: Creator attempting to delete nonexistant item" # Add an item after deleted items send "2012 92 3 0 { } 2 { 1014 00000000 0 [holl "D5"] 1015 00000000 0 [holl "D6"] }\n" simple_expect "=2012" "AIT: Add item after deleted items (add)" send "2013 90 3\n" simple_expect "=2013 $any_time 7 0 6 0 3 { 0 9 6 3 2 2 } 2 { 5 1014 7 $any_time 00000000 0 [holl "D5"] 6 1015 7 $any_time 00000000 0 [holl "D6"] }" "AIT: Add item after deleted item (read)" # Non-related person attempting to delete an item kom_logout kom_login 8 "pw3" 0 send "2014 92 3 1 { 5 } 0 { }\n" simple_expect "%2014 49 0" "AIT: Nonrelated person deleting item (delete)" send "2014 90 3\n" simple_expect "=2014 $any_time 7 0 6 0 3 { 0 9 6 3 2 2 } 2 { 5 1014 7 $any_time 00000000 0 [holl "D5"] 6 1015 7 $any_time 00000000 0 [holl "D6"] }" "AIT: Nonrelated person deleting item (read)" # Supervisor of creator deleting one item kom_logout kom_login 6 "pw1" 0 send "2015 92 3 1 { 5 } 0 { }\n" simple_expect "=2015" "AIT: Supervisor deleting one item (delete)" send "2016 90 3\n" simple_expect "=2016 $any_time 7 0 6 0 3 { 0 9 6 3 2 2 } 1 { 6 1015 7 $any_time 00000000 0 [holl "D6"] }" "AIT: Supervisor deleting one item (read)" # Admin deleting one item kom_logout kom_login 5 "gazonk" 0 kom_enable 255 send "2017 92 3 1 { 6 } 0 { }\n" simple_expect "=2017" "AIT: Admin deleting one item (delete)" send "2018 90 3\n" simple_expect "=2018 $any_time 7 0 6 0 3 { 0 9 6 3 2 2 } 0 \\*" "AIT: Admin deleting one item (read)" # Add and delete items at the same time kom_logout kom_login 7 "pw2" 0 send "2019 92 3 0 { } 2 { 1016 00000000 0 [holl "D7"] 1017 00000000 0 [holl "D8"] }\n" simple_expect "=2019" "AIT: Creator adding and deleting at once (prepare)" send "2020 90 3\n" simple_expect "=2020 $any_time 7 0 6 0 3 { 0 9 6 3 2 2 } 2 { 7 1016 7 $any_time 00000000 0 [holl "D7"] 8 1017 7 $any_time 00000000 0 [holl "D8"] }" "AIT: Creator adding and deleting at once (prepare/read)" send "2021 92 3 1 { 7 } 1 { 1018 00000000 0 [holl "D9"] }\n" simple_expect "=2021" "AIT: Creator adding and deleting (add/delete)" send "2022 90 3\n" simple_expect "=2022 $any_time 7 0 6 0 3 { 0 9 6 3 2 2 } 2 { 8 1017 7 $any_time 00000000 0 [holl "D8"] 9 1018 7 $any_time 00000000 0 [holl "D9"] }" "AIT: Creator adding and deleting at once (read)" # Attempt to add and delete items where add fails send "2023 92 3 1 { 8 } 1 { 10000 00000000 0 [holl "FUBAR"] }\n" simple_expect "%2023 49 0" "AIT: Creator adding and deleting with add fail (add)" send "2024 90 3\n" simple_expect "=2024 $any_time 7 0 6 0 3 { 0 9 6 3 2 2 } 2 { 8 1017 7 $any_time 00000000 0 [holl "D8"] 9 1018 7 $any_time 00000000 0 [holl "D9"] }" "AIT: Creator adding and deleting with add fail (read)" # Attempt to add and delete items where delete fails send "2025 92 3 1 { 100 } 1 { 1018 00000000 0 [holl "FUBAR"] }\n" simple_expect "%2025 49 0" "AIT: Creator adding and deleting with delete fail (add)" send "2026 90 3\n" simple_expect "=2026 $any_time 7 0 6 0 3 { 0 9 6 3 2 2 } 2 { 8 1017 7 $any_time 00000000 0 [holl "D8"] 9 1018 7 $any_time 00000000 0 [holl "D9"] }" "AIT: Creator adding and deleting with delete fail (read)" # Check that supervisor can see secret item # Check that supervisor can see author-only item kom_logout "" "AIX: Logging out" kom_login 6 "pw1" 0 "" "AIX: Logging in P6" send "2026 90 1\n" simple_expect "=2026 $any_time 7 0 6 0 3 { 0 9 6 1 3 2 } 3 { 1 1000 7 $any_time 01000000 2 [holl "A1"] 2 1001 7 $any_time 00100000 0 [holl "A2"] 3 1002 7 $any_time 00010000 0 [holl "A3"] }" "AIT: Secret and hide author permissions wrt supervisor" # Check that admin can see secret item # Check that admin can see author-only item kom_logout "" "AIX: Logging out" kom_login 5 "gazonk" 0 "" "AIX: Logging in P5" kom_enable 255 "" "AIX: Enabling" send "2027 90 1\n" simple_expect "=2027 $any_time 7 0 6 0 3 { 0 9 6 1 3 2 } 3 { 1 1000 7 $any_time 01000000 2 [holl "A1"] 2 1001 7 $any_time 00100000 0 [holl "A2"] 3 1002 7 $any_time 00010000 0 [holl "A3"] }" "AIT: Secret and hide author permissions wrt admin" # Check that non-related person cannot see secret item # Check that non-related person cannot see author-only item kom_logout "" "AIX: Logging out" kom_login 8 "pw3" 0 "" "AIX: Logging in as P8" send "2028 90 1\n" simple_expect "=2028 $any_time 7 0 6 0 3 { 0 9 6 1 3 2 } 2 { 1 1000 7 $any_time 01000000 2 [holl "A1"] 3 1002 0 $any_time 00010000 0 [holl "A3"] }" "AIT: Secret and hide author permissions wrt others" # ============================================================ # Basic checks on conferences # kom_logout "" "AIX: Logging Out to start checking confs" kom_login 7 "pw2" 0 "" "AIX: Logging in to start checking confs" # Creator adding a single item send "2029 93 $conf_9 0 { } 1 { 1000 00000000 0 [holl "A1"] }\n" simple_expect "=2029" "AIC: Cretor adding one item (add)" send "2030 91 $conf_9\n" simple_expect "=2030 [holl "Conference 9"] 00001000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 3 0 1 { 1 1000 7 $any_time 00000000 0 [holl "A1"] }" "AIC: Creator adding one item (read)" # Creator adding three items send "2031 93 $conf_9 0 { } 3 { 1001 00000000 0 [holl "A2"] 1002 00100000 0 [holl "A3"] 1003 00010000 0 [holl "A4"] }\n" simple_expect "=2031" "AIC: Creator adding three items (add)" send "2032 91 $conf_9\n" simple_expect "=2032 [holl "Conference 9"] 00001000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 3 0 4 { 1 1000 7 $any_time 00000000 0 [holl "A1"] 2 1001 7 $any_time 00000000 0 [holl "A2"] 3 1002 7 $any_time 00100000 0 [holl "A3"] 4 1003 7 $any_time 00010000 0 [holl "A4"] }" "AIC: Creator adding three items (read)" # Creator deleting single item from the middle of the list send "2033 93 $conf_9 1 { 2 } 0 { }\n" simple_expect "=2033" "AIC: Creator deleting one item (delete)" send "2034 91 $conf_9\n" simple_expect "=2034 [holl "Conference 9"] 00001000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 3 0 3 { 1 1000 7 $any_time 00000000 0 [holl "A1"] 3 1002 7 $any_time 00100000 0 [holl "A3"] 4 1003 7 $any_time 00010000 0 [holl "A4"] }" "AIC: Creator deleting one item (read)" # Creator deleting three items from list send "2035 93 $conf_9 3 { 1 3 4 } 0 { }\n" simple_expect "=2035" "AIC: Creator deleting three items (delete)" send "2036 91 $conf_9\n" simple_expect "=2036 [holl "Conference 9"] 00001000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 3 0 0 \\*" "AIC: Creator deleting three items (read)" # Creator attempting to delete a non-existant item send "2037 93 $conf_9 1 { 1 } 0 { }\n" simple_expect "%2037 49 0" "AIC: Creator deleting nonexistant item (delete)" send "2038 91 $conf_9\n" simple_expect "=2038 [holl "Conference 9"] 00001000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 3 0 0 \\*" "AIC: Creator deleting nonexistant item (read)" # Add an item after deleted items send "2039 93 $conf_9 0 { } 2 { 1004 00000000 0 [holl "A5"] 1005 00000000 0 [holl "A6"] }\n" simple_expect "=2039" "AIC: Creator adding item after deleted items (add)" send "2040 91 $conf_9\n" simple_expect "=2040 [holl "Conference 9"] 00001000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 3 0 2 { 5 1004 7 $any_time 00000000 0 [holl "A5"] 6 1005 7 $any_time 00000000 0 [holl "A6"] }" "AIC: Creator adding item after deleted items (read)" # Non-related person attempting to delete an item kom_logout kom_login 8 "pw3" 0 send "2041 93 $conf_9 1 { 5 } 0 { }\n" simple_expect "%2041 49 0" "AIC: Nonrelated person attempting to delete item (delete" send "2041 91 $conf_9\n" simple_expect "=2041 [holl "Conference 9"] 00001000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 3 0 2 { 5 1004 7 $any_time 00000000 0 [holl "A5"] 6 1005 7 $any_time 00000000 0 [holl "A6"] }" "AIC: Nonrelated person attempting to delete item (read)" # Supervisor of creator deleting one item kom_logout kom_login 6 "pw1" 0 send "2042 93 $conf_9 1 { 5 } 0 { }\n" simple_expect "=2042" "AIC: Supervisor deleting one item (delete)" send "2043 91 $conf_9\n" simple_expect "=2043 [holl "Conference 9"] 00001000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 3 0 1 { 6 1005 7 $any_time 00000000 0 [holl "A6"] }" "AIC: Supervisor deleting one item (read)" # Admin deleting one item kom_logout kom_login 5 "gazonk" 0 kom_enable 255 send "2044 93 $conf_9 1 { 6 } 0 { }\n" simple_expect "=2044" "AIC: Admin deleting one item (delete)" send "2045 91 $conf_9\n" simple_expect "=2045 [holl "Conference 9"] 00001000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 3 0 0 \\*" "AIC: Admin deleting one item (read)" # Add and delete items at the same time kom_logout kom_login 7 "pw2" 0 # Add and delete items at the same time kom_logout kom_login 7 "pw2" 0 send "2046 93 $conf_9 0 { } 2 { 1016 00000000 0 [holl "A7"] 1017 00000000 0 [holl "A8"] }\n" simple_expect "=2046" "AIC: Add and delete items at once (prepare)" send "2046 91 $conf_9\n" simple_expect "=2046 [holl "Conference 9"] 00001000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 3 0 2 { 7 1016 7 $any_time 00000000 0 [holl "A7"] 8 1017 7 $any_time 00000000 0 [holl "A8"] }" "AIC: Add and delete items at once (prepare/read)" send "2047 93 $conf_9 1 { 7 } 1 { 1018 00000000 0 [holl "A9"] }\n" simple_expect "=2047" "AIC: Add and delete items at once (add/delete)" send "2048 91 $conf_9\n" simple_expect "=2048 [holl "Conference 9"] 00001000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 3 0 2 { 8 1017 7 $any_time 00000000 0 [holl "A8"] 9 1018 7 $any_time 00000000 0 [holl "A9"] }" "AIC: Add and delete items at once (read)" # Attempt to add and delete items where add fails send "2049 93 $conf_9 1 { 8 } 1 { 10000 00000000 0 [holl "FUBAR"] }\n" simple_expect "%2049 49 0" "AIC: Add and delete where add fails (add)" send "2050 91 $conf_9\n" simple_expect "=2050 [holl "Conference 9"] 00001000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 3 0 2 { 8 1017 7 $any_time 00000000 0 [holl "A8"] 9 1018 7 $any_time 00000000 0 [holl "A9"] }" "AIC: Add and delete where add fails (read)" # Attempt to add and delete items where delete fails send "2051 93 $conf_9 1 { 100 } 1 { 1018 00000000 0 [holl "FUBAR"] }\n" simple_expect "%2051 49 0" "AIC: Add and delete where delete fails (add)" send "2052 91 $conf_9\n" simple_expect "=2052 [holl "Conference 9"] 00001000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 3 0 2 { 8 1017 7 $any_time 00000000 0 [holl "A8"] 9 1018 7 $any_time 00000000 0 [holl "A9"] }" "AIC: Add and delete where delete fails (read)" # Check that permissions work set conf_10 [ kom_create_conference "Conference 10" "00001000" "3 { 1000 01000000 2 [holl "E1"] 1001 00100000 0 [holl "E2" ] 1003 00010000 0 [holl "E3"] }" ] send "2053 91 $conf_10\n" simple_expect "=2053 [holl "Conference 10"] 00001000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 0 0 3 { 1 1000 7 $any_time 01000000 2 [holl "E1"] 2 1001 7 $any_time 00100000 0 [holl "E2"] 3 1003 7 $any_time 00010000 0 [holl "E3"] }" "AIC: Create conference with items (read)" # Check that supervisor can see secret item # Check that supervisor can see author-only item kom_logout kom_login 6 "pw1" 0 send "2054 91 $conf_10\n" simple_expect "=2054 [holl "Conference 10"] 00001000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 0 0 3 { 1 1000 7 $any_time 01000000 2 [holl "E1"] 2 1001 7 $any_time 00100000 0 [holl "E2"] 3 1003 7 $any_time 00010000 0 [holl "E3"] }" "AIC: Secret and hide author permissions wrt supervisor" # Check that admin can see secret item # Check that admin can see author-only item kom_logout kom_login 5 "gazonk" 0 kom_enable 255 send "2055 91 $conf_10\n" simple_expect "=2055 [holl "Conference 10"] 00001000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 0 0 3 { 1 1000 7 $any_time 01000000 2 [holl "E1"] 2 1001 7 $any_time 00100000 0 [holl "E2"] 3 1003 7 $any_time 00010000 0 [holl "E3"] }" "AIC: Secret and hide author permissions wrt admin" # Check that non-related person cannot see secret item # Check that non-related person cannot see author-only item kom_logout kom_login 8 "pw3" 0 send "2056 91 $conf_10\n" simple_expect "=2056 [holl "Conference 10"] 00001000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 0 0 2 { 1 1000 7 $any_time 01000000 2 [holl "E1"] 3 1003 0 $any_time 00010000 0 [holl "E3"] }" "AIC: Secret and hide author permissions wrt others" # ============================================================ # Basic checks on system # # Try to add as normal user kom_logout kom_login 7 "pw2" 0 send "2100 95 0 { } 1 { 1000 00000000 0 [holl "FUBAR"] }\n" simple_expect "%2100 12 0" "AIS: Add as normal user (add)" send "2100 94\n" simple_expect "=2100 $any_num $any_num $any_num $any_num $any_num $any_num 0 \\*" "AIS: Attempt to add single item as normal user (read)" # Try to add single item as admin kom_logout kom_login 5 "gazonk" 0 send "2101 95 0 { } 1 { 1000 00000000 0 [holl "FUBAR"] }\n" simple_expect "%2101 12 0" "AIS: Add single item as admin without enable (add)" send "2101 94\n" simple_expect "=2101 $any_num $any_num $any_num $any_num $any_num $any_num 0 \\*" "AIS: Attempt to add single item as admin without enable (read)" kom_enable 255 send "2101 95 0 { } 1 { 1000 00000000 0 [holl "S1"] }\n" simple_expect "=2101" "AIS: Add single item as admin with enable (add)" send "2102 94\n" simple_expect "=2102 $any_num $any_num $any_num $any_num $any_num $any_num 1 { 1 1000 5 $any_time 00000000 0 [holl "S1"] }" "AIS: Admin adding single item (read)" # Try to add three items as admin send "2103 95 0 { } 3 { 1001 00000000 0 [holl "S2"] 1002 00000000 0 [holl "S3"] 1003 00000000 0 [holl "S4"] }\n" simple_expect "=2103" "AIS: Add three items as admin with enable (add)" send "2104 94\n" simple_expect "=2104 $any_num $any_num $any_num $any_num $any_num $any_num 4 { 1 1000 5 $any_time 00000000 0 [holl "S1"] 2 1001 5 $any_time 00000000 0 [holl "S2"] 3 1002 5 $any_time 00000000 0 [holl "S3"] 4 1003 5 $any_time 00000000 0 [holl "S4"] }" "AIS: Admin adding three items (read)" # Try to delete as normal person kom_logout kom_login 7 "pw2" 0 send "2105 95 1 { 1 } 0 { }\n" simple_expect "%2105 12 0" "AIS: Attempt to delete as normal user" send "2106 94\n" simple_expect "=2106 $any_num $any_num $any_num $any_num $any_num $any_num 4 { 1 1000 5 $any_time 00000000 0 [holl "S1"] 2 1001 5 $any_time 00000000 0 [holl "S2"] 3 1002 5 $any_time 00000000 0 [holl "S3"] 4 1003 5 $any_time 00000000 0 [holl "S4"] }" "AIS: Attempt to delete as normal user (read)" # Try to delete single item as admin kom_logout kom_login 5 "gazonk" 0 send "2107 95 1 { 1 } 0 { }\n" simple_expect "%2107 12 0" "AIS: Attempt to delete as admin without enable (delete)" send "2108 94\n" simple_expect "=2108 $any_num $any_num $any_num $any_num $any_num $any_num 4 { 1 1000 5 $any_time 00000000 0 [holl "S1"] 2 1001 5 $any_time 00000000 0 [holl "S2"] 3 1002 5 $any_time 00000000 0 [holl "S3"] 4 1003 5 $any_time 00000000 0 [holl "S4"] }" "AIS: Attempt to delete as admin without enable (read)" kom_enable 255 send "2109 95 1 { 1 } 0 { }\n" simple_expect "=2109" "AIS: Delete as admin (delete)" send "2110 94\n" simple_expect "=2110 $any_num $any_num $any_num $any_num $any_num $any_num 3 { 2 1001 5 $any_time 00000000 0 [holl "S2"] 3 1002 5 $any_time 00000000 0 [holl "S3"] 4 1003 5 $any_time 00000000 0 [holl "S4"] }" "AIS: Delete as admin (read)" send "2111 95 1 { 4 } 0 { }\n" simple_expect "=2111" "AIS: Delete last item as admin (delete)" send "2112 94\n" simple_expect "=2112 $any_num $any_num $any_num $any_num $any_num $any_num 2 { 2 1001 5 $any_time 00000000 0 [holl "S2"] 3 1002 5 $any_time 00000000 0 [holl "S3"] }" "AIS: Delete last item as admin (read)" # Try to add after delete # Try to add last, after deleted last item send "2113 95 0 { } 1 { 1000 00000000 0 [holl "S5"] }\n" simple_expect "=2113" "AIS: Add item after deleted item (add)" send "2114 94\n" simple_expect "=2114 $any_num $any_num $any_num $any_num $any_num $any_num 3 { 2 1001 5 $any_time 00000000 0 [holl "S2"] 3 1002 5 $any_time 00000000 0 [holl "S3"] 5 1000 5 $any_time 00000000 0 [holl "S5"] }" "AIS: Add item after deleted item (read)" # Try to delete three items as admin send "2115 95 3 { 2 3 5 } 0 { }\n" simple_expect "=2115" "AIS: Delete three items as admin (delete)" send "2116 94\n" simple_expect "=2116 $any_num $any_num $any_num $any_num $any_num $any_num 0 \\*" "AIS: Delete three items as admin (read)" # Try to add and delete at once send "2117 95 0 { } 1 { 1000 00000000 0 [holl "S6"] }\n" simple_expect "=2117" "AIS: Add and delete at once (prepare, add)" send "2118 94\n" simple_expect "=2118 $any_num $any_num $any_num $any_num $any_num $any_num 1 { 6 1000 5 $any_time 00000000 0 [holl "S6"] }" "AIS: Add and delete at once (prepare, read)" send "2119 95 1 { 6 } 1 { 1009 00000000 0 [holl "S7"] }\n" simple_expect "=2119" "AIS: Add and delete at once (add)" send "2120 94\n" simple_expect "=2120 $any_num $any_num $any_num $any_num $any_num $any_num 1 { 7 1009 5 $any_time 00000000 0 [holl "S7"] }" "AIS: Add and delete at once (read)" # Try add and delete with add fail send "2121 95 1 { 7 } 1 { 10001 00000000 0 [holl "FUBAR"] }\n" simple_expect "%2121 49 0" "AIS: Add and delete with add fail (add)" send "2122 94\n" simple_expect "=2122 $any_num $any_num $any_num $any_num $any_num $any_num 1 { 7 1009 5 $any_time 00000000 0 [holl "S7"] }" "AIS: Add and delete with add fail (read)" # Try add and delete with delete fail send "2123 95 1 { 9 } 1 { 1000 00000000 0 [holl "FUBAR"] }\n" simple_expect "%2123 49 0" send "2124 94\n" simple_expect "=2124 $any_num $any_num $any_num $any_num $any_num $any_num 1 { 7 1009 5 $any_time 00000000 0 [holl "S7"] }" "AIS: Add and delete with delete fail (read)" # Check hide author and secret permissions wrt admin send "2125 95 0 { } 2 { 1010 00100000 0 [holl "SS"] 1011 00010000 0 [holl "HA"] }\n" simple_expect "=2125" "AIS: Check permissions (prepare)" send "2126 94\n" simple_expect "=2126 $any_num $any_num $any_num $any_num $any_num $any_num 3 { 7 1009 5 $any_time 00000000 0 [holl "S7"] 8 1010 5 $any_time 00100000 0 [holl "SS"] 9 1011 5 $any_time 00010000 0 [holl "HA"] }" "AIS: Check permissions wrt admin (read)" kom_enable 0 send "2127 94\n" simple_expect "=2127 $any_num $any_num $any_num $any_num $any_num $any_num 3 { 7 1009 5 $any_time 00000000 0 [holl "S7"] 8 1010 5 $any_time 00100000 0 [holl "SS"] 9 1011 5 $any_time 00010000 0 [holl "HA"] }" "AIS: Check permissions wrt non-enabled admin (read)" # Check hide author and secret permissions wrt other user kom_logout kom_login 7 "pw2" 0 send "2128 94\n" simple_expect "=2128 $any_num $any_num $any_num $any_num $any_num $any_num 2 { 7 1009 5 $any_time 00000000 0 [holl "S7"] 9 1011 0 $any_time 00010000 0 [holl "HA"] }" "AIS: Check permissions wrt normal user (read)" # Clear up garbage kom_logout kom_login 5 "gazonk" 0 kom_enable 255 send "2129 95 3 { 7 8 9 } 0 { }\n" simple_expect "=2129" send "2130 94\n" simple_expect "=2130 $any_num $any_num $any_num $any_num $any_num $any_num 0 \\*" # ============================================================ # Check enforcement of restrictions kom_logout kom_login 7 "pw2" 0 send "1999 86 [holl "Text 3"] 2 { 0 9 2 2 } 0 { }\n" simple_expect "=1999 4" "AI Create comment without items" send "2200 90 4\n" extracting_expect "=2200 ($any*) 0 \\*" text_stat 1 # Add conf-only to text # Add letterbox-only to text # Add system-only to text # Add text-only to text send "2201 92 4 0 { } 1 { 10001 00000000 0 [holl "FUBAR"] }\n" simple_expect "%2201 49 0" "AIR: Add conf-only to text (add)" send "2202 90 4\n" simple_expect "=2202 $text_stat 0 \\*" "AIR: Add conf-only to text (read)" send "2203 92 4 0 { } 1 { 10003 00000000 0 [holl "FUBAR"] }\n" simple_expect "%2203 49 0" "AIR: Add letterbox-only to text (add)" send "2204 90 4\n" simple_expect "=2204 $text_stat 0 \\*" "AIR: Add letterbox-only to text (read)" send "2205 92 4 0 { } 1 { 10000 00000000 0 [holl "FUBAR"] }\n" simple_expect "%2205 49 0" "AIR: Add system-only to text (add)" send "2206 90 4\n" simple_expect "=2206 $text_stat 0 \\*" "AIR: Add system-only to text (read)" send "2207 92 4 0 { } 1 { 10002 00000000 0 [holl "R1"] }\n" simple_expect "=2207" "AIR: Add text-only to text (add)" send "2208 90 4\n" simple_expect "=2208 $text_stat 1 { 1 10002 7 $any_time 00000000 0 [holl "R1"] }" "AIR: Add text-only to text (read)" # Add system-only to letterbox # Add conf-only to letterbox # Add text-only to letterbox # Add letterbox-only to letterbox send "2300 91 7\n" extracting_expect "=2300 ($any*) 0 \\*" conf_stat 1 send "2301 93 7 0 { } 1 { 10000 00000000 0 [holl "FUBAR"] }\n" simple_expect "%2301 49 0" "AIR: Adding system-only to letterbox (add)" send "2302 91 7\n" simple_expect "=2302 $conf_stat 0 \\*" "AIR: Adding system-only to letterbox (read)" send "2303 93 7 0 { } 1 { 10001 00000000 0 [holl "FUBAR"] }\n" simple_expect "%2303 49 0" "AIR: Adding conf-only to letterbox (add)" send "2304 91 7\n" simple_expect "=2304 $conf_stat 0 \\*" "AIR: Adding conf-only to letterbox (read)" send "2305 93 7 0 { } 1 { 10002 00000000 0 [holl "FUBAR"] }\n" simple_expect "%2305 49 0" "AIR: Adding text-only to letterbox (add)" send "2306 91 7\n" simple_expect "=2306 $conf_stat 0 \\*" "AIR: Adding text-only to letterbox (read)" send "2307 93 7 0 { } 1 { 10003 00000000 0 [holl "R2"] }\n" simple_expect "=2307" "AIR: Adding pers-only to letterbox (add)" send "2308 91 7\n" simple_expect "=2308 $conf_stat 1 { 1 10003 7 $any_time 00000000 0 [holl "R2"] }" "AIR: Adding pers-only to letterbox (read)" # Add text-only to conf # Add letterbox-only to conf # Add system-only to conf # Add conf-only to conf kom_create_conference "Conference 11" "00001000" "0 { }" "" "AIX: Create C11" send "2400 91 11\n" extracting_expect "=2400 ($any*) 0 \\*" conf_stat 1 send "2401 93 11 0 { } 1 { 10000 00000000 0 [holl "FUBAR"] }\n" simple_expect "%2401 49 0" "AIR: Adding system-only to conf (add)" send "2402 91 11\n" simple_expect "=2402 $conf_stat 0 \\*" "AIR: Adding system-only to conf (read)" send "2403 93 11 0 { } 1 { 10003 00000000 0 [holl "FUBAR"] }\n" simple_expect "%2403 49 0" "AIR: Adding pers-only to conf (add)" send "2404 91 11\n" simple_expect "=2404 $conf_stat 0 \\*" "AIR: Adding conf-only to conf (read)" send "2405 93 11 0 { } 1 { 10002 00000000 0 [holl "FUBAR"] }\n" simple_expect "%2405 49 0" "AIR: Adding text-only to conf (add)" send "2406 91 11\n" simple_expect "=2406 $conf_stat 0 \\*" "AIR: Adding text-only to conf (read)" send "2407 93 11 0 { } 1 { 10001 00000000 0 [holl "R3"] }\n" simple_expect "=2407" "AIR: Adding conf-only to conf (add)" send "2408 91 11\n" simple_expect "=2408 $conf_stat 1 { 1 10001 7 $any_time 00000000 0 [holl "R3"] }" "AIR: Adding conf-only to conf (read)" # Add text-only to system # Add conf-only to system # Add letterbox-only to system # Add system-only to system kom_logout kom_login 5 "gazonk" 0 kom_enable 255 send "2500 94\n" extracting_expect "=2500 ($any*) 0 \\*" info_struct 1 send "2501 95 0 { } 1 { 10003 00000000 0 [holl "FUBAR"] }\n" simple_expect "%2501 49 0" "AIR: Adding pers-only to system (add)" send "2502 94\n" simple_expect "=2502 $info_struct 0 \\*" "AIR: Adding pers-only to system (read)" send "2503 95 0 { } 1 { 10001 00000000 0 [holl "FUBAR"] }\n" simple_expect "%2503 49 0" "AIR: Adding conf-only to system (add)" send "2504 94\n" simple_expect "=2504 $info_struct 0 \\*" "AIR: Adding conf-only to system (read)" send "2505 95 0 { } 1 { 10002 00000000 0 [holl "FUBAR"] }\n" simple_expect "%2505 49 0" "AIR: Adding text-only to system (add)" send "2506 94\n" simple_expect "=2506 $info_struct 0 \\*" "AIR: Adding text-only to system (read)" send "2507 95 0 { } 1 { 10000 00000000 0 [holl "R4"] }\n" simple_expect "=2507" "AIR: Adding system-only to system (add)" send "2508 94\n" simple_expect "=2508 $info_struct 1 { 10 10000 5 $any_time 00000000 0 [holl "R4"] }" "AIR: Adding system-only to system (read)" # Check forcing of all bits # Check forcing of inherit-limit # Check validation of contents kom_logout kom_login 7 "pw2" 0 send "3000 86 [holl "Text 5"] 2 { 0 9 2 2 } 4 { 2000 00000000 1 [holl "SET"] 2001 11111111 0 [holl "CLR"] 2002 00000000 20 [holl "LIM"] 2002 00000000 1 [holl "ULM"] }\n" simple_expect "=3000 5" send "3001 90 5\n" extracting_expect "=3001 ($any*) 4 { 1 2000 7 $any_time 01111111 1 [holl "SET"] 2 2001 7 $any_time 00000000 0 [holl "CLR"] 3 2002 7 $any_time 00000000 10 [holl "LIM"] 4 2002 7 $any_time 00000000 1 [holl "ULM"] }" text_stat 1 # Clear out the junk send "3002 92 5 4 { 1 2 3 4 } 0 { }\n" simple_expect "=3002" send "3003 90 5\n" simple_expect "=3003 $text_stat 0 \\*" # Check content validation send "3004 92 5 0 { } 1 { 2003 00000000 1 [holl "FAIL"] }\n" simple_expect "%3004 48 0" send "3005 90 5\n" simple_expect "=3005 $text_stat 0 \\*" send "3005 92 5 0 { } 1 { 2003 00000000 0 [holl "GOOD"] }\n" simple_expect "=3005" send "3006 90 5\n" simple_expect "=3006 $text_stat 1 { 5 2003 7 $any_time 00000000 0 [holl "GOOD"] }" # Add author-only as author # Add cant-delete item # Add one-per-person as person A # Add item restricted to create text can be added on create kom_logout kom_login 7 "pw2" 0 send "4000 86 [holl "Text 6"] 2 { 0 9 2 2 } 4 { 2004 00000000 0 [holl "AO"] 2006 00000000 0 [holl "UQ"] 2007 00000000 0 [holl "PM"] 3000 00000000 0 [holl "CT"] }\n" simple_expect "=4000 6" send "4001 90 6\n" extracting_expect "=4001 ($any*) 4 { 1 2004 7 $any_time 00000000 0 [holl "AO"] 2 2006 7 $any_time 00000000 0 [holl "UQ"] 3 2007 7 $any_time 00000000 0 [holl "PM"] 4 3000 7 $any_time 00000000 0 [holl "CT"] }" text_stat 1 # Try to add second one-per-person item as person A send "4002 92 6 0 { } 1 { 2006 00000000 0 [holl "FUBAR"] }\n" simple_expect "%4002 49 0" send "4003 90 6\n" simple_expect "=4003 $text_stat 4 { 1 2004 7 $any_time 00000000 0 [holl "AO"] 2 2006 7 $any_time 00000000 0 [holl "UQ"] 3 2007 7 $any_time 00000000 0 [holl "PM"] 4 3000 7 $any_time 00000000 0 [holl "CT"] }" # Try to delete cant-delete item send "4004 92 6 1 { 3 } 0 { }\n" simple_expect "%4004 49 0" send "4005 90 6\n" simple_expect "=4005 $text_stat 4 { 1 2004 7 $any_time 00000000 0 [holl "AO"] 2 2006 7 $any_time 00000000 0 [holl "UQ"] 3 2007 7 $any_time 00000000 0 [holl "PM"] 4 3000 7 $any_time 00000000 0 [holl "CT"] }" # Try to add create-restricted item after create send "4006 92 6 0 { } 1 { 3000 00000000 0 [holl "FUBAR"] }\n" simple_expect "%4006 49 0" send "4007 90 6\n" simple_expect "=4007 $text_stat 4 { 1 2004 7 $any_time 00000000 0 [holl "AO"] 2 2006 7 $any_time 00000000 0 [holl "UQ"] 3 2007 7 $any_time 00000000 0 [holl "PM"] 4 3000 7 $any_time 00000000 0 [holl "CT"] }" # Log in as person 8 kom_logout kom_login 8 "pw3" 0 # Add two one-per-person at once send "4100 92 6 0 { } 2 { 2006 00000000 0 [holl "AOB1"] 2006 00000000 0 [holl "AOB2"] }\n" simple_expect "%4100 49 0" send "4101 90 6\n" simple_expect "=4101 $text_stat 4 { 1 2004 7 $any_time 00000000 0 [holl "AO"] 2 2006 7 $any_time 00000000 0 [holl "UQ"] 3 2007 7 $any_time 00000000 0 [holl "PM"] 4 3000 7 $any_time 00000000 0 [holl "CT"] }" # Add one-per-person as person B send "4102 92 6 0 { } 1 { 2006 00000000 0 [holl "AOB1"] }\n" simple_expect "=4102" send "4103 90 6\n" simple_expect "=4103 $text_stat 5 { 1 2004 7 $any_time 00000000 0 [holl "AO"] 2 2006 7 $any_time 00000000 0 [holl "UQ"] 3 2007 7 $any_time 00000000 0 [holl "PM"] 4 3000 7 $any_time 00000000 0 [holl "CT"] 5 2006 8 $any_time 00000000 0 [holl "AOB1"] }" # Add another one-per-person as person B send "4104 92 6 0 { } 1 { 2006 00000000 0 [holl "AOB1"] }\n" simple_expect "%4104 49 0" send "4105 90 6\n" simple_expect "=4105 $text_stat 5 { 1 2004 7 $any_time 00000000 0 [holl "AO"] 2 2006 7 $any_time 00000000 0 [holl "UQ"] 3 2007 7 $any_time 00000000 0 [holl "PM"] 4 3000 7 $any_time 00000000 0 [holl "CT"] 5 2006 8 $any_time 00000000 0 [holl "AOB1"] }" # Add author-only to item created by person 7 as person 8 (other person) send "4200 92 6 0 { } 1 { 2004 00000000 0 [holl "FUBAR"] }\n" simple_expect "%4200 49 0" send "4201 90 6\n" simple_expect "=4201 $text_stat 5 { 1 2004 7 $any_time 00000000 0 [holl "AO"] 2 2006 7 $any_time 00000000 0 [holl "UQ"] 3 2007 7 $any_time 00000000 0 [holl "PM"] 4 3000 7 $any_time 00000000 0 [holl "CT"] 5 2006 8 $any_time 00000000 0 [holl "AOB1"] }" # Add author-only to item created by person 7 as person 6 (supervisor) kom_logout kom_login 6 "pw1" 0 send "4202 92 6 0 { } 1 { 2004 00000000 0 [holl "AO2"] }\n" simple_expect "=4202" send "4203 90 6\n" simple_expect "=4203 $text_stat 6 { 1 2004 7 $any_time 00000000 0 [holl "AO"] 2 2006 7 $any_time 00000000 0 [holl "UQ"] 3 2007 7 $any_time 00000000 0 [holl "PM"] 4 3000 7 $any_time 00000000 0 [holl "CT"] 5 2006 8 $any_time 00000000 0 [holl "AOB1"] 6 2004 6 $any_time 00000000 0 [holl "AO2"] }" # Add author-only to item created by person 7 as person 5 (admin) kom_logout kom_login 5 "gazonk" 0 kom_enable 255 send "4204 92 6 0 { } 1 { 2004 00000000 0 [holl "AO3"] }\n" simple_expect "=4204" send "4205 90 6\n" simple_expect "=4205 $text_stat 7 { 1 2004 7 $any_time 00000000 0 [holl "AO"] 2 2006 7 $any_time 00000000 0 [holl "UQ"] 3 2007 7 $any_time 00000000 0 [holl "PM"] 4 3000 7 $any_time 00000000 0 [holl "CT"] 5 2006 8 $any_time 00000000 0 [holl "AOB1"] 6 2004 6 $any_time 00000000 0 [holl "AO2"] 7 2004 5 $any_time 00000000 0 [holl "AO3"] }" # Add supervisor-only to conf 7 item as person 7 kom_logout kom_login 7 "pw2" 0 send "4300 91 7\n" extracting_expect "=4300 ($any*) 1 { 1 10003 7 $any_time 00000000 0 [holl "R2"] }" conf_stat 1 send "4301 93 7 0 { } 1 { 2005 00000000 0 [holl "SO1"] }\n" simple_expect "%4301 49 0" send "4302 91 7\n" simple_expect "=4302 $conf_stat 1 { 1 10003 7 $any_time 00000000 0 [holl "R2"] }" # Add supervisor-only to conf 7 as person 6 kom_logout kom_login 6 "pw1" 0 send "4303 93 7 0 { } 1 { 2005 00000000 0 [holl "SO1"] }\n" simple_expect "=4303" send "4304 91 7\n" simple_expect "=4304 $conf_stat 2 { 1 10003 7 $any_time 00000000 0 [holl "R2"] 2 2005 6 $any_time 00000000 0 [holl "SO1"] }" # Add supervisor-only to conf 7 as person 5 kom_logout kom_login 5 "gazonk" 0 kom_enable 255 send "4305 93 7 0 { } 1 { 2005 00000000 0 [holl "SO2"] }\n" simple_expect "=4305" send "4306 91 7\n" simple_expect "=4306 $conf_stat 3 { 1 10003 7 $any_time 00000000 0 [holl "R2"] 2 2005 6 $any_time 00000000 0 [holl "SO1"] 3 2005 5 $any_time 00000000 0 [holl "SO2"] }" kom_logout kom_login 7 "pw2" 0 # Check that item restricted to create conf can be added on create # Try to add one after create kom_create_conference "Conference 12" "00001000" "1 { 3001 00000000 0 [holl "CC1"] }" send "4399 91 12\n" extracting_expect "=4399 ($any*)" conf_stat 1 send "4400 93 11 0 { } 1 { 3001 00000000 0 [holl "FUBAR"] }\n" simple_expect "%4400 49 0" send "4401 91 12\n" simple_expect "=4401 $conf_stat" # Check that item restricted to create letterbox can be added on create # Try to add one after create kom_create_person "User 13" "pw13" "00000000" "1 { 3002 00000000 0 [holl "CP1"] }" send "4402 91 13\n" extracting_expect "=4402 ($any*)" conf_stat 1 send "4403 93 13 0 { } 1 { 3002 00000000 0 [holl "FUBAR"] }\n" simple_expect "%4403 49 0" send "4404 91 13\n" simple_expect "=4404 $conf_stat" # Check that add trigger is called when adding an item # Check that delete trigger is called when deleting an item # Check that undelete trigger is called when adding and deleting where add fails send "4500 86 [holl "Text 7"] 1 { 0 9 } 0 { }\n" simple_expect "=4500 7" send "4501 90 7\n" simple_expect "=4501 $any_time 7 0 6 0 2 { 0 9 6 7 } 0 \\*" kom_create_conference "Conference 14" "00001000" "0 { }" send "4502 93 14 0 { } 1 { 4000 00000000 0 [holl "7"] }\n" simple_expect "=4502" send "4503 90 7\n" simple_expect "=4503 $any_time 7 0 6 1 2 { 0 9 6 7 } 0 \\*" send "4504 93 14 1 { 1 } 1 { 10000 00000000 0 [holl "FUBAR" ] }\n" simple_expect "%4504 49 0" send "4505 90 7\n" simple_expect "=4505 $any_time 7 0 6 1 2 { 0 9 6 7 } 0 \\*" send "4506 93 14 1 { 1 } 0 { }\n" simple_expect "=4506" send "4507 90 7\n" simple_expect "=4507 $any_time 7 0 6 0 2 { 0 9 6 7 } 0 \\*" kom_logout kom_login 5 "gazonk" 0 kom_enable 255 send "9999 44 0\n" simple_expect "=9999" client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/05.exp0000664000015100472110000004642507721716132016746 # Test suite for lyskomd. # Copyright (C) 1998-1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test of membership functionality # # Preconditions: # Person 5 exists, can enable to 255 and has password "gazonk" # read_versions source "$srcdir/config/prot-a.exp" # ---------------------------------------------------------------------- # startup_05 sets up the database and starts client 0 # # The sample database # # Person 6 "P6"; supervisor 6; password pw1 # Person 7 "P7"; supervisor 6; password pw2 # Person 8 "P8"; supervisor 7; password pw3 # Person 13 "P13"; supervisor 8; password pw4 # Person 14 "P14"; supervisor 14; password pw5 # Set supervisor of P8 to P14 # # Conference 9 "C9"; created by 7; rd_prot # Conference 10 "C10"; created by 7; secret # Conference 11 "C11"; created by 7; forbid_secret # Conference 12 "C12"; created by 7; no flags # ---------------------------------------------------------------------- proc startup_05 {} { client_start 0 talk_to client 0 send "A[holl "DejaGnu test suite"]\n" simple_expect "LysKOM" "MSHIP: Connected" kom_accept_async "0 { }" "" "MSHIP: accept-async" kom_create_person "P6" "pw1" "00000000" "0 { }" kom_login 6 "pw1" 0 kom_create_person "P7" "pw2" "00000000" "0 { }" kom_logout kom_create_person "P8" "pw3" "00000000" "0 { }" kom_logout kom_login 7 "pw2" 0 kom_create_conference "C9" "10000000" "0 { }" kom_create_conference "C10" "10100000" "0 { }" kom_create_conference "C11" "00000100" "0 { }" kom_create_conference "C12" "00000000" "0 { }" kom_logout kom_login 8 "pw3" 0 kom_create_person "P13" "pw4" "00000000" "0 { }" kom_logout kom_create_person "P14" "pw5" "00000000" "0 { }" kom_logout kom_login 5 "gazonk" 0 kom_enable 255 kom_set_supervisor 8 14 } proc shutdown_05 {} { kom_logout kom_login 5 "gazonk" 0 kom_enable 255 send "9999 44 0\n" simple_expect "=9999" client_death 0 lyskomd_death } lyskomd_start startup_05 # ---------------------------------------------------------------------- # Basic tests # # For each test perform the function then get the membership list for # the affected person and then the member list for the affected # conference. # ---------------------------------------------------------------------- # ---------------------------------------------------------------------- # 1. Person 7 becoming member of conference 9. kom_logout kom_login 7 "pw2" 0 send "1000 100 9 7 200 0 00000000\n" simple_expect "=1000" send "1001 101 9 0 10000\n" simple_expect "=1001 1 { 7 7 $any_time 00000000 }" send "1002 99 7 0 10000 0\n" simple_expect "=1002 2 { 0 $any_time 9 200 0 0 \\* 7 $any_time 00000000 1 $any_time 7 255 0 0 \\* 6 $any_time 00000000 }" # ---------------------------------------------------------------------- # 2. Person 7 adding person 8 as member of conference 9 as invitation kom_logout kom_login 7 "pw2" 0 send "1010 100 9 8 200 0 10000000\n" lyskomd_expect "Person 8 added to conference 9 by 7." simple_expect "=1010" send "1011 101 9 0 10000\n" simple_expect "=1011 2 { 7 7 $any_time 00000000 8 7 $any_time 10000000 }" send "1012 99 8 0 10000 0\n" simple_expect "=1012 2 { 0 $any_time 9 200 0 0 \\* 7 $any_time 10000000 1 $any_time 8 255 0 0 \\* 8 $any_time 00000000 }" # ---------------------------------------------------------------------- # 3. Person 8 changing type of membership to 00100000 (secret) kom_logout kom_login 8 "pw3" 0 send "1020 102 8 9 00100000\n" simple_expect "=1020" send "1021 101 9 0 10000\n" simple_expect "=1021 2 { 7 7 $any_time 00000000 8 7 $any_time 00100000 }" send "1022 99 8 0 10000 0\n" simple_expect "=1022 2 { 0 $any_time 9 200 0 0 \\* 7 $any_time 00100000 1 $any_time 8 255 0 0 \\* 8 $any_time 00000000 }" # ---------------------------------------------------------------------- # Try to convert conference 8 to forbid-secret. This should fail. kom_logout kom_login 7 "pw2" 0 send "1023 21 9 00000100\n" simple_expect "%1023 54 8" # ---------------------------------------------------------------------- # 4. Person 7 looking at membership of conference 9 # Person 7 looking at members of conference 9 # Membership of person 8 is not blanked out since person 7 is # organizer of conference 9 kom_logout kom_login 7 "pw2" 0 send "1030 101 9 0 10000\n" simple_expect "=1030 2 { 7 7 $any_time 00000000 8 7 $any_time 00100000 }" send "1031 99 8 0 10000 0\n" simple_expect "=1031 2 { 0 $any_time 9 200 0 0 \\* 7 $any_time 00100000 1 $any_time 8 255 0 0 \\* 8 $any_time 00000000 }" # ---------------------------------------------------------------------- # 5. Person 13 looking at members of conference 9 # Membership of person 8 is blanked out in get-members # Person 13 looking at membership of person 8 # Membership of person 8 is removed in get-membership kom_logout kom_login 13 "pw4" 0 send "1040 101 9 0 10000\n" simple_expect "=1040 2 { 7 7 $any_time 00000000 0 0 $epoch_time 00100000 }" send "1041 99 8 0 10000 0\n" simple_expect "=1041 1 { 0 $any_time 8 255 0 0 \\* 8 $any_time 00000000 }" # ---------------------------------------------------------------------- # 6. Admin looking at members of conference 9 # Admin looking at membership of person 8 kom_logout kom_login 5 "gazonk" 0 send "1050 101 9 0 10000\n" simple_expect "=1050 2 { 7 7 $any_time 00000000 0 0 $epoch_time 00100000 }" send "1051 99 8 0 10000 0\n" simple_expect "=1051 1 { 0 $any_time 8 255 0 0 \\* 8 $any_time 00000000 }" kom_enable 255 send "1052 101 9 0 10000\n" simple_expect "=1052 2 { 7 7 $any_time 00000000 8 7 $any_time 00100000 }" send "1053 99 8 0 10000 0\n" simple_expect "=1053 2 { 0 $any_time 9 200 0 0 \\* 7 $any_time 00100000 1 $any_time 8 255 0 0 \\* 8 $any_time 00000000 }" # ---------------------------------------------------------------------- # 7. Supervisor of P8 looking at membership of person 8 # Supervisor of P8 looking at members of conference 9 # Secret memberships should be visible kom_logout kom_login 14 "pw5" 0 send "1060 101 9 0 10000\n" simple_expect "=1060 2 { 7 7 $any_time 00000000 8 7 $any_time 00100000 }" send "1061 99 8 0 10000 0\n" simple_expect "=1061 2 { 0 $any_time 9 200 0 0 \\* 7 $any_time 00100000 1 $any_time 8 255 0 0 \\* 8 $any_time 00000000 }" # ---------------------------------------------------------------------- # 8. Test that we can't become a secret member of a forbid-secret conf # Test that we can't set mship-type to secret in a forbid-secret conf kom_logout kom_login 8 "pw3" 0 send "1070 100 11 8 201 0 00100000\n" simple_expect "%1070 54 0" send "1071 99 8 0 10000 0\n" simple_expect "=1071 2 { 0 $any_time 9 200 0 0 \\* 7 $any_time 00100000 1 $any_time 8 255 0 0 \\* 8 $any_time 00000000 }" send "1072 101 11 0 10000\n" simple_expect "%1072 19 0" # Become member send "1073 100 11 8 201 0 00000000\n" simple_expect "=1073" send "1074 99 8 0 10000 0\n" simple_expect "=1074 3 { 0 $any_time 11 201 0 0 \\* 8 $any_time 00000000 1 $any_time 9 200 0 0 \\* 7 $any_time 00100000 2 $any_time 8 255 0 0 \\* 8 $any_time 00000000 }" send "1075 101 11 0 10000\n" simple_expect "=1075 1 { 8 8 $any_time 00000000 }" # Change type send "1076 102 8 11 00100000\n" simple_expect "%1076 54 0" send "1077 99 8 0 10000 0\n" simple_expect "=1077 3 { 0 $any_time 11 201 0 0 \\* 8 $any_time 00000000 1 $any_time 9 200 0 0 \\* 7 $any_time 00100000 2 $any_time 8 255 0 0 \\* 8 $any_time 00000000 }" send "1078 101 11 0 10000\n" simple_expect "=1078 1 { 8 8 $any_time 00000000 }" # Ensure that admin cannot set an invalid type kom_logout kom_login 5 "gazonk" 0 kom_enable 255 send "1079 102 8 11 00100000\n" simple_expect "%1079 54 0" send "1079 99 8 0 10000 0\n" simple_expect "=1079 3 { 0 $any_time 11 201 0 0 \\* 8 $any_time 00000000 1 $any_time 9 200 0 0 \\* 7 $any_time 00100000 2 $any_time 8 255 0 0 \\* 8 $any_time 00000000 }" send "1079 101 11 0 10000\n" simple_expect "=1079 1 { 8 8 $any_time 00000000 }" # Ensure that supervisor cannot set an invalid type kom_logout kom_login 14 "pw5" 0 send "1080 102 8 11 00100000\n" simple_expect "%1080 54 0" send "1081 99 8 0 10000 0\n" simple_expect "=1081 3 { 0 $any_time 11 201 0 0 \\* 8 $any_time 00000000 1 $any_time 9 200 0 0 \\* 7 $any_time 00100000 2 $any_time 8 255 0 0 \\* 8 $any_time 00000000 }" send "1082 101 11 0 10000\n" simple_expect "=1082 1 { 8 8 $any_time 00000000 }" # ---------------------------------------------------------------------- # 9. Check that we can set membership type as supervisor # Check that we can set membership type as admin # Check that we cannot set membership type as conference supervisor kom_logout kom_login 14 "pw5" 0 send "1090 102 8 9 00000000\n" simple_expect "=1090" send "1091 101 9 0 10000\n" simple_expect "=1091 2 { 7 7 $any_time 00000000 8 7 $any_time 00000000 }" send "1092 99 8 0 10000 0\n" simple_expect "=1092 3 { 0 $any_time 11 201 0 0 \\* 8 $any_time 00000000 1 $any_time 9 200 0 0 \\* 7 $any_time 00000000 2 $any_time 8 255 0 0 \\* 8 $any_time 00000000 }" kom_logout kom_login 5 "gazonk" 0 kom_enable 255 send "1093 102 8 9 00100000\n" simple_expect "=1093" send "1094 101 9 0 10000\n" simple_expect "=1094 2 { 7 7 $any_time 00000000 8 7 $any_time 00100000 }" send "1095 99 8 0 10000 0\n" simple_expect "=1095 3 { 0 $any_time 11 201 0 0 \\* 8 $any_time 00000000 1 $any_time 9 200 0 0 \\* 7 $any_time 00100000 2 $any_time 8 255 0 0 \\* 8 $any_time 00000000 }" kom_logout kom_login 7 "pw2" 0 send "1096 102 8 9 00000000\n" simple_expect "%1096 12 8" send "1097 101 9 0 10000\n" simple_expect "=1097 2 { 7 7 $any_time 00000000 8 7 $any_time 00100000 }" send "1098 99 8 0 10000 0\n" simple_expect "=1098 3 { 0 $any_time 11 201 0 0 \\* 8 $any_time 00000000 1 $any_time 9 200 0 0 \\* 7 $any_time 00100000 2 $any_time 8 255 0 0 \\* 8 $any_time 00000000 }" # ---------------------------------------------------------------------- # Test various things related to server configuration shutdown_05 lyskomd_start "" \ "Add members by invitation: on Allow reinvitations: off Allow secret memberships: off Garb interval: 9999999 Sync interval: 9999999 " startup_05 # Test that we can force invitation bit kom_logout kom_login 8 "pw3" 0 send "2000 100 12 14 200 0 00000000\n" lyskomd_expect "Person 14 added to conference 12 by 8." simple_expect "=2000" send "2001 99 14 0 10000 0\n" simple_expect "=2001 2 { 0 $any_time 12 200 0 0 \\* 8 $any_time 10000000 1 $any_time 14 255 0 0 \\* 14 $any_time 00000000 }" send "2002 101 12 0 10000\n" simple_expect "=2002 1 { 14 8 $any_time 10000000 }" # Test that we can change membership-type without changing invitation kom_logout kom_login 14 "pw5" 0 send "2003 102 14 12 10000001\n" simple_expect "=2003" send "2004 99 14 0 10000 0\n" simple_expect "=2004 2 { 0 $any_time 12 200 0 0 \\* 8 $any_time 10000001 1 $any_time 14 255 0 0 \\* 14 $any_time 00000000 }" send "2005 101 12 0 10000\n" simple_expect "=2005 1 { 14 8 $any_time 10000001 }" # Test that we can clear invitation bit send "2006 102 14 12 00000000\n" simple_expect "=2006" send "2007 99 14 0 10000 0\n" simple_expect "=2007 2 { 0 $any_time 12 200 0 0 \\* 8 $any_time 00000000 1 $any_time 14 255 0 0 \\* 14 $any_time 00000000 }" send "2008 101 12 0 10000\n" simple_expect "=2008 1 { 14 8 $any_time 00000000 }" # Test that we can't set invitation bit send "2009 102 14 12 10000000\n" simple_expect "%2009 54 0" send "2010 99 14 0 10000 0\n" simple_expect "=2010 2 { 0 $any_time 12 200 0 0 \\* 8 $any_time 00000000 1 $any_time 14 255 0 0 \\* 14 $any_time 00000000 }" send "2011 101 12 0 10000\n" simple_expect "=2011 1 { 14 8 $any_time 00000000 }" # Test that we can't change a membership to a secret membership send "2009 102 14 12 00100000\n" simple_expect "%2009 54 0" send "2010 99 14 0 10000 0\n" simple_expect "=2010 2 { 0 $any_time 12 200 0 0 \\* 8 $any_time 00000000 1 $any_time 14 255 0 0 \\* 14 $any_time 00000000 }" send "2011 101 12 0 10000\n" simple_expect "=2011 1 { 14 8 $any_time 00000000 }" # Test that we can't create a secret membership kom_logout kom_login 8 "pw3" 0 send "2012 100 12 8 201 0 00100000\n" simple_expect "%2012 54 0" send "2013 99 8 0 10000 0\n" simple_expect "=2013 1 { 0 $any_time 8 255 0 0 \\* 8 $any_time 00000000 }" send "2014 101 12 0 10000\n" simple_expect "=2014 1 { 14 8 $any_time 00000000 }" # ====================================================================== # Test old-style calls shutdown_05 lyskomd_start "" "Add members by invitation: on Garb interval: 9999999 Sync interval: 9999999 " startup_05 # ---------------------------------------------------------------------- # Test old-style add-member kom_login 7 "pw2" 0 # Person 7 adds person 13 to conference 12 # Use new-style call to check that invitation bit is set send "3000 14 12 13 200 0\n" lyskomd_expect "Person 13 added to conference 12 by 7." simple_expect "=3000" send "3001 99 13 0 10000 0\n" simple_expect "=3001 2 { 0 $any_time 12 200 0 0 \\* 7 $any_time 10000000 1 $any_time 13 255 0 0 \\* 8 $any_time 00000000 }" send "3002 101 12 0 10000\n" simple_expect "=3002 1 { 13 7 $any_time 10000000 }" # Remove person 13 from conference 12 send "3003 15 12 13\n" simple_expect "=3003" send "3004 99 13 0 10000 0\n" simple_expect "=3004 1 { 0 $any_time 13 255 0 0 \\* 8 $any_time 00000000 }" send "3005 101 12 0 10000\n" simple_expect "%3005 19 0" # Person 8 adds person 13 to conference 12 # Use new-style call to check that invitation bit is unset kom_logout kom_login 8 "pw3" 0 send "3010 14 12 13 201 0\n" lyskomd_expect "Person 13 added to conference 12 by 8." simple_expect "=3010" send "3011 99 13 0 10000 0\n" simple_expect "=3011 2 { 0 $any_time 12 201 0 0 \\* 8 $any_time 00000000 1 $any_time 13 255 0 0 \\* 8 $any_time 00000000 }" send "3012 101 12 0 10000\n" simple_expect "=3012 1 { 13 8 $any_time 00000000 }" # Remove person 13 from conference 12 send "3013 15 12 13\n" simple_expect "=3013" send "3014 99 13 0 10000 0\n" simple_expect "=3014 1 { 0 $any_time 13 255 0 0 \\* 8 $any_time 00000000 }" send "3015 101 12 0 10000\n" simple_expect "%3015 19 0" # Person 5 adds person 13 to conference 12 # Use new-style call to check that invitation bit is unset kom_logout kom_login 5 "gazonk" 0 kom_enable 255 send "3020 14 12 13 202 0\n" lyskomd_expect "Person 13 added to conference 12 by 5." simple_expect "=3020" send "3021 99 13 0 10000 0\n" simple_expect "=3021 2 { 0 $any_time 12 202 0 0 \\* 5 $any_time 00000000 1 $any_time 13 255 0 0 \\* 8 $any_time 00000000 }" send "3022 101 12 0 10000\n" simple_expect "=3022 1 { 13 5 $any_time 00000000 }" # Remove person 13 from conference 12 send "3023 15 12 13\n" simple_expect "=3023" send "3024 99 13 0 10000 0\n" simple_expect "=3024 1 { 0 $any_time 13 255 0 0 \\* 8 $any_time 00000000 }" send "3025 101 12 0 10000\n" simple_expect "%3025 19 0" # Person 13 adds person 13 to conference 12 # Use new-style call to check that invitation bit is unset kom_logout kom_login 13 "pw4" 0 send "3030 14 12 13 203 0\n" simple_expect "=3030" send "3031 99 13 0 10000 0\n" simple_expect "=3031 2 { 0 $any_time 12 203 0 0 \\* 13 $any_time 00000000 1 $any_time 13 255 0 0 \\* 8 $any_time 00000000 }" send "3032 101 12 0 10000\n" simple_expect "=3032 1 { 13 13 $any_time 00000000 }" # ---------------------------------------------------------------------- # Test old-style get-members # Person 13 sets passive bit of membership in conference 12 # Use old-style get-members on conference 12 # Use old-style get-membership on conference 12 kom_logout kom_login 13 "pw4" 0 send "3100 102 13 12 01000000\n" simple_expect "=3100" send "3101 48 12 0 10000\n" simple_expect "=3101 1 { 13 }" send "3102 46 13 0 10000 0\n" simple_expect "=3102 2 { $any_time 12 0 0 0 \\* $any_time 13 255 0 0 \\* }" # Person 13 unsets passive bit of membership in conference 12 # Check that actual priority is now visible send "3103 102 13 12 00000000\n" simple_expect "=3103" send "3104 48 12 0 10000\n" simple_expect "=3104 1 { 13 }" send "3105 46 13 0 10000 0\n" simple_expect "=3105 2 { $any_time 12 203 0 0 \\* $any_time 13 255 0 0 \\* }" # Use old-style add-member to change priority to 0 # Old-style calls should return same as previous test # New-style get-membership should show passive bit set but priority unchanged # New-style get-members should show passive bit set send "3200 14 12 13 0 0\n" simple_expect "=3200" send "3201 48 12 0 10000\n" simple_expect "=3201 1 { 13 }" send "3202 46 13 0 10000 0\n" simple_expect "=3202 2 { $any_time 12 0 0 0 \\* $any_time 13 255 0 0 \\* }" send "3203 99 13 0 10000 0\n" simple_expect "=3203 2 { 0 $any_time 12 203 0 0 \\* 13 $any_time 01000000 1 $any_time 13 255 0 0 \\* 8 $any_time 00000000 }" send "3204 101 12 0 10000\n" simple_expect "=3204 1 { 13 13 $any_time 01000000 }" # ---------------------------------------------------------------------- # Prepare to test get-unread-confs and query-read-texts # This setup assumes that set-membership-type, add-member and # create-text work. kom_logout kom_login 13 "pw4" 0 send "3300 102 13 12 00000000\n" simple_expect "=3300" send "3301 100 11 13 200 255 00000000\n" simple_expect "=3301" send "3302 86 [holl "Unread 1"] 1 { 0 12 } 0 { }\n" simple_expect "=3302 1" send "3303 86 [holl "Unread 2"] 1 { 0 11 } 0 { }\n" simple_expect "=3303 2" # ---------------------------------------------------------------------- # Test get-unread-confs kom_logout kom_login 13 "pw4" 0 send "3310 52 13\n" simple_expect "=3310 2 { 12 11 }" send "3311 102 13 12 01000000\n" simple_expect "=3311" send "3312 52 13\n" simple_expect "=3312 1 { 11 }" send "3313 102 13 11 01000000\n" simple_expect "=3313" send "3314 52 13\n" simple_expect "=3314 0 \\*" send "3315 102 13 12 00000000\n" simple_expect "=3315" send "3316 52 13\n" simple_expect "=3316 1 { 12 }" send "3317 102 13 11 00000000\n" simple_expect "=3317" send "3318 52 13\n" simple_expect "=3318 2 { 12 11 }" # ---------------------------------------------------------------------- # Test query-read-texts wrt membership positions send "3400 99 13 0 10000 0\n" simple_expect "=3400 3 { 0 $any_time 12 203 0 0 \\* 13 $any_time 00000000 1 $any_time 13 255 0 0 \\* 8 $any_time 00000000 2 $any_time 11 200 0 0 \\* 13 $any_time 00000000 }" send "3401 98 13 12\n" simple_expect "=3401 0 $any_time 12 203 0 0 \\* 13 $any_time 00000000" send "3402 98 13 13\n" simple_expect "=3402 1 $any_time 13 255 0 0 \\* 8 $any_time 00000000" send "3403 98 13 11\n" simple_expect "=3403 2 $any_time 11 200 0 0 \\* 13 $any_time 00000000" # ---------------------------------------------------------------------- # We're finished # ---------------------------------------------------------------------- shutdown_05 lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/06.exp0000664000015100472110000003430207721716132016736 # Test suite for lyskomd. # Copyright (C) 1998-1999, 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test of protocol 10 async messages and session issues # # Preconditions: # Person 5 exists, can enable to 255 and has password "gazonk" # Membership functions work # read_versions source "$srcdir/config/prot-a.exp" # ---------------------------------------------------------------------- # startup_06 sets up the database and starts client 0 # # The sample database # # Person 6 "P6"; supervisor 6; password pw1 # Person 7 "P7"; supervisor 6; password pw2 # Person 8 "P8"; supervisor 7; password pw3 # Person 13 "P13"; supervisor 8; password pw4 # Person 14 "P14"; supervisor 14; password pw5 # Set supervisor of P8 to P14 # # Conference 9 "C9"; created by 7; rd_prot # Conference 10 "C10"; created by 7; secret # Conference 11 "C11"; created by 7; forbid_secret # Conference 12 "C12"; created by 7; no flags # # Person 8 is a member of conference 12 # Person 13 is a passive member of conference 12 # # Client 0 is logged on as person 8 # Client 1 is logged on as person 13 # Client 2 is logged on as person 5 with all bits enabled # Client 3 is logged on as person 8 # # No clients are accepting async messages # ---------------------------------------------------------------------- proc startup_06 {} { client_start 0 talk_to client 0 send "A[holl "DejaGnu test suite 1"]\n" simple_expect "LysKOM" kom_accept_async "0 { }" # Set up some users kom_create_person "P6" "pw1" "00000000" "0 { }" kom_login 6 "pw1" 0 kom_create_person "P7" "pw2" "00000000" "0 { }" kom_logout kom_create_person "P8" "pw3" "00000000" "0 { }" # Set up conferences kom_logout kom_login 7 "pw2" 0 kom_create_conference "C9" "10000000" "0 { }" kom_create_conference "C10" "10100000" "0 { }" kom_create_conference "C11" "00000100" "0 { }" kom_create_conference "C12" "00000000" "0 { }" # Set up more users kom_logout kom_login 8 "pw3" 0 kom_create_person "P13" "pw4" "00000000" "0 { }" kom_logout kom_create_person "P14" "pw5" "00000000" "0 { }" kom_logout kom_login 5 "gazonk" 0 kom_enable 255 kom_set_supervisor 8 14 # Set up memberships kom_logout kom_login 8 "pw3" 0 kom_add_member 12 8 200 0 "00000000" kom_logout kom_login 13 "pw4" 0 kom_add_member 12 13 200 0 "01000000" # Set up the clients # talk_to client 0 kom_logout kom_login 8 "pw3" 0 client_start 1 talk_to client 1 send "A[holl "DejaGnu test suite 2"]\n" simple_expect "LysKOM" kom_accept_async "0 { }" kom_login 13 "pw4" 0 client_start 2 talk_to client 2 send "A[holl "DejaGnu test suite 3"]\n" simple_expect "LysKOM" kom_accept_async "0 { }" kom_login 5 "gazonk" 0 kom_enable 255 client_start 3 talk_to client 3 send "A[holl "DejaGnu test suite 2"]\n" simple_expect "LysKOM" kom_accept_async "0 { }" kom_login 8 "pw3" 0 } proc shutdown_06 {} { talk_to client 0 kom_accept_async "0 { }" talk_to client 1 kom_accept_async "0 { }" talk_to client 2 kom_accept_async "0 { }" talk_to client 3 kom_accept_async "0 { }" talk_to client 1 kom_logout talk_to client 2 kom_logout talk_to client 3 kom_logout talk_to client 0 kom_logout kom_login 5 "gazonk" 0 kom_enable 255 send "9999 44 0\n" simple_expect "=9999" client_death 0 client_death 1 client_death 2 client_death 3 lyskomd_death } lyskomd_start startup_06 # ====================================================================== # Test new-text message # ---------------------------------------------------------------------- # Set up accept-async talk_to client 0 kom_accept_async "13 { 5 6 7 8 9 11 12 13 14 15 16 17 18 }\n" talk_to client 1 kom_accept_async "13 { 5 6 7 8 9 11 12 13 14 15 16 17 18 }\n" talk_to client 2 kom_accept_async "13 { 5 6 7 8 9 11 12 13 14 15 16 17 18 }\n" talk_to client 3 kom_accept_async "12 { 5 6 7 8 9 11 12 13 14 16 17 18 }\n" # ---------------------------------------------------------------------- # Create a text in client 2 # Check that message is not sent to non-member talk_to client 2 send "1000 86 [holl "Async test 1"] 1 { 0 12 } 0 { }\n" simple_expect "=1000 1" # Check that message is not sent to passive member talk_to client 1 kom_ping_server # Check that message is sent to active member talk_to client 0 simple_expect ":18 15 1 $any_time 5 0 12 0 2 { 0 12 6 1 } 0 \\*" kom_ping_server # Check that message is blocked by accept-async talk_to client 3 kom_ping_server # ====================================================================== # Test new-text-old message # ---------------------------------------------------------------------- # Set up accept-async talk_to client 0 kom_accept_async "13 { 0 5 6 7 8 9 11 12 13 14 16 17 18 }\n" talk_to client 1 kom_accept_async "13 { 0 5 6 7 8 9 11 12 13 14 16 17 18 }\n" talk_to client 2 kom_accept_async "13 { 0 5 6 7 8 9 11 12 13 14 16 17 18 }\n" talk_to client 3 kom_accept_async "12 { 5 6 7 8 9 11 12 13 14 16 17 18 }\n" # ---------------------------------------------------------------------- # Create a text in client 2 # Check that message is not sent to non-member talk_to client 2 send "1010 86 [holl "Async test 1"] 1 { 0 12 } 0 { }\n" simple_expect "=1010 2" # Check that message is not sent to passive member talk_to client 1 kom_ping_server # Check that message is sent to active member talk_to client 0 simple_expect ":16 0 2 $any_time 5 0 12 0 2 { 0 12 6 2 }" kom_ping_server # Check that message is blocked by accept-async talk_to client 3 kom_ping_server # ====================================================================== # Test new-text-old message # ---------------------------------------------------------------------- # Set up accept-async talk_to client 0 kom_accept_async "14 { 0 5 6 7 8 9 11 12 13 14 15 16 17 18 }\n" talk_to client 1 kom_accept_async "14 { 0 5 6 7 8 9 11 12 13 14 15 16 17 18 }\n" talk_to client 2 kom_accept_async "14 { 0 5 6 7 8 9 11 12 13 14 15 16 17 18 }\n" talk_to client 3 kom_accept_async "13 { 0 5 6 7 8 9 11 12 13 15 16 17 18 }\n" # ---------------------------------------------------------------------- # Delete a text in client 2 # Check that the message is not sent to a non-member talk_to client 2 send "1020 29 1\n" simple_expect "=1020" # Check that the message is not sent to a passive member talk_to client 1 kom_ping_server # Check that message is sent to active member talk_to client 0 simple_expect ":18 14 1 $any_time 5 0 12 0 2 { 0 12 6 1 } 0 \\*" kom_ping_server # Check that message is blocked by accept-async talk_to client 3 kom_ping_server # ====================================================================== # Test new-recipient message # ---------------------------------------------------------------------- # Set up accept-async talk_to client 0 kom_accept_async "14 { 0 5 6 7 8 9 11 12 13 14 15 16 17 18 }\n" talk_to client 1 kom_accept_async "14 { 0 5 6 7 8 9 11 12 13 14 15 16 17 18 }\n" talk_to client 2 kom_accept_async "14 { 0 5 6 7 8 9 11 12 13 14 15 16 17 18 }\n" talk_to client 3 kom_accept_async "13 { 0 5 6 7 8 9 11 12 13 14 15 17 18 }\n" # ---------------------------------------------------------------------- # Add a recipient to text 1 in client 2 # Check that the message is not sent to a non-member talk_to client 2 send "1030 30 2 9 0\n" simple_expect "=1030" # Check that the message is not sent to a passive member talk_to client 1 kom_ping_server # Check that message is sent to active member talk_to client 0 simple_expect ":3 16 2 9 0" kom_ping_server # Check that message is blocked by accept-async talk_to client 3 kom_ping_server # ---------------------------------------------------------------------- # Change recipient type of conference 9 / text 1 in client 2 # Check that the message is not sent to a non-member talk_to client 2 send "1031 30 2 9 1\n" simple_expect "=1031" # Check that the message is not sent to a passive member talk_to client 1 kom_ping_server # Check that message is sent to active member talk_to client 0 simple_expect ":3 16 2 9 1" kom_ping_server # Check that message is blocked by accept-async talk_to client 3 kom_ping_server # ---------------------------------------------------------------------- # Add a BCC recipient to text one in client 2 talk_to client 2 send "1032 30 2 5 15\n" simple_expect ":3 16 2 5 15" simple_expect "=1032" # Check that the message is not sent to any non-members of 5 talk_to client 1 kom_ping_server talk_to client 0 kom_ping_server talk_to client 3 kom_ping_server # ====================================================================== # Test sub-recipient message # ---------------------------------------------------------------------- # Set up accept-async talk_to client 0 kom_accept_async "14 { 0 5 6 7 8 9 11 12 13 14 15 16 17 18 }\n" talk_to client 1 kom_accept_async "14 { 0 5 6 7 8 9 11 12 13 14 15 16 17 18 }\n" talk_to client 2 kom_accept_async "14 { 0 5 6 7 8 9 11 12 13 14 15 16 17 18 }\n" talk_to client 3 kom_accept_async "13 { 0 5 6 7 8 9 11 12 13 14 15 16 18 }\n" # ---------------------------------------------------------------------- # Remove a BCC recipient # Check that no message is sent to non-members of the BCC recipient talk_to client 2 send "1039 31 2 5\n" simple_expect ":3 17 2 5 15" simple_expect "=1039" talk_to client 0 kom_ping_server talk_to client 1 kom_ping_server talk_to client 3 kom_ping_server # ---------------------------------------------------------------------- # Remove a recipient of text 1 in client 2 # Check that the message is not sent to a non-member talk_to client 2 send "1040 31 2 9\n" simple_expect "=1040" # Check that the message is not sent to a passive member talk_to client 1 kom_ping_server # Check that message is sent to active member talk_to client 0 simple_expect ":3 17 2 9 1" kom_ping_server # Check that message is blocked by accept-async talk_to client 3 kom_ping_server # ====================================================================== # Test new-membership message # ---------------------------------------------------------------------- # Set up accept-async talk_to client 0 kom_accept_async "14 { 0 5 6 7 8 9 11 12 13 14 15 16 17 18 }\n" talk_to client 1 kom_accept_async "14 { 0 5 6 7 8 9 11 12 13 14 15 16 17 18 }\n" talk_to client 2 kom_accept_async "14 { 0 5 6 7 8 9 11 12 13 14 15 16 17 18 }\n" talk_to client 3 kom_accept_async "13 { 0 5 6 7 8 9 11 12 13 14 15 16 17 }\n" # ---------------------------------------------------------------------- # Admin adds a membership to person 8 # Check that no async message is sent to others talk_to client 2 send "1050 100 9 8 201 0 00000000\n" lyskomd_expect "Person 8 added to conference 9 by 5." simple_expect "=1050" # Check that async message is not sent to supervisor talk_to client 1 kom_ping_server # Check that async message is sent to person talk_to client 0 simple_expect ":2 18 8 9" kom_ping_server # Check that accept-async can block the message talk_to client 3 kom_ping_server # ---------------------------------------------------------------------- # Admin changes membership of person 8 in conference 12 # Check that no async message is sent to others talk_to client 2 send "1051 100 9 8 202 0 00000000\n" simple_expect "=1051" # Check that async message is not sent to supervisor talk_to client 1 kom_ping_server # Check that async message is not sent to person talk_to client 0 kom_ping_server # Check that accept-async can block the message talk_to client 3 kom_ping_server # ---------------------------------------------------------------------- # Test that new-name messages are sent to the appropriate recipients talk_to client 0 kom_accept_async "1 { 5 }" talk_to client 1 kom_accept_async "1 { 5 }" talk_to client 2 kom_accept_async "1 { 5 }" talk_to client 3 kom_accept_async "1 { 5 }" talk_to client 3 kom_login 7 "pw2" 0 talk_to client 2 send "1060 3 10 [holl "NN"]\n" simple_expect ":3 5 10 [holl "C10"] [holl "NN"]" simple_expect "=1060" talk_to client 1 kom_ping_server talk_to client 0 kom_ping_server talk_to client 3 simple_expect ":3 5 10 [holl "C10"] [holl "NN"]" kom_ping_server talk_to client 3 send "1061 3 10 [holl "C10"]\n" simple_expect ":3 5 10 [holl "NN"] [holl "C10"]" simple_expect "=1061" talk_to client 0 kom_ping_server talk_to client 1 kom_ping_server talk_to client 2 simple_expect ":3 5 10 [holl "NN"] [holl "C10"]" kom_ping_server # ====================================================================== # Test session issues # ------------------------------------------------------------ # Test interpretation of session 0 except for disconnect # disconnect HAS been tested. client_start 4 talk_to client 4 kom_connect "Session Tester" kom_accept_async "0 { }" send "2000 56\n" extracting_expect "=2000 ($any_num)" session_no 1 kom_login 8 "pw3" 0 send "2001 54 0\n" simple_expect "=2001 8 0 $session_no 0H $hollerith $any_num $any_time" send "2002 64 0\n" simple_expect "=2002 8 0 $session_no 0H $hollerith $hollerith $hollerith $any_num $any_time" send "2003 69 [holl "DejaGnu Test Suite"] [holl "2-0"]\n" simple_expect "=2003" send "2004 70 0\n" simple_expect "=2004 [holl "DejaGnu Test Suite"]" send "2005 71 0\n" simple_expect "=2005 [holl "2-0"]" send "2006 55 0\n" simple_expect "=2006" client_death 4 # ====================================================================== shutdown_06 lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/07.exp0000664000015100472110000000777307721716132016753 # Test suite for lyskomd. # Copyright (C) 1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test what happens when too many clients try to connect. lyskomd_start "" "Open files: [expr $PROTECTED_FDS + 5]" # fd 13 client_start 1 talk_to client 1 send "A3Hone\n" simple_expect "LysKOM" "one up" # fd 14 client_start 2 talk_to client 2 send "A3Htwo\n" simple_expect "LysKOM" "two up" # fd 15 client_start 3 talk_to client 3 send "A5Hthree\n" simple_expect "LysKOM" "three up" # fd 16 client_start 4 talk_to client 4 send "A4Hfour\n" simple_expect "LysKOM" "four up" # fd 17 -- not available client_start 5 talk_to client 5 simple_expect "%% No connections left." "five closing down" client_death 5 talk_to client 1 simple_expect ":0 11" talk_to client 2 simple_expect ":0 11" talk_to client 3 simple_expect ":0 11" talk_to client 4 simple_expect ":0 11" # fd 17 -- still not available client_start 6 talk_to client 6 simple_expect "%% No connections left." "six closing down" client_death 6 # The server sends at most one ":0 11" per minute. This test *should* # never take more than a minute, so don't expect any ":0 11" here. ## ## talk_to client 1 ## simple_expect ":0 11" ## talk_to client 2 ## simple_expect ":0 11" ## talk_to client 3 ## simple_expect ":0 11" ## talk_to client 4 ## simple_expect ":0 11" # Shut down fd 15 talk_to client 3 send "1 55 3\n" simple_expect "=1" # simple_expect ":2 13 0 3" client_death 3 talk_to client 1 # simple_expect ":2 13 0 3" talk_to client 2 # simple_expect ":2 13 0 3" talk_to client 4 # simple_expect ":2 13 0 3" # fd 15 client_start 7 talk_to client 7 send "A5Hseven\n" simple_expect "LysKOM" "seven up" # fd 17 -- not available again client_start 8 talk_to client 8 simple_expect "%% No connections left." "eight closing down" client_death 8 # We don't get these messages, since they are only sent at most once # per 60 seconds. ## ## talk_to client 1 ## simple_expect ":0 11" ## talk_to client 2 ## simple_expect ":0 11" ## talk_to client 4 ## simple_expect ":0 11" ## talk_to client 7 ## simple_expect ":0 11" # Check that everything is up talk_to client 1 send "31 56\n" simple_expect "=31 1" talk_to client 2 send "32 56\n" simple_expect "=32 2" talk_to client 4 send "33 56\n" simple_expect "=33 4" talk_to client 7 send "34 56\n" simple_expect "=34 5" # shut 'em all down talk_to client 1 send "2 55 0\n" simple_expect "=2" # simple_expect ":2 13 0 1" client_death 1 talk_to client 2 # simple_expect ":2 13 0 1" talk_to client 4 # simple_expect ":2 13 0 1" talk_to client 7 # simple_expect ":2 13 0 1" talk_to client 2 send "20 55 0\n" simple_expect "=20" # simple_expect ":2 13 0 2" client_death 2 talk_to client 4 # simple_expect ":2 13 0 2" talk_to client 7 # simple_expect ":2 13 0 2" talk_to client 4 send "24 55 0\n" simple_expect "=24" # simple_expect ":2 13 0 4" client_death 4 talk_to client 7 # simple_expect ":2 13 0 4" talk_to client 7 send "27 55 0\n" simple_expect "=27" # simple_expect ":2 13 0 5" client_death 7 client_start 8 talk_to client 8 send "B\n" simple_expect "%%LysKOM unsupported protocol\\." client_death 8 # Test shutdown via a signal system "kill -TERM $lyskomd_pid" lyskomd_death "" signal lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/08.exp0000664000015100472110000000420407721716132016736 # Test suite for lyskomd. # Copyright (C) 1999, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Increase coverage of src/libraries/libcommon/parser.c lyskomd_start client_start 0 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" "connected" # Log in send "1000 0 5 [holl gazonk]\n" simple_expect ":2 9 5 1" "0=login-old caused a login async msg" simple_expect "=1000" "0=login-old succeeded" # Create a few conferences send "1001 10 [holl "Using (the) HURD"] 0000\n" simple_expect "=1001 6" send "1002 10 [holl "Hi! :-)"] 0000\n" simple_expect "=1002 7" send "1003 10 [holl "1 2 3 4 5 6 7 8 9"] 0000\n" simple_expect "=1003 8" send "1004 10 [holl "1 2 3 4 5 6 7 8 9 10"] 0000\n" simple_expect "=1004 9" send "1005 10 [holl "1 2 3 4 5 6 7 8 9 10 11"] 0000\n" simple_expect "=1005 10" send "1006 12 [holl ""]\n" simple_expect "=1006 10 { 1 2 3 4 5 6 7 8 9 10 } { 0000 0000 0000 0000 1001 0000 0000 0000 0000 0000 }" send "1007 12 [holl "1 2 3"]\n" simple_expect "=1007 3 { 8 9 10 } { 0000 0000 0000 }" send "1008 12 [holl "1 2 3 4 5 6 7 8 9 10"]\n" simple_expect "=1008 2 { 9 10 } { 0000 0000 }" # Shut down the server. talk_to client 0 send "1009 42 255\n" simple_expect "=1009" "42=enable succeeded" send "1010 44 0\n" simple_expect "=1010" "44=shutdown-kom succeeded" client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/09.exp0000664000015100472110000003655007721716132016750 # Test suite for lyskomd. # Copyright (C) 1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test the filtering of texts. # # Three players are used: # client 0 person 5 enabled # client 1 person 5 not enabled # client 2 person 6 innocent bystander; no privileges # # Conferences: # conference 7 public; created by 5; person 5 and 6 are members # conference 8 secret; created by 5; person 5 is member # conference 9 secret; created by 6; person 6 is member # lyskomd_start # Establish the sessions and log in. client_start 0 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" "connected" send "1000 80 6 { 0 14 15 16 17 18 }\n" simple_expect "=1000" if {$debug_calls} { send "2000 80 7 { 0 14 15 16 17 18 1000 }\n" simple_expect "=2000" } # Client 0 is logged on as person 5 with privs enabled send "1001 0 5 [holl gazonk]\n" simple_expect "=1001" send "1002 42 255\n" simple_expect "=1002" # Client 1 is logged on as person 5 without privs enabled client_start 1 talk_to client 1 send "A3Hbar\n" simple_expect "LysKOM" "connected" send "1003 80 6 { 0 14 15 16 17 18 }\n" simple_expect "=1003" send "1004 0 5 [holl gazonk]\n" simple_expect "=1004" # Client 2 is logged on as person 6 client_start 2 talk_to client 2 send "A6Hgazonk\n" simple_expect "LysKOM" "connected" send "1005 80 6 { 0 14 15 16 17 18 }\n" simple_expect "=1005" send "1006 89 [holl "Unprivileged"] [holl "citronfromage"] 10000000 0 { }\n" simple_expect "=1006 6" send "1007 0 6 [holl citronfromage]\n" simple_expect "=1007" # Create the conferences # Conference 7 is open, created by person 5 # Conference 8 is secret, created by person 5 # Conference 9 is secret, created by person 6 talk_to client 0 send "1008 88 [holl "conf 7"] 00001000 0 { }\n" simple_expect "=1008 7" send "1009 88 [holl "conf 8"] 10101100 0 { }\n" simple_expect "=1009 8" talk_to client 2 send "1010 88 [holl "conf 9"] 10101100 0 { }\n" simple_expect "=1010 9" # Join the conferences # Person 5 is a member of conference 7, 8 # Person 6 is a member of conference 7, 9 talk_to client 1 send "1011 100 7 5 200 1 00000000\n" simple_expect ":2 18 5 7" talk_to client 0 simple_expect ":2 18 5 7" talk_to client 1 simple_expect "=1011" send "1012 100 8 5 200 2 00000000\n" simple_expect ":2 18 5 8" talk_to client 0 simple_expect ":2 18 5 8" talk_to client 1 simple_expect "=1012" talk_to client 2 send "1013 100 7 6 200 1 00000000\n" simple_expect ":2 18 6 7" simple_expect "=1013" send "1014 100 9 6 200 2 00000000\n" simple_expect ":2 18 6 9" simple_expect "=1014" # Create a few texts which are partly secret # Text 1: created by 5 (session 0) # rcpt 7<1> # rcpt 8<1> (secret to client 2) # bcc 6<1> # aux 1: 20000 secret # aux 2: 20001 public talk_to client 0 send "1015 86 [holl "text 1"] 3 { 0 7 0 8 15 6 } 2 { 20000 00100000 1 [holl "priv"] 20001 00000000 1 [holl "pub"] }\n" extracting_expect ":16 0 1 ($any_time) 5 0 6 0 6 { 0 7 6 1 0 8 6 1 1 6 6 1 }" time_1 1 simple_expect ":18 15 1 $time_1 5 0 6 0 6 { 0 7 6 1 0 8 6 1 15 6 6 1 } 2 { 1 20000 5 $time_1 00100000 1 [holl "priv"] 2 20001 5 $time_1 00000000 1 [holl "pub"] }" talk_to client 1 simple_expect ":16 0 1 $time_1 5 0 6 0 6 { 0 7 6 1 0 8 6 1 1 6 6 1 }" simple_expect ":18 15 1 $time_1 5 0 6 0 6 { 0 7 6 1 0 8 6 1 15 6 6 1 } 2 { 1 20000 5 $time_1 00100000 1 [holl "priv"] 2 20001 5 $time_1 00000000 1 [holl "pub"] }" talk_to client 2 simple_expect ":16 0 1 $time_1 5 0 6 0 4 { 0 7 6 1 1 6 6 1 }" simple_expect ":18 15 1 $time_1 5 0 6 0 4 { 0 7 6 1 15 6 6 1 } 1 { 2 20001 5 $time_1 00000000 1 [holl "pub"] }" talk_to client 0 simple_expect "=1015 1" # Text 2: created by 5 (session 0) # rcpt 7<2> # rcpt 8<2> # bcc 6<2> # aux 1: 20000 secret # aux 2: 20001 public talk_to client 0 send "1016 86 [holl "text 2"] 3 { 0 7 0 8 15 6 } 2 { 20000 00100000 1 [holl "priv"] 20001 00000000 1 [holl "pub"] }\n" extracting_expect ":16 0 2 ($any_time) 5 0 6 0 6 { 0 7 6 2 0 8 6 2 1 6 6 2 }" time_2 1 simple_expect ":18 15 2 $time_2 5 0 6 0 6 { 0 7 6 2 0 8 6 2 15 6 6 2 } 2 { 1 20000 5 $time_2 00100000 1 [holl "priv"] 2 20001 5 $time_2 00000000 1 [holl "pub"] }" talk_to client 1 simple_expect ":16 0 2 $time_2 5 0 6 0 6 { 0 7 6 2 0 8 6 2 1 6 6 2 }" simple_expect ":18 15 2 $time_2 5 0 6 0 6 { 0 7 6 2 0 8 6 2 15 6 6 2 } 2 { 1 20000 5 $time_2 00100000 1 [holl "priv"] 2 20001 5 $time_2 00000000 1 [holl "pub"] }" talk_to client 2 simple_expect ":16 0 2 $time_2 5 0 6 0 4 { 0 7 6 2 1 6 6 2 }" simple_expect ":18 15 2 $time_2 5 0 6 0 4 { 0 7 6 2 15 6 6 2 } 1 { 2 20001 5 $time_2 00000000 1 [holl "pub"] }" talk_to client 0 simple_expect "=1016 2" # Text 3: created by 5 (session 1) # rcpt 7<3> # rcpt 8<3> # bcc 6<3> # aux 1: 20000 secret # aux 2: 20001 public talk_to client 1 set tno 3 send "1017 86 [holl "text 3"] 3 { 0 7 0 8 15 6 } 2 { 20000 00100000 1 [holl "priv"] 20001 00000000 1 [holl "pub"] }\n" extracting_expect ":16 0 $tno ($any_time) 5 0 6 0 6 { 0 7 6 3 0 8 6 3 1 6 6 3 }" time_3 1 simple_expect ":18 15 $tno $time_3 5 0 6 0 6 { 0 7 6 3 0 8 6 3 15 6 6 3 } 2 { 1 20000 5 $time_3 00100000 1 [holl "priv"] 2 20001 5 $time_3 00000000 1 [holl "pub"] }" talk_to client 0 simple_expect ":16 0 $tno $time_3 5 0 6 0 6 { 0 7 6 3 0 8 6 3 1 6 6 3 }" simple_expect ":18 15 $tno $time_3 5 0 6 0 6 { 0 7 6 3 0 8 6 3 15 6 6 3 } 2 { 1 20000 5 $time_3 00100000 1 [holl "priv"] 2 20001 5 $time_3 00000000 1 [holl "pub"] }" talk_to client 2 simple_expect ":16 0 $tno $time_3 5 0 6 0 4 { 0 7 6 3 1 6 6 3 }" # Note how the secret aux-info is filtered away as it should. simple_expect ":18 15 $tno $time_3 5 0 6 0 4 { 0 7 6 3 15 6 6 3 } 1 { 2 20001 5 $time_3 00000000 1 [holl "pub"] }" talk_to client 1 simple_expect "=1017 $tno" # Text 4: created by 5 (session 1) # rcpt 7<4> # rcpt 8<4> # bcc 6<4> # aux 1: 20000 secret # aux 2: 20001 public talk_to client 1 set tno 4 send "1018 86 [holl "text 4"] 3 { 0 7 0 8 15 6 } 2 { 20000 00100000 1 [holl "priv"] 20001 00000000 1 [holl "pub"] }\n" extracting_expect ":16 0 $tno ($any_time) 5 0 6 0 6 { 0 7 6 4 0 8 6 4 1 6 6 4 }" time_4 1 simple_expect ":18 15 $tno $time_4 5 0 6 0 6 { 0 7 6 4 0 8 6 4 15 6 6 4 } 2 { 1 20000 5 $time_4 00100000 1 [holl "priv"] 2 20001 5 $time_4 00000000 1 [holl "pub"] }" talk_to client 0 simple_expect ":16 0 $tno $time_4 5 0 6 0 6 { 0 7 6 4 0 8 6 4 1 6 6 4 }" simple_expect ":18 15 $tno $time_4 5 0 6 0 6 { 0 7 6 4 0 8 6 4 15 6 6 4 } 2 { 1 20000 5 $time_4 00100000 1 [holl "priv"] 2 20001 5 $time_4 00000000 1 [holl "pub"] }" talk_to client 2 simple_expect ":16 0 $tno $time_4 5 0 6 0 4 { 0 7 6 4 1 6 6 4 }" # Note how the secret aux-info is filtered away as it should. simple_expect ":18 15 $tno $time_4 5 0 6 0 4 { 0 7 6 4 15 6 6 4 } 1 { 2 20001 5 $time_4 00000000 1 [holl "pub"] }" talk_to client 1 simple_expect "=1018 $tno" # Text 5: created by 6 # rcpt 7<5> # rcpt 9<1> # aux 1: 20000 secret # aux 2: 20001 public talk_to client 2 set tno 5 send "1019 86 [holl "text 5"] 2 { 0 7 0 9 } 2 { 20000 00100000 1 [holl "priv"] 20001 00000000 1 [holl "pub"] }\n" extracting_expect ":16 0 $tno ($any_time) 6 0 6 0 4 { 0 7 6 5 0 9 6 1 }" time_5 1 simple_expect ":18 15 $tno $time_5 6 0 6 0 4 { 0 7 6 5 0 9 6 1 } 2 { 1 20000 6 $time_5 00100000 1 [holl "priv"] 2 20001 6 $time_5 00000000 1 [holl "pub"] }" talk_to client 0 simple_expect ":16 0 $tno $time_5 6 0 6 0 4 { 0 7 6 5 0 9 6 1 }" simple_expect ":18 15 $tno $time_5 6 0 6 0 4 { 0 7 6 5 0 9 6 1 } 2 { 1 20000 6 $time_5 00100000 1 [holl "priv"] 2 20001 6 $time_5 00000000 1 [holl "pub"] }" talk_to client 1 simple_expect ":16 0 $tno $time_5 6 0 6 0 2 { 0 7 6 5 }" simple_expect ":18 15 $tno $time_5 6 0 6 0 2 { 0 7 6 5 } 1 { 2 20001 6 $time_5 00000000 1 [holl "pub"] }" talk_to client 2 simple_expect "=1019 $tno" # Text 6: created by 6 # rcpt 7<6> # rcpt 9<2> # aux 1: 20000 secret # aux 2: 20001 public talk_to client 2 send "1020 42 255\n" simple_expect "=1020" set tno 6 send "1021 86 [holl "text 5"] 2 { 0 7 0 9 } 2 { 20000 00100000 1 [holl "priv"] 20001 00000000 1 [holl "pub"] }\n" extracting_expect ":16 0 $tno ($any_time) 6 0 6 0 4 { 0 7 6 6 0 9 6 2 }" time_6 1 simple_expect ":18 15 $tno $time_6 6 0 6 0 4 { 0 7 6 6 0 9 6 2 } 2 { 1 20000 6 $time_6 00100000 1 [holl "priv"] 2 20001 6 $time_6 00000000 1 [holl "pub"] }" talk_to client 0 simple_expect ":16 0 $tno $time_6 6 0 6 0 4 { 0 7 6 6 0 9 6 2 }" simple_expect ":18 15 $tno $time_6 6 0 6 0 4 { 0 7 6 6 0 9 6 2 } 2 { 1 20000 6 $time_6 00100000 1 [holl "priv"] 2 20001 6 $time_6 00000000 1 [holl "pub"] }" talk_to client 1 simple_expect ":16 0 $tno $time_6 6 0 6 0 2 { 0 7 6 6 }" simple_expect ":18 15 $tno $time_6 6 0 6 0 2 { 0 7 6 6 } 1 { 2 20001 6 $time_6 00000000 1 [holl "pub"] }" talk_to client 2 simple_expect "=1021 $tno" send "1022 42 0\n" simple_expect "=1022" # Run the garb once. if {$debug_calls} { talk_to client 0 send "1023 1003\n" lyskomd_expect "MSG: garb restarted." simple_expect "=1023" lyskomd_expect "MSG: garb started." lyskomd_expect "MSG: garb ready. 0 texts deleted." simple_expect ":1 1000 0" # check that no async messages were produced send "1024 35\n" simple_expect "=1024 $any_time" talk_to client 1 send "1025 35\n" simple_expect "=1025 $any_time" talk_to client 2 send "1026 35\n" simple_expect "=1026 $any_time" } else { unsupported "testing the garb -- use configure --with-debug-calls to enable" } # Delete text 1 talk_to client 0 send "1027 29 1\n" simple_expect ":18 14 1 $time_1 5 0 6 0 6 { 0 7 6 1 0 8 6 1 15 6 6 1 } 2 { 1 20000 5 $time_1 00100000 1 [holl "priv"] 2 20001 5 $time_1 00000000 1 [holl "pub"] }" talk_to client 1 simple_expect ":18 14 1 $time_1 5 0 6 0 6 { 0 7 6 1 0 8 6 1 15 6 6 1 } 2 { 1 20000 5 $time_1 00100000 1 [holl "priv"] 2 20001 5 $time_1 00000000 1 [holl "pub"] }" talk_to client 2 simple_expect ":18 14 1 $time_1 5 0 6 0 4 { 0 7 6 1 15 6 6 1 } 1 { 2 20001 5 $time_1 00000000 1 [holl "pub"] }" talk_to client 0 simple_expect "=1027" # Delete text 3 talk_to client 1 send "1028 29 3\n" simple_expect ":18 14 3 $time_3 5 0 6 0 6 { 0 7 6 3 0 8 6 3 15 6 6 3 } 2 { 1 20000 5 $time_3 00100000 1 [holl "priv"] 2 20001 5 $time_3 00000000 1 [holl "pub"] }" talk_to client 0 simple_expect ":18 14 3 $time_3 5 0 6 0 6 { 0 7 6 3 0 8 6 3 15 6 6 3 } 2 { 1 20000 5 $time_3 00100000 1 [holl "priv"] 2 20001 5 $time_3 00000000 1 [holl "pub"] }" talk_to client 2 simple_expect ":18 14 3 $time_3 5 0 6 0 4 { 0 7 6 3 15 6 6 3 } 1 { 2 20001 5 $time_3 00000000 1 [holl "pub"] }" talk_to client 1 simple_expect "=1028" # Delete text 5 talk_to client 2 send "1029 29 5\n" simple_expect ":18 14 5 $time_5 6 0 6 0 4 { 0 7 6 5 0 9 6 1 } 2 { 1 20000 6 $time_5 00100000 1 [holl "priv"] 2 20001 6 $time_5 00000000 1 [holl "pub"] }" talk_to client 0 simple_expect ":18 14 5 $time_5 6 0 6 0 4 { 0 7 6 5 0 9 6 1 } 2 { 1 20000 6 $time_5 00100000 1 [holl "priv"] 2 20001 6 $time_5 00000000 1 [holl "pub"] }" talk_to client 1 simple_expect ":18 14 5 $time_5 6 0 6 0 2 { 0 7 6 5 } 1 { 2 20001 6 $time_5 00000000 1 [holl "pub"] }" talk_to client 2 simple_expect "=1029" if {$debug_calls} { # Run the garb. Nothing is deleted. talk_to client 0 send "1030 1003\n" lyskomd_expect "MSG: garb restarted." simple_expect "=1030" lyskomd_expect "MSG: garb started." lyskomd_expect "MSG: garb ready. 0 texts deleted." simple_expect ":1 1000 0" # check that no async messages were produced send "1031 35\n" simple_expect "=1031 $any_time" talk_to client 1 send "1032 35\n" simple_expect "=1032 $any_time" talk_to client 2 send "1033 35\n" simple_expect "=1033 $any_time" # Backdate texts 76 days. talk_to client 0 send "1034 1002 2 [expr {76 * 24 * 3600}]\n" simple_expect "=1034" send "1035 1002 4 [expr {76 * 24 * 3600}]\n" simple_expect "=1035" send "1036 1002 6 [expr {76 * 24 * 3600}]\n" simple_expect "=1036" # Run the garb again. Nothing is deleted. talk_to client 0 send "1037 1003\n" lyskomd_expect "MSG: garb restarted." simple_expect "=1037" lyskomd_expect "MSG: garb started." lyskomd_expect "MSG: garb ready. 0 texts deleted." simple_expect ":1 1000 0" # check that no async messages were produced send "1038 35\n" simple_expect "=1038 $any_time" talk_to client 1 send "1039 35\n" simple_expect "=1039 $any_time" talk_to client 2 send "1040 35\n" simple_expect "=1040 $any_time" # Backdate texts 2 more days. talk_to client 0 send "1041 1002 2 [expr {2 * 24 * 3600}]\n" simple_expect "=1041" send "1042 1002 4 [expr {2 * 24 * 3600}]\n" simple_expect "=1042" send "1043 1002 6 [expr {2 * 24 * 3600}]\n" simple_expect "=1043" # Run the garb -- all three texts should be removed talk_to client 0 send "1044 1003\n" lyskomd_expect "MSG: garb restarted." simple_expect "=1044" lyskomd_expect "MSG: garb started." # Async for deletion of text 2 talk_to client 0 extracting_expect ":18 14 2 ($any_time) 5 0 6 0 6 { 0 7 6 2 0 8 6 2 15 6 6 2 } 2 { 1 20000 5 $time_2 00100000 1 [holl "priv"] 2 20001 5 $time_2 00000000 1 [holl "pub"] }" backdated_time_2 1 talk_to client 1 simple_expect ":18 14 2 $backdated_time_2 5 0 6 0 6 { 0 7 6 2 0 8 6 2 15 6 6 2 } 2 { 1 20000 5 $time_2 00100000 1 [holl "priv"] 2 20001 5 $time_2 00000000 1 [holl "pub"] }" talk_to client 2 simple_expect ":18 14 2 $backdated_time_2 5 0 6 0 4 { 0 7 6 2 15 6 6 2 } 1 { 2 20001 5 $time_2 00000000 1 [holl "pub"] }" # Async for deletion of text 4 talk_to client 0 extracting_expect ":18 14 4 ($any_time) 5 0 6 0 6 { 0 7 6 4 0 8 6 4 15 6 6 4 } 2 { 1 20000 5 $time_4 00100000 1 [holl "priv"] 2 20001 5 $time_4 00000000 1 [holl "pub"] }" backdated_time_4 1 talk_to client 1 simple_expect ":18 14 4 $backdated_time_4 5 0 6 0 6 { 0 7 6 4 0 8 6 4 15 6 6 4 } 2 { 1 20000 5 $time_4 00100000 1 [holl "priv"] 2 20001 5 $time_4 00000000 1 [holl "pub"] }" talk_to client 2 simple_expect ":18 14 4 $backdated_time_4 5 0 6 0 4 { 0 7 6 4 15 6 6 4 } 1 { 2 20001 5 $time_4 00000000 1 [holl "pub"] }" # Async for deletion of text 6 talk_to client 0 extracting_expect ":18 14 6 ($any_time) 6 0 6 0 4 { 0 7 6 6 0 9 6 2 } 2 { 1 20000 6 $time_6 00100000 1 [holl "priv"] 2 20001 6 $time_6 00000000 1 [holl "pub"] }" backdated_time_6 1 talk_to client 1 simple_expect ":18 14 6 $backdated_time_6 6 0 6 0 2 { 0 7 6 6 } 1 { 2 20001 6 $time_6 00000000 1 [holl "pub"] }" talk_to client 2 simple_expect ":18 14 6 $backdated_time_6 6 0 6 0 4 { 0 7 6 6 0 9 6 2 } 2 { 1 20000 6 $time_6 00100000 1 [holl "priv"] 2 20001 6 $time_6 00000000 1 [holl "pub"] }" # Garb ends. lyskomd_expect "MSG: garb ready. 3 texts deleted." talk_to client 0 simple_expect ":1 1000 3" # check that no other async messages were produced send "1045 35\n" simple_expect "=1045 $any_time" talk_to client 1 send "1046 35\n" simple_expect "=1046 $any_time" talk_to client 2 send "1047 35\n" simple_expect "=1047 $any_time" } # Shut down the server. talk_to client 0 send "1048 44 0\n" simple_expect "=1048" client_death 0 client_death 1 client_death 2 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/10.exp0000664000015100472110000000743707721716132016742 # Test suite for lyskomd. # Copyright (C) 1999-2000, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check async-sub-recipient. # # Three players are used: # client 0 person 5 # client 1 person 6 # # conference 7 secret; created by 5; person 5 is member # # Person 5 is a member of 1, 5 and 7. # Person 6 is a member of 1 and 6. # lyskomd_start # Establish the sessions and log in. client_start 0 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" "connected" send "1000 80 5 { 14 15 16 17 18 }\n" simple_expect "=1000" send "1001 0 5 [holl gazonk]\n" simple_expect "=1001" client_start 1 talk_to client 1 send "A6Hgazonk\n" simple_expect "LysKOM" "connected" send "1002 80 5 { 14 15 16 17 18 }\n" simple_expect "=1002" send "1003 89 [holl "Unprivileged"] [holl "citronfromage"] 10000000 0 { }\n" simple_expect "=1003 6" send "1004 0 6 [holl citronfromage]\n" simple_expect "=1004" # Create the secret conference talk_to client 0 send "1005 88 [holl "conf 7"] 1010 0 { }\n" simple_expect "=1005 7" # Join the conferences talk_to client 0 send "1006 100 1 5 200 1 00000000\n" simple_expect ":2 18 5 1" simple_expect "=1006" send "1007 100 7 5 200 2 00000000\n" simple_expect ":2 18 5 7" simple_expect "=1007" talk_to client 1 send "1008 100 1 6 200 1 00000000\n" simple_expect ":2 18 6 1" simple_expect "=1008" # Text 1: created by 5 (session 0) # rcpt 1<1> # cc 7<1> # bcc 6<1> # rcpt 2<1> talk_to client 0 send "1009 86 [holl "text 1"] 4 { 0 1 1 7 15 6 0 2 } 0 { }\n" extracting_expect ":18 15 1 ($any_time) 5 0 6 0 8 { 0 1 6 1 1 7 6 1 15 6 6 1 0 2 6 1 } 0 \\*" time_1 1 talk_to client 1 simple_expect ":18 15 1 $time_1 5 0 6 0 6 { 0 1 6 1 15 6 6 1 0 2 6 1 } 0 \\*" talk_to client 0 simple_expect "=1009 1" # Remove "cc 7<1>". send "1010 31 1 7\n" simple_expect ":3 17 1 7 1" talk_to client 0 simple_expect "=1010" talk_to client 1 send "1011 35\n" simple_expect "=1011 $any_time" # Remove "bcc 6<1>". talk_to client 0 send "1012 31 1 6\n" simple_expect ":3 17 1 6 15" talk_to client 1 simple_expect ":3 17 1 6 15" talk_to client 0 simple_expect "=1012" # Remove "rcpt 2<1>". send "1013 31 1 2\n" simple_expect ":3 17 1 2 0" talk_to client 1 simple_expect ":3 17 1 2 0" talk_to client 0 simple_expect "=1013" talk_to client 1 send "1014 35\n" simple_expect "=1014 $any_time" talk_to client 0 send "1015 90 1\n" simple_expect "=1015 $time_1 5 0 6 0 2 { 0 1 6 1 } 0 \\*" send "1016 56\n" simple_expect "=1016 1" send "1017 64 1\n" simple_expect "=1017 5 0 1 0H $hollerith $hollerith $hollerith $any_num $any_time" send "1018 98 5 1\n" simple_expect "=1018 1 $any_time 1 200 0 0 \\* 5 $any_time 00000000" send "1019 31 1 1\n" simple_expect ":3 17 1 1 0" talk_to client 1 simple_expect ":3 17 1 1 0" talk_to client 0 simple_expect "=1019" # Shut down the server. talk_to client 1 send "1020 55 0\n" simple_expect "=1020" client_death 1 talk_to client 0 send "1021 42 255\n" simple_expect "=1021" send "1022 44 0\n" simple_expect "=1022" client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/11.exp0000664000015100472110000001475107721716132016740 # Test suite for lyskomd. # Copyright (C) 1999, 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test the lock file of lyskomd and dbck. # Start a server that locks the database. lyskomd_start # Start dbck in read-only mode. No lock is required. spawn ../dbck -d config/lyskomd-config set test "dbck started in read-only mode" expect { -re "^Where does the trace want to go today. .stderr.$nl" { pass "Tracing is activated (/dev/null)" send "/dev/null\n" exp_continue } -re "^MSG: init_cache: using datafile\.$nl" { pass "$test" } } set test "read-only dbck sent second line" expect { -re "^Read $any_num confs/persons and $any_num texts, eof at $any_num$nl" { pass "$test" } } set test "read-only dbck sent final line" expect { -re "^Press enter to terminate dbck$nl" { pass "$test" } } send "\n" set test "read-only dbck died" expect { eof { pass "$test"; wait } } unset test # Attempt to start dbck in read-write mode. spawn ../dbck -d -i config/lyskomd-config set test "dbck finds a lock" expect { -re "^Where does the trace want to go today. .stderr.$nl" { pass "Tracing is activated (/dev/null)" send "/dev/null\n" exp_continue } -re "^Database already locked by $any*\.$nl" { pass "$test" } } set test "read-write dbck sent final line" expect { -re "^Press enter to terminate dbck$nl" { pass "$test" } } send "\n" set test "read-write dbck died" expect { eof { pass "$test"; wait } } unset test # Attempt to start a second lyskomd. spawn ../lyskomd -f config/lyskomd-config set test "lyskomd finds a lock" expect { -re "^Where does the trace want to go today. .stderr.$nl" { pass "Tracing is activated (/dev/null)" send "/dev/null\n" exp_continue } -re "Database already locked by $any*:$lyskomd_pid$nl" { pass "$test" } } set test "lyskomd writes an exiting message." expect { -re "Cannot obtain database lock\. Exiting\.$nl" { pass "$test" } } set test "read-write lyskomd sent final line" expect { -re "^\[0-9 :\]* Press enter to terminate lyskomd$nl" { pass "$test" } } send "\n" set test "read-write lyskomd died" expect { eof { pass "$test"; wait } } unset test # Shut down lyskomd. system "kill -TERM $lyskomd_pid" lyskomd_death "" signal # Start a new lyskomd. lyskomd_start # Kill it so that it cannot remove the lock file. system "kill -KILL $lyskomd_pid" set test "lyskomd was killed" expect { eof { pass "$test"; wait } } # Start a new lyskomd. Check that it removes the stale lock file. set new_pid [spawn ../lyskomd -f config/lyskomd-config] set line_leader "\[0-9\]\[0-9\]\[0-9\]\[0-9\]\[0-9\]\[0-9\] \[0-9\]\[0-9\]:\[0-9\]\[0-9\]:\[0-9\]\[0-9\] $new_pid " set test "lyskomd startup" expect { -re "^Where does the trace want to go today. .stderr.$nl" { pass "Tracing is activated (/dev/null)" send "/dev/null\n" exp_continue } -re "^${line_leader}... Version $any* \\(process $new_pid\\) started.$nl" { pass "$test" } timeout {fail "$test (timeout)"} full_buffer {fail "$test (full_buffer)"} eof {fail "$test (eof)"; wait} } set test "stale lock file removed" expect { -re "^${line_leader}WARNING: This server was compiled with --with-debug-calls\\.$nl" { expect -re "^${line_leader}It isn.t safe to use in a production environment.$nl" pass "debug calls are enabled" set debug_calls 1 exp_continue } -re "^${line_leader}Removed stale lock file left by $any*:$lyskomd_pid\.$nl" { pass "$test" } timeout {fail "$test (timeout)"} full_buffer {fail "$test (full_buffer)"} eof {fail "$test (eof)"; wait} } set test "New lock created" expect { -re "^${line_leader}Created lock ($any*)$nl" { pass "$test (lock file $expect_out(1,string)" } timeout {fail "$test (timeout)"} full_buffer {fail "$test (full_buffer)"} eof {fail "$test (eof)"; wait} } simple_expect "Listening for clients on $clientport." simple_expect "Database = [pwd]/db/lyskomd-data" simple_expect "Backup = [pwd]/db/lyskomd-backup" simple_expect "2nd Backup = [pwd]/db/lyskomd-backup-prev" simple_expect "Lock File = [pwd]/db/lyskomd-lock" simple_expect "MSG: init_cache: using datafile." simple_expect "Database saved on $any*" simple_expect "Read 6 confs/persons and 1 texts" simple_expect "MSG: garb started." simple_expect "MSG: garb ready. 0 texts deleted." system "kill -TERM $new_pid" set bypass 0 set test "non-stale lyskomd sent final line" simple_expect "Signal TERM received. Shutting down server." simple_expect "../lyskomd terminated normally." simple_expect "Press enter to terminate lyskomd" send "\n" set test "non-stale lyskomd died" expect { eof { pass "$test"; wait } } unset test # Start a new lyskomd while a lock file for a remote system exists. system "ln -s inet.lysator.liu.se:4711 db/lyskomd-lock" spawn ../lyskomd -f config/lyskomd-config set test "remote lock file found" expect { -re "^Where does the trace want to go today. .stderr.$nl" { pass "Tracing is activated (/dev/null)" send "/dev/null\n" exp_continue } -re "Database already locked by inet\.lysator\.liu\.se:4711$nl" { pass "$test" } } set test "lock complaint" expect { -re "^\[0-9 :\]* Cannot obtain database lock. Exiting.$nl" { pass "$test" } } set test "local lyskomd sent final line" expect { -re "^\[0-9 :\]* Press enter to terminate lyskomd$nl" { pass "$test" } } send "\n" set test "local lyskomd died" expect { eof { pass "$test"; wait } } unset test # Since we use lyskomd_start, but kill the server ourself, we are # left with a dangling lock. Release it. release_lock lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/12.exp0000664000015100472110000000443507721716132016737 # Test suite for lyskomd. # Copyright (C) 1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test for the bug that caused 2.0.0 to sometimes not remove texts # from the created_texts field of a person when the text was removed. # Start a server and set up a minmal environment: # person 6 "Author" # text 1 Written by author, conference 1 as recipient. lyskomd_start "" "Cache person limit: 0\n" client_start 0 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" "connected" send "1000 89 [holl "Author"] [holl "Writer"] 00000000 0 { }\n" simple_expect "=1000 6" send "1001 62 6 [holl "Writer"] 1\n" simple_expect "=1001" send "1002 86 [holl "Text 1"] 1 { 0 1 } 0 { }\n" simple_expect "=1002 1" # Log in as administrator instead. send "1003 62 5 [holl "gazonk"] 1\n" simple_expect "=1003" # Save the database; the Author should then be clean. send "1004 42 255\n" simple_expect "=1004" send "1005 43\n" simple_expect ":0 7" simple_expect ":0 7" simple_expect "=1005" dbck_run talk_to client 0 # Delete the text. send "1006 29 1\n" simple_expect "=1006" # The Author now contains the changed data, but it is not marked as # dirty. Trigger a cache_limit_size. for {set i 0} {$i < 110} {incr i} { send "9 35\n" simple_expect "=9 $any_time" } send "1007 43\n" simple_expect ":0 7" simple_expect ":0 7" simple_expect "=1007" dbck_run talk_to client 0 send "1008 44 0\n" simple_expect "=1008" client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/13.exp0000664000015100472110000000647007721716132016741 # Test suite for lyskomd. # Copyright (C) 1999, 2001, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check conference creation, name changes, and name lookup. read_versions source "$srcdir/config/prot-a.exp" lyskomd_start client_start 0 kom_connect "DejaGnu Test Suite" kom_accept_async "0 { }" kom_login 5 "gazonk" 0 kom_create_conference "Match 6" "00000000" "0 { }" kom_create_conference "Match 7" "00000000" "0 { }" kom_create_conference "Match 8" "00000000" "0 { }" send "1000 76 [holl "Match"] 1 1\n" simple_expect "=1000 3 { [holl "Match 6"] 0000 6 [holl "Match 7"] 0000 7 [holl "Match 8"] 0000 8 }" kom_create_conference "Match 9" "00000000" "0 { }" kom_create_conference "Junk 10" "00000000" "0 { }" send "1001 76 [holl "Match"] 1 1\n" simple_expect "=1001 4 { [holl "Match 6"] 0000 6 [holl "Match 7"] 0000 7 [holl "Match 8"] 0000 8 [holl "Match 9"] 0000 9 }" send "1002 3 6 [holl "Junk 6"]\n" simple_expect "=1002" send "1003 76 [holl "Match"] 1 1\n" simple_expect "=1003 3 { [holl "Match 7"] 0000 7 [holl "Match 8"] 0000 8 [holl "Match 9"] 0000 9 }" send "1004 3 8 [holl "Junk 8"]\n" simple_expect "=1004" send "1005 76 [holl "Match"] 1 1\n" simple_expect "=1005 2 { [holl "Match 7"] 0000 7 [holl "Match 9"] 0000 9 }" send "1006 3 7 [holl "Junk 7"]\n" simple_expect "=1006" send "1007 76 [holl "Match"] 1 1\n" simple_expect "=1007 1 { [holl "Match 9"] 0000 9 }" send "1008 76 [holl "Junk"] 1 1\n" simple_expect "=1008 4 { [holl "Junk 6"] 0000 6 [holl "Junk 7"] 0000 7 [holl "Junk 8"] 0000 8 [holl "Junk 10"] 0000 10 }" send "1009 11 6\n" simple_expect "=1009" send "1010 76 [holl "Match"] 1 1\n" simple_expect "=1010 1 { [holl "Match 9"] 0000 9 }" send "1011 11 9\n" simple_expect "=1011" send "1012 76 [holl "Junk"] 1 1\n" simple_expect "=1012 3 { [holl "Junk 7"] 0000 7 [holl "Junk 8"] 0000 8 [holl "Junk 10"] 0000 10 }" send "1013 76 [holl "Match"] 1 1\n" simple_expect "=1013 0 \\*" kom_create_conference "Junk 11" 00000000 "0 { }\n" send "1014 76 [holl "Junk"] 1 1\n" simple_expect "=1014 4 { [holl "Junk 7"] 0000 7 [holl "Junk 8"] 0000 8 [holl "Junk 10"] 0000 10 [holl "Junk 11"] 0000 11 }" kom_create_conference "Match 12" 00000000 "0 { }\n" send "1015 76 [holl "Junk"] 1 1\n" simple_expect "=1015 4 { [holl "Junk 7"] 0000 7 [holl "Junk 8"] 0000 8 [holl "Junk 10"] 0000 10 [holl "Junk 11"] 0000 11 }" send "1016 76 [holl "Match"] 1 1\n" simple_expect "=1016 1 { [holl "Match 12"] 0000 12 }" kom_enable 255 send "9999 44 0\n" simple_expect "=9999" client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/14.exp0000664000015100472110000000621607721716132016740 # Test suite for lyskomd. # Copyright (C) 1999, 2001, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test that the correct persons can change between # recpt, cc-recpt and bcc-recpt. # Start a server and set up a minmal environment: # person 6 "Author" # text 1 Written by author, conference 1 as recipient. lyskomd_start client_start 0 talk_to client 0 send "A7Hfoo bar\n" simple_expect "LysKOM" "connected" send "1000 89 [holl "Author"] [holl "Writer"] 00000000 0 { }\n" simple_expect "=1000 6" send "1001 62 6 [holl "Writer"] 1\n" simple_expect "=1001" send "1002 86 [holl "Text 1"] 1 { 0 1 } 0 { }\n" simple_expect "=1002 1" send "1003 86 [holl "Text 2"] 1 { 1 1 } 0 { }\n" simple_expect "=1003 2" send "1004 86 [holl "Text 3"] 1 { 15 1 } 0 { }\n" simple_expect "=1004 3" send "1005 30 1 1 1\n" simple_expect "=1005" send "1006 30 2 1 15\n" simple_expect "=1006" send "1007 30 3 1 0\n" simple_expect "=1007" send "1008 1\n" simple_expect "=1008" # Create a new person and attempt to move the texts some more. send "1009 89 [holl "Mover"] [holl "mwm"] 00000000 0 { }\n" simple_expect "=1009 7" send "1010 62 7 [holl "mwm"] 1\n" simple_expect "=1010" send "1011 30 1 1 15\n" simple_expect "%1011 12 1" send "1012 30 2 1 0\n" simple_expect "%1012 12 1" send "1013 30 3 1 1\n" simple_expect "%1013 12 1" # Add one of the texts to a new conference, and then try to change the type. send "1014 30 1 2 0\n" simple_expect "=1014" send "1015 30 1 2 1\n" good_bad_expect "=1015" "%12 2" send "1016 62 5 [holl "gazonk"] 1\n" simple_expect "=1016" send "1017 42 255\n" simple_expect "=1017" # Attempt to add a broken FAQ aux-item with trailing garbage. send "1018 93 4 0 { } 1 { 14 00000000 0 [holl "3garbage"] }\n" simple_expect "%1018 48 0" # Create a proper FAQ item send "1019 93 4 0 { } 1 { 14 00000000 0 [holl "3"] }\n" simple_expect "=1019" # Create another proper FAQ item send "1020 93 2 0 { } 1 { 14 00000000 0 [holl "1"] }\n" simple_expect "=1020" send "1021 91 4\n" simple_expect "=1021 [holl "Nyheter om LysKOM"] 00001000 $any_time $any_time 0 0 0 0 0 0 77 77 0 1 0 0 1 { 1 14 5 $any_time 00000000 1 [holl "3"] }" send "1022 90 3\n" simple_expect "=1022 $any_time 6 0 6 0 2 { 0 1 6 3 } 1 { 1 28 5 $any_time 00001000 0 [holl "4"] }" send "1023 44 0\n" simple_expect "=1023" client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/15.exp0000444000015100472110000065247407723710374016756 # Automatically generated by gen-15.py. Do not edit. lyskomd_start client_start 0 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" "connected 6" send "1000 80 4 { 14 15 16 17 }\n" simple_expect "=1000" send "1001 89 [holl "Person 6"] [holl "foo"] 00000000 0 { }\n" simple_expect "=1001 6" send "1002 62 6 [holl "foo"] 0\n" simple_expect "=1002" client_start 1 talk_to client 1 send "A3Hfoo\n" simple_expect "LysKOM" "connected 7" send "1003 80 4 { 14 15 16 17 }\n" simple_expect "=1003" send "1004 89 [holl "Person 7"] [holl "foo"] 00000000 0 { }\n" simple_expect "=1004 7" send "1005 62 7 [holl "foo"] 0\n" simple_expect "=1005" client_start 2 talk_to client 2 send "A3Hfoo\n" simple_expect "LysKOM" "connected 8" send "1006 80 4 { 14 15 16 17 }\n" simple_expect "=1006" send "1007 89 [holl "Person 8"] [holl "foo"] 00000000 0 { }\n" simple_expect "=1007 8" send "1008 62 8 [holl "foo"] 0\n" simple_expect "=1008" client_start 3 talk_to client 3 send "A3Hfoo\n" simple_expect "LysKOM" "connected 9" send "1009 80 4 { 14 15 16 17 }\n" simple_expect "=1009" send "1010 89 [holl "Person 9"] [holl "foo"] 00000000 0 { }\n" simple_expect "=1010 9" send "1011 62 9 [holl "foo"] 0\n" simple_expect "=1011" talk_to client 1 send "1012 88 [holl "conf 10"] 0000 0 { }\n" simple_expect "=1012 10" send "1013 88 [holl "conf 11"] 1000 0 { }\n" simple_expect "=1013 11" send "1014 88 [holl "conf 12"] 1010 0 { }\n" simple_expect "=1014 12" talk_to client 3 send "1015 88 [holl "conf 13"] 0000 0 { }\n" simple_expect "=1015 13" send "1016 88 [holl "conf 14"] 1000 0 { }\n" simple_expect "=1016 14" send "1017 88 [holl "conf 15"] 1010 0 { }\n" simple_expect "=1017 15" talk_to client 1 send "1018 100 10 7 100 3 00000000\n" simple_expect "=1018" send "1019 100 10 8 100 3 00000000\n" simple_expect "=1019" send "1020 100 11 7 100 3 00000000\n" simple_expect "=1020" send "1021 100 11 8 100 3 00000000\n" simple_expect "=1021" send "1022 100 12 7 100 3 00000000\n" simple_expect "=1022" send "1023 100 12 8 100 3 00000000\n" simple_expect "=1023" talk_to client 3 send "1024 100 13 7 100 6 00000000\n" simple_expect "=1024" send "1025 100 13 8 100 6 00000000\n" simple_expect "=1025" send "1026 100 14 7 100 6 00000000\n" simple_expect "=1026" send "1027 100 14 8 100 6 00000000\n" simple_expect "=1027" send "1028 100 15 7 100 6 00000000\n" simple_expect "=1028" send "1029 100 15 8 100 6 00000000\n" simple_expect "=1029" talk_to lyskomd simple_expect "Person 8 added to conference 10 by 7." simple_expect "Person 8 added to conference 11 by 7." simple_expect "Person 8 added to conference 12 by 7." simple_expect "Person 7 added to conference 13 by 9." simple_expect "Person 8 added to conference 13 by 9." simple_expect "Person 7 added to conference 14 by 9." simple_expect "Person 8 added to conference 14 by 9." simple_expect "Person 7 added to conference 15 by 9." simple_expect "Person 8 added to conference 15 by 9." talk_to client 1 send "1030 15 7 7\n" simple_expect "=1030" send_user "testing simple create+delete\n" talk_to client 0 # Creating text 1 by 6 send "1031 86 [holl "text 1"] 1 { 0 6 } 0 { }\n" simple_expect ":18 15 1 $any_time 6 0 6 0 2 { 0 6 6 1 } 0 \\\*" simple_expect "=1031 1" send "1032 90 1\n" simple_expect "=1032 $any_time 6 0 6 0 2 { 0 6 6 1 } 0 \\\*" talk_to client 1 send "1033 90 1\n" simple_expect "%1033 14 1" talk_to client 2 send "1034 90 1\n" simple_expect "%1034 14 1" talk_to client 3 send "1035 90 1\n" simple_expect "%1035 14 1" talk_to client 0 # Deleting text 1; deleter 6 send "1036 29 1\n" simple_expect ":18 14 1 $any_time 6 0 6 0 2 { 0 6 6 1 } 0 \\\*" simple_expect "=1036" # Creating text 2 by 6 send "1037 86 [holl "text 2"] 1 { 0 7 } 0 { }\n" simple_expect "=1037 2" send "1038 90 2\n" simple_expect "=1038 $any_time 6 0 6 0 2 { 0 7 6 1 } 0 \\\*" talk_to client 1 send "1039 90 2\n" simple_expect "=1039 $any_time 6 0 6 0 2 { 0 7 6 1 } 0 \\\*" talk_to client 2 send "1040 90 2\n" simple_expect "%1040 14 2" talk_to client 3 send "1041 90 2\n" simple_expect "%1041 14 2" talk_to client 0 # Deleting text 2; deleter 6 send "1042 29 2\n" simple_expect "=1042" # Creating text 3 by 6 send "1043 86 [holl "text 3"] 1 { 0 8 } 0 { }\n" talk_to client 2 simple_expect ":18 15 3 $any_time 6 0 6 0 2 { 0 8 6 1 } 0 \\\*" talk_to client 0 simple_expect "=1043 3" send "1044 90 3\n" simple_expect "=1044 $any_time 6 0 6 0 2 { 0 8 6 1 } 0 \\\*" talk_to client 1 send "1045 90 3\n" simple_expect "%1045 14 3" talk_to client 2 send "1046 90 3\n" simple_expect "=1046 $any_time 6 0 6 0 2 { 0 8 6 1 } 0 \\\*" talk_to client 3 send "1047 90 3\n" simple_expect "%1047 14 3" talk_to client 0 # Deleting text 3; deleter 6 send "1048 29 3\n" talk_to client 2 simple_expect ":18 14 3 $any_time 6 0 6 0 2 { 0 8 6 1 } 0 \\\*" talk_to client 0 simple_expect "=1048" # Creating text 4 by 6 send "1049 86 [holl "text 4"] 1 { 0 9 } 0 { }\n" talk_to client 3 simple_expect ":18 15 4 $any_time 6 0 6 0 2 { 0 9 6 1 } 0 \\\*" talk_to client 0 simple_expect "=1049 4" send "1050 90 4\n" simple_expect "=1050 $any_time 6 0 6 0 2 { 0 9 6 1 } 0 \\\*" talk_to client 1 send "1051 90 4\n" simple_expect "%1051 14 4" talk_to client 2 send "1052 90 4\n" simple_expect "%1052 14 4" talk_to client 3 send "1053 90 4\n" simple_expect "=1053 $any_time 6 0 6 0 2 { 0 9 6 1 } 0 \\\*" talk_to client 0 # Deleting text 4; deleter 6 send "1054 29 4\n" talk_to client 3 simple_expect ":18 14 4 $any_time 6 0 6 0 2 { 0 9 6 1 } 0 \\\*" talk_to client 0 simple_expect "=1054" # Creating text 5 by 6 send "1055 86 [holl "text 5"] 1 { 0 10 } 0 { }\n" talk_to client 1 simple_expect ":18 15 5 $any_time 6 0 6 0 2 { 0 10 6 1 } 0 \\\*" talk_to client 2 simple_expect ":18 15 5 $any_time 6 0 6 0 2 { 0 10 6 1 } 0 \\\*" talk_to client 0 simple_expect "=1055 5" send "1056 90 5\n" simple_expect "=1056 $any_time 6 0 6 0 2 { 0 10 6 1 } 0 \\\*" talk_to client 1 send "1057 90 5\n" simple_expect "=1057 $any_time 6 0 6 0 2 { 0 10 6 1 } 0 \\\*" talk_to client 2 send "1058 90 5\n" simple_expect "=1058 $any_time 6 0 6 0 2 { 0 10 6 1 } 0 \\\*" talk_to client 3 send "1059 90 5\n" simple_expect "=1059 $any_time 6 0 6 0 2 { 0 10 6 1 } 0 \\\*" talk_to client 0 # Deleting text 5; deleter 6 send "1060 29 5\n" talk_to client 1 simple_expect ":18 14 5 $any_time 6 0 6 0 2 { 0 10 6 1 } 0 \\\*" talk_to client 2 simple_expect ":18 14 5 $any_time 6 0 6 0 2 { 0 10 6 1 } 0 \\\*" talk_to client 0 simple_expect "=1060" # Creating text 6 by 6 send "1061 86 [holl "text 6"] 1 { 0 11 } 0 { }\n" talk_to client 1 simple_expect ":18 15 6 $any_time 6 0 6 0 2 { 0 11 6 1 } 0 \\\*" talk_to client 2 simple_expect ":18 15 6 $any_time 6 0 6 0 2 { 0 11 6 1 } 0 \\\*" talk_to client 0 simple_expect "=1061 6" send "1062 90 6\n" simple_expect "=1062 $any_time 6 0 6 0 2 { 0 11 6 1 } 0 \\\*" talk_to client 1 send "1063 90 6\n" simple_expect "=1063 $any_time 6 0 6 0 2 { 0 11 6 1 } 0 \\\*" talk_to client 2 send "1064 90 6\n" simple_expect "=1064 $any_time 6 0 6 0 2 { 0 11 6 1 } 0 \\\*" talk_to client 3 send "1065 90 6\n" simple_expect "%1065 14 6" talk_to client 0 # Deleting text 6; deleter 6 send "1066 29 6\n" talk_to client 1 simple_expect ":18 14 6 $any_time 6 0 6 0 2 { 0 11 6 1 } 0 \\\*" talk_to client 2 simple_expect ":18 14 6 $any_time 6 0 6 0 2 { 0 11 6 1 } 0 \\\*" talk_to client 0 simple_expect "=1066" # Creating text 7 by 6 send "1067 86 [holl "text 7"] 1 { 0 13 } 0 { }\n" talk_to client 1 simple_expect ":18 15 7 $any_time 6 0 6 0 2 { 0 13 6 1 } 0 \\\*" talk_to client 2 simple_expect ":18 15 7 $any_time 6 0 6 0 2 { 0 13 6 1 } 0 \\\*" talk_to client 0 simple_expect "=1067 7" send "1068 90 7\n" simple_expect "=1068 $any_time 6 0 6 0 2 { 0 13 6 1 } 0 \\\*" talk_to client 1 send "1069 90 7\n" simple_expect "=1069 $any_time 6 0 6 0 2 { 0 13 6 1 } 0 \\\*" talk_to client 2 send "1070 90 7\n" simple_expect "=1070 $any_time 6 0 6 0 2 { 0 13 6 1 } 0 \\\*" talk_to client 3 send "1071 90 7\n" simple_expect "=1071 $any_time 6 0 6 0 2 { 0 13 6 1 } 0 \\\*" talk_to client 0 # Deleting text 7; deleter 6 send "1072 29 7\n" talk_to client 1 simple_expect ":18 14 7 $any_time 6 0 6 0 2 { 0 13 6 1 } 0 \\\*" talk_to client 2 simple_expect ":18 14 7 $any_time 6 0 6 0 2 { 0 13 6 1 } 0 \\\*" talk_to client 0 simple_expect "=1072" # Creating text 8 by 6 send "1073 86 [holl "text 8"] 1 { 0 14 } 0 { }\n" talk_to client 1 simple_expect ":18 15 8 $any_time 6 0 6 0 2 { 0 14 6 1 } 0 \\\*" talk_to client 2 simple_expect ":18 15 8 $any_time 6 0 6 0 2 { 0 14 6 1 } 0 \\\*" talk_to client 0 simple_expect "=1073 8" send "1074 90 8\n" simple_expect "=1074 $any_time 6 0 6 0 2 { 0 14 6 1 } 0 \\\*" talk_to client 1 send "1075 90 8\n" simple_expect "=1075 $any_time 6 0 6 0 2 { 0 14 6 1 } 0 \\\*" talk_to client 2 send "1076 90 8\n" simple_expect "=1076 $any_time 6 0 6 0 2 { 0 14 6 1 } 0 \\\*" talk_to client 3 send "1077 90 8\n" simple_expect "=1077 $any_time 6 0 6 0 2 { 0 14 6 1 } 0 \\\*" talk_to client 0 # Deleting text 8; deleter 6 send "1078 29 8\n" talk_to client 1 simple_expect ":18 14 8 $any_time 6 0 6 0 2 { 0 14 6 1 } 0 \\\*" talk_to client 2 simple_expect ":18 14 8 $any_time 6 0 6 0 2 { 0 14 6 1 } 0 \\\*" talk_to client 0 simple_expect "=1078" # Creating text 9 by 6 send "1079 86 [holl "text 9"] 1 { 1 6 } 0 { }\n" simple_expect ":18 15 9 $any_time 6 0 6 0 2 { 1 6 6 2 } 0 \\\*" simple_expect "=1079 9" send "1080 90 9\n" simple_expect "=1080 $any_time 6 0 6 0 2 { 1 6 6 2 } 0 \\\*" talk_to client 1 send "1081 90 9\n" simple_expect "%1081 14 9" talk_to client 2 send "1082 90 9\n" simple_expect "%1082 14 9" talk_to client 3 send "1083 90 9\n" simple_expect "%1083 14 9" talk_to client 0 # Deleting text 9; deleter 6 send "1084 29 9\n" simple_expect ":18 14 9 $any_time 6 0 6 0 2 { 1 6 6 2 } 0 \\\*" simple_expect "=1084" # Creating text 10 by 6 send "1085 86 [holl "text 10"] 1 { 1 7 } 0 { }\n" simple_expect "=1085 10" send "1086 90 10\n" simple_expect "=1086 $any_time 6 0 7 0 2 { 1 7 6 2 } 0 \\\*" talk_to client 1 send "1087 90 10\n" simple_expect "=1087 $any_time 6 0 7 0 2 { 1 7 6 2 } 0 \\\*" talk_to client 2 send "1088 90 10\n" simple_expect "%1088 14 10" talk_to client 3 send "1089 90 10\n" simple_expect "%1089 14 10" talk_to client 0 # Deleting text 10; deleter 6 send "1090 29 10\n" simple_expect "=1090" # Creating text 11 by 6 send "1091 86 [holl "text 11"] 1 { 1 8 } 0 { }\n" talk_to client 2 simple_expect ":18 15 11 $any_time 6 0 7 0 2 { 1 8 6 2 } 0 \\\*" talk_to client 0 simple_expect "=1091 11" send "1092 90 11\n" simple_expect "=1092 $any_time 6 0 7 0 2 { 1 8 6 2 } 0 \\\*" talk_to client 1 send "1093 90 11\n" simple_expect "%1093 14 11" talk_to client 2 send "1094 90 11\n" simple_expect "=1094 $any_time 6 0 7 0 2 { 1 8 6 2 } 0 \\\*" talk_to client 3 send "1095 90 11\n" simple_expect "%1095 14 11" talk_to client 0 # Deleting text 11; deleter 6 send "1096 29 11\n" talk_to client 2 simple_expect ":18 14 11 $any_time 6 0 7 0 2 { 1 8 6 2 } 0 \\\*" talk_to client 0 simple_expect "=1096" # Creating text 12 by 6 send "1097 86 [holl "text 12"] 1 { 1 9 } 0 { }\n" talk_to client 3 simple_expect ":18 15 12 $any_time 6 0 7 0 2 { 1 9 6 2 } 0 \\\*" talk_to client 0 simple_expect "=1097 12" send "1098 90 12\n" simple_expect "=1098 $any_time 6 0 7 0 2 { 1 9 6 2 } 0 \\\*" talk_to client 1 send "1099 90 12\n" simple_expect "%1099 14 12" talk_to client 2 send "1100 90 12\n" simple_expect "%1100 14 12" talk_to client 3 send "1101 90 12\n" simple_expect "=1101 $any_time 6 0 7 0 2 { 1 9 6 2 } 0 \\\*" talk_to client 0 # Deleting text 12; deleter 6 send "1102 29 12\n" talk_to client 3 simple_expect ":18 14 12 $any_time 6 0 7 0 2 { 1 9 6 2 } 0 \\\*" talk_to client 0 simple_expect "=1102" # Creating text 13 by 6 send "1103 86 [holl "text 13"] 1 { 1 10 } 0 { }\n" talk_to client 1 simple_expect ":18 15 13 $any_time 6 0 7 0 2 { 1 10 6 2 } 0 \\\*" talk_to client 2 simple_expect ":18 15 13 $any_time 6 0 7 0 2 { 1 10 6 2 } 0 \\\*" talk_to client 0 simple_expect "=1103 13" send "1104 90 13\n" simple_expect "=1104 $any_time 6 0 7 0 2 { 1 10 6 2 } 0 \\\*" talk_to client 1 send "1105 90 13\n" simple_expect "=1105 $any_time 6 0 7 0 2 { 1 10 6 2 } 0 \\\*" talk_to client 2 send "1106 90 13\n" simple_expect "=1106 $any_time 6 0 7 0 2 { 1 10 6 2 } 0 \\\*" talk_to client 3 send "1107 90 13\n" simple_expect "=1107 $any_time 6 0 7 0 2 { 1 10 6 2 } 0 \\\*" talk_to client 0 # Deleting text 13; deleter 6 send "1108 29 13\n" talk_to client 1 simple_expect ":18 14 13 $any_time 6 0 7 0 2 { 1 10 6 2 } 0 \\\*" talk_to client 2 simple_expect ":18 14 13 $any_time 6 0 7 0 2 { 1 10 6 2 } 0 \\\*" talk_to client 0 simple_expect "=1108" # Creating text 14 by 6 send "1109 86 [holl "text 14"] 1 { 1 11 } 0 { }\n" talk_to client 1 simple_expect ":18 15 14 $any_time 6 0 7 0 2 { 1 11 6 2 } 0 \\\*" talk_to client 2 simple_expect ":18 15 14 $any_time 6 0 7 0 2 { 1 11 6 2 } 0 \\\*" talk_to client 0 simple_expect "=1109 14" send "1110 90 14\n" simple_expect "=1110 $any_time 6 0 7 0 2 { 1 11 6 2 } 0 \\\*" talk_to client 1 send "1111 90 14\n" simple_expect "=1111 $any_time 6 0 7 0 2 { 1 11 6 2 } 0 \\\*" talk_to client 2 send "1112 90 14\n" simple_expect "=1112 $any_time 6 0 7 0 2 { 1 11 6 2 } 0 \\\*" talk_to client 3 send "1113 90 14\n" simple_expect "%1113 14 14" talk_to client 0 # Deleting text 14; deleter 6 send "1114 29 14\n" talk_to client 1 simple_expect ":18 14 14 $any_time 6 0 7 0 2 { 1 11 6 2 } 0 \\\*" talk_to client 2 simple_expect ":18 14 14 $any_time 6 0 7 0 2 { 1 11 6 2 } 0 \\\*" talk_to client 0 simple_expect "=1114" # Creating text 15 by 6 send "1115 86 [holl "text 15"] 1 { 1 13 } 0 { }\n" talk_to client 1 simple_expect ":18 15 15 $any_time 6 0 7 0 2 { 1 13 6 2 } 0 \\\*" talk_to client 2 simple_expect ":18 15 15 $any_time 6 0 7 0 2 { 1 13 6 2 } 0 \\\*" talk_to client 0 simple_expect "=1115 15" send "1116 90 15\n" simple_expect "=1116 $any_time 6 0 7 0 2 { 1 13 6 2 } 0 \\\*" talk_to client 1 send "1117 90 15\n" simple_expect "=1117 $any_time 6 0 7 0 2 { 1 13 6 2 } 0 \\\*" talk_to client 2 send "1118 90 15\n" simple_expect "=1118 $any_time 6 0 7 0 2 { 1 13 6 2 } 0 \\\*" talk_to client 3 send "1119 90 15\n" simple_expect "=1119 $any_time 6 0 7 0 2 { 1 13 6 2 } 0 \\\*" talk_to client 0 # Deleting text 15; deleter 6 send "1120 29 15\n" talk_to client 1 simple_expect ":18 14 15 $any_time 6 0 7 0 2 { 1 13 6 2 } 0 \\\*" talk_to client 2 simple_expect ":18 14 15 $any_time 6 0 7 0 2 { 1 13 6 2 } 0 \\\*" talk_to client 0 simple_expect "=1120" # Creating text 16 by 6 send "1121 86 [holl "text 16"] 1 { 1 14 } 0 { }\n" talk_to client 1 simple_expect ":18 15 16 $any_time 6 0 7 0 2 { 1 14 6 2 } 0 \\\*" talk_to client 2 simple_expect ":18 15 16 $any_time 6 0 7 0 2 { 1 14 6 2 } 0 \\\*" talk_to client 0 simple_expect "=1121 16" send "1122 90 16\n" simple_expect "=1122 $any_time 6 0 7 0 2 { 1 14 6 2 } 0 \\\*" talk_to client 1 send "1123 90 16\n" simple_expect "=1123 $any_time 6 0 7 0 2 { 1 14 6 2 } 0 \\\*" talk_to client 2 send "1124 90 16\n" simple_expect "=1124 $any_time 6 0 7 0 2 { 1 14 6 2 } 0 \\\*" talk_to client 3 send "1125 90 16\n" simple_expect "=1125 $any_time 6 0 7 0 2 { 1 14 6 2 } 0 \\\*" talk_to client 0 # Deleting text 16; deleter 6 send "1126 29 16\n" talk_to client 1 simple_expect ":18 14 16 $any_time 6 0 7 0 2 { 1 14 6 2 } 0 \\\*" talk_to client 2 simple_expect ":18 14 16 $any_time 6 0 7 0 2 { 1 14 6 2 } 0 \\\*" talk_to client 0 simple_expect "=1126" # Creating text 17 by 6 send "1127 86 [holl "text 17"] 1 { 15 6 } 0 { }\n" simple_expect ":18 15 17 $any_time 6 0 7 0 2 { 15 6 6 3 } 0 \\\*" simple_expect "=1127 17" send "1128 90 17\n" simple_expect "=1128 $any_time 6 0 7 0 2 { 15 6 6 3 } 0 \\\*" talk_to client 1 send "1129 90 17\n" simple_expect "%1129 14 17" talk_to client 2 send "1130 90 17\n" simple_expect "%1130 14 17" talk_to client 3 send "1131 90 17\n" simple_expect "%1131 14 17" talk_to client 0 # Deleting text 17; deleter 6 send "1132 29 17\n" simple_expect ":18 14 17 $any_time 6 0 7 0 2 { 15 6 6 3 } 0 \\\*" simple_expect "=1132" # Creating text 18 by 6 send "1133 86 [holl "text 18"] 1 { 15 7 } 0 { }\n" simple_expect "=1133 18" send "1134 90 18\n" simple_expect "=1134 $any_time 6 0 7 0 2 { 15 7 6 3 } 0 \\\*" talk_to client 1 send "1135 90 18\n" simple_expect "=1135 $any_time 6 0 7 0 2 { 15 7 6 3 } 0 \\\*" talk_to client 2 send "1136 90 18\n" simple_expect "%1136 14 18" talk_to client 3 send "1137 90 18\n" simple_expect "%1137 14 18" talk_to client 0 # Deleting text 18; deleter 6 send "1138 29 18\n" simple_expect "=1138" # Creating text 19 by 6 send "1139 86 [holl "text 19"] 1 { 15 8 } 0 { }\n" talk_to client 2 simple_expect ":18 15 19 $any_time 6 0 7 0 2 { 15 8 6 3 } 0 \\\*" talk_to client 0 simple_expect "=1139 19" send "1140 90 19\n" simple_expect "=1140 $any_time 6 0 7 0 2 { 15 8 6 3 } 0 \\\*" talk_to client 1 send "1141 90 19\n" simple_expect "%1141 14 19" talk_to client 2 send "1142 90 19\n" simple_expect "=1142 $any_time 6 0 7 0 2 { 15 8 6 3 } 0 \\\*" talk_to client 3 send "1143 90 19\n" simple_expect "%1143 14 19" talk_to client 0 # Deleting text 19; deleter 6 send "1144 29 19\n" talk_to client 2 simple_expect ":18 14 19 $any_time 6 0 7 0 2 { 15 8 6 3 } 0 \\\*" talk_to client 0 simple_expect "=1144" # Creating text 20 by 6 send "1145 86 [holl "text 20"] 1 { 15 9 } 0 { }\n" talk_to client 3 simple_expect ":18 15 20 $any_time 6 0 7 0 2 { 15 9 6 3 } 0 \\\*" talk_to client 0 simple_expect "=1145 20" send "1146 90 20\n" simple_expect "=1146 $any_time 6 0 7 0 2 { 15 9 6 3 } 0 \\\*" talk_to client 1 send "1147 90 20\n" simple_expect "%1147 14 20" talk_to client 2 send "1148 90 20\n" simple_expect "%1148 14 20" talk_to client 3 send "1149 90 20\n" simple_expect "=1149 $any_time 6 0 7 0 2 { 15 9 6 3 } 0 \\\*" talk_to client 0 # Deleting text 20; deleter 6 send "1150 29 20\n" talk_to client 3 simple_expect ":18 14 20 $any_time 6 0 7 0 2 { 15 9 6 3 } 0 \\\*" talk_to client 0 simple_expect "=1150" # Creating text 21 by 6 send "1151 86 [holl "text 21"] 1 { 15 10 } 0 { }\n" talk_to client 1 simple_expect ":18 15 21 $any_time 6 0 7 0 2 { 15 10 6 3 } 0 \\\*" talk_to client 2 simple_expect ":18 15 21 $any_time 6 0 7 0 2 { 15 10 6 3 } 0 \\\*" talk_to client 0 simple_expect "=1151 21" send "1152 90 21\n" simple_expect "=1152 $any_time 6 0 7 0 2 { 15 10 6 3 } 0 \\\*" talk_to client 1 send "1153 90 21\n" simple_expect "=1153 $any_time 6 0 7 0 2 { 15 10 6 3 } 0 \\\*" talk_to client 2 send "1154 90 21\n" simple_expect "=1154 $any_time 6 0 7 0 2 { 15 10 6 3 } 0 \\\*" talk_to client 3 send "1155 90 21\n" simple_expect "=1155 $any_time 6 0 7 0 2 { 15 10 6 3 } 0 \\\*" talk_to client 0 # Deleting text 21; deleter 6 send "1156 29 21\n" talk_to client 1 simple_expect ":18 14 21 $any_time 6 0 7 0 2 { 15 10 6 3 } 0 \\\*" talk_to client 2 simple_expect ":18 14 21 $any_time 6 0 7 0 2 { 15 10 6 3 } 0 \\\*" talk_to client 0 simple_expect "=1156" # Creating text 22 by 6 send "1157 86 [holl "text 22"] 1 { 15 11 } 0 { }\n" talk_to client 1 simple_expect ":18 15 22 $any_time 6 0 7 0 2 { 15 11 6 3 } 0 \\\*" talk_to client 2 simple_expect ":18 15 22 $any_time 6 0 7 0 2 { 15 11 6 3 } 0 \\\*" talk_to client 0 simple_expect "=1157 22" send "1158 90 22\n" simple_expect "=1158 $any_time 6 0 7 0 2 { 15 11 6 3 } 0 \\\*" talk_to client 1 send "1159 90 22\n" simple_expect "=1159 $any_time 6 0 7 0 2 { 15 11 6 3 } 0 \\\*" talk_to client 2 send "1160 90 22\n" simple_expect "=1160 $any_time 6 0 7 0 2 { 15 11 6 3 } 0 \\\*" talk_to client 3 send "1161 90 22\n" simple_expect "%1161 14 22" talk_to client 0 # Deleting text 22; deleter 6 send "1162 29 22\n" talk_to client 1 simple_expect ":18 14 22 $any_time 6 0 7 0 2 { 15 11 6 3 } 0 \\\*" talk_to client 2 simple_expect ":18 14 22 $any_time 6 0 7 0 2 { 15 11 6 3 } 0 \\\*" talk_to client 0 simple_expect "=1162" # Creating text 23 by 6 send "1163 86 [holl "text 23"] 1 { 15 13 } 0 { }\n" talk_to client 1 simple_expect ":18 15 23 $any_time 6 0 7 0 2 { 15 13 6 3 } 0 \\\*" talk_to client 2 simple_expect ":18 15 23 $any_time 6 0 7 0 2 { 15 13 6 3 } 0 \\\*" talk_to client 0 simple_expect "=1163 23" send "1164 90 23\n" simple_expect "=1164 $any_time 6 0 7 0 2 { 15 13 6 3 } 0 \\\*" talk_to client 1 send "1165 90 23\n" simple_expect "=1165 $any_time 6 0 7 0 2 { 15 13 6 3 } 0 \\\*" talk_to client 2 send "1166 90 23\n" simple_expect "=1166 $any_time 6 0 7 0 2 { 15 13 6 3 } 0 \\\*" talk_to client 3 send "1167 90 23\n" simple_expect "=1167 $any_time 6 0 7 0 2 { 15 13 6 3 } 0 \\\*" talk_to client 0 # Deleting text 23; deleter 6 send "1168 29 23\n" talk_to client 1 simple_expect ":18 14 23 $any_time 6 0 7 0 2 { 15 13 6 3 } 0 \\\*" talk_to client 2 simple_expect ":18 14 23 $any_time 6 0 7 0 2 { 15 13 6 3 } 0 \\\*" talk_to client 0 simple_expect "=1168" # Creating text 24 by 6 send "1169 86 [holl "text 24"] 1 { 15 14 } 0 { }\n" talk_to client 1 simple_expect ":18 15 24 $any_time 6 0 7 0 2 { 15 14 6 3 } 0 \\\*" talk_to client 2 simple_expect ":18 15 24 $any_time 6 0 7 0 2 { 15 14 6 3 } 0 \\\*" talk_to client 0 simple_expect "=1169 24" send "1170 90 24\n" simple_expect "=1170 $any_time 6 0 7 0 2 { 15 14 6 3 } 0 \\\*" talk_to client 1 send "1171 90 24\n" simple_expect "=1171 $any_time 6 0 7 0 2 { 15 14 6 3 } 0 \\\*" talk_to client 2 send "1172 90 24\n" simple_expect "=1172 $any_time 6 0 7 0 2 { 15 14 6 3 } 0 \\\*" talk_to client 3 send "1173 90 24\n" simple_expect "=1173 $any_time 6 0 7 0 2 { 15 14 6 3 } 0 \\\*" talk_to client 0 # Deleting text 24; deleter 6 send "1174 29 24\n" talk_to client 1 simple_expect ":18 14 24 $any_time 6 0 7 0 2 { 15 14 6 3 } 0 \\\*" talk_to client 2 simple_expect ":18 14 24 $any_time 6 0 7 0 2 { 15 14 6 3 } 0 \\\*" talk_to client 0 simple_expect "=1174" talk_to client 1 # Creating text 25 by 7 send "1175 86 [holl "text 25"] 1 { 0 6 } 0 { }\n" talk_to client 0 simple_expect ":18 15 25 $any_time 7 0 7 0 2 { 0 6 6 4 } 0 \\\*" talk_to client 1 simple_expect "=1175 25" talk_to client 0 send "1176 90 25\n" simple_expect "=1176 $any_time 7 0 7 0 2 { 0 6 6 4 } 0 \\\*" talk_to client 1 send "1177 90 25\n" simple_expect "=1177 $any_time 7 0 7 0 2 { 0 6 6 4 } 0 \\\*" talk_to client 2 send "1178 90 25\n" simple_expect "%1178 14 25" talk_to client 3 send "1179 90 25\n" simple_expect "%1179 14 25" talk_to client 1 # Deleting text 25; deleter 7 send "1180 29 25\n" talk_to client 0 simple_expect ":18 14 25 $any_time 7 0 7 0 2 { 0 6 6 4 } 0 \\\*" talk_to client 1 simple_expect "=1180" # Creating text 26 by 7 send "1181 86 [holl "text 26"] 1 { 0 7 } 0 { }\n" simple_expect "=1181 26" talk_to client 0 send "1182 90 26\n" simple_expect "%1182 14 26" talk_to client 1 send "1183 90 26\n" simple_expect "=1183 $any_time 7 0 7 0 2 { 0 7 6 4 } 0 \\\*" talk_to client 2 send "1184 90 26\n" simple_expect "%1184 14 26" talk_to client 3 send "1185 90 26\n" simple_expect "%1185 14 26" talk_to client 1 # Deleting text 26; deleter 7 send "1186 29 26\n" simple_expect "=1186" # Creating text 27 by 7 send "1187 86 [holl "text 27"] 1 { 0 8 } 0 { }\n" talk_to client 2 simple_expect ":18 15 27 $any_time 7 0 7 0 2 { 0 8 6 4 } 0 \\\*" talk_to client 1 simple_expect "=1187 27" talk_to client 0 send "1188 90 27\n" simple_expect "%1188 14 27" talk_to client 1 send "1189 90 27\n" simple_expect "=1189 $any_time 7 0 7 0 2 { 0 8 6 4 } 0 \\\*" talk_to client 2 send "1190 90 27\n" simple_expect "=1190 $any_time 7 0 7 0 2 { 0 8 6 4 } 0 \\\*" talk_to client 3 send "1191 90 27\n" simple_expect "%1191 14 27" talk_to client 1 # Deleting text 27; deleter 7 send "1192 29 27\n" talk_to client 2 simple_expect ":18 14 27 $any_time 7 0 7 0 2 { 0 8 6 4 } 0 \\\*" talk_to client 1 simple_expect "=1192" # Creating text 28 by 7 send "1193 86 [holl "text 28"] 1 { 0 9 } 0 { }\n" talk_to client 3 simple_expect ":18 15 28 $any_time 7 0 7 0 2 { 0 9 6 4 } 0 \\\*" talk_to client 1 simple_expect "=1193 28" talk_to client 0 send "1194 90 28\n" simple_expect "%1194 14 28" talk_to client 1 send "1195 90 28\n" simple_expect "=1195 $any_time 7 0 7 0 2 { 0 9 6 4 } 0 \\\*" talk_to client 2 send "1196 90 28\n" simple_expect "%1196 14 28" talk_to client 3 send "1197 90 28\n" simple_expect "=1197 $any_time 7 0 7 0 2 { 0 9 6 4 } 0 \\\*" talk_to client 1 # Deleting text 28; deleter 7 send "1198 29 28\n" talk_to client 3 simple_expect ":18 14 28 $any_time 7 0 7 0 2 { 0 9 6 4 } 0 \\\*" talk_to client 1 simple_expect "=1198" # Creating text 29 by 7 send "1199 86 [holl "text 29"] 1 { 0 10 } 0 { }\n" simple_expect ":18 15 29 $any_time 7 0 7 0 2 { 0 10 6 4 } 0 \\\*" talk_to client 2 simple_expect ":18 15 29 $any_time 7 0 7 0 2 { 0 10 6 4 } 0 \\\*" talk_to client 1 simple_expect "=1199 29" talk_to client 0 send "1200 90 29\n" simple_expect "=1200 $any_time 7 0 7 0 2 { 0 10 6 4 } 0 \\\*" talk_to client 1 send "1201 90 29\n" simple_expect "=1201 $any_time 7 0 7 0 2 { 0 10 6 4 } 0 \\\*" talk_to client 2 send "1202 90 29\n" simple_expect "=1202 $any_time 7 0 7 0 2 { 0 10 6 4 } 0 \\\*" talk_to client 3 send "1203 90 29\n" simple_expect "=1203 $any_time 7 0 7 0 2 { 0 10 6 4 } 0 \\\*" talk_to client 1 # Deleting text 29; deleter 7 send "1204 29 29\n" simple_expect ":18 14 29 $any_time 7 0 7 0 2 { 0 10 6 4 } 0 \\\*" talk_to client 2 simple_expect ":18 14 29 $any_time 7 0 7 0 2 { 0 10 6 4 } 0 \\\*" talk_to client 1 simple_expect "=1204" # Creating text 30 by 7 send "1205 86 [holl "text 30"] 1 { 0 11 } 0 { }\n" simple_expect ":18 15 30 $any_time 7 0 7 0 2 { 0 11 6 4 } 0 \\\*" talk_to client 2 simple_expect ":18 15 30 $any_time 7 0 7 0 2 { 0 11 6 4 } 0 \\\*" talk_to client 1 simple_expect "=1205 30" talk_to client 0 send "1206 90 30\n" simple_expect "%1206 14 30" talk_to client 1 send "1207 90 30\n" simple_expect "=1207 $any_time 7 0 7 0 2 { 0 11 6 4 } 0 \\\*" talk_to client 2 send "1208 90 30\n" simple_expect "=1208 $any_time 7 0 7 0 2 { 0 11 6 4 } 0 \\\*" talk_to client 3 send "1209 90 30\n" simple_expect "%1209 14 30" talk_to client 1 # Deleting text 30; deleter 7 send "1210 29 30\n" simple_expect ":18 14 30 $any_time 7 0 7 0 2 { 0 11 6 4 } 0 \\\*" talk_to client 2 simple_expect ":18 14 30 $any_time 7 0 7 0 2 { 0 11 6 4 } 0 \\\*" talk_to client 1 simple_expect "=1210" # Creating text 31 by 7 send "1211 86 [holl "text 31"] 1 { 0 12 } 0 { }\n" simple_expect ":18 15 31 $any_time 7 0 7 0 2 { 0 12 6 1 } 0 \\\*" talk_to client 2 simple_expect ":18 15 31 $any_time 7 0 7 0 2 { 0 12 6 1 } 0 \\\*" talk_to client 1 simple_expect "=1211 31" talk_to client 0 send "1212 90 31\n" simple_expect "%1212 14 31" talk_to client 1 send "1213 90 31\n" simple_expect "=1213 $any_time 7 0 7 0 2 { 0 12 6 1 } 0 \\\*" talk_to client 2 send "1214 90 31\n" simple_expect "=1214 $any_time 7 0 7 0 2 { 0 12 6 1 } 0 \\\*" talk_to client 3 send "1215 90 31\n" simple_expect "%1215 14 31" talk_to client 1 # Deleting text 31; deleter 7 send "1216 29 31\n" simple_expect ":18 14 31 $any_time 7 0 7 0 2 { 0 12 6 1 } 0 \\\*" talk_to client 2 simple_expect ":18 14 31 $any_time 7 0 7 0 2 { 0 12 6 1 } 0 \\\*" talk_to client 1 simple_expect "=1216" # Creating text 32 by 7 send "1217 86 [holl "text 32"] 1 { 0 13 } 0 { }\n" simple_expect ":18 15 32 $any_time 7 0 7 0 2 { 0 13 6 4 } 0 \\\*" talk_to client 2 simple_expect ":18 15 32 $any_time 7 0 7 0 2 { 0 13 6 4 } 0 \\\*" talk_to client 1 simple_expect "=1217 32" talk_to client 0 send "1218 90 32\n" simple_expect "=1218 $any_time 7 0 7 0 2 { 0 13 6 4 } 0 \\\*" talk_to client 1 send "1219 90 32\n" simple_expect "=1219 $any_time 7 0 7 0 2 { 0 13 6 4 } 0 \\\*" talk_to client 2 send "1220 90 32\n" simple_expect "=1220 $any_time 7 0 7 0 2 { 0 13 6 4 } 0 \\\*" talk_to client 3 send "1221 90 32\n" simple_expect "=1221 $any_time 7 0 7 0 2 { 0 13 6 4 } 0 \\\*" talk_to client 1 # Deleting text 32; deleter 7 send "1222 29 32\n" simple_expect ":18 14 32 $any_time 7 0 7 0 2 { 0 13 6 4 } 0 \\\*" talk_to client 2 simple_expect ":18 14 32 $any_time 7 0 7 0 2 { 0 13 6 4 } 0 \\\*" talk_to client 1 simple_expect "=1222" # Creating text 33 by 7 send "1223 86 [holl "text 33"] 1 { 0 14 } 0 { }\n" simple_expect ":18 15 33 $any_time 7 0 7 0 2 { 0 14 6 4 } 0 \\\*" talk_to client 2 simple_expect ":18 15 33 $any_time 7 0 7 0 2 { 0 14 6 4 } 0 \\\*" talk_to client 1 simple_expect "=1223 33" talk_to client 0 send "1224 90 33\n" simple_expect "%1224 14 33" talk_to client 1 send "1225 90 33\n" simple_expect "=1225 $any_time 7 0 7 0 2 { 0 14 6 4 } 0 \\\*" talk_to client 2 send "1226 90 33\n" simple_expect "=1226 $any_time 7 0 7 0 2 { 0 14 6 4 } 0 \\\*" talk_to client 3 send "1227 90 33\n" simple_expect "=1227 $any_time 7 0 7 0 2 { 0 14 6 4 } 0 \\\*" talk_to client 1 # Deleting text 33; deleter 7 send "1228 29 33\n" simple_expect ":18 14 33 $any_time 7 0 7 0 2 { 0 14 6 4 } 0 \\\*" talk_to client 2 simple_expect ":18 14 33 $any_time 7 0 7 0 2 { 0 14 6 4 } 0 \\\*" talk_to client 1 simple_expect "=1228" # Creating text 34 by 7 send "1229 86 [holl "text 34"] 1 { 0 15 } 0 { }\n" simple_expect ":18 15 34 $any_time 7 0 7 0 2 { 0 15 6 1 } 0 \\\*" talk_to client 2 simple_expect ":18 15 34 $any_time 7 0 7 0 2 { 0 15 6 1 } 0 \\\*" talk_to client 1 simple_expect "=1229 34" talk_to client 0 send "1230 90 34\n" simple_expect "%1230 14 34" talk_to client 1 send "1231 90 34\n" simple_expect "=1231 $any_time 7 0 7 0 2 { 0 15 6 1 } 0 \\\*" talk_to client 2 send "1232 90 34\n" simple_expect "=1232 $any_time 7 0 7 0 2 { 0 15 6 1 } 0 \\\*" talk_to client 3 send "1233 90 34\n" simple_expect "=1233 $any_time 7 0 7 0 2 { 0 15 6 1 } 0 \\\*" talk_to client 1 # Deleting text 34; deleter 7 send "1234 29 34\n" simple_expect ":18 14 34 $any_time 7 0 7 0 2 { 0 15 6 1 } 0 \\\*" talk_to client 2 simple_expect ":18 14 34 $any_time 7 0 7 0 2 { 0 15 6 1 } 0 \\\*" talk_to client 1 simple_expect "=1234" # Creating text 35 by 7 send "1235 86 [holl "text 35"] 1 { 1 6 } 0 { }\n" talk_to client 0 simple_expect ":18 15 35 $any_time 7 0 7 0 2 { 1 6 6 5 } 0 \\\*" talk_to client 1 simple_expect "=1235 35" talk_to client 0 send "1236 90 35\n" simple_expect "=1236 $any_time 7 0 7 0 2 { 1 6 6 5 } 0 \\\*" talk_to client 1 send "1237 90 35\n" simple_expect "=1237 $any_time 7 0 7 0 2 { 1 6 6 5 } 0 \\\*" talk_to client 2 send "1238 90 35\n" simple_expect "%1238 14 35" talk_to client 3 send "1239 90 35\n" simple_expect "%1239 14 35" talk_to client 1 # Deleting text 35; deleter 7 send "1240 29 35\n" talk_to client 0 simple_expect ":18 14 35 $any_time 7 0 7 0 2 { 1 6 6 5 } 0 \\\*" talk_to client 1 simple_expect "=1240" # Creating text 36 by 7 send "1241 86 [holl "text 36"] 1 { 1 7 } 0 { }\n" simple_expect "=1241 36" talk_to client 0 send "1242 90 36\n" simple_expect "%1242 14 36" talk_to client 1 send "1243 90 36\n" simple_expect "=1243 $any_time 7 0 7 0 2 { 1 7 6 5 } 0 \\\*" talk_to client 2 send "1244 90 36\n" simple_expect "%1244 14 36" talk_to client 3 send "1245 90 36\n" simple_expect "%1245 14 36" talk_to client 1 # Deleting text 36; deleter 7 send "1246 29 36\n" simple_expect "=1246" # Creating text 37 by 7 send "1247 86 [holl "text 37"] 1 { 1 8 } 0 { }\n" talk_to client 2 simple_expect ":18 15 37 $any_time 7 0 7 0 2 { 1 8 6 5 } 0 \\\*" talk_to client 1 simple_expect "=1247 37" talk_to client 0 send "1248 90 37\n" simple_expect "%1248 14 37" talk_to client 1 send "1249 90 37\n" simple_expect "=1249 $any_time 7 0 7 0 2 { 1 8 6 5 } 0 \\\*" talk_to client 2 send "1250 90 37\n" simple_expect "=1250 $any_time 7 0 7 0 2 { 1 8 6 5 } 0 \\\*" talk_to client 3 send "1251 90 37\n" simple_expect "%1251 14 37" talk_to client 1 # Deleting text 37; deleter 7 send "1252 29 37\n" talk_to client 2 simple_expect ":18 14 37 $any_time 7 0 7 0 2 { 1 8 6 5 } 0 \\\*" talk_to client 1 simple_expect "=1252" # Creating text 38 by 7 send "1253 86 [holl "text 38"] 1 { 1 9 } 0 { }\n" talk_to client 3 simple_expect ":18 15 38 $any_time 7 0 7 0 2 { 1 9 6 5 } 0 \\\*" talk_to client 1 simple_expect "=1253 38" talk_to client 0 send "1254 90 38\n" simple_expect "%1254 14 38" talk_to client 1 send "1255 90 38\n" simple_expect "=1255 $any_time 7 0 7 0 2 { 1 9 6 5 } 0 \\\*" talk_to client 2 send "1256 90 38\n" simple_expect "%1256 14 38" talk_to client 3 send "1257 90 38\n" simple_expect "=1257 $any_time 7 0 7 0 2 { 1 9 6 5 } 0 \\\*" talk_to client 1 # Deleting text 38; deleter 7 send "1258 29 38\n" talk_to client 3 simple_expect ":18 14 38 $any_time 7 0 7 0 2 { 1 9 6 5 } 0 \\\*" talk_to client 1 simple_expect "=1258" # Creating text 39 by 7 send "1259 86 [holl "text 39"] 1 { 1 10 } 0 { }\n" simple_expect ":18 15 39 $any_time 7 0 7 0 2 { 1 10 6 5 } 0 \\\*" talk_to client 2 simple_expect ":18 15 39 $any_time 7 0 7 0 2 { 1 10 6 5 } 0 \\\*" talk_to client 1 simple_expect "=1259 39" talk_to client 0 send "1260 90 39\n" simple_expect "=1260 $any_time 7 0 7 0 2 { 1 10 6 5 } 0 \\\*" talk_to client 1 send "1261 90 39\n" simple_expect "=1261 $any_time 7 0 7 0 2 { 1 10 6 5 } 0 \\\*" talk_to client 2 send "1262 90 39\n" simple_expect "=1262 $any_time 7 0 7 0 2 { 1 10 6 5 } 0 \\\*" talk_to client 3 send "1263 90 39\n" simple_expect "=1263 $any_time 7 0 7 0 2 { 1 10 6 5 } 0 \\\*" talk_to client 1 # Deleting text 39; deleter 7 send "1264 29 39\n" simple_expect ":18 14 39 $any_time 7 0 7 0 2 { 1 10 6 5 } 0 \\\*" talk_to client 2 simple_expect ":18 14 39 $any_time 7 0 7 0 2 { 1 10 6 5 } 0 \\\*" talk_to client 1 simple_expect "=1264" # Creating text 40 by 7 send "1265 86 [holl "text 40"] 1 { 1 11 } 0 { }\n" simple_expect ":18 15 40 $any_time 7 0 7 0 2 { 1 11 6 5 } 0 \\\*" talk_to client 2 simple_expect ":18 15 40 $any_time 7 0 7 0 2 { 1 11 6 5 } 0 \\\*" talk_to client 1 simple_expect "=1265 40" talk_to client 0 send "1266 90 40\n" simple_expect "%1266 14 40" talk_to client 1 send "1267 90 40\n" simple_expect "=1267 $any_time 7 0 7 0 2 { 1 11 6 5 } 0 \\\*" talk_to client 2 send "1268 90 40\n" simple_expect "=1268 $any_time 7 0 7 0 2 { 1 11 6 5 } 0 \\\*" talk_to client 3 send "1269 90 40\n" simple_expect "%1269 14 40" talk_to client 1 # Deleting text 40; deleter 7 send "1270 29 40\n" simple_expect ":18 14 40 $any_time 7 0 7 0 2 { 1 11 6 5 } 0 \\\*" talk_to client 2 simple_expect ":18 14 40 $any_time 7 0 7 0 2 { 1 11 6 5 } 0 \\\*" talk_to client 1 simple_expect "=1270" # Creating text 41 by 7 send "1271 86 [holl "text 41"] 1 { 1 12 } 0 { }\n" simple_expect ":18 15 41 $any_time 7 0 7 0 2 { 1 12 6 2 } 0 \\\*" talk_to client 2 simple_expect ":18 15 41 $any_time 7 0 7 0 2 { 1 12 6 2 } 0 \\\*" talk_to client 1 simple_expect "=1271 41" talk_to client 0 send "1272 90 41\n" simple_expect "%1272 14 41" talk_to client 1 send "1273 90 41\n" simple_expect "=1273 $any_time 7 0 7 0 2 { 1 12 6 2 } 0 \\\*" talk_to client 2 send "1274 90 41\n" simple_expect "=1274 $any_time 7 0 7 0 2 { 1 12 6 2 } 0 \\\*" talk_to client 3 send "1275 90 41\n" simple_expect "%1275 14 41" talk_to client 1 # Deleting text 41; deleter 7 send "1276 29 41\n" simple_expect ":18 14 41 $any_time 7 0 7 0 2 { 1 12 6 2 } 0 \\\*" talk_to client 2 simple_expect ":18 14 41 $any_time 7 0 7 0 2 { 1 12 6 2 } 0 \\\*" talk_to client 1 simple_expect "=1276" # Creating text 42 by 7 send "1277 86 [holl "text 42"] 1 { 1 13 } 0 { }\n" simple_expect ":18 15 42 $any_time 7 0 7 0 2 { 1 13 6 5 } 0 \\\*" talk_to client 2 simple_expect ":18 15 42 $any_time 7 0 7 0 2 { 1 13 6 5 } 0 \\\*" talk_to client 1 simple_expect "=1277 42" talk_to client 0 send "1278 90 42\n" simple_expect "=1278 $any_time 7 0 7 0 2 { 1 13 6 5 } 0 \\\*" talk_to client 1 send "1279 90 42\n" simple_expect "=1279 $any_time 7 0 7 0 2 { 1 13 6 5 } 0 \\\*" talk_to client 2 send "1280 90 42\n" simple_expect "=1280 $any_time 7 0 7 0 2 { 1 13 6 5 } 0 \\\*" talk_to client 3 send "1281 90 42\n" simple_expect "=1281 $any_time 7 0 7 0 2 { 1 13 6 5 } 0 \\\*" talk_to client 1 # Deleting text 42; deleter 7 send "1282 29 42\n" simple_expect ":18 14 42 $any_time 7 0 7 0 2 { 1 13 6 5 } 0 \\\*" talk_to client 2 simple_expect ":18 14 42 $any_time 7 0 7 0 2 { 1 13 6 5 } 0 \\\*" talk_to client 1 simple_expect "=1282" # Creating text 43 by 7 send "1283 86 [holl "text 43"] 1 { 1 14 } 0 { }\n" simple_expect ":18 15 43 $any_time 7 0 7 0 2 { 1 14 6 5 } 0 \\\*" talk_to client 2 simple_expect ":18 15 43 $any_time 7 0 7 0 2 { 1 14 6 5 } 0 \\\*" talk_to client 1 simple_expect "=1283 43" talk_to client 0 send "1284 90 43\n" simple_expect "%1284 14 43" talk_to client 1 send "1285 90 43\n" simple_expect "=1285 $any_time 7 0 7 0 2 { 1 14 6 5 } 0 \\\*" talk_to client 2 send "1286 90 43\n" simple_expect "=1286 $any_time 7 0 7 0 2 { 1 14 6 5 } 0 \\\*" talk_to client 3 send "1287 90 43\n" simple_expect "=1287 $any_time 7 0 7 0 2 { 1 14 6 5 } 0 \\\*" talk_to client 1 # Deleting text 43; deleter 7 send "1288 29 43\n" simple_expect ":18 14 43 $any_time 7 0 7 0 2 { 1 14 6 5 } 0 \\\*" talk_to client 2 simple_expect ":18 14 43 $any_time 7 0 7 0 2 { 1 14 6 5 } 0 \\\*" talk_to client 1 simple_expect "=1288" # Creating text 44 by 7 send "1289 86 [holl "text 44"] 1 { 1 15 } 0 { }\n" simple_expect ":18 15 44 $any_time 7 0 7 0 2 { 1 15 6 2 } 0 \\\*" talk_to client 2 simple_expect ":18 15 44 $any_time 7 0 7 0 2 { 1 15 6 2 } 0 \\\*" talk_to client 1 simple_expect "=1289 44" talk_to client 0 send "1290 90 44\n" simple_expect "%1290 14 44" talk_to client 1 send "1291 90 44\n" simple_expect "=1291 $any_time 7 0 7 0 2 { 1 15 6 2 } 0 \\\*" talk_to client 2 send "1292 90 44\n" simple_expect "=1292 $any_time 7 0 7 0 2 { 1 15 6 2 } 0 \\\*" talk_to client 3 send "1293 90 44\n" simple_expect "=1293 $any_time 7 0 7 0 2 { 1 15 6 2 } 0 \\\*" talk_to client 1 # Deleting text 44; deleter 7 send "1294 29 44\n" simple_expect ":18 14 44 $any_time 7 0 7 0 2 { 1 15 6 2 } 0 \\\*" talk_to client 2 simple_expect ":18 14 44 $any_time 7 0 7 0 2 { 1 15 6 2 } 0 \\\*" talk_to client 1 simple_expect "=1294" # Creating text 45 by 7 send "1295 86 [holl "text 45"] 1 { 15 6 } 0 { }\n" talk_to client 0 simple_expect ":18 15 45 $any_time 7 0 7 0 2 { 15 6 6 6 } 0 \\\*" talk_to client 1 simple_expect "=1295 45" talk_to client 0 send "1296 90 45\n" simple_expect "=1296 $any_time 7 0 7 0 2 { 15 6 6 6 } 0 \\\*" talk_to client 1 send "1297 90 45\n" simple_expect "=1297 $any_time 7 0 7 0 2 { 15 6 6 6 } 0 \\\*" talk_to client 2 send "1298 90 45\n" simple_expect "%1298 14 45" talk_to client 3 send "1299 90 45\n" simple_expect "%1299 14 45" talk_to client 1 # Deleting text 45; deleter 7 send "1300 29 45\n" talk_to client 0 simple_expect ":18 14 45 $any_time 7 0 7 0 2 { 15 6 6 6 } 0 \\\*" talk_to client 1 simple_expect "=1300" # Creating text 46 by 7 send "1301 86 [holl "text 46"] 1 { 15 7 } 0 { }\n" simple_expect "=1301 46" talk_to client 0 send "1302 90 46\n" simple_expect "%1302 14 46" talk_to client 1 send "1303 90 46\n" simple_expect "=1303 $any_time 7 0 7 0 2 { 15 7 6 6 } 0 \\\*" talk_to client 2 send "1304 90 46\n" simple_expect "%1304 14 46" talk_to client 3 send "1305 90 46\n" simple_expect "%1305 14 46" talk_to client 1 # Deleting text 46; deleter 7 send "1306 29 46\n" simple_expect "=1306" # Creating text 47 by 7 send "1307 86 [holl "text 47"] 1 { 15 8 } 0 { }\n" talk_to client 2 simple_expect ":18 15 47 $any_time 7 0 7 0 2 { 15 8 6 6 } 0 \\\*" talk_to client 1 simple_expect "=1307 47" talk_to client 0 send "1308 90 47\n" simple_expect "%1308 14 47" talk_to client 1 send "1309 90 47\n" simple_expect "=1309 $any_time 7 0 7 0 2 { 15 8 6 6 } 0 \\\*" talk_to client 2 send "1310 90 47\n" simple_expect "=1310 $any_time 7 0 7 0 2 { 15 8 6 6 } 0 \\\*" talk_to client 3 send "1311 90 47\n" simple_expect "%1311 14 47" talk_to client 1 # Deleting text 47; deleter 7 send "1312 29 47\n" talk_to client 2 simple_expect ":18 14 47 $any_time 7 0 7 0 2 { 15 8 6 6 } 0 \\\*" talk_to client 1 simple_expect "=1312" # Creating text 48 by 7 send "1313 86 [holl "text 48"] 1 { 15 9 } 0 { }\n" talk_to client 3 simple_expect ":18 15 48 $any_time 7 0 7 0 2 { 15 9 6 6 } 0 \\\*" talk_to client 1 simple_expect "=1313 48" talk_to client 0 send "1314 90 48\n" simple_expect "%1314 14 48" talk_to client 1 send "1315 90 48\n" simple_expect "=1315 $any_time 7 0 7 0 2 { 15 9 6 6 } 0 \\\*" talk_to client 2 send "1316 90 48\n" simple_expect "%1316 14 48" talk_to client 3 send "1317 90 48\n" simple_expect "=1317 $any_time 7 0 7 0 2 { 15 9 6 6 } 0 \\\*" talk_to client 1 # Deleting text 48; deleter 7 send "1318 29 48\n" talk_to client 3 simple_expect ":18 14 48 $any_time 7 0 7 0 2 { 15 9 6 6 } 0 \\\*" talk_to client 1 simple_expect "=1318" # Creating text 49 by 7 send "1319 86 [holl "text 49"] 1 { 15 10 } 0 { }\n" simple_expect ":18 15 49 $any_time 7 0 7 0 2 { 15 10 6 6 } 0 \\\*" talk_to client 2 simple_expect ":18 15 49 $any_time 7 0 7 0 2 { 15 10 6 6 } 0 \\\*" talk_to client 1 simple_expect "=1319 49" talk_to client 0 send "1320 90 49\n" simple_expect "=1320 $any_time 7 0 7 0 2 { 15 10 6 6 } 0 \\\*" talk_to client 1 send "1321 90 49\n" simple_expect "=1321 $any_time 7 0 7 0 2 { 15 10 6 6 } 0 \\\*" talk_to client 2 send "1322 90 49\n" simple_expect "=1322 $any_time 7 0 7 0 2 { 15 10 6 6 } 0 \\\*" talk_to client 3 send "1323 90 49\n" simple_expect "=1323 $any_time 7 0 7 0 2 { 15 10 6 6 } 0 \\\*" talk_to client 1 # Deleting text 49; deleter 7 send "1324 29 49\n" simple_expect ":18 14 49 $any_time 7 0 7 0 2 { 15 10 6 6 } 0 \\\*" talk_to client 2 simple_expect ":18 14 49 $any_time 7 0 7 0 2 { 15 10 6 6 } 0 \\\*" talk_to client 1 simple_expect "=1324" # Creating text 50 by 7 send "1325 86 [holl "text 50"] 1 { 15 11 } 0 { }\n" simple_expect ":18 15 50 $any_time 7 0 7 0 2 { 15 11 6 6 } 0 \\\*" talk_to client 2 simple_expect ":18 15 50 $any_time 7 0 7 0 2 { 15 11 6 6 } 0 \\\*" talk_to client 1 simple_expect "=1325 50" talk_to client 0 send "1326 90 50\n" simple_expect "%1326 14 50" talk_to client 1 send "1327 90 50\n" simple_expect "=1327 $any_time 7 0 7 0 2 { 15 11 6 6 } 0 \\\*" talk_to client 2 send "1328 90 50\n" simple_expect "=1328 $any_time 7 0 7 0 2 { 15 11 6 6 } 0 \\\*" talk_to client 3 send "1329 90 50\n" simple_expect "%1329 14 50" talk_to client 1 # Deleting text 50; deleter 7 send "1330 29 50\n" simple_expect ":18 14 50 $any_time 7 0 7 0 2 { 15 11 6 6 } 0 \\\*" talk_to client 2 simple_expect ":18 14 50 $any_time 7 0 7 0 2 { 15 11 6 6 } 0 \\\*" talk_to client 1 simple_expect "=1330" # Creating text 51 by 7 send "1331 86 [holl "text 51"] 1 { 15 12 } 0 { }\n" simple_expect ":18 15 51 $any_time 7 0 7 0 2 { 15 12 6 3 } 0 \\\*" talk_to client 2 simple_expect ":18 15 51 $any_time 7 0 7 0 2 { 15 12 6 3 } 0 \\\*" talk_to client 1 simple_expect "=1331 51" talk_to client 0 send "1332 90 51\n" simple_expect "%1332 14 51" talk_to client 1 send "1333 90 51\n" simple_expect "=1333 $any_time 7 0 7 0 2 { 15 12 6 3 } 0 \\\*" talk_to client 2 send "1334 90 51\n" simple_expect "=1334 $any_time 7 0 7 0 2 { 15 12 6 3 } 0 \\\*" talk_to client 3 send "1335 90 51\n" simple_expect "%1335 14 51" talk_to client 1 # Deleting text 51; deleter 7 send "1336 29 51\n" simple_expect ":18 14 51 $any_time 7 0 7 0 2 { 15 12 6 3 } 0 \\\*" talk_to client 2 simple_expect ":18 14 51 $any_time 7 0 7 0 2 { 15 12 6 3 } 0 \\\*" talk_to client 1 simple_expect "=1336" # Creating text 52 by 7 send "1337 86 [holl "text 52"] 1 { 15 13 } 0 { }\n" simple_expect ":18 15 52 $any_time 7 0 7 0 2 { 15 13 6 6 } 0 \\\*" talk_to client 2 simple_expect ":18 15 52 $any_time 7 0 7 0 2 { 15 13 6 6 } 0 \\\*" talk_to client 1 simple_expect "=1337 52" talk_to client 0 send "1338 90 52\n" simple_expect "=1338 $any_time 7 0 7 0 2 { 15 13 6 6 } 0 \\\*" talk_to client 1 send "1339 90 52\n" simple_expect "=1339 $any_time 7 0 7 0 2 { 15 13 6 6 } 0 \\\*" talk_to client 2 send "1340 90 52\n" simple_expect "=1340 $any_time 7 0 7 0 2 { 15 13 6 6 } 0 \\\*" talk_to client 3 send "1341 90 52\n" simple_expect "=1341 $any_time 7 0 7 0 2 { 15 13 6 6 } 0 \\\*" talk_to client 1 # Deleting text 52; deleter 7 send "1342 29 52\n" simple_expect ":18 14 52 $any_time 7 0 7 0 2 { 15 13 6 6 } 0 \\\*" talk_to client 2 simple_expect ":18 14 52 $any_time 7 0 7 0 2 { 15 13 6 6 } 0 \\\*" talk_to client 1 simple_expect "=1342" # Creating text 53 by 7 send "1343 86 [holl "text 53"] 1 { 15 14 } 0 { }\n" simple_expect ":18 15 53 $any_time 7 0 7 0 2 { 15 14 6 6 } 0 \\\*" talk_to client 2 simple_expect ":18 15 53 $any_time 7 0 7 0 2 { 15 14 6 6 } 0 \\\*" talk_to client 1 simple_expect "=1343 53" talk_to client 0 send "1344 90 53\n" simple_expect "%1344 14 53" talk_to client 1 send "1345 90 53\n" simple_expect "=1345 $any_time 7 0 7 0 2 { 15 14 6 6 } 0 \\\*" talk_to client 2 send "1346 90 53\n" simple_expect "=1346 $any_time 7 0 7 0 2 { 15 14 6 6 } 0 \\\*" talk_to client 3 send "1347 90 53\n" simple_expect "=1347 $any_time 7 0 7 0 2 { 15 14 6 6 } 0 \\\*" talk_to client 1 # Deleting text 53; deleter 7 send "1348 29 53\n" simple_expect ":18 14 53 $any_time 7 0 7 0 2 { 15 14 6 6 } 0 \\\*" talk_to client 2 simple_expect ":18 14 53 $any_time 7 0 7 0 2 { 15 14 6 6 } 0 \\\*" talk_to client 1 simple_expect "=1348" # Creating text 54 by 7 send "1349 86 [holl "text 54"] 1 { 15 15 } 0 { }\n" simple_expect ":18 15 54 $any_time 7 0 7 0 2 { 15 15 6 3 } 0 \\\*" talk_to client 2 simple_expect ":18 15 54 $any_time 7 0 7 0 2 { 15 15 6 3 } 0 \\\*" talk_to client 1 simple_expect "=1349 54" talk_to client 0 send "1350 90 54\n" simple_expect "%1350 14 54" talk_to client 1 send "1351 90 54\n" simple_expect "=1351 $any_time 7 0 7 0 2 { 15 15 6 3 } 0 \\\*" talk_to client 2 send "1352 90 54\n" simple_expect "=1352 $any_time 7 0 7 0 2 { 15 15 6 3 } 0 \\\*" talk_to client 3 send "1353 90 54\n" simple_expect "=1353 $any_time 7 0 7 0 2 { 15 15 6 3 } 0 \\\*" talk_to client 1 # Deleting text 54; deleter 7 send "1354 29 54\n" simple_expect ":18 14 54 $any_time 7 0 7 0 2 { 15 15 6 3 } 0 \\\*" talk_to client 2 simple_expect ":18 14 54 $any_time 7 0 7 0 2 { 15 15 6 3 } 0 \\\*" talk_to client 1 simple_expect "=1354" talk_to client 2 # Creating text 55 by 8 send "1355 86 [holl "text 55"] 1 { 0 6 } 0 { }\n" talk_to client 0 simple_expect ":18 15 55 $any_time 8 0 7 0 2 { 0 6 6 7 } 0 \\\*" talk_to client 2 simple_expect "=1355 55" talk_to client 0 send "1356 90 55\n" simple_expect "=1356 $any_time 8 0 7 0 2 { 0 6 6 7 } 0 \\\*" talk_to client 1 send "1357 90 55\n" simple_expect "%1357 14 55" talk_to client 2 send "1358 90 55\n" simple_expect "=1358 $any_time 8 0 7 0 2 { 0 6 6 7 } 0 \\\*" talk_to client 3 send "1359 90 55\n" simple_expect "%1359 14 55" talk_to client 2 # Deleting text 55; deleter 8 send "1360 29 55\n" talk_to client 0 simple_expect ":18 14 55 $any_time 8 0 7 0 2 { 0 6 6 7 } 0 \\\*" talk_to client 2 simple_expect "=1360" # Creating text 56 by 8 send "1361 86 [holl "text 56"] 1 { 0 7 } 0 { }\n" simple_expect "=1361 56" talk_to client 0 send "1362 90 56\n" simple_expect "%1362 14 56" talk_to client 1 send "1363 90 56\n" simple_expect "=1363 $any_time 8 0 7 0 2 { 0 7 6 7 } 0 \\\*" talk_to client 2 send "1364 90 56\n" simple_expect "=1364 $any_time 8 0 7 0 2 { 0 7 6 7 } 0 \\\*" talk_to client 3 send "1365 90 56\n" simple_expect "%1365 14 56" talk_to client 2 # Deleting text 56; deleter 8 send "1366 29 56\n" simple_expect "=1366" # Creating text 57 by 8 send "1367 86 [holl "text 57"] 1 { 0 8 } 0 { }\n" simple_expect ":18 15 57 $any_time 8 0 7 0 2 { 0 8 6 7 } 0 \\\*" simple_expect "=1367 57" talk_to client 0 send "1368 90 57\n" simple_expect "%1368 14 57" talk_to client 1 send "1369 90 57\n" simple_expect "%1369 14 57" talk_to client 2 send "1370 90 57\n" simple_expect "=1370 $any_time 8 0 7 0 2 { 0 8 6 7 } 0 \\\*" talk_to client 3 send "1371 90 57\n" simple_expect "%1371 14 57" talk_to client 2 # Deleting text 57; deleter 8 send "1372 29 57\n" simple_expect ":18 14 57 $any_time 8 0 7 0 2 { 0 8 6 7 } 0 \\\*" simple_expect "=1372" # Creating text 58 by 8 send "1373 86 [holl "text 58"] 1 { 0 9 } 0 { }\n" talk_to client 3 simple_expect ":18 15 58 $any_time 8 0 7 0 2 { 0 9 6 7 } 0 \\\*" talk_to client 2 simple_expect "=1373 58" talk_to client 0 send "1374 90 58\n" simple_expect "%1374 14 58" talk_to client 1 send "1375 90 58\n" simple_expect "%1375 14 58" talk_to client 2 send "1376 90 58\n" simple_expect "=1376 $any_time 8 0 7 0 2 { 0 9 6 7 } 0 \\\*" talk_to client 3 send "1377 90 58\n" simple_expect "=1377 $any_time 8 0 7 0 2 { 0 9 6 7 } 0 \\\*" talk_to client 2 # Deleting text 58; deleter 8 send "1378 29 58\n" talk_to client 3 simple_expect ":18 14 58 $any_time 8 0 7 0 2 { 0 9 6 7 } 0 \\\*" talk_to client 2 simple_expect "=1378" # Creating text 59 by 8 send "1379 86 [holl "text 59"] 1 { 0 10 } 0 { }\n" talk_to client 1 simple_expect ":18 15 59 $any_time 8 0 7 0 2 { 0 10 6 7 } 0 \\\*" talk_to client 2 simple_expect ":18 15 59 $any_time 8 0 7 0 2 { 0 10 6 7 } 0 \\\*" simple_expect "=1379 59" talk_to client 0 send "1380 90 59\n" simple_expect "=1380 $any_time 8 0 7 0 2 { 0 10 6 7 } 0 \\\*" talk_to client 1 send "1381 90 59\n" simple_expect "=1381 $any_time 8 0 7 0 2 { 0 10 6 7 } 0 \\\*" talk_to client 2 send "1382 90 59\n" simple_expect "=1382 $any_time 8 0 7 0 2 { 0 10 6 7 } 0 \\\*" talk_to client 3 send "1383 90 59\n" simple_expect "=1383 $any_time 8 0 7 0 2 { 0 10 6 7 } 0 \\\*" talk_to client 2 # Deleting text 59; deleter 8 send "1384 29 59\n" talk_to client 1 simple_expect ":18 14 59 $any_time 8 0 7 0 2 { 0 10 6 7 } 0 \\\*" talk_to client 2 simple_expect ":18 14 59 $any_time 8 0 7 0 2 { 0 10 6 7 } 0 \\\*" simple_expect "=1384" # Creating text 60 by 8 send "1385 86 [holl "text 60"] 1 { 0 11 } 0 { }\n" talk_to client 1 simple_expect ":18 15 60 $any_time 8 0 7 0 2 { 0 11 6 7 } 0 \\\*" talk_to client 2 simple_expect ":18 15 60 $any_time 8 0 7 0 2 { 0 11 6 7 } 0 \\\*" simple_expect "=1385 60" talk_to client 0 send "1386 90 60\n" simple_expect "%1386 14 60" talk_to client 1 send "1387 90 60\n" simple_expect "=1387 $any_time 8 0 7 0 2 { 0 11 6 7 } 0 \\\*" talk_to client 2 send "1388 90 60\n" simple_expect "=1388 $any_time 8 0 7 0 2 { 0 11 6 7 } 0 \\\*" talk_to client 3 send "1389 90 60\n" simple_expect "%1389 14 60" talk_to client 2 # Deleting text 60; deleter 8 send "1390 29 60\n" talk_to client 1 simple_expect ":18 14 60 $any_time 8 0 7 0 2 { 0 11 6 7 } 0 \\\*" talk_to client 2 simple_expect ":18 14 60 $any_time 8 0 7 0 2 { 0 11 6 7 } 0 \\\*" simple_expect "=1390" # Creating text 61 by 8 send "1391 86 [holl "text 61"] 1 { 0 12 } 0 { }\n" talk_to client 1 simple_expect ":18 15 61 $any_time 8 0 7 0 2 { 0 12 6 4 } 0 \\\*" talk_to client 2 simple_expect ":18 15 61 $any_time 8 0 7 0 2 { 0 12 6 4 } 0 \\\*" simple_expect "=1391 61" talk_to client 0 send "1392 90 61\n" simple_expect "%1392 14 61" talk_to client 1 send "1393 90 61\n" simple_expect "=1393 $any_time 8 0 7 0 2 { 0 12 6 4 } 0 \\\*" talk_to client 2 send "1394 90 61\n" simple_expect "=1394 $any_time 8 0 7 0 2 { 0 12 6 4 } 0 \\\*" talk_to client 3 send "1395 90 61\n" simple_expect "%1395 14 61" talk_to client 2 # Deleting text 61; deleter 8 send "1396 29 61\n" talk_to client 1 simple_expect ":18 14 61 $any_time 8 0 7 0 2 { 0 12 6 4 } 0 \\\*" talk_to client 2 simple_expect ":18 14 61 $any_time 8 0 7 0 2 { 0 12 6 4 } 0 \\\*" simple_expect "=1396" # Creating text 62 by 8 send "1397 86 [holl "text 62"] 1 { 0 13 } 0 { }\n" talk_to client 1 simple_expect ":18 15 62 $any_time 8 0 7 0 2 { 0 13 6 7 } 0 \\\*" talk_to client 2 simple_expect ":18 15 62 $any_time 8 0 7 0 2 { 0 13 6 7 } 0 \\\*" simple_expect "=1397 62" talk_to client 0 send "1398 90 62\n" simple_expect "=1398 $any_time 8 0 7 0 2 { 0 13 6 7 } 0 \\\*" talk_to client 1 send "1399 90 62\n" simple_expect "=1399 $any_time 8 0 7 0 2 { 0 13 6 7 } 0 \\\*" talk_to client 2 send "1400 90 62\n" simple_expect "=1400 $any_time 8 0 7 0 2 { 0 13 6 7 } 0 \\\*" talk_to client 3 send "1401 90 62\n" simple_expect "=1401 $any_time 8 0 7 0 2 { 0 13 6 7 } 0 \\\*" talk_to client 2 # Deleting text 62; deleter 8 send "1402 29 62\n" talk_to client 1 simple_expect ":18 14 62 $any_time 8 0 7 0 2 { 0 13 6 7 } 0 \\\*" talk_to client 2 simple_expect ":18 14 62 $any_time 8 0 7 0 2 { 0 13 6 7 } 0 \\\*" simple_expect "=1402" # Creating text 63 by 8 send "1403 86 [holl "text 63"] 1 { 0 14 } 0 { }\n" talk_to client 1 simple_expect ":18 15 63 $any_time 8 0 7 0 2 { 0 14 6 7 } 0 \\\*" talk_to client 2 simple_expect ":18 15 63 $any_time 8 0 7 0 2 { 0 14 6 7 } 0 \\\*" simple_expect "=1403 63" talk_to client 0 send "1404 90 63\n" simple_expect "%1404 14 63" talk_to client 1 send "1405 90 63\n" simple_expect "=1405 $any_time 8 0 7 0 2 { 0 14 6 7 } 0 \\\*" talk_to client 2 send "1406 90 63\n" simple_expect "=1406 $any_time 8 0 7 0 2 { 0 14 6 7 } 0 \\\*" talk_to client 3 send "1407 90 63\n" simple_expect "=1407 $any_time 8 0 7 0 2 { 0 14 6 7 } 0 \\\*" talk_to client 2 # Deleting text 63; deleter 8 send "1408 29 63\n" talk_to client 1 simple_expect ":18 14 63 $any_time 8 0 7 0 2 { 0 14 6 7 } 0 \\\*" talk_to client 2 simple_expect ":18 14 63 $any_time 8 0 7 0 2 { 0 14 6 7 } 0 \\\*" simple_expect "=1408" # Creating text 64 by 8 send "1409 86 [holl "text 64"] 1 { 0 15 } 0 { }\n" talk_to client 1 simple_expect ":18 15 64 $any_time 8 0 7 0 2 { 0 15 6 4 } 0 \\\*" talk_to client 2 simple_expect ":18 15 64 $any_time 8 0 7 0 2 { 0 15 6 4 } 0 \\\*" simple_expect "=1409 64" talk_to client 0 send "1410 90 64\n" simple_expect "%1410 14 64" talk_to client 1 send "1411 90 64\n" simple_expect "=1411 $any_time 8 0 7 0 2 { 0 15 6 4 } 0 \\\*" talk_to client 2 send "1412 90 64\n" simple_expect "=1412 $any_time 8 0 7 0 2 { 0 15 6 4 } 0 \\\*" talk_to client 3 send "1413 90 64\n" simple_expect "=1413 $any_time 8 0 7 0 2 { 0 15 6 4 } 0 \\\*" talk_to client 2 # Deleting text 64; deleter 8 send "1414 29 64\n" talk_to client 1 simple_expect ":18 14 64 $any_time 8 0 7 0 2 { 0 15 6 4 } 0 \\\*" talk_to client 2 simple_expect ":18 14 64 $any_time 8 0 7 0 2 { 0 15 6 4 } 0 \\\*" simple_expect "=1414" # Creating text 65 by 8 send "1415 86 [holl "text 65"] 1 { 1 6 } 0 { }\n" talk_to client 0 simple_expect ":18 15 65 $any_time 8 0 7 0 2 { 1 6 6 8 } 0 \\\*" talk_to client 2 simple_expect "=1415 65" talk_to client 0 send "1416 90 65\n" simple_expect "=1416 $any_time 8 0 7 0 2 { 1 6 6 8 } 0 \\\*" talk_to client 1 send "1417 90 65\n" simple_expect "%1417 14 65" talk_to client 2 send "1418 90 65\n" simple_expect "=1418 $any_time 8 0 7 0 2 { 1 6 6 8 } 0 \\\*" talk_to client 3 send "1419 90 65\n" simple_expect "%1419 14 65" talk_to client 2 # Deleting text 65; deleter 8 send "1420 29 65\n" talk_to client 0 simple_expect ":18 14 65 $any_time 8 0 7 0 2 { 1 6 6 8 } 0 \\\*" talk_to client 2 simple_expect "=1420" # Creating text 66 by 8 send "1421 86 [holl "text 66"] 1 { 1 7 } 0 { }\n" simple_expect "=1421 66" talk_to client 0 send "1422 90 66\n" simple_expect "%1422 14 66" talk_to client 1 send "1423 90 66\n" simple_expect "=1423 $any_time 8 0 7 0 2 { 1 7 6 8 } 0 \\\*" talk_to client 2 send "1424 90 66\n" simple_expect "=1424 $any_time 8 0 7 0 2 { 1 7 6 8 } 0 \\\*" talk_to client 3 send "1425 90 66\n" simple_expect "%1425 14 66" talk_to client 2 # Deleting text 66; deleter 8 send "1426 29 66\n" simple_expect "=1426" # Creating text 67 by 8 send "1427 86 [holl "text 67"] 1 { 1 8 } 0 { }\n" simple_expect ":18 15 67 $any_time 8 0 7 0 2 { 1 8 6 8 } 0 \\\*" simple_expect "=1427 67" talk_to client 0 send "1428 90 67\n" simple_expect "%1428 14 67" talk_to client 1 send "1429 90 67\n" simple_expect "%1429 14 67" talk_to client 2 send "1430 90 67\n" simple_expect "=1430 $any_time 8 0 7 0 2 { 1 8 6 8 } 0 \\\*" talk_to client 3 send "1431 90 67\n" simple_expect "%1431 14 67" talk_to client 2 # Deleting text 67; deleter 8 send "1432 29 67\n" simple_expect ":18 14 67 $any_time 8 0 7 0 2 { 1 8 6 8 } 0 \\\*" simple_expect "=1432" # Creating text 68 by 8 send "1433 86 [holl "text 68"] 1 { 1 9 } 0 { }\n" talk_to client 3 simple_expect ":18 15 68 $any_time 8 0 7 0 2 { 1 9 6 8 } 0 \\\*" talk_to client 2 simple_expect "=1433 68" talk_to client 0 send "1434 90 68\n" simple_expect "%1434 14 68" talk_to client 1 send "1435 90 68\n" simple_expect "%1435 14 68" talk_to client 2 send "1436 90 68\n" simple_expect "=1436 $any_time 8 0 7 0 2 { 1 9 6 8 } 0 \\\*" talk_to client 3 send "1437 90 68\n" simple_expect "=1437 $any_time 8 0 7 0 2 { 1 9 6 8 } 0 \\\*" talk_to client 2 # Deleting text 68; deleter 8 send "1438 29 68\n" talk_to client 3 simple_expect ":18 14 68 $any_time 8 0 7 0 2 { 1 9 6 8 } 0 \\\*" talk_to client 2 simple_expect "=1438" # Creating text 69 by 8 send "1439 86 [holl "text 69"] 1 { 1 10 } 0 { }\n" talk_to client 1 simple_expect ":18 15 69 $any_time 8 0 7 0 2 { 1 10 6 8 } 0 \\\*" talk_to client 2 simple_expect ":18 15 69 $any_time 8 0 7 0 2 { 1 10 6 8 } 0 \\\*" simple_expect "=1439 69" talk_to client 0 send "1440 90 69\n" simple_expect "=1440 $any_time 8 0 7 0 2 { 1 10 6 8 } 0 \\\*" talk_to client 1 send "1441 90 69\n" simple_expect "=1441 $any_time 8 0 7 0 2 { 1 10 6 8 } 0 \\\*" talk_to client 2 send "1442 90 69\n" simple_expect "=1442 $any_time 8 0 7 0 2 { 1 10 6 8 } 0 \\\*" talk_to client 3 send "1443 90 69\n" simple_expect "=1443 $any_time 8 0 7 0 2 { 1 10 6 8 } 0 \\\*" talk_to client 2 # Deleting text 69; deleter 8 send "1444 29 69\n" talk_to client 1 simple_expect ":18 14 69 $any_time 8 0 7 0 2 { 1 10 6 8 } 0 \\\*" talk_to client 2 simple_expect ":18 14 69 $any_time 8 0 7 0 2 { 1 10 6 8 } 0 \\\*" simple_expect "=1444" # Creating text 70 by 8 send "1445 86 [holl "text 70"] 1 { 1 11 } 0 { }\n" talk_to client 1 simple_expect ":18 15 70 $any_time 8 0 7 0 2 { 1 11 6 8 } 0 \\\*" talk_to client 2 simple_expect ":18 15 70 $any_time 8 0 7 0 2 { 1 11 6 8 } 0 \\\*" simple_expect "=1445 70" talk_to client 0 send "1446 90 70\n" simple_expect "%1446 14 70" talk_to client 1 send "1447 90 70\n" simple_expect "=1447 $any_time 8 0 7 0 2 { 1 11 6 8 } 0 \\\*" talk_to client 2 send "1448 90 70\n" simple_expect "=1448 $any_time 8 0 7 0 2 { 1 11 6 8 } 0 \\\*" talk_to client 3 send "1449 90 70\n" simple_expect "%1449 14 70" talk_to client 2 # Deleting text 70; deleter 8 send "1450 29 70\n" talk_to client 1 simple_expect ":18 14 70 $any_time 8 0 7 0 2 { 1 11 6 8 } 0 \\\*" talk_to client 2 simple_expect ":18 14 70 $any_time 8 0 7 0 2 { 1 11 6 8 } 0 \\\*" simple_expect "=1450" # Creating text 71 by 8 send "1451 86 [holl "text 71"] 1 { 1 12 } 0 { }\n" talk_to client 1 simple_expect ":18 15 71 $any_time 8 0 7 0 2 { 1 12 6 5 } 0 \\\*" talk_to client 2 simple_expect ":18 15 71 $any_time 8 0 7 0 2 { 1 12 6 5 } 0 \\\*" simple_expect "=1451 71" talk_to client 0 send "1452 90 71\n" simple_expect "%1452 14 71" talk_to client 1 send "1453 90 71\n" simple_expect "=1453 $any_time 8 0 7 0 2 { 1 12 6 5 } 0 \\\*" talk_to client 2 send "1454 90 71\n" simple_expect "=1454 $any_time 8 0 7 0 2 { 1 12 6 5 } 0 \\\*" talk_to client 3 send "1455 90 71\n" simple_expect "%1455 14 71" talk_to client 2 # Deleting text 71; deleter 8 send "1456 29 71\n" talk_to client 1 simple_expect ":18 14 71 $any_time 8 0 7 0 2 { 1 12 6 5 } 0 \\\*" talk_to client 2 simple_expect ":18 14 71 $any_time 8 0 7 0 2 { 1 12 6 5 } 0 \\\*" simple_expect "=1456" # Creating text 72 by 8 send "1457 86 [holl "text 72"] 1 { 1 13 } 0 { }\n" talk_to client 1 simple_expect ":18 15 72 $any_time 8 0 7 0 2 { 1 13 6 8 } 0 \\\*" talk_to client 2 simple_expect ":18 15 72 $any_time 8 0 7 0 2 { 1 13 6 8 } 0 \\\*" simple_expect "=1457 72" talk_to client 0 send "1458 90 72\n" simple_expect "=1458 $any_time 8 0 7 0 2 { 1 13 6 8 } 0 \\\*" talk_to client 1 send "1459 90 72\n" simple_expect "=1459 $any_time 8 0 7 0 2 { 1 13 6 8 } 0 \\\*" talk_to client 2 send "1460 90 72\n" simple_expect "=1460 $any_time 8 0 7 0 2 { 1 13 6 8 } 0 \\\*" talk_to client 3 send "1461 90 72\n" simple_expect "=1461 $any_time 8 0 7 0 2 { 1 13 6 8 } 0 \\\*" talk_to client 2 # Deleting text 72; deleter 8 send "1462 29 72\n" talk_to client 1 simple_expect ":18 14 72 $any_time 8 0 7 0 2 { 1 13 6 8 } 0 \\\*" talk_to client 2 simple_expect ":18 14 72 $any_time 8 0 7 0 2 { 1 13 6 8 } 0 \\\*" simple_expect "=1462" # Creating text 73 by 8 send "1463 86 [holl "text 73"] 1 { 1 14 } 0 { }\n" talk_to client 1 simple_expect ":18 15 73 $any_time 8 0 7 0 2 { 1 14 6 8 } 0 \\\*" talk_to client 2 simple_expect ":18 15 73 $any_time 8 0 7 0 2 { 1 14 6 8 } 0 \\\*" simple_expect "=1463 73" talk_to client 0 send "1464 90 73\n" simple_expect "%1464 14 73" talk_to client 1 send "1465 90 73\n" simple_expect "=1465 $any_time 8 0 7 0 2 { 1 14 6 8 } 0 \\\*" talk_to client 2 send "1466 90 73\n" simple_expect "=1466 $any_time 8 0 7 0 2 { 1 14 6 8 } 0 \\\*" talk_to client 3 send "1467 90 73\n" simple_expect "=1467 $any_time 8 0 7 0 2 { 1 14 6 8 } 0 \\\*" talk_to client 2 # Deleting text 73; deleter 8 send "1468 29 73\n" talk_to client 1 simple_expect ":18 14 73 $any_time 8 0 7 0 2 { 1 14 6 8 } 0 \\\*" talk_to client 2 simple_expect ":18 14 73 $any_time 8 0 7 0 2 { 1 14 6 8 } 0 \\\*" simple_expect "=1468" # Creating text 74 by 8 send "1469 86 [holl "text 74"] 1 { 1 15 } 0 { }\n" talk_to client 1 simple_expect ":18 15 74 $any_time 8 0 7 0 2 { 1 15 6 5 } 0 \\\*" talk_to client 2 simple_expect ":18 15 74 $any_time 8 0 7 0 2 { 1 15 6 5 } 0 \\\*" simple_expect "=1469 74" talk_to client 0 send "1470 90 74\n" simple_expect "%1470 14 74" talk_to client 1 send "1471 90 74\n" simple_expect "=1471 $any_time 8 0 7 0 2 { 1 15 6 5 } 0 \\\*" talk_to client 2 send "1472 90 74\n" simple_expect "=1472 $any_time 8 0 7 0 2 { 1 15 6 5 } 0 \\\*" talk_to client 3 send "1473 90 74\n" simple_expect "=1473 $any_time 8 0 7 0 2 { 1 15 6 5 } 0 \\\*" talk_to client 2 # Deleting text 74; deleter 8 send "1474 29 74\n" talk_to client 1 simple_expect ":18 14 74 $any_time 8 0 7 0 2 { 1 15 6 5 } 0 \\\*" talk_to client 2 simple_expect ":18 14 74 $any_time 8 0 7 0 2 { 1 15 6 5 } 0 \\\*" simple_expect "=1474" # Creating text 75 by 8 send "1475 86 [holl "text 75"] 1 { 15 6 } 0 { }\n" talk_to client 0 simple_expect ":18 15 75 $any_time 8 0 7 0 2 { 15 6 6 9 } 0 \\\*" talk_to client 2 simple_expect "=1475 75" talk_to client 0 send "1476 90 75\n" simple_expect "=1476 $any_time 8 0 7 0 2 { 15 6 6 9 } 0 \\\*" talk_to client 1 send "1477 90 75\n" simple_expect "%1477 14 75" talk_to client 2 send "1478 90 75\n" simple_expect "=1478 $any_time 8 0 7 0 2 { 15 6 6 9 } 0 \\\*" talk_to client 3 send "1479 90 75\n" simple_expect "%1479 14 75" talk_to client 2 # Deleting text 75; deleter 8 send "1480 29 75\n" talk_to client 0 simple_expect ":18 14 75 $any_time 8 0 7 0 2 { 15 6 6 9 } 0 \\\*" talk_to client 2 simple_expect "=1480" # Creating text 76 by 8 send "1481 86 [holl "text 76"] 1 { 15 7 } 0 { }\n" simple_expect "=1481 76" talk_to client 0 send "1482 90 76\n" simple_expect "%1482 14 76" talk_to client 1 send "1483 90 76\n" simple_expect "=1483 $any_time 8 0 7 0 2 { 15 7 6 9 } 0 \\\*" talk_to client 2 send "1484 90 76\n" simple_expect "=1484 $any_time 8 0 7 0 2 { 15 7 6 9 } 0 \\\*" talk_to client 3 send "1485 90 76\n" simple_expect "%1485 14 76" talk_to client 2 # Deleting text 76; deleter 8 send "1486 29 76\n" simple_expect "=1486" # Creating text 77 by 8 send "1487 86 [holl "text 77"] 1 { 15 8 } 0 { }\n" simple_expect ":18 15 77 $any_time 8 0 7 0 2 { 15 8 6 9 } 0 \\\*" simple_expect "=1487 77" talk_to client 0 send "1488 90 77\n" simple_expect "%1488 14 77" talk_to client 1 send "1489 90 77\n" simple_expect "%1489 14 77" talk_to client 2 send "1490 90 77\n" simple_expect "=1490 $any_time 8 0 7 0 2 { 15 8 6 9 } 0 \\\*" talk_to client 3 send "1491 90 77\n" simple_expect "%1491 14 77" talk_to client 2 # Deleting text 77; deleter 8 send "1492 29 77\n" simple_expect ":18 14 77 $any_time 8 0 7 0 2 { 15 8 6 9 } 0 \\\*" simple_expect "=1492" # Creating text 78 by 8 send "1493 86 [holl "text 78"] 1 { 15 9 } 0 { }\n" talk_to client 3 simple_expect ":18 15 78 $any_time 8 0 7 0 2 { 15 9 6 9 } 0 \\\*" talk_to client 2 simple_expect "=1493 78" talk_to client 0 send "1494 90 78\n" simple_expect "%1494 14 78" talk_to client 1 send "1495 90 78\n" simple_expect "%1495 14 78" talk_to client 2 send "1496 90 78\n" simple_expect "=1496 $any_time 8 0 7 0 2 { 15 9 6 9 } 0 \\\*" talk_to client 3 send "1497 90 78\n" simple_expect "=1497 $any_time 8 0 7 0 2 { 15 9 6 9 } 0 \\\*" talk_to client 2 # Deleting text 78; deleter 8 send "1498 29 78\n" talk_to client 3 simple_expect ":18 14 78 $any_time 8 0 7 0 2 { 15 9 6 9 } 0 \\\*" talk_to client 2 simple_expect "=1498" # Creating text 79 by 8 send "1499 86 [holl "text 79"] 1 { 15 10 } 0 { }\n" talk_to client 1 simple_expect ":18 15 79 $any_time 8 0 7 0 2 { 15 10 6 9 } 0 \\\*" talk_to client 2 simple_expect ":18 15 79 $any_time 8 0 7 0 2 { 15 10 6 9 } 0 \\\*" simple_expect "=1499 79" talk_to client 0 send "1500 90 79\n" simple_expect "=1500 $any_time 8 0 7 0 2 { 15 10 6 9 } 0 \\\*" talk_to client 1 send "1501 90 79\n" simple_expect "=1501 $any_time 8 0 7 0 2 { 15 10 6 9 } 0 \\\*" talk_to client 2 send "1502 90 79\n" simple_expect "=1502 $any_time 8 0 7 0 2 { 15 10 6 9 } 0 \\\*" talk_to client 3 send "1503 90 79\n" simple_expect "=1503 $any_time 8 0 7 0 2 { 15 10 6 9 } 0 \\\*" talk_to client 2 # Deleting text 79; deleter 8 send "1504 29 79\n" talk_to client 1 simple_expect ":18 14 79 $any_time 8 0 7 0 2 { 15 10 6 9 } 0 \\\*" talk_to client 2 simple_expect ":18 14 79 $any_time 8 0 7 0 2 { 15 10 6 9 } 0 \\\*" simple_expect "=1504" # Creating text 80 by 8 send "1505 86 [holl "text 80"] 1 { 15 11 } 0 { }\n" talk_to client 1 simple_expect ":18 15 80 $any_time 8 0 7 0 2 { 15 11 6 9 } 0 \\\*" talk_to client 2 simple_expect ":18 15 80 $any_time 8 0 7 0 2 { 15 11 6 9 } 0 \\\*" simple_expect "=1505 80" talk_to client 0 send "1506 90 80\n" simple_expect "%1506 14 80" talk_to client 1 send "1507 90 80\n" simple_expect "=1507 $any_time 8 0 7 0 2 { 15 11 6 9 } 0 \\\*" talk_to client 2 send "1508 90 80\n" simple_expect "=1508 $any_time 8 0 7 0 2 { 15 11 6 9 } 0 \\\*" talk_to client 3 send "1509 90 80\n" simple_expect "%1509 14 80" talk_to client 2 # Deleting text 80; deleter 8 send "1510 29 80\n" talk_to client 1 simple_expect ":18 14 80 $any_time 8 0 7 0 2 { 15 11 6 9 } 0 \\\*" talk_to client 2 simple_expect ":18 14 80 $any_time 8 0 7 0 2 { 15 11 6 9 } 0 \\\*" simple_expect "=1510" # Creating text 81 by 8 send "1511 86 [holl "text 81"] 1 { 15 12 } 0 { }\n" talk_to client 1 simple_expect ":18 15 81 $any_time 8 0 7 0 2 { 15 12 6 6 } 0 \\\*" talk_to client 2 simple_expect ":18 15 81 $any_time 8 0 7 0 2 { 15 12 6 6 } 0 \\\*" simple_expect "=1511 81" talk_to client 0 send "1512 90 81\n" simple_expect "%1512 14 81" talk_to client 1 send "1513 90 81\n" simple_expect "=1513 $any_time 8 0 7 0 2 { 15 12 6 6 } 0 \\\*" talk_to client 2 send "1514 90 81\n" simple_expect "=1514 $any_time 8 0 7 0 2 { 15 12 6 6 } 0 \\\*" talk_to client 3 send "1515 90 81\n" simple_expect "%1515 14 81" talk_to client 2 # Deleting text 81; deleter 8 send "1516 29 81\n" talk_to client 1 simple_expect ":18 14 81 $any_time 8 0 7 0 2 { 15 12 6 6 } 0 \\\*" talk_to client 2 simple_expect ":18 14 81 $any_time 8 0 7 0 2 { 15 12 6 6 } 0 \\\*" simple_expect "=1516" # Creating text 82 by 8 send "1517 86 [holl "text 82"] 1 { 15 13 } 0 { }\n" talk_to client 1 simple_expect ":18 15 82 $any_time 8 0 7 0 2 { 15 13 6 9 } 0 \\\*" talk_to client 2 simple_expect ":18 15 82 $any_time 8 0 7 0 2 { 15 13 6 9 } 0 \\\*" simple_expect "=1517 82" talk_to client 0 send "1518 90 82\n" simple_expect "=1518 $any_time 8 0 7 0 2 { 15 13 6 9 } 0 \\\*" talk_to client 1 send "1519 90 82\n" simple_expect "=1519 $any_time 8 0 7 0 2 { 15 13 6 9 } 0 \\\*" talk_to client 2 send "1520 90 82\n" simple_expect "=1520 $any_time 8 0 7 0 2 { 15 13 6 9 } 0 \\\*" talk_to client 3 send "1521 90 82\n" simple_expect "=1521 $any_time 8 0 7 0 2 { 15 13 6 9 } 0 \\\*" talk_to client 2 # Deleting text 82; deleter 8 send "1522 29 82\n" talk_to client 1 simple_expect ":18 14 82 $any_time 8 0 7 0 2 { 15 13 6 9 } 0 \\\*" talk_to client 2 simple_expect ":18 14 82 $any_time 8 0 7 0 2 { 15 13 6 9 } 0 \\\*" simple_expect "=1522" # Creating text 83 by 8 send "1523 86 [holl "text 83"] 1 { 15 14 } 0 { }\n" talk_to client 1 simple_expect ":18 15 83 $any_time 8 0 7 0 2 { 15 14 6 9 } 0 \\\*" talk_to client 2 simple_expect ":18 15 83 $any_time 8 0 7 0 2 { 15 14 6 9 } 0 \\\*" simple_expect "=1523 83" talk_to client 0 send "1524 90 83\n" simple_expect "%1524 14 83" talk_to client 1 send "1525 90 83\n" simple_expect "=1525 $any_time 8 0 7 0 2 { 15 14 6 9 } 0 \\\*" talk_to client 2 send "1526 90 83\n" simple_expect "=1526 $any_time 8 0 7 0 2 { 15 14 6 9 } 0 \\\*" talk_to client 3 send "1527 90 83\n" simple_expect "=1527 $any_time 8 0 7 0 2 { 15 14 6 9 } 0 \\\*" talk_to client 2 # Deleting text 83; deleter 8 send "1528 29 83\n" talk_to client 1 simple_expect ":18 14 83 $any_time 8 0 7 0 2 { 15 14 6 9 } 0 \\\*" talk_to client 2 simple_expect ":18 14 83 $any_time 8 0 7 0 2 { 15 14 6 9 } 0 \\\*" simple_expect "=1528" # Creating text 84 by 8 send "1529 86 [holl "text 84"] 1 { 15 15 } 0 { }\n" talk_to client 1 simple_expect ":18 15 84 $any_time 8 0 7 0 2 { 15 15 6 6 } 0 \\\*" talk_to client 2 simple_expect ":18 15 84 $any_time 8 0 7 0 2 { 15 15 6 6 } 0 \\\*" simple_expect "=1529 84" talk_to client 0 send "1530 90 84\n" simple_expect "%1530 14 84" talk_to client 1 send "1531 90 84\n" simple_expect "=1531 $any_time 8 0 7 0 2 { 15 15 6 6 } 0 \\\*" talk_to client 2 send "1532 90 84\n" simple_expect "=1532 $any_time 8 0 7 0 2 { 15 15 6 6 } 0 \\\*" talk_to client 3 send "1533 90 84\n" simple_expect "=1533 $any_time 8 0 7 0 2 { 15 15 6 6 } 0 \\\*" talk_to client 2 # Deleting text 84; deleter 8 send "1534 29 84\n" talk_to client 1 simple_expect ":18 14 84 $any_time 8 0 7 0 2 { 15 15 6 6 } 0 \\\*" talk_to client 2 simple_expect ":18 14 84 $any_time 8 0 7 0 2 { 15 15 6 6 } 0 \\\*" simple_expect "=1534" talk_to client 3 # Creating text 85 by 9 send "1535 86 [holl "text 85"] 1 { 0 6 } 0 { }\n" talk_to client 0 simple_expect ":18 15 85 $any_time 9 0 7 0 2 { 0 6 6 10 } 0 \\\*" talk_to client 3 simple_expect "=1535 85" talk_to client 0 send "1536 90 85\n" simple_expect "=1536 $any_time 9 0 7 0 2 { 0 6 6 10 } 0 \\\*" talk_to client 1 send "1537 90 85\n" simple_expect "%1537 14 85" talk_to client 2 send "1538 90 85\n" simple_expect "%1538 14 85" talk_to client 3 send "1539 90 85\n" simple_expect "=1539 $any_time 9 0 7 0 2 { 0 6 6 10 } 0 \\\*" # Deleting text 85; deleter 9 send "1540 29 85\n" talk_to client 0 simple_expect ":18 14 85 $any_time 9 0 7 0 2 { 0 6 6 10 } 0 \\\*" talk_to client 3 simple_expect "=1540" # Creating text 86 by 9 send "1541 86 [holl "text 86"] 1 { 0 7 } 0 { }\n" simple_expect "=1541 86" talk_to client 0 send "1542 90 86\n" simple_expect "%1542 14 86" talk_to client 1 send "1543 90 86\n" simple_expect "=1543 $any_time 9 0 7 0 2 { 0 7 6 10 } 0 \\\*" talk_to client 2 send "1544 90 86\n" simple_expect "%1544 14 86" talk_to client 3 send "1545 90 86\n" simple_expect "=1545 $any_time 9 0 7 0 2 { 0 7 6 10 } 0 \\\*" # Deleting text 86; deleter 9 send "1546 29 86\n" simple_expect "=1546" # Creating text 87 by 9 send "1547 86 [holl "text 87"] 1 { 0 8 } 0 { }\n" talk_to client 2 simple_expect ":18 15 87 $any_time 9 0 7 0 2 { 0 8 6 10 } 0 \\\*" talk_to client 3 simple_expect "=1547 87" talk_to client 0 send "1548 90 87\n" simple_expect "%1548 14 87" talk_to client 1 send "1549 90 87\n" simple_expect "%1549 14 87" talk_to client 2 send "1550 90 87\n" simple_expect "=1550 $any_time 9 0 7 0 2 { 0 8 6 10 } 0 \\\*" talk_to client 3 send "1551 90 87\n" simple_expect "=1551 $any_time 9 0 7 0 2 { 0 8 6 10 } 0 \\\*" # Deleting text 87; deleter 9 send "1552 29 87\n" talk_to client 2 simple_expect ":18 14 87 $any_time 9 0 7 0 2 { 0 8 6 10 } 0 \\\*" talk_to client 3 simple_expect "=1552" # Creating text 88 by 9 send "1553 86 [holl "text 88"] 1 { 0 9 } 0 { }\n" simple_expect ":18 15 88 $any_time 9 0 7 0 2 { 0 9 6 10 } 0 \\\*" simple_expect "=1553 88" talk_to client 0 send "1554 90 88\n" simple_expect "%1554 14 88" talk_to client 1 send "1555 90 88\n" simple_expect "%1555 14 88" talk_to client 2 send "1556 90 88\n" simple_expect "%1556 14 88" talk_to client 3 send "1557 90 88\n" simple_expect "=1557 $any_time 9 0 7 0 2 { 0 9 6 10 } 0 \\\*" # Deleting text 88; deleter 9 send "1558 29 88\n" simple_expect ":18 14 88 $any_time 9 0 7 0 2 { 0 9 6 10 } 0 \\\*" simple_expect "=1558" # Creating text 89 by 9 send "1559 86 [holl "text 89"] 1 { 0 10 } 0 { }\n" talk_to client 1 simple_expect ":18 15 89 $any_time 9 0 7 0 2 { 0 10 6 10 } 0 \\\*" talk_to client 2 simple_expect ":18 15 89 $any_time 9 0 7 0 2 { 0 10 6 10 } 0 \\\*" talk_to client 3 simple_expect "=1559 89" talk_to client 0 send "1560 90 89\n" simple_expect "=1560 $any_time 9 0 7 0 2 { 0 10 6 10 } 0 \\\*" talk_to client 1 send "1561 90 89\n" simple_expect "=1561 $any_time 9 0 7 0 2 { 0 10 6 10 } 0 \\\*" talk_to client 2 send "1562 90 89\n" simple_expect "=1562 $any_time 9 0 7 0 2 { 0 10 6 10 } 0 \\\*" talk_to client 3 send "1563 90 89\n" simple_expect "=1563 $any_time 9 0 7 0 2 { 0 10 6 10 } 0 \\\*" # Deleting text 89; deleter 9 send "1564 29 89\n" talk_to client 1 simple_expect ":18 14 89 $any_time 9 0 7 0 2 { 0 10 6 10 } 0 \\\*" talk_to client 2 simple_expect ":18 14 89 $any_time 9 0 7 0 2 { 0 10 6 10 } 0 \\\*" talk_to client 3 simple_expect "=1564" # Creating text 90 by 9 send "1565 86 [holl "text 90"] 1 { 0 11 } 0 { }\n" talk_to client 1 simple_expect ":18 15 90 $any_time 9 0 7 0 2 { 0 11 6 10 } 0 \\\*" talk_to client 2 simple_expect ":18 15 90 $any_time 9 0 7 0 2 { 0 11 6 10 } 0 \\\*" talk_to client 3 simple_expect "=1565 90" talk_to client 0 send "1566 90 90\n" simple_expect "%1566 14 90" talk_to client 1 send "1567 90 90\n" simple_expect "=1567 $any_time 9 0 7 0 2 { 0 11 6 10 } 0 \\\*" talk_to client 2 send "1568 90 90\n" simple_expect "=1568 $any_time 9 0 7 0 2 { 0 11 6 10 } 0 \\\*" talk_to client 3 send "1569 90 90\n" simple_expect "=1569 $any_time 9 0 7 0 2 { 0 11 6 10 } 0 \\\*" # Deleting text 90; deleter 9 send "1570 29 90\n" talk_to client 1 simple_expect ":18 14 90 $any_time 9 0 7 0 2 { 0 11 6 10 } 0 \\\*" talk_to client 2 simple_expect ":18 14 90 $any_time 9 0 7 0 2 { 0 11 6 10 } 0 \\\*" talk_to client 3 simple_expect "=1570" # Creating text 91 by 9 send "1571 86 [holl "text 91"] 1 { 0 13 } 0 { }\n" talk_to client 1 simple_expect ":18 15 91 $any_time 9 0 7 0 2 { 0 13 6 10 } 0 \\\*" talk_to client 2 simple_expect ":18 15 91 $any_time 9 0 7 0 2 { 0 13 6 10 } 0 \\\*" talk_to client 3 simple_expect "=1571 91" talk_to client 0 send "1572 90 91\n" simple_expect "=1572 $any_time 9 0 7 0 2 { 0 13 6 10 } 0 \\\*" talk_to client 1 send "1573 90 91\n" simple_expect "=1573 $any_time 9 0 7 0 2 { 0 13 6 10 } 0 \\\*" talk_to client 2 send "1574 90 91\n" simple_expect "=1574 $any_time 9 0 7 0 2 { 0 13 6 10 } 0 \\\*" talk_to client 3 send "1575 90 91\n" simple_expect "=1575 $any_time 9 0 7 0 2 { 0 13 6 10 } 0 \\\*" # Deleting text 91; deleter 9 send "1576 29 91\n" talk_to client 1 simple_expect ":18 14 91 $any_time 9 0 7 0 2 { 0 13 6 10 } 0 \\\*" talk_to client 2 simple_expect ":18 14 91 $any_time 9 0 7 0 2 { 0 13 6 10 } 0 \\\*" talk_to client 3 simple_expect "=1576" # Creating text 92 by 9 send "1577 86 [holl "text 92"] 1 { 0 14 } 0 { }\n" talk_to client 1 simple_expect ":18 15 92 $any_time 9 0 7 0 2 { 0 14 6 10 } 0 \\\*" talk_to client 2 simple_expect ":18 15 92 $any_time 9 0 7 0 2 { 0 14 6 10 } 0 \\\*" talk_to client 3 simple_expect "=1577 92" talk_to client 0 send "1578 90 92\n" simple_expect "%1578 14 92" talk_to client 1 send "1579 90 92\n" simple_expect "=1579 $any_time 9 0 7 0 2 { 0 14 6 10 } 0 \\\*" talk_to client 2 send "1580 90 92\n" simple_expect "=1580 $any_time 9 0 7 0 2 { 0 14 6 10 } 0 \\\*" talk_to client 3 send "1581 90 92\n" simple_expect "=1581 $any_time 9 0 7 0 2 { 0 14 6 10 } 0 \\\*" # Deleting text 92; deleter 9 send "1582 29 92\n" talk_to client 1 simple_expect ":18 14 92 $any_time 9 0 7 0 2 { 0 14 6 10 } 0 \\\*" talk_to client 2 simple_expect ":18 14 92 $any_time 9 0 7 0 2 { 0 14 6 10 } 0 \\\*" talk_to client 3 simple_expect "=1582" # Creating text 93 by 9 send "1583 86 [holl "text 93"] 1 { 1 6 } 0 { }\n" talk_to client 0 simple_expect ":18 15 93 $any_time 9 0 7 0 2 { 1 6 6 11 } 0 \\\*" talk_to client 3 simple_expect "=1583 93" talk_to client 0 send "1584 90 93\n" simple_expect "=1584 $any_time 9 0 7 0 2 { 1 6 6 11 } 0 \\\*" talk_to client 1 send "1585 90 93\n" simple_expect "%1585 14 93" talk_to client 2 send "1586 90 93\n" simple_expect "%1586 14 93" talk_to client 3 send "1587 90 93\n" simple_expect "=1587 $any_time 9 0 7 0 2 { 1 6 6 11 } 0 \\\*" # Deleting text 93; deleter 9 send "1588 29 93\n" talk_to client 0 simple_expect ":18 14 93 $any_time 9 0 7 0 2 { 1 6 6 11 } 0 \\\*" talk_to client 3 simple_expect "=1588" # Creating text 94 by 9 send "1589 86 [holl "text 94"] 1 { 1 7 } 0 { }\n" simple_expect "=1589 94" talk_to client 0 send "1590 90 94\n" simple_expect "%1590 14 94" talk_to client 1 send "1591 90 94\n" simple_expect "=1591 $any_time 9 0 7 0 2 { 1 7 6 11 } 0 \\\*" talk_to client 2 send "1592 90 94\n" simple_expect "%1592 14 94" talk_to client 3 send "1593 90 94\n" simple_expect "=1593 $any_time 9 0 7 0 2 { 1 7 6 11 } 0 \\\*" # Deleting text 94; deleter 9 send "1594 29 94\n" simple_expect "=1594" # Creating text 95 by 9 send "1595 86 [holl "text 95"] 1 { 1 8 } 0 { }\n" talk_to client 2 simple_expect ":18 15 95 $any_time 9 0 7 0 2 { 1 8 6 11 } 0 \\\*" talk_to client 3 simple_expect "=1595 95" talk_to client 0 send "1596 90 95\n" simple_expect "%1596 14 95" talk_to client 1 send "1597 90 95\n" simple_expect "%1597 14 95" talk_to client 2 send "1598 90 95\n" simple_expect "=1598 $any_time 9 0 7 0 2 { 1 8 6 11 } 0 \\\*" talk_to client 3 send "1599 90 95\n" simple_expect "=1599 $any_time 9 0 7 0 2 { 1 8 6 11 } 0 \\\*" # Deleting text 95; deleter 9 send "1600 29 95\n" talk_to client 2 simple_expect ":18 14 95 $any_time 9 0 7 0 2 { 1 8 6 11 } 0 \\\*" talk_to client 3 simple_expect "=1600" # Creating text 96 by 9 send "1601 86 [holl "text 96"] 1 { 1 9 } 0 { }\n" simple_expect ":18 15 96 $any_time 9 0 7 0 2 { 1 9 6 11 } 0 \\\*" simple_expect "=1601 96" talk_to client 0 send "1602 90 96\n" simple_expect "%1602 14 96" talk_to client 1 send "1603 90 96\n" simple_expect "%1603 14 96" talk_to client 2 send "1604 90 96\n" simple_expect "%1604 14 96" talk_to client 3 send "1605 90 96\n" simple_expect "=1605 $any_time 9 0 7 0 2 { 1 9 6 11 } 0 \\\*" # Deleting text 96; deleter 9 send "1606 29 96\n" simple_expect ":18 14 96 $any_time 9 0 7 0 2 { 1 9 6 11 } 0 \\\*" simple_expect "=1606" # Creating text 97 by 9 send "1607 86 [holl "text 97"] 1 { 1 10 } 0 { }\n" talk_to client 1 simple_expect ":18 15 97 $any_time 9 0 7 0 2 { 1 10 6 11 } 0 \\\*" talk_to client 2 simple_expect ":18 15 97 $any_time 9 0 7 0 2 { 1 10 6 11 } 0 \\\*" talk_to client 3 simple_expect "=1607 97" talk_to client 0 send "1608 90 97\n" simple_expect "=1608 $any_time 9 0 7 0 2 { 1 10 6 11 } 0 \\\*" talk_to client 1 send "1609 90 97\n" simple_expect "=1609 $any_time 9 0 7 0 2 { 1 10 6 11 } 0 \\\*" talk_to client 2 send "1610 90 97\n" simple_expect "=1610 $any_time 9 0 7 0 2 { 1 10 6 11 } 0 \\\*" talk_to client 3 send "1611 90 97\n" simple_expect "=1611 $any_time 9 0 7 0 2 { 1 10 6 11 } 0 \\\*" # Deleting text 97; deleter 9 send "1612 29 97\n" talk_to client 1 simple_expect ":18 14 97 $any_time 9 0 7 0 2 { 1 10 6 11 } 0 \\\*" talk_to client 2 simple_expect ":18 14 97 $any_time 9 0 7 0 2 { 1 10 6 11 } 0 \\\*" talk_to client 3 simple_expect "=1612" # Creating text 98 by 9 send "1613 86 [holl "text 98"] 1 { 1 11 } 0 { }\n" talk_to client 1 simple_expect ":18 15 98 $any_time 9 0 7 0 2 { 1 11 6 11 } 0 \\\*" talk_to client 2 simple_expect ":18 15 98 $any_time 9 0 7 0 2 { 1 11 6 11 } 0 \\\*" talk_to client 3 simple_expect "=1613 98" talk_to client 0 send "1614 90 98\n" simple_expect "%1614 14 98" talk_to client 1 send "1615 90 98\n" simple_expect "=1615 $any_time 9 0 7 0 2 { 1 11 6 11 } 0 \\\*" talk_to client 2 send "1616 90 98\n" simple_expect "=1616 $any_time 9 0 7 0 2 { 1 11 6 11 } 0 \\\*" talk_to client 3 send "1617 90 98\n" simple_expect "=1617 $any_time 9 0 7 0 2 { 1 11 6 11 } 0 \\\*" # Deleting text 98; deleter 9 send "1618 29 98\n" talk_to client 1 simple_expect ":18 14 98 $any_time 9 0 7 0 2 { 1 11 6 11 } 0 \\\*" talk_to client 2 simple_expect ":18 14 98 $any_time 9 0 7 0 2 { 1 11 6 11 } 0 \\\*" talk_to client 3 simple_expect "=1618" # Creating text 99 by 9 send "1619 86 [holl "text 99"] 1 { 1 13 } 0 { }\n" talk_to client 1 simple_expect ":18 15 99 $any_time 9 0 7 0 2 { 1 13 6 11 } 0 \\\*" talk_to client 2 simple_expect ":18 15 99 $any_time 9 0 7 0 2 { 1 13 6 11 } 0 \\\*" talk_to client 3 simple_expect "=1619 99" talk_to client 0 send "1620 90 99\n" simple_expect "=1620 $any_time 9 0 7 0 2 { 1 13 6 11 } 0 \\\*" talk_to client 1 send "1621 90 99\n" simple_expect "=1621 $any_time 9 0 7 0 2 { 1 13 6 11 } 0 \\\*" talk_to client 2 send "1622 90 99\n" simple_expect "=1622 $any_time 9 0 7 0 2 { 1 13 6 11 } 0 \\\*" talk_to client 3 send "1623 90 99\n" simple_expect "=1623 $any_time 9 0 7 0 2 { 1 13 6 11 } 0 \\\*" # Deleting text 99; deleter 9 send "1624 29 99\n" talk_to client 1 simple_expect ":18 14 99 $any_time 9 0 7 0 2 { 1 13 6 11 } 0 \\\*" talk_to client 2 simple_expect ":18 14 99 $any_time 9 0 7 0 2 { 1 13 6 11 } 0 \\\*" talk_to client 3 simple_expect "=1624" # Creating text 100 by 9 send "1625 86 [holl "text 100"] 1 { 1 14 } 0 { }\n" talk_to client 1 simple_expect ":18 15 100 $any_time 9 0 8 0 2 { 1 14 6 11 } 0 \\\*" talk_to client 2 simple_expect ":18 15 100 $any_time 9 0 8 0 2 { 1 14 6 11 } 0 \\\*" talk_to client 3 simple_expect "=1625 100" talk_to client 0 send "1626 90 100\n" simple_expect "%1626 14 100" talk_to client 1 send "1627 90 100\n" simple_expect "=1627 $any_time 9 0 8 0 2 { 1 14 6 11 } 0 \\\*" talk_to client 2 send "1628 90 100\n" simple_expect "=1628 $any_time 9 0 8 0 2 { 1 14 6 11 } 0 \\\*" talk_to client 3 send "1629 90 100\n" simple_expect "=1629 $any_time 9 0 8 0 2 { 1 14 6 11 } 0 \\\*" # Deleting text 100; deleter 9 send "1630 29 100\n" talk_to client 1 simple_expect ":18 14 100 $any_time 9 0 8 0 2 { 1 14 6 11 } 0 \\\*" talk_to client 2 simple_expect ":18 14 100 $any_time 9 0 8 0 2 { 1 14 6 11 } 0 \\\*" talk_to client 3 simple_expect "=1630" # Creating text 101 by 9 send "1631 86 [holl "text 101"] 1 { 15 6 } 0 { }\n" talk_to client 0 simple_expect ":18 15 101 $any_time 9 0 8 0 2 { 15 6 6 12 } 0 \\\*" talk_to client 3 simple_expect "=1631 101" talk_to client 0 send "1632 90 101\n" simple_expect "=1632 $any_time 9 0 8 0 2 { 15 6 6 12 } 0 \\\*" talk_to client 1 send "1633 90 101\n" simple_expect "%1633 14 101" talk_to client 2 send "1634 90 101\n" simple_expect "%1634 14 101" talk_to client 3 send "1635 90 101\n" simple_expect "=1635 $any_time 9 0 8 0 2 { 15 6 6 12 } 0 \\\*" # Deleting text 101; deleter 9 send "1636 29 101\n" talk_to client 0 simple_expect ":18 14 101 $any_time 9 0 8 0 2 { 15 6 6 12 } 0 \\\*" talk_to client 3 simple_expect "=1636" # Creating text 102 by 9 send "1637 86 [holl "text 102"] 1 { 15 7 } 0 { }\n" simple_expect "=1637 102" talk_to client 0 send "1638 90 102\n" simple_expect "%1638 14 102" talk_to client 1 send "1639 90 102\n" simple_expect "=1639 $any_time 9 0 8 0 2 { 15 7 6 12 } 0 \\\*" talk_to client 2 send "1640 90 102\n" simple_expect "%1640 14 102" talk_to client 3 send "1641 90 102\n" simple_expect "=1641 $any_time 9 0 8 0 2 { 15 7 6 12 } 0 \\\*" # Deleting text 102; deleter 9 send "1642 29 102\n" simple_expect "=1642" # Creating text 103 by 9 send "1643 86 [holl "text 103"] 1 { 15 8 } 0 { }\n" talk_to client 2 simple_expect ":18 15 103 $any_time 9 0 8 0 2 { 15 8 6 12 } 0 \\\*" talk_to client 3 simple_expect "=1643 103" talk_to client 0 send "1644 90 103\n" simple_expect "%1644 14 103" talk_to client 1 send "1645 90 103\n" simple_expect "%1645 14 103" talk_to client 2 send "1646 90 103\n" simple_expect "=1646 $any_time 9 0 8 0 2 { 15 8 6 12 } 0 \\\*" talk_to client 3 send "1647 90 103\n" simple_expect "=1647 $any_time 9 0 8 0 2 { 15 8 6 12 } 0 \\\*" # Deleting text 103; deleter 9 send "1648 29 103\n" talk_to client 2 simple_expect ":18 14 103 $any_time 9 0 8 0 2 { 15 8 6 12 } 0 \\\*" talk_to client 3 simple_expect "=1648" # Creating text 104 by 9 send "1649 86 [holl "text 104"] 1 { 15 9 } 0 { }\n" simple_expect ":18 15 104 $any_time 9 0 8 0 2 { 15 9 6 12 } 0 \\\*" simple_expect "=1649 104" talk_to client 0 send "1650 90 104\n" simple_expect "%1650 14 104" talk_to client 1 send "1651 90 104\n" simple_expect "%1651 14 104" talk_to client 2 send "1652 90 104\n" simple_expect "%1652 14 104" talk_to client 3 send "1653 90 104\n" simple_expect "=1653 $any_time 9 0 8 0 2 { 15 9 6 12 } 0 \\\*" # Deleting text 104; deleter 9 send "1654 29 104\n" simple_expect ":18 14 104 $any_time 9 0 8 0 2 { 15 9 6 12 } 0 \\\*" simple_expect "=1654" # Creating text 105 by 9 send "1655 86 [holl "text 105"] 1 { 15 10 } 0 { }\n" talk_to client 1 simple_expect ":18 15 105 $any_time 9 0 8 0 2 { 15 10 6 12 } 0 \\\*" talk_to client 2 simple_expect ":18 15 105 $any_time 9 0 8 0 2 { 15 10 6 12 } 0 \\\*" talk_to client 3 simple_expect "=1655 105" talk_to client 0 send "1656 90 105\n" simple_expect "=1656 $any_time 9 0 8 0 2 { 15 10 6 12 } 0 \\\*" talk_to client 1 send "1657 90 105\n" simple_expect "=1657 $any_time 9 0 8 0 2 { 15 10 6 12 } 0 \\\*" talk_to client 2 send "1658 90 105\n" simple_expect "=1658 $any_time 9 0 8 0 2 { 15 10 6 12 } 0 \\\*" talk_to client 3 send "1659 90 105\n" simple_expect "=1659 $any_time 9 0 8 0 2 { 15 10 6 12 } 0 \\\*" # Deleting text 105; deleter 9 send "1660 29 105\n" talk_to client 1 simple_expect ":18 14 105 $any_time 9 0 8 0 2 { 15 10 6 12 } 0 \\\*" talk_to client 2 simple_expect ":18 14 105 $any_time 9 0 8 0 2 { 15 10 6 12 } 0 \\\*" talk_to client 3 simple_expect "=1660" # Creating text 106 by 9 send "1661 86 [holl "text 106"] 1 { 15 11 } 0 { }\n" talk_to client 1 simple_expect ":18 15 106 $any_time 9 0 8 0 2 { 15 11 6 12 } 0 \\\*" talk_to client 2 simple_expect ":18 15 106 $any_time 9 0 8 0 2 { 15 11 6 12 } 0 \\\*" talk_to client 3 simple_expect "=1661 106" talk_to client 0 send "1662 90 106\n" simple_expect "%1662 14 106" talk_to client 1 send "1663 90 106\n" simple_expect "=1663 $any_time 9 0 8 0 2 { 15 11 6 12 } 0 \\\*" talk_to client 2 send "1664 90 106\n" simple_expect "=1664 $any_time 9 0 8 0 2 { 15 11 6 12 } 0 \\\*" talk_to client 3 send "1665 90 106\n" simple_expect "=1665 $any_time 9 0 8 0 2 { 15 11 6 12 } 0 \\\*" # Deleting text 106; deleter 9 send "1666 29 106\n" talk_to client 1 simple_expect ":18 14 106 $any_time 9 0 8 0 2 { 15 11 6 12 } 0 \\\*" talk_to client 2 simple_expect ":18 14 106 $any_time 9 0 8 0 2 { 15 11 6 12 } 0 \\\*" talk_to client 3 simple_expect "=1666" # Creating text 107 by 9 send "1667 86 [holl "text 107"] 1 { 15 13 } 0 { }\n" talk_to client 1 simple_expect ":18 15 107 $any_time 9 0 8 0 2 { 15 13 6 12 } 0 \\\*" talk_to client 2 simple_expect ":18 15 107 $any_time 9 0 8 0 2 { 15 13 6 12 } 0 \\\*" talk_to client 3 simple_expect "=1667 107" talk_to client 0 send "1668 90 107\n" simple_expect "=1668 $any_time 9 0 8 0 2 { 15 13 6 12 } 0 \\\*" talk_to client 1 send "1669 90 107\n" simple_expect "=1669 $any_time 9 0 8 0 2 { 15 13 6 12 } 0 \\\*" talk_to client 2 send "1670 90 107\n" simple_expect "=1670 $any_time 9 0 8 0 2 { 15 13 6 12 } 0 \\\*" talk_to client 3 send "1671 90 107\n" simple_expect "=1671 $any_time 9 0 8 0 2 { 15 13 6 12 } 0 \\\*" # Deleting text 107; deleter 9 send "1672 29 107\n" talk_to client 1 simple_expect ":18 14 107 $any_time 9 0 8 0 2 { 15 13 6 12 } 0 \\\*" talk_to client 2 simple_expect ":18 14 107 $any_time 9 0 8 0 2 { 15 13 6 12 } 0 \\\*" talk_to client 3 simple_expect "=1672" # Creating text 108 by 9 send "1673 86 [holl "text 108"] 1 { 15 14 } 0 { }\n" talk_to client 1 simple_expect ":18 15 108 $any_time 9 0 8 0 2 { 15 14 6 12 } 0 \\\*" talk_to client 2 simple_expect ":18 15 108 $any_time 9 0 8 0 2 { 15 14 6 12 } 0 \\\*" talk_to client 3 simple_expect "=1673 108" talk_to client 0 send "1674 90 108\n" simple_expect "%1674 14 108" talk_to client 1 send "1675 90 108\n" simple_expect "=1675 $any_time 9 0 8 0 2 { 15 14 6 12 } 0 \\\*" talk_to client 2 send "1676 90 108\n" simple_expect "=1676 $any_time 9 0 8 0 2 { 15 14 6 12 } 0 \\\*" talk_to client 3 send "1677 90 108\n" simple_expect "=1677 $any_time 9 0 8 0 2 { 15 14 6 12 } 0 \\\*" # Deleting text 108; deleter 9 send "1678 29 108\n" talk_to client 1 simple_expect ":18 14 108 $any_time 9 0 8 0 2 { 15 14 6 12 } 0 \\\*" talk_to client 2 simple_expect ":18 14 108 $any_time 9 0 8 0 2 { 15 14 6 12 } 0 \\\*" talk_to client 3 simple_expect "=1678" send_user "testing simple create+add+delete\n" talk_to client 0 # Creating text 109 by 6 send "1679 86 [holl "text 109"] 0 { } 0 { }\n" simple_expect "=1679 109" send "1680 90 109\n" simple_expect "=1680 $any_time 6 0 8 0 0 \\\* 0 \\\*" talk_to client 1 send "1681 90 109\n" simple_expect "%1681 14 109" talk_to client 2 send "1682 90 109\n" simple_expect "%1682 14 109" talk_to client 3 send "1683 90 109\n" simple_expect "%1683 14 109" talk_to client 0 # Adding recipient to text 109; adder 6 send "1684 30 109 6 0\n" simple_expect ":3 16 109 6 0" simple_expect "=1684" send "1685 90 109\n" simple_expect "=1685 $any_time 6 0 8 0 3 { 0 6 6 13 9 $any_time } 0 \\\*" talk_to client 1 send "1686 90 109\n" simple_expect "%1686 14 109" talk_to client 2 send "1687 90 109\n" simple_expect "%1687 14 109" talk_to client 3 send "1688 90 109\n" simple_expect "%1688 14 109" talk_to client 0 # Deleting text 109; deleter 6 send "1689 29 109\n" simple_expect ":18 14 109 $any_time 6 0 8 0 3 { 0 6 6 13 9 $any_time } 0 \\\*" simple_expect "=1689" # Creating text 110 by 6 send "1690 86 [holl "text 110"] 0 { } 0 { }\n" simple_expect "=1690 110" send "1691 90 110\n" simple_expect "=1691 $any_time 6 0 8 0 0 \\\* 0 \\\*" talk_to client 1 send "1692 90 110\n" simple_expect "%1692 14 110" talk_to client 2 send "1693 90 110\n" simple_expect "%1693 14 110" talk_to client 3 send "1694 90 110\n" simple_expect "%1694 14 110" talk_to client 0 # Adding recipient to text 110; adder 6 send "1695 30 110 7 0\n" simple_expect "=1695" send "1696 90 110\n" simple_expect "=1696 $any_time 6 0 8 0 3 { 0 7 6 13 9 $any_time } 0 \\\*" talk_to client 1 send "1697 90 110\n" simple_expect "=1697 $any_time 6 0 8 0 3 { 0 7 6 13 9 $any_time } 0 \\\*" talk_to client 2 send "1698 90 110\n" simple_expect "%1698 14 110" talk_to client 3 send "1699 90 110\n" simple_expect "%1699 14 110" talk_to client 0 # Deleting text 110; deleter 6 send "1700 29 110\n" simple_expect "=1700" # Creating text 111 by 6 send "1701 86 [holl "text 111"] 0 { } 0 { }\n" simple_expect "=1701 111" send "1702 90 111\n" simple_expect "=1702 $any_time 6 0 8 0 0 \\\* 0 \\\*" talk_to client 1 send "1703 90 111\n" simple_expect "%1703 14 111" talk_to client 2 send "1704 90 111\n" simple_expect "%1704 14 111" talk_to client 3 send "1705 90 111\n" simple_expect "%1705 14 111" talk_to client 0 # Adding recipient to text 111; adder 6 send "1706 30 111 8 0\n" talk_to client 2 simple_expect ":3 16 111 8 0" talk_to client 0 simple_expect "=1706" send "1707 90 111\n" simple_expect "=1707 $any_time 6 0 8 0 3 { 0 8 6 13 9 $any_time } 0 \\\*" talk_to client 1 send "1708 90 111\n" simple_expect "%1708 14 111" talk_to client 2 send "1709 90 111\n" simple_expect "=1709 $any_time 6 0 8 0 3 { 0 8 6 13 9 $any_time } 0 \\\*" talk_to client 3 send "1710 90 111\n" simple_expect "%1710 14 111" talk_to client 0 # Deleting text 111; deleter 6 send "1711 29 111\n" talk_to client 2 simple_expect ":18 14 111 $any_time 6 0 8 0 3 { 0 8 6 13 9 $any_time } 0 \\\*" talk_to client 0 simple_expect "=1711" # Creating text 112 by 6 send "1712 86 [holl "text 112"] 0 { } 0 { }\n" simple_expect "=1712 112" send "1713 90 112\n" simple_expect "=1713 $any_time 6 0 8 0 0 \\\* 0 \\\*" talk_to client 1 send "1714 90 112\n" simple_expect "%1714 14 112" talk_to client 2 send "1715 90 112\n" simple_expect "%1715 14 112" talk_to client 3 send "1716 90 112\n" simple_expect "%1716 14 112" talk_to client 0 # Adding recipient to text 112; adder 6 send "1717 30 112 9 0\n" talk_to client 3 simple_expect ":3 16 112 9 0" talk_to client 0 simple_expect "=1717" send "1718 90 112\n" simple_expect "=1718 $any_time 6 0 8 0 3 { 0 9 6 13 9 $any_time } 0 \\\*" talk_to client 1 send "1719 90 112\n" simple_expect "%1719 14 112" talk_to client 2 send "1720 90 112\n" simple_expect "%1720 14 112" talk_to client 3 send "1721 90 112\n" simple_expect "=1721 $any_time 6 0 8 0 3 { 0 9 6 13 9 $any_time } 0 \\\*" talk_to client 0 # Deleting text 112; deleter 6 send "1722 29 112\n" talk_to client 3 simple_expect ":18 14 112 $any_time 6 0 8 0 3 { 0 9 6 13 9 $any_time } 0 \\\*" talk_to client 0 simple_expect "=1722" # Creating text 113 by 6 send "1723 86 [holl "text 113"] 0 { } 0 { }\n" simple_expect "=1723 113" send "1724 90 113\n" simple_expect "=1724 $any_time 6 0 8 0 0 \\\* 0 \\\*" talk_to client 1 send "1725 90 113\n" simple_expect "%1725 14 113" talk_to client 2 send "1726 90 113\n" simple_expect "%1726 14 113" talk_to client 3 send "1727 90 113\n" simple_expect "%1727 14 113" talk_to client 0 # Adding recipient to text 113; adder 6 send "1728 30 113 10 0\n" talk_to client 1 simple_expect ":3 16 113 10 0" talk_to client 2 simple_expect ":3 16 113 10 0" talk_to client 0 simple_expect "=1728" send "1729 90 113\n" simple_expect "=1729 $any_time 6 0 8 0 3 { 0 10 6 13 9 $any_time } 0 \\\*" talk_to client 1 send "1730 90 113\n" simple_expect "=1730 $any_time 6 0 8 0 3 { 0 10 6 13 9 $any_time } 0 \\\*" talk_to client 2 send "1731 90 113\n" simple_expect "=1731 $any_time 6 0 8 0 3 { 0 10 6 13 9 $any_time } 0 \\\*" talk_to client 3 send "1732 90 113\n" simple_expect "=1732 $any_time 6 0 8 0 3 { 0 10 6 13 9 $any_time } 0 \\\*" talk_to client 0 # Deleting text 113; deleter 6 send "1733 29 113\n" talk_to client 1 simple_expect ":18 14 113 $any_time 6 0 8 0 3 { 0 10 6 13 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 113 $any_time 6 0 8 0 3 { 0 10 6 13 9 $any_time } 0 \\\*" talk_to client 0 simple_expect "=1733" # Creating text 114 by 6 send "1734 86 [holl "text 114"] 0 { } 0 { }\n" simple_expect "=1734 114" send "1735 90 114\n" simple_expect "=1735 $any_time 6 0 8 0 0 \\\* 0 \\\*" talk_to client 1 send "1736 90 114\n" simple_expect "%1736 14 114" talk_to client 2 send "1737 90 114\n" simple_expect "%1737 14 114" talk_to client 3 send "1738 90 114\n" simple_expect "%1738 14 114" talk_to client 0 # Adding recipient to text 114; adder 6 send "1739 30 114 11 0\n" talk_to client 1 simple_expect ":3 16 114 11 0" talk_to client 2 simple_expect ":3 16 114 11 0" talk_to client 0 simple_expect "=1739" send "1740 90 114\n" simple_expect "=1740 $any_time 6 0 8 0 3 { 0 11 6 13 9 $any_time } 0 \\\*" talk_to client 1 send "1741 90 114\n" simple_expect "=1741 $any_time 6 0 8 0 3 { 0 11 6 13 9 $any_time } 0 \\\*" talk_to client 2 send "1742 90 114\n" simple_expect "=1742 $any_time 6 0 8 0 3 { 0 11 6 13 9 $any_time } 0 \\\*" talk_to client 3 send "1743 90 114\n" simple_expect "%1743 14 114" talk_to client 0 # Deleting text 114; deleter 6 send "1744 29 114\n" talk_to client 1 simple_expect ":18 14 114 $any_time 6 0 8 0 3 { 0 11 6 13 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 114 $any_time 6 0 8 0 3 { 0 11 6 13 9 $any_time } 0 \\\*" talk_to client 0 simple_expect "=1744" # Creating text 115 by 6 send "1745 86 [holl "text 115"] 0 { } 0 { }\n" simple_expect "=1745 115" send "1746 90 115\n" simple_expect "=1746 $any_time 6 0 8 0 0 \\\* 0 \\\*" talk_to client 1 send "1747 90 115\n" simple_expect "%1747 14 115" talk_to client 2 send "1748 90 115\n" simple_expect "%1748 14 115" talk_to client 3 send "1749 90 115\n" simple_expect "%1749 14 115" talk_to client 0 # Adding recipient to text 115; adder 6 send "1750 30 115 13 0\n" talk_to client 1 simple_expect ":3 16 115 13 0" talk_to client 2 simple_expect ":3 16 115 13 0" talk_to client 0 simple_expect "=1750" send "1751 90 115\n" simple_expect "=1751 $any_time 6 0 8 0 3 { 0 13 6 13 9 $any_time } 0 \\\*" talk_to client 1 send "1752 90 115\n" simple_expect "=1752 $any_time 6 0 8 0 3 { 0 13 6 13 9 $any_time } 0 \\\*" talk_to client 2 send "1753 90 115\n" simple_expect "=1753 $any_time 6 0 8 0 3 { 0 13 6 13 9 $any_time } 0 \\\*" talk_to client 3 send "1754 90 115\n" simple_expect "=1754 $any_time 6 0 8 0 3 { 0 13 6 13 9 $any_time } 0 \\\*" talk_to client 0 # Deleting text 115; deleter 6 send "1755 29 115\n" talk_to client 1 simple_expect ":18 14 115 $any_time 6 0 8 0 3 { 0 13 6 13 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 115 $any_time 6 0 8 0 3 { 0 13 6 13 9 $any_time } 0 \\\*" talk_to client 0 simple_expect "=1755" # Creating text 116 by 6 send "1756 86 [holl "text 116"] 0 { } 0 { }\n" simple_expect "=1756 116" send "1757 90 116\n" simple_expect "=1757 $any_time 6 0 8 0 0 \\\* 0 \\\*" talk_to client 1 send "1758 90 116\n" simple_expect "%1758 14 116" talk_to client 2 send "1759 90 116\n" simple_expect "%1759 14 116" talk_to client 3 send "1760 90 116\n" simple_expect "%1760 14 116" talk_to client 0 # Adding recipient to text 116; adder 6 send "1761 30 116 14 0\n" talk_to client 1 simple_expect ":3 16 116 14 0" talk_to client 2 simple_expect ":3 16 116 14 0" talk_to client 0 simple_expect "=1761" send "1762 90 116\n" simple_expect "=1762 $any_time 6 0 8 0 3 { 0 14 6 13 9 $any_time } 0 \\\*" talk_to client 1 send "1763 90 116\n" simple_expect "=1763 $any_time 6 0 8 0 3 { 0 14 6 13 9 $any_time } 0 \\\*" talk_to client 2 send "1764 90 116\n" simple_expect "=1764 $any_time 6 0 8 0 3 { 0 14 6 13 9 $any_time } 0 \\\*" talk_to client 3 send "1765 90 116\n" simple_expect "=1765 $any_time 6 0 8 0 3 { 0 14 6 13 9 $any_time } 0 \\\*" talk_to client 0 # Deleting text 116; deleter 6 send "1766 29 116\n" talk_to client 1 simple_expect ":18 14 116 $any_time 6 0 8 0 3 { 0 14 6 13 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 116 $any_time 6 0 8 0 3 { 0 14 6 13 9 $any_time } 0 \\\*" talk_to client 0 simple_expect "=1766" # Creating text 117 by 6 send "1767 86 [holl "text 117"] 0 { } 0 { }\n" simple_expect "=1767 117" send "1768 90 117\n" simple_expect "=1768 $any_time 6 0 8 0 0 \\\* 0 \\\*" talk_to client 1 send "1769 90 117\n" simple_expect "%1769 14 117" talk_to client 2 send "1770 90 117\n" simple_expect "%1770 14 117" talk_to client 3 send "1771 90 117\n" simple_expect "%1771 14 117" talk_to client 0 # Adding recipient to text 117; adder 6 send "1772 30 117 6 1\n" simple_expect ":3 16 117 6 1" simple_expect "=1772" send "1773 90 117\n" simple_expect "=1773 $any_time 6 0 8 0 3 { 1 6 6 14 9 $any_time } 0 \\\*" talk_to client 1 send "1774 90 117\n" simple_expect "%1774 14 117" talk_to client 2 send "1775 90 117\n" simple_expect "%1775 14 117" talk_to client 3 send "1776 90 117\n" simple_expect "%1776 14 117" talk_to client 0 # Deleting text 117; deleter 6 send "1777 29 117\n" simple_expect ":18 14 117 $any_time 6 0 8 0 3 { 1 6 6 14 9 $any_time } 0 \\\*" simple_expect "=1777" # Creating text 118 by 6 send "1778 86 [holl "text 118"] 0 { } 0 { }\n" simple_expect "=1778 118" send "1779 90 118\n" simple_expect "=1779 $any_time 6 0 8 0 0 \\\* 0 \\\*" talk_to client 1 send "1780 90 118\n" simple_expect "%1780 14 118" talk_to client 2 send "1781 90 118\n" simple_expect "%1781 14 118" talk_to client 3 send "1782 90 118\n" simple_expect "%1782 14 118" talk_to client 0 # Adding recipient to text 118; adder 6 send "1783 30 118 7 1\n" simple_expect "=1783" send "1784 90 118\n" simple_expect "=1784 $any_time 6 0 8 0 3 { 1 7 6 14 9 $any_time } 0 \\\*" talk_to client 1 send "1785 90 118\n" simple_expect "=1785 $any_time 6 0 8 0 3 { 1 7 6 14 9 $any_time } 0 \\\*" talk_to client 2 send "1786 90 118\n" simple_expect "%1786 14 118" talk_to client 3 send "1787 90 118\n" simple_expect "%1787 14 118" talk_to client 0 # Deleting text 118; deleter 6 send "1788 29 118\n" simple_expect "=1788" # Creating text 119 by 6 send "1789 86 [holl "text 119"] 0 { } 0 { }\n" simple_expect "=1789 119" send "1790 90 119\n" simple_expect "=1790 $any_time 6 0 8 0 0 \\\* 0 \\\*" talk_to client 1 send "1791 90 119\n" simple_expect "%1791 14 119" talk_to client 2 send "1792 90 119\n" simple_expect "%1792 14 119" talk_to client 3 send "1793 90 119\n" simple_expect "%1793 14 119" talk_to client 0 # Adding recipient to text 119; adder 6 send "1794 30 119 8 1\n" talk_to client 2 simple_expect ":3 16 119 8 1" talk_to client 0 simple_expect "=1794" send "1795 90 119\n" simple_expect "=1795 $any_time 6 0 8 0 3 { 1 8 6 14 9 $any_time } 0 \\\*" talk_to client 1 send "1796 90 119\n" simple_expect "%1796 14 119" talk_to client 2 send "1797 90 119\n" simple_expect "=1797 $any_time 6 0 8 0 3 { 1 8 6 14 9 $any_time } 0 \\\*" talk_to client 3 send "1798 90 119\n" simple_expect "%1798 14 119" talk_to client 0 # Deleting text 119; deleter 6 send "1799 29 119\n" talk_to client 2 simple_expect ":18 14 119 $any_time 6 0 8 0 3 { 1 8 6 14 9 $any_time } 0 \\\*" talk_to client 0 simple_expect "=1799" # Creating text 120 by 6 send "1800 86 [holl "text 120"] 0 { } 0 { }\n" simple_expect "=1800 120" send "1801 90 120\n" simple_expect "=1801 $any_time 6 0 8 0 0 \\\* 0 \\\*" talk_to client 1 send "1802 90 120\n" simple_expect "%1802 14 120" talk_to client 2 send "1803 90 120\n" simple_expect "%1803 14 120" talk_to client 3 send "1804 90 120\n" simple_expect "%1804 14 120" talk_to client 0 # Adding recipient to text 120; adder 6 send "1805 30 120 9 1\n" talk_to client 3 simple_expect ":3 16 120 9 1" talk_to client 0 simple_expect "=1805" send "1806 90 120\n" simple_expect "=1806 $any_time 6 0 8 0 3 { 1 9 6 14 9 $any_time } 0 \\\*" talk_to client 1 send "1807 90 120\n" simple_expect "%1807 14 120" talk_to client 2 send "1808 90 120\n" simple_expect "%1808 14 120" talk_to client 3 send "1809 90 120\n" simple_expect "=1809 $any_time 6 0 8 0 3 { 1 9 6 14 9 $any_time } 0 \\\*" talk_to client 0 # Deleting text 120; deleter 6 send "1810 29 120\n" talk_to client 3 simple_expect ":18 14 120 $any_time 6 0 8 0 3 { 1 9 6 14 9 $any_time } 0 \\\*" talk_to client 0 simple_expect "=1810" # Creating text 121 by 6 send "1811 86 [holl "text 121"] 0 { } 0 { }\n" simple_expect "=1811 121" send "1812 90 121\n" simple_expect "=1812 $any_time 6 0 8 0 0 \\\* 0 \\\*" talk_to client 1 send "1813 90 121\n" simple_expect "%1813 14 121" talk_to client 2 send "1814 90 121\n" simple_expect "%1814 14 121" talk_to client 3 send "1815 90 121\n" simple_expect "%1815 14 121" talk_to client 0 # Adding recipient to text 121; adder 6 send "1816 30 121 10 1\n" talk_to client 1 simple_expect ":3 16 121 10 1" talk_to client 2 simple_expect ":3 16 121 10 1" talk_to client 0 simple_expect "=1816" send "1817 90 121\n" simple_expect "=1817 $any_time 6 0 8 0 3 { 1 10 6 14 9 $any_time } 0 \\\*" talk_to client 1 send "1818 90 121\n" simple_expect "=1818 $any_time 6 0 8 0 3 { 1 10 6 14 9 $any_time } 0 \\\*" talk_to client 2 send "1819 90 121\n" simple_expect "=1819 $any_time 6 0 8 0 3 { 1 10 6 14 9 $any_time } 0 \\\*" talk_to client 3 send "1820 90 121\n" simple_expect "=1820 $any_time 6 0 8 0 3 { 1 10 6 14 9 $any_time } 0 \\\*" talk_to client 0 # Deleting text 121; deleter 6 send "1821 29 121\n" talk_to client 1 simple_expect ":18 14 121 $any_time 6 0 8 0 3 { 1 10 6 14 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 121 $any_time 6 0 8 0 3 { 1 10 6 14 9 $any_time } 0 \\\*" talk_to client 0 simple_expect "=1821" # Creating text 122 by 6 send "1822 86 [holl "text 122"] 0 { } 0 { }\n" simple_expect "=1822 122" send "1823 90 122\n" simple_expect "=1823 $any_time 6 0 8 0 0 \\\* 0 \\\*" talk_to client 1 send "1824 90 122\n" simple_expect "%1824 14 122" talk_to client 2 send "1825 90 122\n" simple_expect "%1825 14 122" talk_to client 3 send "1826 90 122\n" simple_expect "%1826 14 122" talk_to client 0 # Adding recipient to text 122; adder 6 send "1827 30 122 11 1\n" talk_to client 1 simple_expect ":3 16 122 11 1" talk_to client 2 simple_expect ":3 16 122 11 1" talk_to client 0 simple_expect "=1827" send "1828 90 122\n" simple_expect "=1828 $any_time 6 0 8 0 3 { 1 11 6 14 9 $any_time } 0 \\\*" talk_to client 1 send "1829 90 122\n" simple_expect "=1829 $any_time 6 0 8 0 3 { 1 11 6 14 9 $any_time } 0 \\\*" talk_to client 2 send "1830 90 122\n" simple_expect "=1830 $any_time 6 0 8 0 3 { 1 11 6 14 9 $any_time } 0 \\\*" talk_to client 3 send "1831 90 122\n" simple_expect "%1831 14 122" talk_to client 0 # Deleting text 122; deleter 6 send "1832 29 122\n" talk_to client 1 simple_expect ":18 14 122 $any_time 6 0 8 0 3 { 1 11 6 14 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 122 $any_time 6 0 8 0 3 { 1 11 6 14 9 $any_time } 0 \\\*" talk_to client 0 simple_expect "=1832" # Creating text 123 by 6 send "1833 86 [holl "text 123"] 0 { } 0 { }\n" simple_expect "=1833 123" send "1834 90 123\n" simple_expect "=1834 $any_time 6 0 8 0 0 \\\* 0 \\\*" talk_to client 1 send "1835 90 123\n" simple_expect "%1835 14 123" talk_to client 2 send "1836 90 123\n" simple_expect "%1836 14 123" talk_to client 3 send "1837 90 123\n" simple_expect "%1837 14 123" talk_to client 0 # Adding recipient to text 123; adder 6 send "1838 30 123 13 1\n" talk_to client 1 simple_expect ":3 16 123 13 1" talk_to client 2 simple_expect ":3 16 123 13 1" talk_to client 0 simple_expect "=1838" send "1839 90 123\n" simple_expect "=1839 $any_time 6 0 8 0 3 { 1 13 6 14 9 $any_time } 0 \\\*" talk_to client 1 send "1840 90 123\n" simple_expect "=1840 $any_time 6 0 8 0 3 { 1 13 6 14 9 $any_time } 0 \\\*" talk_to client 2 send "1841 90 123\n" simple_expect "=1841 $any_time 6 0 8 0 3 { 1 13 6 14 9 $any_time } 0 \\\*" talk_to client 3 send "1842 90 123\n" simple_expect "=1842 $any_time 6 0 8 0 3 { 1 13 6 14 9 $any_time } 0 \\\*" talk_to client 0 # Deleting text 123; deleter 6 send "1843 29 123\n" talk_to client 1 simple_expect ":18 14 123 $any_time 6 0 8 0 3 { 1 13 6 14 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 123 $any_time 6 0 8 0 3 { 1 13 6 14 9 $any_time } 0 \\\*" talk_to client 0 simple_expect "=1843" # Creating text 124 by 6 send "1844 86 [holl "text 124"] 0 { } 0 { }\n" simple_expect "=1844 124" send "1845 90 124\n" simple_expect "=1845 $any_time 6 0 8 0 0 \\\* 0 \\\*" talk_to client 1 send "1846 90 124\n" simple_expect "%1846 14 124" talk_to client 2 send "1847 90 124\n" simple_expect "%1847 14 124" talk_to client 3 send "1848 90 124\n" simple_expect "%1848 14 124" talk_to client 0 # Adding recipient to text 124; adder 6 send "1849 30 124 14 1\n" talk_to client 1 simple_expect ":3 16 124 14 1" talk_to client 2 simple_expect ":3 16 124 14 1" talk_to client 0 simple_expect "=1849" send "1850 90 124\n" simple_expect "=1850 $any_time 6 0 8 0 3 { 1 14 6 14 9 $any_time } 0 \\\*" talk_to client 1 send "1851 90 124\n" simple_expect "=1851 $any_time 6 0 8 0 3 { 1 14 6 14 9 $any_time } 0 \\\*" talk_to client 2 send "1852 90 124\n" simple_expect "=1852 $any_time 6 0 8 0 3 { 1 14 6 14 9 $any_time } 0 \\\*" talk_to client 3 send "1853 90 124\n" simple_expect "=1853 $any_time 6 0 8 0 3 { 1 14 6 14 9 $any_time } 0 \\\*" talk_to client 0 # Deleting text 124; deleter 6 send "1854 29 124\n" talk_to client 1 simple_expect ":18 14 124 $any_time 6 0 8 0 3 { 1 14 6 14 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 124 $any_time 6 0 8 0 3 { 1 14 6 14 9 $any_time } 0 \\\*" talk_to client 0 simple_expect "=1854" # Creating text 125 by 6 send "1855 86 [holl "text 125"] 0 { } 0 { }\n" simple_expect "=1855 125" send "1856 90 125\n" simple_expect "=1856 $any_time 6 0 8 0 0 \\\* 0 \\\*" talk_to client 1 send "1857 90 125\n" simple_expect "%1857 14 125" talk_to client 2 send "1858 90 125\n" simple_expect "%1858 14 125" talk_to client 3 send "1859 90 125\n" simple_expect "%1859 14 125" talk_to client 0 # Adding recipient to text 125; adder 6 send "1860 30 125 6 15\n" simple_expect ":3 16 125 6 15" simple_expect "=1860" send "1861 90 125\n" simple_expect "=1861 $any_time 6 0 8 0 3 { 15 6 6 15 9 $any_time } 0 \\\*" talk_to client 1 send "1862 90 125\n" simple_expect "%1862 14 125" talk_to client 2 send "1863 90 125\n" simple_expect "%1863 14 125" talk_to client 3 send "1864 90 125\n" simple_expect "%1864 14 125" talk_to client 0 # Deleting text 125; deleter 6 send "1865 29 125\n" simple_expect ":18 14 125 $any_time 6 0 8 0 3 { 15 6 6 15 9 $any_time } 0 \\\*" simple_expect "=1865" # Creating text 126 by 6 send "1866 86 [holl "text 126"] 0 { } 0 { }\n" simple_expect "=1866 126" send "1867 90 126\n" simple_expect "=1867 $any_time 6 0 8 0 0 \\\* 0 \\\*" talk_to client 1 send "1868 90 126\n" simple_expect "%1868 14 126" talk_to client 2 send "1869 90 126\n" simple_expect "%1869 14 126" talk_to client 3 send "1870 90 126\n" simple_expect "%1870 14 126" talk_to client 0 # Adding recipient to text 126; adder 6 send "1871 30 126 7 15\n" simple_expect "=1871" send "1872 90 126\n" simple_expect "=1872 $any_time 6 0 8 0 3 { 15 7 6 15 9 $any_time } 0 \\\*" talk_to client 1 send "1873 90 126\n" simple_expect "=1873 $any_time 6 0 8 0 3 { 15 7 6 15 9 $any_time } 0 \\\*" talk_to client 2 send "1874 90 126\n" simple_expect "%1874 14 126" talk_to client 3 send "1875 90 126\n" simple_expect "%1875 14 126" talk_to client 0 # Deleting text 126; deleter 6 send "1876 29 126\n" simple_expect "=1876" # Creating text 127 by 6 send "1877 86 [holl "text 127"] 0 { } 0 { }\n" simple_expect "=1877 127" send "1878 90 127\n" simple_expect "=1878 $any_time 6 0 8 0 0 \\\* 0 \\\*" talk_to client 1 send "1879 90 127\n" simple_expect "%1879 14 127" talk_to client 2 send "1880 90 127\n" simple_expect "%1880 14 127" talk_to client 3 send "1881 90 127\n" simple_expect "%1881 14 127" talk_to client 0 # Adding recipient to text 127; adder 6 send "1882 30 127 8 15\n" talk_to client 2 simple_expect ":3 16 127 8 15" talk_to client 0 simple_expect "=1882" send "1883 90 127\n" simple_expect "=1883 $any_time 6 0 8 0 3 { 15 8 6 15 9 $any_time } 0 \\\*" talk_to client 1 send "1884 90 127\n" simple_expect "%1884 14 127" talk_to client 2 send "1885 90 127\n" simple_expect "=1885 $any_time 6 0 8 0 3 { 15 8 6 15 9 $any_time } 0 \\\*" talk_to client 3 send "1886 90 127\n" simple_expect "%1886 14 127" talk_to client 0 # Deleting text 127; deleter 6 send "1887 29 127\n" talk_to client 2 simple_expect ":18 14 127 $any_time 6 0 8 0 3 { 15 8 6 15 9 $any_time } 0 \\\*" talk_to client 0 simple_expect "=1887" # Creating text 128 by 6 send "1888 86 [holl "text 128"] 0 { } 0 { }\n" simple_expect "=1888 128" send "1889 90 128\n" simple_expect "=1889 $any_time 6 0 8 0 0 \\\* 0 \\\*" talk_to client 1 send "1890 90 128\n" simple_expect "%1890 14 128" talk_to client 2 send "1891 90 128\n" simple_expect "%1891 14 128" talk_to client 3 send "1892 90 128\n" simple_expect "%1892 14 128" talk_to client 0 # Adding recipient to text 128; adder 6 send "1893 30 128 9 15\n" talk_to client 3 simple_expect ":3 16 128 9 15" talk_to client 0 simple_expect "=1893" send "1894 90 128\n" simple_expect "=1894 $any_time 6 0 8 0 3 { 15 9 6 15 9 $any_time } 0 \\\*" talk_to client 1 send "1895 90 128\n" simple_expect "%1895 14 128" talk_to client 2 send "1896 90 128\n" simple_expect "%1896 14 128" talk_to client 3 send "1897 90 128\n" simple_expect "=1897 $any_time 6 0 8 0 3 { 15 9 6 15 9 $any_time } 0 \\\*" talk_to client 0 # Deleting text 128; deleter 6 send "1898 29 128\n" talk_to client 3 simple_expect ":18 14 128 $any_time 6 0 8 0 3 { 15 9 6 15 9 $any_time } 0 \\\*" talk_to client 0 simple_expect "=1898" # Creating text 129 by 6 send "1899 86 [holl "text 129"] 0 { } 0 { }\n" simple_expect "=1899 129" send "1900 90 129\n" simple_expect "=1900 $any_time 6 0 8 0 0 \\\* 0 \\\*" talk_to client 1 send "1901 90 129\n" simple_expect "%1901 14 129" talk_to client 2 send "1902 90 129\n" simple_expect "%1902 14 129" talk_to client 3 send "1903 90 129\n" simple_expect "%1903 14 129" talk_to client 0 # Adding recipient to text 129; adder 6 send "1904 30 129 10 15\n" talk_to client 1 simple_expect ":3 16 129 10 15" talk_to client 2 simple_expect ":3 16 129 10 15" talk_to client 0 simple_expect "=1904" send "1905 90 129\n" simple_expect "=1905 $any_time 6 0 8 0 3 { 15 10 6 15 9 $any_time } 0 \\\*" talk_to client 1 send "1906 90 129\n" simple_expect "=1906 $any_time 6 0 8 0 3 { 15 10 6 15 9 $any_time } 0 \\\*" talk_to client 2 send "1907 90 129\n" simple_expect "=1907 $any_time 6 0 8 0 3 { 15 10 6 15 9 $any_time } 0 \\\*" talk_to client 3 send "1908 90 129\n" simple_expect "=1908 $any_time 6 0 8 0 3 { 15 10 6 15 9 $any_time } 0 \\\*" talk_to client 0 # Deleting text 129; deleter 6 send "1909 29 129\n" talk_to client 1 simple_expect ":18 14 129 $any_time 6 0 8 0 3 { 15 10 6 15 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 129 $any_time 6 0 8 0 3 { 15 10 6 15 9 $any_time } 0 \\\*" talk_to client 0 simple_expect "=1909" # Creating text 130 by 6 send "1910 86 [holl "text 130"] 0 { } 0 { }\n" simple_expect "=1910 130" send "1911 90 130\n" simple_expect "=1911 $any_time 6 0 8 0 0 \\\* 0 \\\*" talk_to client 1 send "1912 90 130\n" simple_expect "%1912 14 130" talk_to client 2 send "1913 90 130\n" simple_expect "%1913 14 130" talk_to client 3 send "1914 90 130\n" simple_expect "%1914 14 130" talk_to client 0 # Adding recipient to text 130; adder 6 send "1915 30 130 11 15\n" talk_to client 1 simple_expect ":3 16 130 11 15" talk_to client 2 simple_expect ":3 16 130 11 15" talk_to client 0 simple_expect "=1915" send "1916 90 130\n" simple_expect "=1916 $any_time 6 0 8 0 3 { 15 11 6 15 9 $any_time } 0 \\\*" talk_to client 1 send "1917 90 130\n" simple_expect "=1917 $any_time 6 0 8 0 3 { 15 11 6 15 9 $any_time } 0 \\\*" talk_to client 2 send "1918 90 130\n" simple_expect "=1918 $any_time 6 0 8 0 3 { 15 11 6 15 9 $any_time } 0 \\\*" talk_to client 3 send "1919 90 130\n" simple_expect "%1919 14 130" talk_to client 0 # Deleting text 130; deleter 6 send "1920 29 130\n" talk_to client 1 simple_expect ":18 14 130 $any_time 6 0 8 0 3 { 15 11 6 15 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 130 $any_time 6 0 8 0 3 { 15 11 6 15 9 $any_time } 0 \\\*" talk_to client 0 simple_expect "=1920" # Creating text 131 by 6 send "1921 86 [holl "text 131"] 0 { } 0 { }\n" simple_expect "=1921 131" send "1922 90 131\n" simple_expect "=1922 $any_time 6 0 8 0 0 \\\* 0 \\\*" talk_to client 1 send "1923 90 131\n" simple_expect "%1923 14 131" talk_to client 2 send "1924 90 131\n" simple_expect "%1924 14 131" talk_to client 3 send "1925 90 131\n" simple_expect "%1925 14 131" talk_to client 0 # Adding recipient to text 131; adder 6 send "1926 30 131 13 15\n" talk_to client 1 simple_expect ":3 16 131 13 15" talk_to client 2 simple_expect ":3 16 131 13 15" talk_to client 0 simple_expect "=1926" send "1927 90 131\n" simple_expect "=1927 $any_time 6 0 8 0 3 { 15 13 6 15 9 $any_time } 0 \\\*" talk_to client 1 send "1928 90 131\n" simple_expect "=1928 $any_time 6 0 8 0 3 { 15 13 6 15 9 $any_time } 0 \\\*" talk_to client 2 send "1929 90 131\n" simple_expect "=1929 $any_time 6 0 8 0 3 { 15 13 6 15 9 $any_time } 0 \\\*" talk_to client 3 send "1930 90 131\n" simple_expect "=1930 $any_time 6 0 8 0 3 { 15 13 6 15 9 $any_time } 0 \\\*" talk_to client 0 # Deleting text 131; deleter 6 send "1931 29 131\n" talk_to client 1 simple_expect ":18 14 131 $any_time 6 0 8 0 3 { 15 13 6 15 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 131 $any_time 6 0 8 0 3 { 15 13 6 15 9 $any_time } 0 \\\*" talk_to client 0 simple_expect "=1931" # Creating text 132 by 6 send "1932 86 [holl "text 132"] 0 { } 0 { }\n" simple_expect "=1932 132" send "1933 90 132\n" simple_expect "=1933 $any_time 6 0 8 0 0 \\\* 0 \\\*" talk_to client 1 send "1934 90 132\n" simple_expect "%1934 14 132" talk_to client 2 send "1935 90 132\n" simple_expect "%1935 14 132" talk_to client 3 send "1936 90 132\n" simple_expect "%1936 14 132" talk_to client 0 # Adding recipient to text 132; adder 6 send "1937 30 132 14 15\n" talk_to client 1 simple_expect ":3 16 132 14 15" talk_to client 2 simple_expect ":3 16 132 14 15" talk_to client 0 simple_expect "=1937" send "1938 90 132\n" simple_expect "=1938 $any_time 6 0 8 0 3 { 15 14 6 15 9 $any_time } 0 \\\*" talk_to client 1 send "1939 90 132\n" simple_expect "=1939 $any_time 6 0 8 0 3 { 15 14 6 15 9 $any_time } 0 \\\*" talk_to client 2 send "1940 90 132\n" simple_expect "=1940 $any_time 6 0 8 0 3 { 15 14 6 15 9 $any_time } 0 \\\*" talk_to client 3 send "1941 90 132\n" simple_expect "=1941 $any_time 6 0 8 0 3 { 15 14 6 15 9 $any_time } 0 \\\*" talk_to client 0 # Deleting text 132; deleter 6 send "1942 29 132\n" talk_to client 1 simple_expect ":18 14 132 $any_time 6 0 8 0 3 { 15 14 6 15 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 132 $any_time 6 0 8 0 3 { 15 14 6 15 9 $any_time } 0 \\\*" talk_to client 0 simple_expect "=1942" talk_to client 1 # Creating text 133 by 7 send "1943 86 [holl "text 133"] 0 { } 0 { }\n" simple_expect "=1943 133" talk_to client 0 send "1944 90 133\n" simple_expect "%1944 14 133" talk_to client 1 send "1945 90 133\n" simple_expect "=1945 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "1946 90 133\n" simple_expect "%1946 14 133" talk_to client 3 send "1947 90 133\n" simple_expect "%1947 14 133" talk_to client 1 # Adding recipient to text 133; adder 7 send "1948 30 133 6 0\n" talk_to client 0 simple_expect ":3 16 133 6 0" talk_to client 1 simple_expect "=1948" talk_to client 0 send "1949 90 133\n" simple_expect "=1949 $any_time 7 0 8 0 3 { 0 6 6 16 9 $any_time } 0 \\\*" talk_to client 1 send "1950 90 133\n" simple_expect "=1950 $any_time 7 0 8 0 3 { 0 6 6 16 9 $any_time } 0 \\\*" talk_to client 2 send "1951 90 133\n" simple_expect "%1951 14 133" talk_to client 3 send "1952 90 133\n" simple_expect "%1952 14 133" talk_to client 1 # Deleting text 133; deleter 7 send "1953 29 133\n" talk_to client 0 simple_expect ":18 14 133 $any_time 7 0 8 0 3 { 0 6 6 16 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=1953" # Creating text 134 by 7 send "1954 86 [holl "text 134"] 0 { } 0 { }\n" simple_expect "=1954 134" talk_to client 0 send "1955 90 134\n" simple_expect "%1955 14 134" talk_to client 1 send "1956 90 134\n" simple_expect "=1956 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "1957 90 134\n" simple_expect "%1957 14 134" talk_to client 3 send "1958 90 134\n" simple_expect "%1958 14 134" talk_to client 1 # Adding recipient to text 134; adder 7 send "1959 30 134 7 0\n" simple_expect "=1959" talk_to client 0 send "1960 90 134\n" simple_expect "%1960 14 134" talk_to client 1 send "1961 90 134\n" simple_expect "=1961 $any_time 7 0 8 0 3 { 0 7 6 16 9 $any_time } 0 \\\*" talk_to client 2 send "1962 90 134\n" simple_expect "%1962 14 134" talk_to client 3 send "1963 90 134\n" simple_expect "%1963 14 134" talk_to client 1 # Deleting text 134; deleter 7 send "1964 29 134\n" simple_expect "=1964" # Creating text 135 by 7 send "1965 86 [holl "text 135"] 0 { } 0 { }\n" simple_expect "=1965 135" talk_to client 0 send "1966 90 135\n" simple_expect "%1966 14 135" talk_to client 1 send "1967 90 135\n" simple_expect "=1967 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "1968 90 135\n" simple_expect "%1968 14 135" talk_to client 3 send "1969 90 135\n" simple_expect "%1969 14 135" talk_to client 1 # Adding recipient to text 135; adder 7 send "1970 30 135 8 0\n" talk_to client 2 simple_expect ":3 16 135 8 0" talk_to client 1 simple_expect "=1970" talk_to client 0 send "1971 90 135\n" simple_expect "%1971 14 135" talk_to client 1 send "1972 90 135\n" simple_expect "=1972 $any_time 7 0 8 0 3 { 0 8 6 16 9 $any_time } 0 \\\*" talk_to client 2 send "1973 90 135\n" simple_expect "=1973 $any_time 7 0 8 0 3 { 0 8 6 16 9 $any_time } 0 \\\*" talk_to client 3 send "1974 90 135\n" simple_expect "%1974 14 135" talk_to client 1 # Deleting text 135; deleter 7 send "1975 29 135\n" talk_to client 2 simple_expect ":18 14 135 $any_time 7 0 8 0 3 { 0 8 6 16 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=1975" # Creating text 136 by 7 send "1976 86 [holl "text 136"] 0 { } 0 { }\n" simple_expect "=1976 136" talk_to client 0 send "1977 90 136\n" simple_expect "%1977 14 136" talk_to client 1 send "1978 90 136\n" simple_expect "=1978 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "1979 90 136\n" simple_expect "%1979 14 136" talk_to client 3 send "1980 90 136\n" simple_expect "%1980 14 136" talk_to client 1 # Adding recipient to text 136; adder 7 send "1981 30 136 9 0\n" talk_to client 3 simple_expect ":3 16 136 9 0" talk_to client 1 simple_expect "=1981" talk_to client 0 send "1982 90 136\n" simple_expect "%1982 14 136" talk_to client 1 send "1983 90 136\n" simple_expect "=1983 $any_time 7 0 8 0 3 { 0 9 6 16 9 $any_time } 0 \\\*" talk_to client 2 send "1984 90 136\n" simple_expect "%1984 14 136" talk_to client 3 send "1985 90 136\n" simple_expect "=1985 $any_time 7 0 8 0 3 { 0 9 6 16 9 $any_time } 0 \\\*" talk_to client 1 # Deleting text 136; deleter 7 send "1986 29 136\n" talk_to client 3 simple_expect ":18 14 136 $any_time 7 0 8 0 3 { 0 9 6 16 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=1986" # Creating text 137 by 7 send "1987 86 [holl "text 137"] 0 { } 0 { }\n" simple_expect "=1987 137" talk_to client 0 send "1988 90 137\n" simple_expect "%1988 14 137" talk_to client 1 send "1989 90 137\n" simple_expect "=1989 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "1990 90 137\n" simple_expect "%1990 14 137" talk_to client 3 send "1991 90 137\n" simple_expect "%1991 14 137" talk_to client 1 # Adding recipient to text 137; adder 7 send "1992 30 137 10 0\n" simple_expect ":3 16 137 10 0" talk_to client 2 simple_expect ":3 16 137 10 0" talk_to client 1 simple_expect "=1992" talk_to client 0 send "1993 90 137\n" simple_expect "=1993 $any_time 7 0 8 0 3 { 0 10 6 16 9 $any_time } 0 \\\*" talk_to client 1 send "1994 90 137\n" simple_expect "=1994 $any_time 7 0 8 0 3 { 0 10 6 16 9 $any_time } 0 \\\*" talk_to client 2 send "1995 90 137\n" simple_expect "=1995 $any_time 7 0 8 0 3 { 0 10 6 16 9 $any_time } 0 \\\*" talk_to client 3 send "1996 90 137\n" simple_expect "=1996 $any_time 7 0 8 0 3 { 0 10 6 16 9 $any_time } 0 \\\*" talk_to client 1 # Deleting text 137; deleter 7 send "1997 29 137\n" simple_expect ":18 14 137 $any_time 7 0 8 0 3 { 0 10 6 16 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 137 $any_time 7 0 8 0 3 { 0 10 6 16 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=1997" # Creating text 138 by 7 send "1998 86 [holl "text 138"] 0 { } 0 { }\n" simple_expect "=1998 138" talk_to client 0 send "1999 90 138\n" simple_expect "%1999 14 138" talk_to client 1 send "2000 90 138\n" simple_expect "=2000 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "2001 90 138\n" simple_expect "%2001 14 138" talk_to client 3 send "2002 90 138\n" simple_expect "%2002 14 138" talk_to client 1 # Adding recipient to text 138; adder 7 send "2003 30 138 11 0\n" simple_expect ":3 16 138 11 0" talk_to client 2 simple_expect ":3 16 138 11 0" talk_to client 1 simple_expect "=2003" talk_to client 0 send "2004 90 138\n" simple_expect "%2004 14 138" talk_to client 1 send "2005 90 138\n" simple_expect "=2005 $any_time 7 0 8 0 3 { 0 11 6 16 9 $any_time } 0 \\\*" talk_to client 2 send "2006 90 138\n" simple_expect "=2006 $any_time 7 0 8 0 3 { 0 11 6 16 9 $any_time } 0 \\\*" talk_to client 3 send "2007 90 138\n" simple_expect "%2007 14 138" talk_to client 1 # Deleting text 138; deleter 7 send "2008 29 138\n" simple_expect ":18 14 138 $any_time 7 0 8 0 3 { 0 11 6 16 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 138 $any_time 7 0 8 0 3 { 0 11 6 16 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=2008" # Creating text 139 by 7 send "2009 86 [holl "text 139"] 0 { } 0 { }\n" simple_expect "=2009 139" talk_to client 0 send "2010 90 139\n" simple_expect "%2010 14 139" talk_to client 1 send "2011 90 139\n" simple_expect "=2011 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "2012 90 139\n" simple_expect "%2012 14 139" talk_to client 3 send "2013 90 139\n" simple_expect "%2013 14 139" talk_to client 1 # Adding recipient to text 139; adder 7 send "2014 30 139 12 0\n" simple_expect ":3 16 139 12 0" talk_to client 2 simple_expect ":3 16 139 12 0" talk_to client 1 simple_expect "=2014" talk_to client 0 send "2015 90 139\n" simple_expect "%2015 14 139" talk_to client 1 send "2016 90 139\n" simple_expect "=2016 $any_time 7 0 8 0 3 { 0 12 6 7 9 $any_time } 0 \\\*" talk_to client 2 send "2017 90 139\n" simple_expect "=2017 $any_time 7 0 8 0 3 { 0 12 6 7 9 $any_time } 0 \\\*" talk_to client 3 send "2018 90 139\n" simple_expect "%2018 14 139" talk_to client 1 # Deleting text 139; deleter 7 send "2019 29 139\n" simple_expect ":18 14 139 $any_time 7 0 8 0 3 { 0 12 6 7 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 139 $any_time 7 0 8 0 3 { 0 12 6 7 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=2019" # Creating text 140 by 7 send "2020 86 [holl "text 140"] 0 { } 0 { }\n" simple_expect "=2020 140" talk_to client 0 send "2021 90 140\n" simple_expect "%2021 14 140" talk_to client 1 send "2022 90 140\n" simple_expect "=2022 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "2023 90 140\n" simple_expect "%2023 14 140" talk_to client 3 send "2024 90 140\n" simple_expect "%2024 14 140" talk_to client 1 # Adding recipient to text 140; adder 7 send "2025 30 140 13 0\n" simple_expect ":3 16 140 13 0" talk_to client 2 simple_expect ":3 16 140 13 0" talk_to client 1 simple_expect "=2025" talk_to client 0 send "2026 90 140\n" simple_expect "=2026 $any_time 7 0 8 0 3 { 0 13 6 16 9 $any_time } 0 \\\*" talk_to client 1 send "2027 90 140\n" simple_expect "=2027 $any_time 7 0 8 0 3 { 0 13 6 16 9 $any_time } 0 \\\*" talk_to client 2 send "2028 90 140\n" simple_expect "=2028 $any_time 7 0 8 0 3 { 0 13 6 16 9 $any_time } 0 \\\*" talk_to client 3 send "2029 90 140\n" simple_expect "=2029 $any_time 7 0 8 0 3 { 0 13 6 16 9 $any_time } 0 \\\*" talk_to client 1 # Deleting text 140; deleter 7 send "2030 29 140\n" simple_expect ":18 14 140 $any_time 7 0 8 0 3 { 0 13 6 16 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 140 $any_time 7 0 8 0 3 { 0 13 6 16 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=2030" # Creating text 141 by 7 send "2031 86 [holl "text 141"] 0 { } 0 { }\n" simple_expect "=2031 141" talk_to client 0 send "2032 90 141\n" simple_expect "%2032 14 141" talk_to client 1 send "2033 90 141\n" simple_expect "=2033 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "2034 90 141\n" simple_expect "%2034 14 141" talk_to client 3 send "2035 90 141\n" simple_expect "%2035 14 141" talk_to client 1 # Adding recipient to text 141; adder 7 send "2036 30 141 14 0\n" simple_expect ":3 16 141 14 0" talk_to client 2 simple_expect ":3 16 141 14 0" talk_to client 1 simple_expect "=2036" talk_to client 0 send "2037 90 141\n" simple_expect "%2037 14 141" talk_to client 1 send "2038 90 141\n" simple_expect "=2038 $any_time 7 0 8 0 3 { 0 14 6 16 9 $any_time } 0 \\\*" talk_to client 2 send "2039 90 141\n" simple_expect "=2039 $any_time 7 0 8 0 3 { 0 14 6 16 9 $any_time } 0 \\\*" talk_to client 3 send "2040 90 141\n" simple_expect "=2040 $any_time 7 0 8 0 3 { 0 14 6 16 9 $any_time } 0 \\\*" talk_to client 1 # Deleting text 141; deleter 7 send "2041 29 141\n" simple_expect ":18 14 141 $any_time 7 0 8 0 3 { 0 14 6 16 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 141 $any_time 7 0 8 0 3 { 0 14 6 16 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=2041" # Creating text 142 by 7 send "2042 86 [holl "text 142"] 0 { } 0 { }\n" simple_expect "=2042 142" talk_to client 0 send "2043 90 142\n" simple_expect "%2043 14 142" talk_to client 1 send "2044 90 142\n" simple_expect "=2044 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "2045 90 142\n" simple_expect "%2045 14 142" talk_to client 3 send "2046 90 142\n" simple_expect "%2046 14 142" talk_to client 1 # Adding recipient to text 142; adder 7 send "2047 30 142 15 0\n" simple_expect ":3 16 142 15 0" talk_to client 2 simple_expect ":3 16 142 15 0" talk_to client 1 simple_expect "=2047" talk_to client 0 send "2048 90 142\n" simple_expect "%2048 14 142" talk_to client 1 send "2049 90 142\n" simple_expect "=2049 $any_time 7 0 8 0 3 { 0 15 6 7 9 $any_time } 0 \\\*" talk_to client 2 send "2050 90 142\n" simple_expect "=2050 $any_time 7 0 8 0 3 { 0 15 6 7 9 $any_time } 0 \\\*" talk_to client 3 send "2051 90 142\n" simple_expect "=2051 $any_time 7 0 8 0 3 { 0 15 6 7 9 $any_time } 0 \\\*" talk_to client 1 # Deleting text 142; deleter 7 send "2052 29 142\n" simple_expect ":18 14 142 $any_time 7 0 8 0 3 { 0 15 6 7 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 142 $any_time 7 0 8 0 3 { 0 15 6 7 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=2052" # Creating text 143 by 7 send "2053 86 [holl "text 143"] 0 { } 0 { }\n" simple_expect "=2053 143" talk_to client 0 send "2054 90 143\n" simple_expect "%2054 14 143" talk_to client 1 send "2055 90 143\n" simple_expect "=2055 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "2056 90 143\n" simple_expect "%2056 14 143" talk_to client 3 send "2057 90 143\n" simple_expect "%2057 14 143" talk_to client 1 # Adding recipient to text 143; adder 7 send "2058 30 143 6 1\n" talk_to client 0 simple_expect ":3 16 143 6 1" talk_to client 1 simple_expect "=2058" talk_to client 0 send "2059 90 143\n" simple_expect "=2059 $any_time 7 0 8 0 3 { 1 6 6 17 9 $any_time } 0 \\\*" talk_to client 1 send "2060 90 143\n" simple_expect "=2060 $any_time 7 0 8 0 3 { 1 6 6 17 9 $any_time } 0 \\\*" talk_to client 2 send "2061 90 143\n" simple_expect "%2061 14 143" talk_to client 3 send "2062 90 143\n" simple_expect "%2062 14 143" talk_to client 1 # Deleting text 143; deleter 7 send "2063 29 143\n" talk_to client 0 simple_expect ":18 14 143 $any_time 7 0 8 0 3 { 1 6 6 17 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=2063" # Creating text 144 by 7 send "2064 86 [holl "text 144"] 0 { } 0 { }\n" simple_expect "=2064 144" talk_to client 0 send "2065 90 144\n" simple_expect "%2065 14 144" talk_to client 1 send "2066 90 144\n" simple_expect "=2066 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "2067 90 144\n" simple_expect "%2067 14 144" talk_to client 3 send "2068 90 144\n" simple_expect "%2068 14 144" talk_to client 1 # Adding recipient to text 144; adder 7 send "2069 30 144 7 1\n" simple_expect "=2069" talk_to client 0 send "2070 90 144\n" simple_expect "%2070 14 144" talk_to client 1 send "2071 90 144\n" simple_expect "=2071 $any_time 7 0 8 0 3 { 1 7 6 17 9 $any_time } 0 \\\*" talk_to client 2 send "2072 90 144\n" simple_expect "%2072 14 144" talk_to client 3 send "2073 90 144\n" simple_expect "%2073 14 144" talk_to client 1 # Deleting text 144; deleter 7 send "2074 29 144\n" simple_expect "=2074" # Creating text 145 by 7 send "2075 86 [holl "text 145"] 0 { } 0 { }\n" simple_expect "=2075 145" talk_to client 0 send "2076 90 145\n" simple_expect "%2076 14 145" talk_to client 1 send "2077 90 145\n" simple_expect "=2077 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "2078 90 145\n" simple_expect "%2078 14 145" talk_to client 3 send "2079 90 145\n" simple_expect "%2079 14 145" talk_to client 1 # Adding recipient to text 145; adder 7 send "2080 30 145 8 1\n" talk_to client 2 simple_expect ":3 16 145 8 1" talk_to client 1 simple_expect "=2080" talk_to client 0 send "2081 90 145\n" simple_expect "%2081 14 145" talk_to client 1 send "2082 90 145\n" simple_expect "=2082 $any_time 7 0 8 0 3 { 1 8 6 17 9 $any_time } 0 \\\*" talk_to client 2 send "2083 90 145\n" simple_expect "=2083 $any_time 7 0 8 0 3 { 1 8 6 17 9 $any_time } 0 \\\*" talk_to client 3 send "2084 90 145\n" simple_expect "%2084 14 145" talk_to client 1 # Deleting text 145; deleter 7 send "2085 29 145\n" talk_to client 2 simple_expect ":18 14 145 $any_time 7 0 8 0 3 { 1 8 6 17 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=2085" # Creating text 146 by 7 send "2086 86 [holl "text 146"] 0 { } 0 { }\n" simple_expect "=2086 146" talk_to client 0 send "2087 90 146\n" simple_expect "%2087 14 146" talk_to client 1 send "2088 90 146\n" simple_expect "=2088 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "2089 90 146\n" simple_expect "%2089 14 146" talk_to client 3 send "2090 90 146\n" simple_expect "%2090 14 146" talk_to client 1 # Adding recipient to text 146; adder 7 send "2091 30 146 9 1\n" talk_to client 3 simple_expect ":3 16 146 9 1" talk_to client 1 simple_expect "=2091" talk_to client 0 send "2092 90 146\n" simple_expect "%2092 14 146" talk_to client 1 send "2093 90 146\n" simple_expect "=2093 $any_time 7 0 8 0 3 { 1 9 6 17 9 $any_time } 0 \\\*" talk_to client 2 send "2094 90 146\n" simple_expect "%2094 14 146" talk_to client 3 send "2095 90 146\n" simple_expect "=2095 $any_time 7 0 8 0 3 { 1 9 6 17 9 $any_time } 0 \\\*" talk_to client 1 # Deleting text 146; deleter 7 send "2096 29 146\n" talk_to client 3 simple_expect ":18 14 146 $any_time 7 0 8 0 3 { 1 9 6 17 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=2096" # Creating text 147 by 7 send "2097 86 [holl "text 147"] 0 { } 0 { }\n" simple_expect "=2097 147" talk_to client 0 send "2098 90 147\n" simple_expect "%2098 14 147" talk_to client 1 send "2099 90 147\n" simple_expect "=2099 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "2100 90 147\n" simple_expect "%2100 14 147" talk_to client 3 send "2101 90 147\n" simple_expect "%2101 14 147" talk_to client 1 # Adding recipient to text 147; adder 7 send "2102 30 147 10 1\n" simple_expect ":3 16 147 10 1" talk_to client 2 simple_expect ":3 16 147 10 1" talk_to client 1 simple_expect "=2102" talk_to client 0 send "2103 90 147\n" simple_expect "=2103 $any_time 7 0 8 0 3 { 1 10 6 17 9 $any_time } 0 \\\*" talk_to client 1 send "2104 90 147\n" simple_expect "=2104 $any_time 7 0 8 0 3 { 1 10 6 17 9 $any_time } 0 \\\*" talk_to client 2 send "2105 90 147\n" simple_expect "=2105 $any_time 7 0 8 0 3 { 1 10 6 17 9 $any_time } 0 \\\*" talk_to client 3 send "2106 90 147\n" simple_expect "=2106 $any_time 7 0 8 0 3 { 1 10 6 17 9 $any_time } 0 \\\*" talk_to client 1 # Deleting text 147; deleter 7 send "2107 29 147\n" simple_expect ":18 14 147 $any_time 7 0 8 0 3 { 1 10 6 17 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 147 $any_time 7 0 8 0 3 { 1 10 6 17 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=2107" # Creating text 148 by 7 send "2108 86 [holl "text 148"] 0 { } 0 { }\n" simple_expect "=2108 148" talk_to client 0 send "2109 90 148\n" simple_expect "%2109 14 148" talk_to client 1 send "2110 90 148\n" simple_expect "=2110 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "2111 90 148\n" simple_expect "%2111 14 148" talk_to client 3 send "2112 90 148\n" simple_expect "%2112 14 148" talk_to client 1 # Adding recipient to text 148; adder 7 send "2113 30 148 11 1\n" simple_expect ":3 16 148 11 1" talk_to client 2 simple_expect ":3 16 148 11 1" talk_to client 1 simple_expect "=2113" talk_to client 0 send "2114 90 148\n" simple_expect "%2114 14 148" talk_to client 1 send "2115 90 148\n" simple_expect "=2115 $any_time 7 0 8 0 3 { 1 11 6 17 9 $any_time } 0 \\\*" talk_to client 2 send "2116 90 148\n" simple_expect "=2116 $any_time 7 0 8 0 3 { 1 11 6 17 9 $any_time } 0 \\\*" talk_to client 3 send "2117 90 148\n" simple_expect "%2117 14 148" talk_to client 1 # Deleting text 148; deleter 7 send "2118 29 148\n" simple_expect ":18 14 148 $any_time 7 0 8 0 3 { 1 11 6 17 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 148 $any_time 7 0 8 0 3 { 1 11 6 17 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=2118" # Creating text 149 by 7 send "2119 86 [holl "text 149"] 0 { } 0 { }\n" simple_expect "=2119 149" talk_to client 0 send "2120 90 149\n" simple_expect "%2120 14 149" talk_to client 1 send "2121 90 149\n" simple_expect "=2121 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "2122 90 149\n" simple_expect "%2122 14 149" talk_to client 3 send "2123 90 149\n" simple_expect "%2123 14 149" talk_to client 1 # Adding recipient to text 149; adder 7 send "2124 30 149 12 1\n" simple_expect ":3 16 149 12 1" talk_to client 2 simple_expect ":3 16 149 12 1" talk_to client 1 simple_expect "=2124" talk_to client 0 send "2125 90 149\n" simple_expect "%2125 14 149" talk_to client 1 send "2126 90 149\n" simple_expect "=2126 $any_time 7 0 8 0 3 { 1 12 6 8 9 $any_time } 0 \\\*" talk_to client 2 send "2127 90 149\n" simple_expect "=2127 $any_time 7 0 8 0 3 { 1 12 6 8 9 $any_time } 0 \\\*" talk_to client 3 send "2128 90 149\n" simple_expect "%2128 14 149" talk_to client 1 # Deleting text 149; deleter 7 send "2129 29 149\n" simple_expect ":18 14 149 $any_time 7 0 8 0 3 { 1 12 6 8 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 149 $any_time 7 0 8 0 3 { 1 12 6 8 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=2129" # Creating text 150 by 7 send "2130 86 [holl "text 150"] 0 { } 0 { }\n" simple_expect "=2130 150" talk_to client 0 send "2131 90 150\n" simple_expect "%2131 14 150" talk_to client 1 send "2132 90 150\n" simple_expect "=2132 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "2133 90 150\n" simple_expect "%2133 14 150" talk_to client 3 send "2134 90 150\n" simple_expect "%2134 14 150" talk_to client 1 # Adding recipient to text 150; adder 7 send "2135 30 150 13 1\n" simple_expect ":3 16 150 13 1" talk_to client 2 simple_expect ":3 16 150 13 1" talk_to client 1 simple_expect "=2135" talk_to client 0 send "2136 90 150\n" simple_expect "=2136 $any_time 7 0 8 0 3 { 1 13 6 17 9 $any_time } 0 \\\*" talk_to client 1 send "2137 90 150\n" simple_expect "=2137 $any_time 7 0 8 0 3 { 1 13 6 17 9 $any_time } 0 \\\*" talk_to client 2 send "2138 90 150\n" simple_expect "=2138 $any_time 7 0 8 0 3 { 1 13 6 17 9 $any_time } 0 \\\*" talk_to client 3 send "2139 90 150\n" simple_expect "=2139 $any_time 7 0 8 0 3 { 1 13 6 17 9 $any_time } 0 \\\*" talk_to client 1 # Deleting text 150; deleter 7 send "2140 29 150\n" simple_expect ":18 14 150 $any_time 7 0 8 0 3 { 1 13 6 17 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 150 $any_time 7 0 8 0 3 { 1 13 6 17 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=2140" # Creating text 151 by 7 send "2141 86 [holl "text 151"] 0 { } 0 { }\n" simple_expect "=2141 151" talk_to client 0 send "2142 90 151\n" simple_expect "%2142 14 151" talk_to client 1 send "2143 90 151\n" simple_expect "=2143 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "2144 90 151\n" simple_expect "%2144 14 151" talk_to client 3 send "2145 90 151\n" simple_expect "%2145 14 151" talk_to client 1 # Adding recipient to text 151; adder 7 send "2146 30 151 14 1\n" simple_expect ":3 16 151 14 1" talk_to client 2 simple_expect ":3 16 151 14 1" talk_to client 1 simple_expect "=2146" talk_to client 0 send "2147 90 151\n" simple_expect "%2147 14 151" talk_to client 1 send "2148 90 151\n" simple_expect "=2148 $any_time 7 0 8 0 3 { 1 14 6 17 9 $any_time } 0 \\\*" talk_to client 2 send "2149 90 151\n" simple_expect "=2149 $any_time 7 0 8 0 3 { 1 14 6 17 9 $any_time } 0 \\\*" talk_to client 3 send "2150 90 151\n" simple_expect "=2150 $any_time 7 0 8 0 3 { 1 14 6 17 9 $any_time } 0 \\\*" talk_to client 1 # Deleting text 151; deleter 7 send "2151 29 151\n" simple_expect ":18 14 151 $any_time 7 0 8 0 3 { 1 14 6 17 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 151 $any_time 7 0 8 0 3 { 1 14 6 17 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=2151" # Creating text 152 by 7 send "2152 86 [holl "text 152"] 0 { } 0 { }\n" simple_expect "=2152 152" talk_to client 0 send "2153 90 152\n" simple_expect "%2153 14 152" talk_to client 1 send "2154 90 152\n" simple_expect "=2154 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "2155 90 152\n" simple_expect "%2155 14 152" talk_to client 3 send "2156 90 152\n" simple_expect "%2156 14 152" talk_to client 1 # Adding recipient to text 152; adder 7 send "2157 30 152 15 1\n" simple_expect ":3 16 152 15 1" talk_to client 2 simple_expect ":3 16 152 15 1" talk_to client 1 simple_expect "=2157" talk_to client 0 send "2158 90 152\n" simple_expect "%2158 14 152" talk_to client 1 send "2159 90 152\n" simple_expect "=2159 $any_time 7 0 8 0 3 { 1 15 6 8 9 $any_time } 0 \\\*" talk_to client 2 send "2160 90 152\n" simple_expect "=2160 $any_time 7 0 8 0 3 { 1 15 6 8 9 $any_time } 0 \\\*" talk_to client 3 send "2161 90 152\n" simple_expect "=2161 $any_time 7 0 8 0 3 { 1 15 6 8 9 $any_time } 0 \\\*" talk_to client 1 # Deleting text 152; deleter 7 send "2162 29 152\n" simple_expect ":18 14 152 $any_time 7 0 8 0 3 { 1 15 6 8 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 152 $any_time 7 0 8 0 3 { 1 15 6 8 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=2162" # Creating text 153 by 7 send "2163 86 [holl "text 153"] 0 { } 0 { }\n" simple_expect "=2163 153" talk_to client 0 send "2164 90 153\n" simple_expect "%2164 14 153" talk_to client 1 send "2165 90 153\n" simple_expect "=2165 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "2166 90 153\n" simple_expect "%2166 14 153" talk_to client 3 send "2167 90 153\n" simple_expect "%2167 14 153" talk_to client 1 # Adding recipient to text 153; adder 7 send "2168 30 153 6 15\n" talk_to client 0 simple_expect ":3 16 153 6 15" talk_to client 1 simple_expect "=2168" talk_to client 0 send "2169 90 153\n" simple_expect "=2169 $any_time 7 0 8 0 3 { 15 6 6 18 9 $any_time } 0 \\\*" talk_to client 1 send "2170 90 153\n" simple_expect "=2170 $any_time 7 0 8 0 3 { 15 6 6 18 9 $any_time } 0 \\\*" talk_to client 2 send "2171 90 153\n" simple_expect "%2171 14 153" talk_to client 3 send "2172 90 153\n" simple_expect "%2172 14 153" talk_to client 1 # Deleting text 153; deleter 7 send "2173 29 153\n" talk_to client 0 simple_expect ":18 14 153 $any_time 7 0 8 0 3 { 15 6 6 18 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=2173" # Creating text 154 by 7 send "2174 86 [holl "text 154"] 0 { } 0 { }\n" simple_expect "=2174 154" talk_to client 0 send "2175 90 154\n" simple_expect "%2175 14 154" talk_to client 1 send "2176 90 154\n" simple_expect "=2176 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "2177 90 154\n" simple_expect "%2177 14 154" talk_to client 3 send "2178 90 154\n" simple_expect "%2178 14 154" talk_to client 1 # Adding recipient to text 154; adder 7 send "2179 30 154 7 15\n" simple_expect "=2179" talk_to client 0 send "2180 90 154\n" simple_expect "%2180 14 154" talk_to client 1 send "2181 90 154\n" simple_expect "=2181 $any_time 7 0 8 0 3 { 15 7 6 18 9 $any_time } 0 \\\*" talk_to client 2 send "2182 90 154\n" simple_expect "%2182 14 154" talk_to client 3 send "2183 90 154\n" simple_expect "%2183 14 154" talk_to client 1 # Deleting text 154; deleter 7 send "2184 29 154\n" simple_expect "=2184" # Creating text 155 by 7 send "2185 86 [holl "text 155"] 0 { } 0 { }\n" simple_expect "=2185 155" talk_to client 0 send "2186 90 155\n" simple_expect "%2186 14 155" talk_to client 1 send "2187 90 155\n" simple_expect "=2187 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "2188 90 155\n" simple_expect "%2188 14 155" talk_to client 3 send "2189 90 155\n" simple_expect "%2189 14 155" talk_to client 1 # Adding recipient to text 155; adder 7 send "2190 30 155 8 15\n" talk_to client 2 simple_expect ":3 16 155 8 15" talk_to client 1 simple_expect "=2190" talk_to client 0 send "2191 90 155\n" simple_expect "%2191 14 155" talk_to client 1 send "2192 90 155\n" simple_expect "=2192 $any_time 7 0 8 0 3 { 15 8 6 18 9 $any_time } 0 \\\*" talk_to client 2 send "2193 90 155\n" simple_expect "=2193 $any_time 7 0 8 0 3 { 15 8 6 18 9 $any_time } 0 \\\*" talk_to client 3 send "2194 90 155\n" simple_expect "%2194 14 155" talk_to client 1 # Deleting text 155; deleter 7 send "2195 29 155\n" talk_to client 2 simple_expect ":18 14 155 $any_time 7 0 8 0 3 { 15 8 6 18 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=2195" # Creating text 156 by 7 send "2196 86 [holl "text 156"] 0 { } 0 { }\n" simple_expect "=2196 156" talk_to client 0 send "2197 90 156\n" simple_expect "%2197 14 156" talk_to client 1 send "2198 90 156\n" simple_expect "=2198 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "2199 90 156\n" simple_expect "%2199 14 156" talk_to client 3 send "2200 90 156\n" simple_expect "%2200 14 156" talk_to client 1 # Adding recipient to text 156; adder 7 send "2201 30 156 9 15\n" talk_to client 3 simple_expect ":3 16 156 9 15" talk_to client 1 simple_expect "=2201" talk_to client 0 send "2202 90 156\n" simple_expect "%2202 14 156" talk_to client 1 send "2203 90 156\n" simple_expect "=2203 $any_time 7 0 8 0 3 { 15 9 6 18 9 $any_time } 0 \\\*" talk_to client 2 send "2204 90 156\n" simple_expect "%2204 14 156" talk_to client 3 send "2205 90 156\n" simple_expect "=2205 $any_time 7 0 8 0 3 { 15 9 6 18 9 $any_time } 0 \\\*" talk_to client 1 # Deleting text 156; deleter 7 send "2206 29 156\n" talk_to client 3 simple_expect ":18 14 156 $any_time 7 0 8 0 3 { 15 9 6 18 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=2206" # Creating text 157 by 7 send "2207 86 [holl "text 157"] 0 { } 0 { }\n" simple_expect "=2207 157" talk_to client 0 send "2208 90 157\n" simple_expect "%2208 14 157" talk_to client 1 send "2209 90 157\n" simple_expect "=2209 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "2210 90 157\n" simple_expect "%2210 14 157" talk_to client 3 send "2211 90 157\n" simple_expect "%2211 14 157" talk_to client 1 # Adding recipient to text 157; adder 7 send "2212 30 157 10 15\n" simple_expect ":3 16 157 10 15" talk_to client 2 simple_expect ":3 16 157 10 15" talk_to client 1 simple_expect "=2212" talk_to client 0 send "2213 90 157\n" simple_expect "=2213 $any_time 7 0 8 0 3 { 15 10 6 18 9 $any_time } 0 \\\*" talk_to client 1 send "2214 90 157\n" simple_expect "=2214 $any_time 7 0 8 0 3 { 15 10 6 18 9 $any_time } 0 \\\*" talk_to client 2 send "2215 90 157\n" simple_expect "=2215 $any_time 7 0 8 0 3 { 15 10 6 18 9 $any_time } 0 \\\*" talk_to client 3 send "2216 90 157\n" simple_expect "=2216 $any_time 7 0 8 0 3 { 15 10 6 18 9 $any_time } 0 \\\*" talk_to client 1 # Deleting text 157; deleter 7 send "2217 29 157\n" simple_expect ":18 14 157 $any_time 7 0 8 0 3 { 15 10 6 18 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 157 $any_time 7 0 8 0 3 { 15 10 6 18 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=2217" # Creating text 158 by 7 send "2218 86 [holl "text 158"] 0 { } 0 { }\n" simple_expect "=2218 158" talk_to client 0 send "2219 90 158\n" simple_expect "%2219 14 158" talk_to client 1 send "2220 90 158\n" simple_expect "=2220 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "2221 90 158\n" simple_expect "%2221 14 158" talk_to client 3 send "2222 90 158\n" simple_expect "%2222 14 158" talk_to client 1 # Adding recipient to text 158; adder 7 send "2223 30 158 11 15\n" simple_expect ":3 16 158 11 15" talk_to client 2 simple_expect ":3 16 158 11 15" talk_to client 1 simple_expect "=2223" talk_to client 0 send "2224 90 158\n" simple_expect "%2224 14 158" talk_to client 1 send "2225 90 158\n" simple_expect "=2225 $any_time 7 0 8 0 3 { 15 11 6 18 9 $any_time } 0 \\\*" talk_to client 2 send "2226 90 158\n" simple_expect "=2226 $any_time 7 0 8 0 3 { 15 11 6 18 9 $any_time } 0 \\\*" talk_to client 3 send "2227 90 158\n" simple_expect "%2227 14 158" talk_to client 1 # Deleting text 158; deleter 7 send "2228 29 158\n" simple_expect ":18 14 158 $any_time 7 0 8 0 3 { 15 11 6 18 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 158 $any_time 7 0 8 0 3 { 15 11 6 18 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=2228" # Creating text 159 by 7 send "2229 86 [holl "text 159"] 0 { } 0 { }\n" simple_expect "=2229 159" talk_to client 0 send "2230 90 159\n" simple_expect "%2230 14 159" talk_to client 1 send "2231 90 159\n" simple_expect "=2231 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "2232 90 159\n" simple_expect "%2232 14 159" talk_to client 3 send "2233 90 159\n" simple_expect "%2233 14 159" talk_to client 1 # Adding recipient to text 159; adder 7 send "2234 30 159 12 15\n" simple_expect ":3 16 159 12 15" talk_to client 2 simple_expect ":3 16 159 12 15" talk_to client 1 simple_expect "=2234" talk_to client 0 send "2235 90 159\n" simple_expect "%2235 14 159" talk_to client 1 send "2236 90 159\n" simple_expect "=2236 $any_time 7 0 8 0 3 { 15 12 6 9 9 $any_time } 0 \\\*" talk_to client 2 send "2237 90 159\n" simple_expect "=2237 $any_time 7 0 8 0 3 { 15 12 6 9 9 $any_time } 0 \\\*" talk_to client 3 send "2238 90 159\n" simple_expect "%2238 14 159" talk_to client 1 # Deleting text 159; deleter 7 send "2239 29 159\n" simple_expect ":18 14 159 $any_time 7 0 8 0 3 { 15 12 6 9 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 159 $any_time 7 0 8 0 3 { 15 12 6 9 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=2239" # Creating text 160 by 7 send "2240 86 [holl "text 160"] 0 { } 0 { }\n" simple_expect "=2240 160" talk_to client 0 send "2241 90 160\n" simple_expect "%2241 14 160" talk_to client 1 send "2242 90 160\n" simple_expect "=2242 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "2243 90 160\n" simple_expect "%2243 14 160" talk_to client 3 send "2244 90 160\n" simple_expect "%2244 14 160" talk_to client 1 # Adding recipient to text 160; adder 7 send "2245 30 160 13 15\n" simple_expect ":3 16 160 13 15" talk_to client 2 simple_expect ":3 16 160 13 15" talk_to client 1 simple_expect "=2245" talk_to client 0 send "2246 90 160\n" simple_expect "=2246 $any_time 7 0 8 0 3 { 15 13 6 18 9 $any_time } 0 \\\*" talk_to client 1 send "2247 90 160\n" simple_expect "=2247 $any_time 7 0 8 0 3 { 15 13 6 18 9 $any_time } 0 \\\*" talk_to client 2 send "2248 90 160\n" simple_expect "=2248 $any_time 7 0 8 0 3 { 15 13 6 18 9 $any_time } 0 \\\*" talk_to client 3 send "2249 90 160\n" simple_expect "=2249 $any_time 7 0 8 0 3 { 15 13 6 18 9 $any_time } 0 \\\*" talk_to client 1 # Deleting text 160; deleter 7 send "2250 29 160\n" simple_expect ":18 14 160 $any_time 7 0 8 0 3 { 15 13 6 18 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 160 $any_time 7 0 8 0 3 { 15 13 6 18 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=2250" # Creating text 161 by 7 send "2251 86 [holl "text 161"] 0 { } 0 { }\n" simple_expect "=2251 161" talk_to client 0 send "2252 90 161\n" simple_expect "%2252 14 161" talk_to client 1 send "2253 90 161\n" simple_expect "=2253 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "2254 90 161\n" simple_expect "%2254 14 161" talk_to client 3 send "2255 90 161\n" simple_expect "%2255 14 161" talk_to client 1 # Adding recipient to text 161; adder 7 send "2256 30 161 14 15\n" simple_expect ":3 16 161 14 15" talk_to client 2 simple_expect ":3 16 161 14 15" talk_to client 1 simple_expect "=2256" talk_to client 0 send "2257 90 161\n" simple_expect "%2257 14 161" talk_to client 1 send "2258 90 161\n" simple_expect "=2258 $any_time 7 0 8 0 3 { 15 14 6 18 9 $any_time } 0 \\\*" talk_to client 2 send "2259 90 161\n" simple_expect "=2259 $any_time 7 0 8 0 3 { 15 14 6 18 9 $any_time } 0 \\\*" talk_to client 3 send "2260 90 161\n" simple_expect "=2260 $any_time 7 0 8 0 3 { 15 14 6 18 9 $any_time } 0 \\\*" talk_to client 1 # Deleting text 161; deleter 7 send "2261 29 161\n" simple_expect ":18 14 161 $any_time 7 0 8 0 3 { 15 14 6 18 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 161 $any_time 7 0 8 0 3 { 15 14 6 18 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=2261" # Creating text 162 by 7 send "2262 86 [holl "text 162"] 0 { } 0 { }\n" simple_expect "=2262 162" talk_to client 0 send "2263 90 162\n" simple_expect "%2263 14 162" talk_to client 1 send "2264 90 162\n" simple_expect "=2264 $any_time 7 0 8 0 0 \\\* 0 \\\*" talk_to client 2 send "2265 90 162\n" simple_expect "%2265 14 162" talk_to client 3 send "2266 90 162\n" simple_expect "%2266 14 162" talk_to client 1 # Adding recipient to text 162; adder 7 send "2267 30 162 15 15\n" simple_expect ":3 16 162 15 15" talk_to client 2 simple_expect ":3 16 162 15 15" talk_to client 1 simple_expect "=2267" talk_to client 0 send "2268 90 162\n" simple_expect "%2268 14 162" talk_to client 1 send "2269 90 162\n" simple_expect "=2269 $any_time 7 0 8 0 3 { 15 15 6 9 9 $any_time } 0 \\\*" talk_to client 2 send "2270 90 162\n" simple_expect "=2270 $any_time 7 0 8 0 3 { 15 15 6 9 9 $any_time } 0 \\\*" talk_to client 3 send "2271 90 162\n" simple_expect "=2271 $any_time 7 0 8 0 3 { 15 15 6 9 9 $any_time } 0 \\\*" talk_to client 1 # Deleting text 162; deleter 7 send "2272 29 162\n" simple_expect ":18 14 162 $any_time 7 0 8 0 3 { 15 15 6 9 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 162 $any_time 7 0 8 0 3 { 15 15 6 9 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=2272" talk_to client 2 # Creating text 163 by 8 send "2273 86 [holl "text 163"] 0 { } 0 { }\n" simple_expect "=2273 163" talk_to client 0 send "2274 90 163\n" simple_expect "%2274 14 163" talk_to client 1 send "2275 90 163\n" simple_expect "%2275 14 163" talk_to client 2 send "2276 90 163\n" simple_expect "=2276 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2277 90 163\n" simple_expect "%2277 14 163" talk_to client 2 # Adding recipient to text 163; adder 8 send "2278 30 163 6 0\n" talk_to client 0 simple_expect ":3 16 163 6 0" talk_to client 2 simple_expect "=2278" talk_to client 0 send "2279 90 163\n" simple_expect "=2279 $any_time 8 0 8 0 3 { 0 6 6 19 9 $any_time } 0 \\\*" talk_to client 1 send "2280 90 163\n" simple_expect "%2280 14 163" talk_to client 2 send "2281 90 163\n" simple_expect "=2281 $any_time 8 0 8 0 3 { 0 6 6 19 9 $any_time } 0 \\\*" talk_to client 3 send "2282 90 163\n" simple_expect "%2282 14 163" talk_to client 2 # Deleting text 163; deleter 8 send "2283 29 163\n" talk_to client 0 simple_expect ":18 14 163 $any_time 8 0 8 0 3 { 0 6 6 19 9 $any_time } 0 \\\*" talk_to client 2 simple_expect "=2283" # Creating text 164 by 8 send "2284 86 [holl "text 164"] 0 { } 0 { }\n" simple_expect "=2284 164" talk_to client 0 send "2285 90 164\n" simple_expect "%2285 14 164" talk_to client 1 send "2286 90 164\n" simple_expect "%2286 14 164" talk_to client 2 send "2287 90 164\n" simple_expect "=2287 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2288 90 164\n" simple_expect "%2288 14 164" talk_to client 2 # Adding recipient to text 164; adder 8 send "2289 30 164 7 0\n" simple_expect "=2289" talk_to client 0 send "2290 90 164\n" simple_expect "%2290 14 164" talk_to client 1 send "2291 90 164\n" simple_expect "=2291 $any_time 8 0 8 0 3 { 0 7 6 19 9 $any_time } 0 \\\*" talk_to client 2 send "2292 90 164\n" simple_expect "=2292 $any_time 8 0 8 0 3 { 0 7 6 19 9 $any_time } 0 \\\*" talk_to client 3 send "2293 90 164\n" simple_expect "%2293 14 164" talk_to client 2 # Deleting text 164; deleter 8 send "2294 29 164\n" simple_expect "=2294" # Creating text 165 by 8 send "2295 86 [holl "text 165"] 0 { } 0 { }\n" simple_expect "=2295 165" talk_to client 0 send "2296 90 165\n" simple_expect "%2296 14 165" talk_to client 1 send "2297 90 165\n" simple_expect "%2297 14 165" talk_to client 2 send "2298 90 165\n" simple_expect "=2298 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2299 90 165\n" simple_expect "%2299 14 165" talk_to client 2 # Adding recipient to text 165; adder 8 send "2300 30 165 8 0\n" simple_expect ":3 16 165 8 0" simple_expect "=2300" talk_to client 0 send "2301 90 165\n" simple_expect "%2301 14 165" talk_to client 1 send "2302 90 165\n" simple_expect "%2302 14 165" talk_to client 2 send "2303 90 165\n" simple_expect "=2303 $any_time 8 0 8 0 3 { 0 8 6 19 9 $any_time } 0 \\\*" talk_to client 3 send "2304 90 165\n" simple_expect "%2304 14 165" talk_to client 2 # Deleting text 165; deleter 8 send "2305 29 165\n" simple_expect ":18 14 165 $any_time 8 0 8 0 3 { 0 8 6 19 9 $any_time } 0 \\\*" simple_expect "=2305" # Creating text 166 by 8 send "2306 86 [holl "text 166"] 0 { } 0 { }\n" simple_expect "=2306 166" talk_to client 0 send "2307 90 166\n" simple_expect "%2307 14 166" talk_to client 1 send "2308 90 166\n" simple_expect "%2308 14 166" talk_to client 2 send "2309 90 166\n" simple_expect "=2309 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2310 90 166\n" simple_expect "%2310 14 166" talk_to client 2 # Adding recipient to text 166; adder 8 send "2311 30 166 9 0\n" talk_to client 3 simple_expect ":3 16 166 9 0" talk_to client 2 simple_expect "=2311" talk_to client 0 send "2312 90 166\n" simple_expect "%2312 14 166" talk_to client 1 send "2313 90 166\n" simple_expect "%2313 14 166" talk_to client 2 send "2314 90 166\n" simple_expect "=2314 $any_time 8 0 8 0 3 { 0 9 6 19 9 $any_time } 0 \\\*" talk_to client 3 send "2315 90 166\n" simple_expect "=2315 $any_time 8 0 8 0 3 { 0 9 6 19 9 $any_time } 0 \\\*" talk_to client 2 # Deleting text 166; deleter 8 send "2316 29 166\n" talk_to client 3 simple_expect ":18 14 166 $any_time 8 0 8 0 3 { 0 9 6 19 9 $any_time } 0 \\\*" talk_to client 2 simple_expect "=2316" # Creating text 167 by 8 send "2317 86 [holl "text 167"] 0 { } 0 { }\n" simple_expect "=2317 167" talk_to client 0 send "2318 90 167\n" simple_expect "%2318 14 167" talk_to client 1 send "2319 90 167\n" simple_expect "%2319 14 167" talk_to client 2 send "2320 90 167\n" simple_expect "=2320 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2321 90 167\n" simple_expect "%2321 14 167" talk_to client 2 # Adding recipient to text 167; adder 8 send "2322 30 167 10 0\n" talk_to client 1 simple_expect ":3 16 167 10 0" talk_to client 2 simple_expect ":3 16 167 10 0" simple_expect "=2322" talk_to client 0 send "2323 90 167\n" simple_expect "=2323 $any_time 8 0 8 0 3 { 0 10 6 19 9 $any_time } 0 \\\*" talk_to client 1 send "2324 90 167\n" simple_expect "=2324 $any_time 8 0 8 0 3 { 0 10 6 19 9 $any_time } 0 \\\*" talk_to client 2 send "2325 90 167\n" simple_expect "=2325 $any_time 8 0 8 0 3 { 0 10 6 19 9 $any_time } 0 \\\*" talk_to client 3 send "2326 90 167\n" simple_expect "=2326 $any_time 8 0 8 0 3 { 0 10 6 19 9 $any_time } 0 \\\*" talk_to client 2 # Deleting text 167; deleter 8 send "2327 29 167\n" talk_to client 1 simple_expect ":18 14 167 $any_time 8 0 8 0 3 { 0 10 6 19 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 167 $any_time 8 0 8 0 3 { 0 10 6 19 9 $any_time } 0 \\\*" simple_expect "=2327" # Creating text 168 by 8 send "2328 86 [holl "text 168"] 0 { } 0 { }\n" simple_expect "=2328 168" talk_to client 0 send "2329 90 168\n" simple_expect "%2329 14 168" talk_to client 1 send "2330 90 168\n" simple_expect "%2330 14 168" talk_to client 2 send "2331 90 168\n" simple_expect "=2331 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2332 90 168\n" simple_expect "%2332 14 168" talk_to client 2 # Adding recipient to text 168; adder 8 send "2333 30 168 11 0\n" talk_to client 1 simple_expect ":3 16 168 11 0" talk_to client 2 simple_expect ":3 16 168 11 0" simple_expect "=2333" talk_to client 0 send "2334 90 168\n" simple_expect "%2334 14 168" talk_to client 1 send "2335 90 168\n" simple_expect "=2335 $any_time 8 0 8 0 3 { 0 11 6 19 9 $any_time } 0 \\\*" talk_to client 2 send "2336 90 168\n" simple_expect "=2336 $any_time 8 0 8 0 3 { 0 11 6 19 9 $any_time } 0 \\\*" talk_to client 3 send "2337 90 168\n" simple_expect "%2337 14 168" talk_to client 2 # Deleting text 168; deleter 8 send "2338 29 168\n" talk_to client 1 simple_expect ":18 14 168 $any_time 8 0 8 0 3 { 0 11 6 19 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 168 $any_time 8 0 8 0 3 { 0 11 6 19 9 $any_time } 0 \\\*" simple_expect "=2338" # Creating text 169 by 8 send "2339 86 [holl "text 169"] 0 { } 0 { }\n" simple_expect "=2339 169" talk_to client 0 send "2340 90 169\n" simple_expect "%2340 14 169" talk_to client 1 send "2341 90 169\n" simple_expect "%2341 14 169" talk_to client 2 send "2342 90 169\n" simple_expect "=2342 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2343 90 169\n" simple_expect "%2343 14 169" talk_to client 2 # Adding recipient to text 169; adder 8 send "2344 30 169 12 0\n" talk_to client 1 simple_expect ":3 16 169 12 0" talk_to client 2 simple_expect ":3 16 169 12 0" simple_expect "=2344" talk_to client 0 send "2345 90 169\n" simple_expect "%2345 14 169" talk_to client 1 send "2346 90 169\n" simple_expect "=2346 $any_time 8 0 8 0 3 { 0 12 6 10 9 $any_time } 0 \\\*" talk_to client 2 send "2347 90 169\n" simple_expect "=2347 $any_time 8 0 8 0 3 { 0 12 6 10 9 $any_time } 0 \\\*" talk_to client 3 send "2348 90 169\n" simple_expect "%2348 14 169" talk_to client 2 # Deleting text 169; deleter 8 send "2349 29 169\n" talk_to client 1 simple_expect ":18 14 169 $any_time 8 0 8 0 3 { 0 12 6 10 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 169 $any_time 8 0 8 0 3 { 0 12 6 10 9 $any_time } 0 \\\*" simple_expect "=2349" # Creating text 170 by 8 send "2350 86 [holl "text 170"] 0 { } 0 { }\n" simple_expect "=2350 170" talk_to client 0 send "2351 90 170\n" simple_expect "%2351 14 170" talk_to client 1 send "2352 90 170\n" simple_expect "%2352 14 170" talk_to client 2 send "2353 90 170\n" simple_expect "=2353 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2354 90 170\n" simple_expect "%2354 14 170" talk_to client 2 # Adding recipient to text 170; adder 8 send "2355 30 170 13 0\n" talk_to client 1 simple_expect ":3 16 170 13 0" talk_to client 2 simple_expect ":3 16 170 13 0" simple_expect "=2355" talk_to client 0 send "2356 90 170\n" simple_expect "=2356 $any_time 8 0 8 0 3 { 0 13 6 19 9 $any_time } 0 \\\*" talk_to client 1 send "2357 90 170\n" simple_expect "=2357 $any_time 8 0 8 0 3 { 0 13 6 19 9 $any_time } 0 \\\*" talk_to client 2 send "2358 90 170\n" simple_expect "=2358 $any_time 8 0 8 0 3 { 0 13 6 19 9 $any_time } 0 \\\*" talk_to client 3 send "2359 90 170\n" simple_expect "=2359 $any_time 8 0 8 0 3 { 0 13 6 19 9 $any_time } 0 \\\*" talk_to client 2 # Deleting text 170; deleter 8 send "2360 29 170\n" talk_to client 1 simple_expect ":18 14 170 $any_time 8 0 8 0 3 { 0 13 6 19 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 170 $any_time 8 0 8 0 3 { 0 13 6 19 9 $any_time } 0 \\\*" simple_expect "=2360" # Creating text 171 by 8 send "2361 86 [holl "text 171"] 0 { } 0 { }\n" simple_expect "=2361 171" talk_to client 0 send "2362 90 171\n" simple_expect "%2362 14 171" talk_to client 1 send "2363 90 171\n" simple_expect "%2363 14 171" talk_to client 2 send "2364 90 171\n" simple_expect "=2364 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2365 90 171\n" simple_expect "%2365 14 171" talk_to client 2 # Adding recipient to text 171; adder 8 send "2366 30 171 14 0\n" talk_to client 1 simple_expect ":3 16 171 14 0" talk_to client 2 simple_expect ":3 16 171 14 0" simple_expect "=2366" talk_to client 0 send "2367 90 171\n" simple_expect "%2367 14 171" talk_to client 1 send "2368 90 171\n" simple_expect "=2368 $any_time 8 0 8 0 3 { 0 14 6 19 9 $any_time } 0 \\\*" talk_to client 2 send "2369 90 171\n" simple_expect "=2369 $any_time 8 0 8 0 3 { 0 14 6 19 9 $any_time } 0 \\\*" talk_to client 3 send "2370 90 171\n" simple_expect "=2370 $any_time 8 0 8 0 3 { 0 14 6 19 9 $any_time } 0 \\\*" talk_to client 2 # Deleting text 171; deleter 8 send "2371 29 171\n" talk_to client 1 simple_expect ":18 14 171 $any_time 8 0 8 0 3 { 0 14 6 19 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 171 $any_time 8 0 8 0 3 { 0 14 6 19 9 $any_time } 0 \\\*" simple_expect "=2371" # Creating text 172 by 8 send "2372 86 [holl "text 172"] 0 { } 0 { }\n" simple_expect "=2372 172" talk_to client 0 send "2373 90 172\n" simple_expect "%2373 14 172" talk_to client 1 send "2374 90 172\n" simple_expect "%2374 14 172" talk_to client 2 send "2375 90 172\n" simple_expect "=2375 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2376 90 172\n" simple_expect "%2376 14 172" talk_to client 2 # Adding recipient to text 172; adder 8 send "2377 30 172 15 0\n" talk_to client 1 simple_expect ":3 16 172 15 0" talk_to client 2 simple_expect ":3 16 172 15 0" simple_expect "=2377" talk_to client 0 send "2378 90 172\n" simple_expect "%2378 14 172" talk_to client 1 send "2379 90 172\n" simple_expect "=2379 $any_time 8 0 8 0 3 { 0 15 6 10 9 $any_time } 0 \\\*" talk_to client 2 send "2380 90 172\n" simple_expect "=2380 $any_time 8 0 8 0 3 { 0 15 6 10 9 $any_time } 0 \\\*" talk_to client 3 send "2381 90 172\n" simple_expect "=2381 $any_time 8 0 8 0 3 { 0 15 6 10 9 $any_time } 0 \\\*" talk_to client 2 # Deleting text 172; deleter 8 send "2382 29 172\n" talk_to client 1 simple_expect ":18 14 172 $any_time 8 0 8 0 3 { 0 15 6 10 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 172 $any_time 8 0 8 0 3 { 0 15 6 10 9 $any_time } 0 \\\*" simple_expect "=2382" # Creating text 173 by 8 send "2383 86 [holl "text 173"] 0 { } 0 { }\n" simple_expect "=2383 173" talk_to client 0 send "2384 90 173\n" simple_expect "%2384 14 173" talk_to client 1 send "2385 90 173\n" simple_expect "%2385 14 173" talk_to client 2 send "2386 90 173\n" simple_expect "=2386 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2387 90 173\n" simple_expect "%2387 14 173" talk_to client 2 # Adding recipient to text 173; adder 8 send "2388 30 173 6 1\n" talk_to client 0 simple_expect ":3 16 173 6 1" talk_to client 2 simple_expect "=2388" talk_to client 0 send "2389 90 173\n" simple_expect "=2389 $any_time 8 0 8 0 3 { 1 6 6 20 9 $any_time } 0 \\\*" talk_to client 1 send "2390 90 173\n" simple_expect "%2390 14 173" talk_to client 2 send "2391 90 173\n" simple_expect "=2391 $any_time 8 0 8 0 3 { 1 6 6 20 9 $any_time } 0 \\\*" talk_to client 3 send "2392 90 173\n" simple_expect "%2392 14 173" talk_to client 2 # Deleting text 173; deleter 8 send "2393 29 173\n" talk_to client 0 simple_expect ":18 14 173 $any_time 8 0 8 0 3 { 1 6 6 20 9 $any_time } 0 \\\*" talk_to client 2 simple_expect "=2393" # Creating text 174 by 8 send "2394 86 [holl "text 174"] 0 { } 0 { }\n" simple_expect "=2394 174" talk_to client 0 send "2395 90 174\n" simple_expect "%2395 14 174" talk_to client 1 send "2396 90 174\n" simple_expect "%2396 14 174" talk_to client 2 send "2397 90 174\n" simple_expect "=2397 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2398 90 174\n" simple_expect "%2398 14 174" talk_to client 2 # Adding recipient to text 174; adder 8 send "2399 30 174 7 1\n" simple_expect "=2399" talk_to client 0 send "2400 90 174\n" simple_expect "%2400 14 174" talk_to client 1 send "2401 90 174\n" simple_expect "=2401 $any_time 8 0 8 0 3 { 1 7 6 20 9 $any_time } 0 \\\*" talk_to client 2 send "2402 90 174\n" simple_expect "=2402 $any_time 8 0 8 0 3 { 1 7 6 20 9 $any_time } 0 \\\*" talk_to client 3 send "2403 90 174\n" simple_expect "%2403 14 174" talk_to client 2 # Deleting text 174; deleter 8 send "2404 29 174\n" simple_expect "=2404" # Creating text 175 by 8 send "2405 86 [holl "text 175"] 0 { } 0 { }\n" simple_expect "=2405 175" talk_to client 0 send "2406 90 175\n" simple_expect "%2406 14 175" talk_to client 1 send "2407 90 175\n" simple_expect "%2407 14 175" talk_to client 2 send "2408 90 175\n" simple_expect "=2408 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2409 90 175\n" simple_expect "%2409 14 175" talk_to client 2 # Adding recipient to text 175; adder 8 send "2410 30 175 8 1\n" simple_expect ":3 16 175 8 1" simple_expect "=2410" talk_to client 0 send "2411 90 175\n" simple_expect "%2411 14 175" talk_to client 1 send "2412 90 175\n" simple_expect "%2412 14 175" talk_to client 2 send "2413 90 175\n" simple_expect "=2413 $any_time 8 0 8 0 3 { 1 8 6 20 9 $any_time } 0 \\\*" talk_to client 3 send "2414 90 175\n" simple_expect "%2414 14 175" talk_to client 2 # Deleting text 175; deleter 8 send "2415 29 175\n" simple_expect ":18 14 175 $any_time 8 0 8 0 3 { 1 8 6 20 9 $any_time } 0 \\\*" simple_expect "=2415" # Creating text 176 by 8 send "2416 86 [holl "text 176"] 0 { } 0 { }\n" simple_expect "=2416 176" talk_to client 0 send "2417 90 176\n" simple_expect "%2417 14 176" talk_to client 1 send "2418 90 176\n" simple_expect "%2418 14 176" talk_to client 2 send "2419 90 176\n" simple_expect "=2419 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2420 90 176\n" simple_expect "%2420 14 176" talk_to client 2 # Adding recipient to text 176; adder 8 send "2421 30 176 9 1\n" talk_to client 3 simple_expect ":3 16 176 9 1" talk_to client 2 simple_expect "=2421" talk_to client 0 send "2422 90 176\n" simple_expect "%2422 14 176" talk_to client 1 send "2423 90 176\n" simple_expect "%2423 14 176" talk_to client 2 send "2424 90 176\n" simple_expect "=2424 $any_time 8 0 8 0 3 { 1 9 6 20 9 $any_time } 0 \\\*" talk_to client 3 send "2425 90 176\n" simple_expect "=2425 $any_time 8 0 8 0 3 { 1 9 6 20 9 $any_time } 0 \\\*" talk_to client 2 # Deleting text 176; deleter 8 send "2426 29 176\n" talk_to client 3 simple_expect ":18 14 176 $any_time 8 0 8 0 3 { 1 9 6 20 9 $any_time } 0 \\\*" talk_to client 2 simple_expect "=2426" # Creating text 177 by 8 send "2427 86 [holl "text 177"] 0 { } 0 { }\n" simple_expect "=2427 177" talk_to client 0 send "2428 90 177\n" simple_expect "%2428 14 177" talk_to client 1 send "2429 90 177\n" simple_expect "%2429 14 177" talk_to client 2 send "2430 90 177\n" simple_expect "=2430 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2431 90 177\n" simple_expect "%2431 14 177" talk_to client 2 # Adding recipient to text 177; adder 8 send "2432 30 177 10 1\n" talk_to client 1 simple_expect ":3 16 177 10 1" talk_to client 2 simple_expect ":3 16 177 10 1" simple_expect "=2432" talk_to client 0 send "2433 90 177\n" simple_expect "=2433 $any_time 8 0 8 0 3 { 1 10 6 20 9 $any_time } 0 \\\*" talk_to client 1 send "2434 90 177\n" simple_expect "=2434 $any_time 8 0 8 0 3 { 1 10 6 20 9 $any_time } 0 \\\*" talk_to client 2 send "2435 90 177\n" simple_expect "=2435 $any_time 8 0 8 0 3 { 1 10 6 20 9 $any_time } 0 \\\*" talk_to client 3 send "2436 90 177\n" simple_expect "=2436 $any_time 8 0 8 0 3 { 1 10 6 20 9 $any_time } 0 \\\*" talk_to client 2 # Deleting text 177; deleter 8 send "2437 29 177\n" talk_to client 1 simple_expect ":18 14 177 $any_time 8 0 8 0 3 { 1 10 6 20 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 177 $any_time 8 0 8 0 3 { 1 10 6 20 9 $any_time } 0 \\\*" simple_expect "=2437" # Creating text 178 by 8 send "2438 86 [holl "text 178"] 0 { } 0 { }\n" simple_expect "=2438 178" talk_to client 0 send "2439 90 178\n" simple_expect "%2439 14 178" talk_to client 1 send "2440 90 178\n" simple_expect "%2440 14 178" talk_to client 2 send "2441 90 178\n" simple_expect "=2441 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2442 90 178\n" simple_expect "%2442 14 178" talk_to client 2 # Adding recipient to text 178; adder 8 send "2443 30 178 11 1\n" talk_to client 1 simple_expect ":3 16 178 11 1" talk_to client 2 simple_expect ":3 16 178 11 1" simple_expect "=2443" talk_to client 0 send "2444 90 178\n" simple_expect "%2444 14 178" talk_to client 1 send "2445 90 178\n" simple_expect "=2445 $any_time 8 0 8 0 3 { 1 11 6 20 9 $any_time } 0 \\\*" talk_to client 2 send "2446 90 178\n" simple_expect "=2446 $any_time 8 0 8 0 3 { 1 11 6 20 9 $any_time } 0 \\\*" talk_to client 3 send "2447 90 178\n" simple_expect "%2447 14 178" talk_to client 2 # Deleting text 178; deleter 8 send "2448 29 178\n" talk_to client 1 simple_expect ":18 14 178 $any_time 8 0 8 0 3 { 1 11 6 20 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 178 $any_time 8 0 8 0 3 { 1 11 6 20 9 $any_time } 0 \\\*" simple_expect "=2448" # Creating text 179 by 8 send "2449 86 [holl "text 179"] 0 { } 0 { }\n" simple_expect "=2449 179" talk_to client 0 send "2450 90 179\n" simple_expect "%2450 14 179" talk_to client 1 send "2451 90 179\n" simple_expect "%2451 14 179" talk_to client 2 send "2452 90 179\n" simple_expect "=2452 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2453 90 179\n" simple_expect "%2453 14 179" talk_to client 2 # Adding recipient to text 179; adder 8 send "2454 30 179 12 1\n" talk_to client 1 simple_expect ":3 16 179 12 1" talk_to client 2 simple_expect ":3 16 179 12 1" simple_expect "=2454" talk_to client 0 send "2455 90 179\n" simple_expect "%2455 14 179" talk_to client 1 send "2456 90 179\n" simple_expect "=2456 $any_time 8 0 8 0 3 { 1 12 6 11 9 $any_time } 0 \\\*" talk_to client 2 send "2457 90 179\n" simple_expect "=2457 $any_time 8 0 8 0 3 { 1 12 6 11 9 $any_time } 0 \\\*" talk_to client 3 send "2458 90 179\n" simple_expect "%2458 14 179" talk_to client 2 # Deleting text 179; deleter 8 send "2459 29 179\n" talk_to client 1 simple_expect ":18 14 179 $any_time 8 0 8 0 3 { 1 12 6 11 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 179 $any_time 8 0 8 0 3 { 1 12 6 11 9 $any_time } 0 \\\*" simple_expect "=2459" # Creating text 180 by 8 send "2460 86 [holl "text 180"] 0 { } 0 { }\n" simple_expect "=2460 180" talk_to client 0 send "2461 90 180\n" simple_expect "%2461 14 180" talk_to client 1 send "2462 90 180\n" simple_expect "%2462 14 180" talk_to client 2 send "2463 90 180\n" simple_expect "=2463 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2464 90 180\n" simple_expect "%2464 14 180" talk_to client 2 # Adding recipient to text 180; adder 8 send "2465 30 180 13 1\n" talk_to client 1 simple_expect ":3 16 180 13 1" talk_to client 2 simple_expect ":3 16 180 13 1" simple_expect "=2465" talk_to client 0 send "2466 90 180\n" simple_expect "=2466 $any_time 8 0 8 0 3 { 1 13 6 20 9 $any_time } 0 \\\*" talk_to client 1 send "2467 90 180\n" simple_expect "=2467 $any_time 8 0 8 0 3 { 1 13 6 20 9 $any_time } 0 \\\*" talk_to client 2 send "2468 90 180\n" simple_expect "=2468 $any_time 8 0 8 0 3 { 1 13 6 20 9 $any_time } 0 \\\*" talk_to client 3 send "2469 90 180\n" simple_expect "=2469 $any_time 8 0 8 0 3 { 1 13 6 20 9 $any_time } 0 \\\*" talk_to client 2 # Deleting text 180; deleter 8 send "2470 29 180\n" talk_to client 1 simple_expect ":18 14 180 $any_time 8 0 8 0 3 { 1 13 6 20 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 180 $any_time 8 0 8 0 3 { 1 13 6 20 9 $any_time } 0 \\\*" simple_expect "=2470" # Creating text 181 by 8 send "2471 86 [holl "text 181"] 0 { } 0 { }\n" simple_expect "=2471 181" talk_to client 0 send "2472 90 181\n" simple_expect "%2472 14 181" talk_to client 1 send "2473 90 181\n" simple_expect "%2473 14 181" talk_to client 2 send "2474 90 181\n" simple_expect "=2474 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2475 90 181\n" simple_expect "%2475 14 181" talk_to client 2 # Adding recipient to text 181; adder 8 send "2476 30 181 14 1\n" talk_to client 1 simple_expect ":3 16 181 14 1" talk_to client 2 simple_expect ":3 16 181 14 1" simple_expect "=2476" talk_to client 0 send "2477 90 181\n" simple_expect "%2477 14 181" talk_to client 1 send "2478 90 181\n" simple_expect "=2478 $any_time 8 0 8 0 3 { 1 14 6 20 9 $any_time } 0 \\\*" talk_to client 2 send "2479 90 181\n" simple_expect "=2479 $any_time 8 0 8 0 3 { 1 14 6 20 9 $any_time } 0 \\\*" talk_to client 3 send "2480 90 181\n" simple_expect "=2480 $any_time 8 0 8 0 3 { 1 14 6 20 9 $any_time } 0 \\\*" talk_to client 2 # Deleting text 181; deleter 8 send "2481 29 181\n" talk_to client 1 simple_expect ":18 14 181 $any_time 8 0 8 0 3 { 1 14 6 20 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 181 $any_time 8 0 8 0 3 { 1 14 6 20 9 $any_time } 0 \\\*" simple_expect "=2481" # Creating text 182 by 8 send "2482 86 [holl "text 182"] 0 { } 0 { }\n" simple_expect "=2482 182" talk_to client 0 send "2483 90 182\n" simple_expect "%2483 14 182" talk_to client 1 send "2484 90 182\n" simple_expect "%2484 14 182" talk_to client 2 send "2485 90 182\n" simple_expect "=2485 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2486 90 182\n" simple_expect "%2486 14 182" talk_to client 2 # Adding recipient to text 182; adder 8 send "2487 30 182 15 1\n" talk_to client 1 simple_expect ":3 16 182 15 1" talk_to client 2 simple_expect ":3 16 182 15 1" simple_expect "=2487" talk_to client 0 send "2488 90 182\n" simple_expect "%2488 14 182" talk_to client 1 send "2489 90 182\n" simple_expect "=2489 $any_time 8 0 8 0 3 { 1 15 6 11 9 $any_time } 0 \\\*" talk_to client 2 send "2490 90 182\n" simple_expect "=2490 $any_time 8 0 8 0 3 { 1 15 6 11 9 $any_time } 0 \\\*" talk_to client 3 send "2491 90 182\n" simple_expect "=2491 $any_time 8 0 8 0 3 { 1 15 6 11 9 $any_time } 0 \\\*" talk_to client 2 # Deleting text 182; deleter 8 send "2492 29 182\n" talk_to client 1 simple_expect ":18 14 182 $any_time 8 0 8 0 3 { 1 15 6 11 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 182 $any_time 8 0 8 0 3 { 1 15 6 11 9 $any_time } 0 \\\*" simple_expect "=2492" # Creating text 183 by 8 send "2493 86 [holl "text 183"] 0 { } 0 { }\n" simple_expect "=2493 183" talk_to client 0 send "2494 90 183\n" simple_expect "%2494 14 183" talk_to client 1 send "2495 90 183\n" simple_expect "%2495 14 183" talk_to client 2 send "2496 90 183\n" simple_expect "=2496 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2497 90 183\n" simple_expect "%2497 14 183" talk_to client 2 # Adding recipient to text 183; adder 8 send "2498 30 183 6 15\n" talk_to client 0 simple_expect ":3 16 183 6 15" talk_to client 2 simple_expect "=2498" talk_to client 0 send "2499 90 183\n" simple_expect "=2499 $any_time 8 0 8 0 3 { 15 6 6 21 9 $any_time } 0 \\\*" talk_to client 1 send "2500 90 183\n" simple_expect "%2500 14 183" talk_to client 2 send "2501 90 183\n" simple_expect "=2501 $any_time 8 0 8 0 3 { 15 6 6 21 9 $any_time } 0 \\\*" talk_to client 3 send "2502 90 183\n" simple_expect "%2502 14 183" talk_to client 2 # Deleting text 183; deleter 8 send "2503 29 183\n" talk_to client 0 simple_expect ":18 14 183 $any_time 8 0 8 0 3 { 15 6 6 21 9 $any_time } 0 \\\*" talk_to client 2 simple_expect "=2503" # Creating text 184 by 8 send "2504 86 [holl "text 184"] 0 { } 0 { }\n" simple_expect "=2504 184" talk_to client 0 send "2505 90 184\n" simple_expect "%2505 14 184" talk_to client 1 send "2506 90 184\n" simple_expect "%2506 14 184" talk_to client 2 send "2507 90 184\n" simple_expect "=2507 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2508 90 184\n" simple_expect "%2508 14 184" talk_to client 2 # Adding recipient to text 184; adder 8 send "2509 30 184 7 15\n" simple_expect "=2509" talk_to client 0 send "2510 90 184\n" simple_expect "%2510 14 184" talk_to client 1 send "2511 90 184\n" simple_expect "=2511 $any_time 8 0 8 0 3 { 15 7 6 21 9 $any_time } 0 \\\*" talk_to client 2 send "2512 90 184\n" simple_expect "=2512 $any_time 8 0 8 0 3 { 15 7 6 21 9 $any_time } 0 \\\*" talk_to client 3 send "2513 90 184\n" simple_expect "%2513 14 184" talk_to client 2 # Deleting text 184; deleter 8 send "2514 29 184\n" simple_expect "=2514" # Creating text 185 by 8 send "2515 86 [holl "text 185"] 0 { } 0 { }\n" simple_expect "=2515 185" talk_to client 0 send "2516 90 185\n" simple_expect "%2516 14 185" talk_to client 1 send "2517 90 185\n" simple_expect "%2517 14 185" talk_to client 2 send "2518 90 185\n" simple_expect "=2518 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2519 90 185\n" simple_expect "%2519 14 185" talk_to client 2 # Adding recipient to text 185; adder 8 send "2520 30 185 8 15\n" simple_expect ":3 16 185 8 15" simple_expect "=2520" talk_to client 0 send "2521 90 185\n" simple_expect "%2521 14 185" talk_to client 1 send "2522 90 185\n" simple_expect "%2522 14 185" talk_to client 2 send "2523 90 185\n" simple_expect "=2523 $any_time 8 0 8 0 3 { 15 8 6 21 9 $any_time } 0 \\\*" talk_to client 3 send "2524 90 185\n" simple_expect "%2524 14 185" talk_to client 2 # Deleting text 185; deleter 8 send "2525 29 185\n" simple_expect ":18 14 185 $any_time 8 0 8 0 3 { 15 8 6 21 9 $any_time } 0 \\\*" simple_expect "=2525" # Creating text 186 by 8 send "2526 86 [holl "text 186"] 0 { } 0 { }\n" simple_expect "=2526 186" talk_to client 0 send "2527 90 186\n" simple_expect "%2527 14 186" talk_to client 1 send "2528 90 186\n" simple_expect "%2528 14 186" talk_to client 2 send "2529 90 186\n" simple_expect "=2529 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2530 90 186\n" simple_expect "%2530 14 186" talk_to client 2 # Adding recipient to text 186; adder 8 send "2531 30 186 9 15\n" talk_to client 3 simple_expect ":3 16 186 9 15" talk_to client 2 simple_expect "=2531" talk_to client 0 send "2532 90 186\n" simple_expect "%2532 14 186" talk_to client 1 send "2533 90 186\n" simple_expect "%2533 14 186" talk_to client 2 send "2534 90 186\n" simple_expect "=2534 $any_time 8 0 8 0 3 { 15 9 6 21 9 $any_time } 0 \\\*" talk_to client 3 send "2535 90 186\n" simple_expect "=2535 $any_time 8 0 8 0 3 { 15 9 6 21 9 $any_time } 0 \\\*" talk_to client 2 # Deleting text 186; deleter 8 send "2536 29 186\n" talk_to client 3 simple_expect ":18 14 186 $any_time 8 0 8 0 3 { 15 9 6 21 9 $any_time } 0 \\\*" talk_to client 2 simple_expect "=2536" # Creating text 187 by 8 send "2537 86 [holl "text 187"] 0 { } 0 { }\n" simple_expect "=2537 187" talk_to client 0 send "2538 90 187\n" simple_expect "%2538 14 187" talk_to client 1 send "2539 90 187\n" simple_expect "%2539 14 187" talk_to client 2 send "2540 90 187\n" simple_expect "=2540 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2541 90 187\n" simple_expect "%2541 14 187" talk_to client 2 # Adding recipient to text 187; adder 8 send "2542 30 187 10 15\n" talk_to client 1 simple_expect ":3 16 187 10 15" talk_to client 2 simple_expect ":3 16 187 10 15" simple_expect "=2542" talk_to client 0 send "2543 90 187\n" simple_expect "=2543 $any_time 8 0 8 0 3 { 15 10 6 21 9 $any_time } 0 \\\*" talk_to client 1 send "2544 90 187\n" simple_expect "=2544 $any_time 8 0 8 0 3 { 15 10 6 21 9 $any_time } 0 \\\*" talk_to client 2 send "2545 90 187\n" simple_expect "=2545 $any_time 8 0 8 0 3 { 15 10 6 21 9 $any_time } 0 \\\*" talk_to client 3 send "2546 90 187\n" simple_expect "=2546 $any_time 8 0 8 0 3 { 15 10 6 21 9 $any_time } 0 \\\*" talk_to client 2 # Deleting text 187; deleter 8 send "2547 29 187\n" talk_to client 1 simple_expect ":18 14 187 $any_time 8 0 8 0 3 { 15 10 6 21 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 187 $any_time 8 0 8 0 3 { 15 10 6 21 9 $any_time } 0 \\\*" simple_expect "=2547" # Creating text 188 by 8 send "2548 86 [holl "text 188"] 0 { } 0 { }\n" simple_expect "=2548 188" talk_to client 0 send "2549 90 188\n" simple_expect "%2549 14 188" talk_to client 1 send "2550 90 188\n" simple_expect "%2550 14 188" talk_to client 2 send "2551 90 188\n" simple_expect "=2551 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2552 90 188\n" simple_expect "%2552 14 188" talk_to client 2 # Adding recipient to text 188; adder 8 send "2553 30 188 11 15\n" talk_to client 1 simple_expect ":3 16 188 11 15" talk_to client 2 simple_expect ":3 16 188 11 15" simple_expect "=2553" talk_to client 0 send "2554 90 188\n" simple_expect "%2554 14 188" talk_to client 1 send "2555 90 188\n" simple_expect "=2555 $any_time 8 0 8 0 3 { 15 11 6 21 9 $any_time } 0 \\\*" talk_to client 2 send "2556 90 188\n" simple_expect "=2556 $any_time 8 0 8 0 3 { 15 11 6 21 9 $any_time } 0 \\\*" talk_to client 3 send "2557 90 188\n" simple_expect "%2557 14 188" talk_to client 2 # Deleting text 188; deleter 8 send "2558 29 188\n" talk_to client 1 simple_expect ":18 14 188 $any_time 8 0 8 0 3 { 15 11 6 21 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 188 $any_time 8 0 8 0 3 { 15 11 6 21 9 $any_time } 0 \\\*" simple_expect "=2558" # Creating text 189 by 8 send "2559 86 [holl "text 189"] 0 { } 0 { }\n" simple_expect "=2559 189" talk_to client 0 send "2560 90 189\n" simple_expect "%2560 14 189" talk_to client 1 send "2561 90 189\n" simple_expect "%2561 14 189" talk_to client 2 send "2562 90 189\n" simple_expect "=2562 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2563 90 189\n" simple_expect "%2563 14 189" talk_to client 2 # Adding recipient to text 189; adder 8 send "2564 30 189 12 15\n" talk_to client 1 simple_expect ":3 16 189 12 15" talk_to client 2 simple_expect ":3 16 189 12 15" simple_expect "=2564" talk_to client 0 send "2565 90 189\n" simple_expect "%2565 14 189" talk_to client 1 send "2566 90 189\n" simple_expect "=2566 $any_time 8 0 8 0 3 { 15 12 6 12 9 $any_time } 0 \\\*" talk_to client 2 send "2567 90 189\n" simple_expect "=2567 $any_time 8 0 8 0 3 { 15 12 6 12 9 $any_time } 0 \\\*" talk_to client 3 send "2568 90 189\n" simple_expect "%2568 14 189" talk_to client 2 # Deleting text 189; deleter 8 send "2569 29 189\n" talk_to client 1 simple_expect ":18 14 189 $any_time 8 0 8 0 3 { 15 12 6 12 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 189 $any_time 8 0 8 0 3 { 15 12 6 12 9 $any_time } 0 \\\*" simple_expect "=2569" # Creating text 190 by 8 send "2570 86 [holl "text 190"] 0 { } 0 { }\n" simple_expect "=2570 190" talk_to client 0 send "2571 90 190\n" simple_expect "%2571 14 190" talk_to client 1 send "2572 90 190\n" simple_expect "%2572 14 190" talk_to client 2 send "2573 90 190\n" simple_expect "=2573 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2574 90 190\n" simple_expect "%2574 14 190" talk_to client 2 # Adding recipient to text 190; adder 8 send "2575 30 190 13 15\n" talk_to client 1 simple_expect ":3 16 190 13 15" talk_to client 2 simple_expect ":3 16 190 13 15" simple_expect "=2575" talk_to client 0 send "2576 90 190\n" simple_expect "=2576 $any_time 8 0 8 0 3 { 15 13 6 21 9 $any_time } 0 \\\*" talk_to client 1 send "2577 90 190\n" simple_expect "=2577 $any_time 8 0 8 0 3 { 15 13 6 21 9 $any_time } 0 \\\*" talk_to client 2 send "2578 90 190\n" simple_expect "=2578 $any_time 8 0 8 0 3 { 15 13 6 21 9 $any_time } 0 \\\*" talk_to client 3 send "2579 90 190\n" simple_expect "=2579 $any_time 8 0 8 0 3 { 15 13 6 21 9 $any_time } 0 \\\*" talk_to client 2 # Deleting text 190; deleter 8 send "2580 29 190\n" talk_to client 1 simple_expect ":18 14 190 $any_time 8 0 8 0 3 { 15 13 6 21 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 190 $any_time 8 0 8 0 3 { 15 13 6 21 9 $any_time } 0 \\\*" simple_expect "=2580" # Creating text 191 by 8 send "2581 86 [holl "text 191"] 0 { } 0 { }\n" simple_expect "=2581 191" talk_to client 0 send "2582 90 191\n" simple_expect "%2582 14 191" talk_to client 1 send "2583 90 191\n" simple_expect "%2583 14 191" talk_to client 2 send "2584 90 191\n" simple_expect "=2584 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2585 90 191\n" simple_expect "%2585 14 191" talk_to client 2 # Adding recipient to text 191; adder 8 send "2586 30 191 14 15\n" talk_to client 1 simple_expect ":3 16 191 14 15" talk_to client 2 simple_expect ":3 16 191 14 15" simple_expect "=2586" talk_to client 0 send "2587 90 191\n" simple_expect "%2587 14 191" talk_to client 1 send "2588 90 191\n" simple_expect "=2588 $any_time 8 0 8 0 3 { 15 14 6 21 9 $any_time } 0 \\\*" talk_to client 2 send "2589 90 191\n" simple_expect "=2589 $any_time 8 0 8 0 3 { 15 14 6 21 9 $any_time } 0 \\\*" talk_to client 3 send "2590 90 191\n" simple_expect "=2590 $any_time 8 0 8 0 3 { 15 14 6 21 9 $any_time } 0 \\\*" talk_to client 2 # Deleting text 191; deleter 8 send "2591 29 191\n" talk_to client 1 simple_expect ":18 14 191 $any_time 8 0 8 0 3 { 15 14 6 21 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 191 $any_time 8 0 8 0 3 { 15 14 6 21 9 $any_time } 0 \\\*" simple_expect "=2591" # Creating text 192 by 8 send "2592 86 [holl "text 192"] 0 { } 0 { }\n" simple_expect "=2592 192" talk_to client 0 send "2593 90 192\n" simple_expect "%2593 14 192" talk_to client 1 send "2594 90 192\n" simple_expect "%2594 14 192" talk_to client 2 send "2595 90 192\n" simple_expect "=2595 $any_time 8 0 8 0 0 \\\* 0 \\\*" talk_to client 3 send "2596 90 192\n" simple_expect "%2596 14 192" talk_to client 2 # Adding recipient to text 192; adder 8 send "2597 30 192 15 15\n" talk_to client 1 simple_expect ":3 16 192 15 15" talk_to client 2 simple_expect ":3 16 192 15 15" simple_expect "=2597" talk_to client 0 send "2598 90 192\n" simple_expect "%2598 14 192" talk_to client 1 send "2599 90 192\n" simple_expect "=2599 $any_time 8 0 8 0 3 { 15 15 6 12 9 $any_time } 0 \\\*" talk_to client 2 send "2600 90 192\n" simple_expect "=2600 $any_time 8 0 8 0 3 { 15 15 6 12 9 $any_time } 0 \\\*" talk_to client 3 send "2601 90 192\n" simple_expect "=2601 $any_time 8 0 8 0 3 { 15 15 6 12 9 $any_time } 0 \\\*" talk_to client 2 # Deleting text 192; deleter 8 send "2602 29 192\n" talk_to client 1 simple_expect ":18 14 192 $any_time 8 0 8 0 3 { 15 15 6 12 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 192 $any_time 8 0 8 0 3 { 15 15 6 12 9 $any_time } 0 \\\*" simple_expect "=2602" talk_to client 3 # Creating text 193 by 9 send "2603 86 [holl "text 193"] 0 { } 0 { }\n" simple_expect "=2603 193" talk_to client 0 send "2604 90 193\n" simple_expect "%2604 14 193" talk_to client 1 send "2605 90 193\n" simple_expect "%2605 14 193" talk_to client 2 send "2606 90 193\n" simple_expect "%2606 14 193" talk_to client 3 send "2607 90 193\n" simple_expect "=2607 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 193; adder 9 send "2608 30 193 6 0\n" talk_to client 0 simple_expect ":3 16 193 6 0" talk_to client 3 simple_expect "=2608" talk_to client 0 send "2609 90 193\n" simple_expect "=2609 $any_time 9 0 8 0 3 { 0 6 6 22 9 $any_time } 0 \\\*" talk_to client 1 send "2610 90 193\n" simple_expect "%2610 14 193" talk_to client 2 send "2611 90 193\n" simple_expect "%2611 14 193" talk_to client 3 send "2612 90 193\n" simple_expect "=2612 $any_time 9 0 8 0 3 { 0 6 6 22 9 $any_time } 0 \\\*" # Deleting text 193; deleter 9 send "2613 29 193\n" talk_to client 0 simple_expect ":18 14 193 $any_time 9 0 8 0 3 { 0 6 6 22 9 $any_time } 0 \\\*" talk_to client 3 simple_expect "=2613" # Creating text 194 by 9 send "2614 86 [holl "text 194"] 0 { } 0 { }\n" simple_expect "=2614 194" talk_to client 0 send "2615 90 194\n" simple_expect "%2615 14 194" talk_to client 1 send "2616 90 194\n" simple_expect "%2616 14 194" talk_to client 2 send "2617 90 194\n" simple_expect "%2617 14 194" talk_to client 3 send "2618 90 194\n" simple_expect "=2618 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 194; adder 9 send "2619 30 194 7 0\n" simple_expect "=2619" talk_to client 0 send "2620 90 194\n" simple_expect "%2620 14 194" talk_to client 1 send "2621 90 194\n" simple_expect "=2621 $any_time 9 0 8 0 3 { 0 7 6 22 9 $any_time } 0 \\\*" talk_to client 2 send "2622 90 194\n" simple_expect "%2622 14 194" talk_to client 3 send "2623 90 194\n" simple_expect "=2623 $any_time 9 0 8 0 3 { 0 7 6 22 9 $any_time } 0 \\\*" # Deleting text 194; deleter 9 send "2624 29 194\n" simple_expect "=2624" # Creating text 195 by 9 send "2625 86 [holl "text 195"] 0 { } 0 { }\n" simple_expect "=2625 195" talk_to client 0 send "2626 90 195\n" simple_expect "%2626 14 195" talk_to client 1 send "2627 90 195\n" simple_expect "%2627 14 195" talk_to client 2 send "2628 90 195\n" simple_expect "%2628 14 195" talk_to client 3 send "2629 90 195\n" simple_expect "=2629 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 195; adder 9 send "2630 30 195 8 0\n" talk_to client 2 simple_expect ":3 16 195 8 0" talk_to client 3 simple_expect "=2630" talk_to client 0 send "2631 90 195\n" simple_expect "%2631 14 195" talk_to client 1 send "2632 90 195\n" simple_expect "%2632 14 195" talk_to client 2 send "2633 90 195\n" simple_expect "=2633 $any_time 9 0 8 0 3 { 0 8 6 22 9 $any_time } 0 \\\*" talk_to client 3 send "2634 90 195\n" simple_expect "=2634 $any_time 9 0 8 0 3 { 0 8 6 22 9 $any_time } 0 \\\*" # Deleting text 195; deleter 9 send "2635 29 195\n" talk_to client 2 simple_expect ":18 14 195 $any_time 9 0 8 0 3 { 0 8 6 22 9 $any_time } 0 \\\*" talk_to client 3 simple_expect "=2635" # Creating text 196 by 9 send "2636 86 [holl "text 196"] 0 { } 0 { }\n" simple_expect "=2636 196" talk_to client 0 send "2637 90 196\n" simple_expect "%2637 14 196" talk_to client 1 send "2638 90 196\n" simple_expect "%2638 14 196" talk_to client 2 send "2639 90 196\n" simple_expect "%2639 14 196" talk_to client 3 send "2640 90 196\n" simple_expect "=2640 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 196; adder 9 send "2641 30 196 9 0\n" simple_expect ":3 16 196 9 0" simple_expect "=2641" talk_to client 0 send "2642 90 196\n" simple_expect "%2642 14 196" talk_to client 1 send "2643 90 196\n" simple_expect "%2643 14 196" talk_to client 2 send "2644 90 196\n" simple_expect "%2644 14 196" talk_to client 3 send "2645 90 196\n" simple_expect "=2645 $any_time 9 0 8 0 3 { 0 9 6 22 9 $any_time } 0 \\\*" # Deleting text 196; deleter 9 send "2646 29 196\n" simple_expect ":18 14 196 $any_time 9 0 8 0 3 { 0 9 6 22 9 $any_time } 0 \\\*" simple_expect "=2646" # Creating text 197 by 9 send "2647 86 [holl "text 197"] 0 { } 0 { }\n" simple_expect "=2647 197" talk_to client 0 send "2648 90 197\n" simple_expect "%2648 14 197" talk_to client 1 send "2649 90 197\n" simple_expect "%2649 14 197" talk_to client 2 send "2650 90 197\n" simple_expect "%2650 14 197" talk_to client 3 send "2651 90 197\n" simple_expect "=2651 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 197; adder 9 send "2652 30 197 10 0\n" talk_to client 1 simple_expect ":3 16 197 10 0" talk_to client 2 simple_expect ":3 16 197 10 0" talk_to client 3 simple_expect "=2652" talk_to client 0 send "2653 90 197\n" simple_expect "=2653 $any_time 9 0 8 0 3 { 0 10 6 22 9 $any_time } 0 \\\*" talk_to client 1 send "2654 90 197\n" simple_expect "=2654 $any_time 9 0 8 0 3 { 0 10 6 22 9 $any_time } 0 \\\*" talk_to client 2 send "2655 90 197\n" simple_expect "=2655 $any_time 9 0 8 0 3 { 0 10 6 22 9 $any_time } 0 \\\*" talk_to client 3 send "2656 90 197\n" simple_expect "=2656 $any_time 9 0 8 0 3 { 0 10 6 22 9 $any_time } 0 \\\*" # Deleting text 197; deleter 9 send "2657 29 197\n" talk_to client 1 simple_expect ":18 14 197 $any_time 9 0 8 0 3 { 0 10 6 22 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 197 $any_time 9 0 8 0 3 { 0 10 6 22 9 $any_time } 0 \\\*" talk_to client 3 simple_expect "=2657" # Creating text 198 by 9 send "2658 86 [holl "text 198"] 0 { } 0 { }\n" simple_expect "=2658 198" talk_to client 0 send "2659 90 198\n" simple_expect "%2659 14 198" talk_to client 1 send "2660 90 198\n" simple_expect "%2660 14 198" talk_to client 2 send "2661 90 198\n" simple_expect "%2661 14 198" talk_to client 3 send "2662 90 198\n" simple_expect "=2662 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 198; adder 9 send "2663 30 198 11 0\n" talk_to client 1 simple_expect ":3 16 198 11 0" talk_to client 2 simple_expect ":3 16 198 11 0" talk_to client 3 simple_expect "=2663" talk_to client 0 send "2664 90 198\n" simple_expect "%2664 14 198" talk_to client 1 send "2665 90 198\n" simple_expect "=2665 $any_time 9 0 8 0 3 { 0 11 6 22 9 $any_time } 0 \\\*" talk_to client 2 send "2666 90 198\n" simple_expect "=2666 $any_time 9 0 8 0 3 { 0 11 6 22 9 $any_time } 0 \\\*" talk_to client 3 send "2667 90 198\n" simple_expect "=2667 $any_time 9 0 8 0 3 { 0 11 6 22 9 $any_time } 0 \\\*" # Deleting text 198; deleter 9 send "2668 29 198\n" talk_to client 1 simple_expect ":18 14 198 $any_time 9 0 8 0 3 { 0 11 6 22 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 198 $any_time 9 0 8 0 3 { 0 11 6 22 9 $any_time } 0 \\\*" talk_to client 3 simple_expect "=2668" # Creating text 199 by 9 send "2669 86 [holl "text 199"] 0 { } 0 { }\n" simple_expect "=2669 199" talk_to client 0 send "2670 90 199\n" simple_expect "%2670 14 199" talk_to client 1 send "2671 90 199\n" simple_expect "%2671 14 199" talk_to client 2 send "2672 90 199\n" simple_expect "%2672 14 199" talk_to client 3 send "2673 90 199\n" simple_expect "=2673 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 199; adder 9 send "2674 30 199 13 0\n" talk_to client 1 simple_expect ":3 16 199 13 0" talk_to client 2 simple_expect ":3 16 199 13 0" talk_to client 3 simple_expect "=2674" talk_to client 0 send "2675 90 199\n" simple_expect "=2675 $any_time 9 0 8 0 3 { 0 13 6 22 9 $any_time } 0 \\\*" talk_to client 1 send "2676 90 199\n" simple_expect "=2676 $any_time 9 0 8 0 3 { 0 13 6 22 9 $any_time } 0 \\\*" talk_to client 2 send "2677 90 199\n" simple_expect "=2677 $any_time 9 0 8 0 3 { 0 13 6 22 9 $any_time } 0 \\\*" talk_to client 3 send "2678 90 199\n" simple_expect "=2678 $any_time 9 0 8 0 3 { 0 13 6 22 9 $any_time } 0 \\\*" # Deleting text 199; deleter 9 send "2679 29 199\n" talk_to client 1 simple_expect ":18 14 199 $any_time 9 0 8 0 3 { 0 13 6 22 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 199 $any_time 9 0 8 0 3 { 0 13 6 22 9 $any_time } 0 \\\*" talk_to client 3 simple_expect "=2679" # Creating text 200 by 9 send "2680 86 [holl "text 200"] 0 { } 0 { }\n" simple_expect "=2680 200" talk_to client 0 send "2681 90 200\n" simple_expect "%2681 14 200" talk_to client 1 send "2682 90 200\n" simple_expect "%2682 14 200" talk_to client 2 send "2683 90 200\n" simple_expect "%2683 14 200" talk_to client 3 send "2684 90 200\n" simple_expect "=2684 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 200; adder 9 send "2685 30 200 14 0\n" talk_to client 1 simple_expect ":3 16 200 14 0" talk_to client 2 simple_expect ":3 16 200 14 0" talk_to client 3 simple_expect "=2685" talk_to client 0 send "2686 90 200\n" simple_expect "%2686 14 200" talk_to client 1 send "2687 90 200\n" simple_expect "=2687 $any_time 9 0 8 0 3 { 0 14 6 22 9 $any_time } 0 \\\*" talk_to client 2 send "2688 90 200\n" simple_expect "=2688 $any_time 9 0 8 0 3 { 0 14 6 22 9 $any_time } 0 \\\*" talk_to client 3 send "2689 90 200\n" simple_expect "=2689 $any_time 9 0 8 0 3 { 0 14 6 22 9 $any_time } 0 \\\*" # Deleting text 200; deleter 9 send "2690 29 200\n" talk_to client 1 simple_expect ":18 14 200 $any_time 9 0 8 0 3 { 0 14 6 22 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 200 $any_time 9 0 8 0 3 { 0 14 6 22 9 $any_time } 0 \\\*" talk_to client 3 simple_expect "=2690" # Creating text 201 by 9 send "2691 86 [holl "text 201"] 0 { } 0 { }\n" simple_expect "=2691 201" talk_to client 0 send "2692 90 201\n" simple_expect "%2692 14 201" talk_to client 1 send "2693 90 201\n" simple_expect "%2693 14 201" talk_to client 2 send "2694 90 201\n" simple_expect "%2694 14 201" talk_to client 3 send "2695 90 201\n" simple_expect "=2695 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 201; adder 9 send "2696 30 201 6 1\n" talk_to client 0 simple_expect ":3 16 201 6 1" talk_to client 3 simple_expect "=2696" talk_to client 0 send "2697 90 201\n" simple_expect "=2697 $any_time 9 0 8 0 3 { 1 6 6 23 9 $any_time } 0 \\\*" talk_to client 1 send "2698 90 201\n" simple_expect "%2698 14 201" talk_to client 2 send "2699 90 201\n" simple_expect "%2699 14 201" talk_to client 3 send "2700 90 201\n" simple_expect "=2700 $any_time 9 0 8 0 3 { 1 6 6 23 9 $any_time } 0 \\\*" # Deleting text 201; deleter 9 send "2701 29 201\n" talk_to client 0 simple_expect ":18 14 201 $any_time 9 0 8 0 3 { 1 6 6 23 9 $any_time } 0 \\\*" talk_to client 3 simple_expect "=2701" # Creating text 202 by 9 send "2702 86 [holl "text 202"] 0 { } 0 { }\n" simple_expect "=2702 202" talk_to client 0 send "2703 90 202\n" simple_expect "%2703 14 202" talk_to client 1 send "2704 90 202\n" simple_expect "%2704 14 202" talk_to client 2 send "2705 90 202\n" simple_expect "%2705 14 202" talk_to client 3 send "2706 90 202\n" simple_expect "=2706 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 202; adder 9 send "2707 30 202 7 1\n" simple_expect "=2707" talk_to client 0 send "2708 90 202\n" simple_expect "%2708 14 202" talk_to client 1 send "2709 90 202\n" simple_expect "=2709 $any_time 9 0 8 0 3 { 1 7 6 23 9 $any_time } 0 \\\*" talk_to client 2 send "2710 90 202\n" simple_expect "%2710 14 202" talk_to client 3 send "2711 90 202\n" simple_expect "=2711 $any_time 9 0 8 0 3 { 1 7 6 23 9 $any_time } 0 \\\*" # Deleting text 202; deleter 9 send "2712 29 202\n" simple_expect "=2712" # Creating text 203 by 9 send "2713 86 [holl "text 203"] 0 { } 0 { }\n" simple_expect "=2713 203" talk_to client 0 send "2714 90 203\n" simple_expect "%2714 14 203" talk_to client 1 send "2715 90 203\n" simple_expect "%2715 14 203" talk_to client 2 send "2716 90 203\n" simple_expect "%2716 14 203" talk_to client 3 send "2717 90 203\n" simple_expect "=2717 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 203; adder 9 send "2718 30 203 8 1\n" talk_to client 2 simple_expect ":3 16 203 8 1" talk_to client 3 simple_expect "=2718" talk_to client 0 send "2719 90 203\n" simple_expect "%2719 14 203" talk_to client 1 send "2720 90 203\n" simple_expect "%2720 14 203" talk_to client 2 send "2721 90 203\n" simple_expect "=2721 $any_time 9 0 8 0 3 { 1 8 6 23 9 $any_time } 0 \\\*" talk_to client 3 send "2722 90 203\n" simple_expect "=2722 $any_time 9 0 8 0 3 { 1 8 6 23 9 $any_time } 0 \\\*" # Deleting text 203; deleter 9 send "2723 29 203\n" talk_to client 2 simple_expect ":18 14 203 $any_time 9 0 8 0 3 { 1 8 6 23 9 $any_time } 0 \\\*" talk_to client 3 simple_expect "=2723" # Creating text 204 by 9 send "2724 86 [holl "text 204"] 0 { } 0 { }\n" simple_expect "=2724 204" talk_to client 0 send "2725 90 204\n" simple_expect "%2725 14 204" talk_to client 1 send "2726 90 204\n" simple_expect "%2726 14 204" talk_to client 2 send "2727 90 204\n" simple_expect "%2727 14 204" talk_to client 3 send "2728 90 204\n" simple_expect "=2728 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 204; adder 9 send "2729 30 204 9 1\n" simple_expect ":3 16 204 9 1" simple_expect "=2729" talk_to client 0 send "2730 90 204\n" simple_expect "%2730 14 204" talk_to client 1 send "2731 90 204\n" simple_expect "%2731 14 204" talk_to client 2 send "2732 90 204\n" simple_expect "%2732 14 204" talk_to client 3 send "2733 90 204\n" simple_expect "=2733 $any_time 9 0 8 0 3 { 1 9 6 23 9 $any_time } 0 \\\*" # Deleting text 204; deleter 9 send "2734 29 204\n" simple_expect ":18 14 204 $any_time 9 0 8 0 3 { 1 9 6 23 9 $any_time } 0 \\\*" simple_expect "=2734" # Creating text 205 by 9 send "2735 86 [holl "text 205"] 0 { } 0 { }\n" simple_expect "=2735 205" talk_to client 0 send "2736 90 205\n" simple_expect "%2736 14 205" talk_to client 1 send "2737 90 205\n" simple_expect "%2737 14 205" talk_to client 2 send "2738 90 205\n" simple_expect "%2738 14 205" talk_to client 3 send "2739 90 205\n" simple_expect "=2739 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 205; adder 9 send "2740 30 205 10 1\n" talk_to client 1 simple_expect ":3 16 205 10 1" talk_to client 2 simple_expect ":3 16 205 10 1" talk_to client 3 simple_expect "=2740" talk_to client 0 send "2741 90 205\n" simple_expect "=2741 $any_time 9 0 8 0 3 { 1 10 6 23 9 $any_time } 0 \\\*" talk_to client 1 send "2742 90 205\n" simple_expect "=2742 $any_time 9 0 8 0 3 { 1 10 6 23 9 $any_time } 0 \\\*" talk_to client 2 send "2743 90 205\n" simple_expect "=2743 $any_time 9 0 8 0 3 { 1 10 6 23 9 $any_time } 0 \\\*" talk_to client 3 send "2744 90 205\n" simple_expect "=2744 $any_time 9 0 8 0 3 { 1 10 6 23 9 $any_time } 0 \\\*" # Deleting text 205; deleter 9 send "2745 29 205\n" talk_to client 1 simple_expect ":18 14 205 $any_time 9 0 8 0 3 { 1 10 6 23 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 205 $any_time 9 0 8 0 3 { 1 10 6 23 9 $any_time } 0 \\\*" talk_to client 3 simple_expect "=2745" # Creating text 206 by 9 send "2746 86 [holl "text 206"] 0 { } 0 { }\n" simple_expect "=2746 206" talk_to client 0 send "2747 90 206\n" simple_expect "%2747 14 206" talk_to client 1 send "2748 90 206\n" simple_expect "%2748 14 206" talk_to client 2 send "2749 90 206\n" simple_expect "%2749 14 206" talk_to client 3 send "2750 90 206\n" simple_expect "=2750 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 206; adder 9 send "2751 30 206 11 1\n" talk_to client 1 simple_expect ":3 16 206 11 1" talk_to client 2 simple_expect ":3 16 206 11 1" talk_to client 3 simple_expect "=2751" talk_to client 0 send "2752 90 206\n" simple_expect "%2752 14 206" talk_to client 1 send "2753 90 206\n" simple_expect "=2753 $any_time 9 0 8 0 3 { 1 11 6 23 9 $any_time } 0 \\\*" talk_to client 2 send "2754 90 206\n" simple_expect "=2754 $any_time 9 0 8 0 3 { 1 11 6 23 9 $any_time } 0 \\\*" talk_to client 3 send "2755 90 206\n" simple_expect "=2755 $any_time 9 0 8 0 3 { 1 11 6 23 9 $any_time } 0 \\\*" # Deleting text 206; deleter 9 send "2756 29 206\n" talk_to client 1 simple_expect ":18 14 206 $any_time 9 0 8 0 3 { 1 11 6 23 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 206 $any_time 9 0 8 0 3 { 1 11 6 23 9 $any_time } 0 \\\*" talk_to client 3 simple_expect "=2756" # Creating text 207 by 9 send "2757 86 [holl "text 207"] 0 { } 0 { }\n" simple_expect "=2757 207" talk_to client 0 send "2758 90 207\n" simple_expect "%2758 14 207" talk_to client 1 send "2759 90 207\n" simple_expect "%2759 14 207" talk_to client 2 send "2760 90 207\n" simple_expect "%2760 14 207" talk_to client 3 send "2761 90 207\n" simple_expect "=2761 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 207; adder 9 send "2762 30 207 13 1\n" talk_to client 1 simple_expect ":3 16 207 13 1" talk_to client 2 simple_expect ":3 16 207 13 1" talk_to client 3 simple_expect "=2762" talk_to client 0 send "2763 90 207\n" simple_expect "=2763 $any_time 9 0 8 0 3 { 1 13 6 23 9 $any_time } 0 \\\*" talk_to client 1 send "2764 90 207\n" simple_expect "=2764 $any_time 9 0 8 0 3 { 1 13 6 23 9 $any_time } 0 \\\*" talk_to client 2 send "2765 90 207\n" simple_expect "=2765 $any_time 9 0 8 0 3 { 1 13 6 23 9 $any_time } 0 \\\*" talk_to client 3 send "2766 90 207\n" simple_expect "=2766 $any_time 9 0 8 0 3 { 1 13 6 23 9 $any_time } 0 \\\*" # Deleting text 207; deleter 9 send "2767 29 207\n" talk_to client 1 simple_expect ":18 14 207 $any_time 9 0 8 0 3 { 1 13 6 23 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 207 $any_time 9 0 8 0 3 { 1 13 6 23 9 $any_time } 0 \\\*" talk_to client 3 simple_expect "=2767" # Creating text 208 by 9 send "2768 86 [holl "text 208"] 0 { } 0 { }\n" simple_expect "=2768 208" talk_to client 0 send "2769 90 208\n" simple_expect "%2769 14 208" talk_to client 1 send "2770 90 208\n" simple_expect "%2770 14 208" talk_to client 2 send "2771 90 208\n" simple_expect "%2771 14 208" talk_to client 3 send "2772 90 208\n" simple_expect "=2772 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 208; adder 9 send "2773 30 208 14 1\n" talk_to client 1 simple_expect ":3 16 208 14 1" talk_to client 2 simple_expect ":3 16 208 14 1" talk_to client 3 simple_expect "=2773" talk_to client 0 send "2774 90 208\n" simple_expect "%2774 14 208" talk_to client 1 send "2775 90 208\n" simple_expect "=2775 $any_time 9 0 8 0 3 { 1 14 6 23 9 $any_time } 0 \\\*" talk_to client 2 send "2776 90 208\n" simple_expect "=2776 $any_time 9 0 8 0 3 { 1 14 6 23 9 $any_time } 0 \\\*" talk_to client 3 send "2777 90 208\n" simple_expect "=2777 $any_time 9 0 8 0 3 { 1 14 6 23 9 $any_time } 0 \\\*" # Deleting text 208; deleter 9 send "2778 29 208\n" talk_to client 1 simple_expect ":18 14 208 $any_time 9 0 8 0 3 { 1 14 6 23 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 208 $any_time 9 0 8 0 3 { 1 14 6 23 9 $any_time } 0 \\\*" talk_to client 3 simple_expect "=2778" # Creating text 209 by 9 send "2779 86 [holl "text 209"] 0 { } 0 { }\n" simple_expect "=2779 209" talk_to client 0 send "2780 90 209\n" simple_expect "%2780 14 209" talk_to client 1 send "2781 90 209\n" simple_expect "%2781 14 209" talk_to client 2 send "2782 90 209\n" simple_expect "%2782 14 209" talk_to client 3 send "2783 90 209\n" simple_expect "=2783 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 209; adder 9 send "2784 30 209 6 15\n" talk_to client 0 simple_expect ":3 16 209 6 15" talk_to client 3 simple_expect "=2784" talk_to client 0 send "2785 90 209\n" simple_expect "=2785 $any_time 9 0 8 0 3 { 15 6 6 24 9 $any_time } 0 \\\*" talk_to client 1 send "2786 90 209\n" simple_expect "%2786 14 209" talk_to client 2 send "2787 90 209\n" simple_expect "%2787 14 209" talk_to client 3 send "2788 90 209\n" simple_expect "=2788 $any_time 9 0 8 0 3 { 15 6 6 24 9 $any_time } 0 \\\*" # Deleting text 209; deleter 9 send "2789 29 209\n" talk_to client 0 simple_expect ":18 14 209 $any_time 9 0 8 0 3 { 15 6 6 24 9 $any_time } 0 \\\*" talk_to client 3 simple_expect "=2789" # Creating text 210 by 9 send "2790 86 [holl "text 210"] 0 { } 0 { }\n" simple_expect "=2790 210" talk_to client 0 send "2791 90 210\n" simple_expect "%2791 14 210" talk_to client 1 send "2792 90 210\n" simple_expect "%2792 14 210" talk_to client 2 send "2793 90 210\n" simple_expect "%2793 14 210" talk_to client 3 send "2794 90 210\n" simple_expect "=2794 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 210; adder 9 send "2795 30 210 7 15\n" simple_expect "=2795" talk_to client 0 send "2796 90 210\n" simple_expect "%2796 14 210" talk_to client 1 send "2797 90 210\n" simple_expect "=2797 $any_time 9 0 8 0 3 { 15 7 6 24 9 $any_time } 0 \\\*" talk_to client 2 send "2798 90 210\n" simple_expect "%2798 14 210" talk_to client 3 send "2799 90 210\n" simple_expect "=2799 $any_time 9 0 8 0 3 { 15 7 6 24 9 $any_time } 0 \\\*" # Deleting text 210; deleter 9 send "2800 29 210\n" simple_expect "=2800" # Creating text 211 by 9 send "2801 86 [holl "text 211"] 0 { } 0 { }\n" simple_expect "=2801 211" talk_to client 0 send "2802 90 211\n" simple_expect "%2802 14 211" talk_to client 1 send "2803 90 211\n" simple_expect "%2803 14 211" talk_to client 2 send "2804 90 211\n" simple_expect "%2804 14 211" talk_to client 3 send "2805 90 211\n" simple_expect "=2805 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 211; adder 9 send "2806 30 211 8 15\n" talk_to client 2 simple_expect ":3 16 211 8 15" talk_to client 3 simple_expect "=2806" talk_to client 0 send "2807 90 211\n" simple_expect "%2807 14 211" talk_to client 1 send "2808 90 211\n" simple_expect "%2808 14 211" talk_to client 2 send "2809 90 211\n" simple_expect "=2809 $any_time 9 0 8 0 3 { 15 8 6 24 9 $any_time } 0 \\\*" talk_to client 3 send "2810 90 211\n" simple_expect "=2810 $any_time 9 0 8 0 3 { 15 8 6 24 9 $any_time } 0 \\\*" # Deleting text 211; deleter 9 send "2811 29 211\n" talk_to client 2 simple_expect ":18 14 211 $any_time 9 0 8 0 3 { 15 8 6 24 9 $any_time } 0 \\\*" talk_to client 3 simple_expect "=2811" # Creating text 212 by 9 send "2812 86 [holl "text 212"] 0 { } 0 { }\n" simple_expect "=2812 212" talk_to client 0 send "2813 90 212\n" simple_expect "%2813 14 212" talk_to client 1 send "2814 90 212\n" simple_expect "%2814 14 212" talk_to client 2 send "2815 90 212\n" simple_expect "%2815 14 212" talk_to client 3 send "2816 90 212\n" simple_expect "=2816 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 212; adder 9 send "2817 30 212 9 15\n" simple_expect ":3 16 212 9 15" simple_expect "=2817" talk_to client 0 send "2818 90 212\n" simple_expect "%2818 14 212" talk_to client 1 send "2819 90 212\n" simple_expect "%2819 14 212" talk_to client 2 send "2820 90 212\n" simple_expect "%2820 14 212" talk_to client 3 send "2821 90 212\n" simple_expect "=2821 $any_time 9 0 8 0 3 { 15 9 6 24 9 $any_time } 0 \\\*" # Deleting text 212; deleter 9 send "2822 29 212\n" simple_expect ":18 14 212 $any_time 9 0 8 0 3 { 15 9 6 24 9 $any_time } 0 \\\*" simple_expect "=2822" # Creating text 213 by 9 send "2823 86 [holl "text 213"] 0 { } 0 { }\n" simple_expect "=2823 213" talk_to client 0 send "2824 90 213\n" simple_expect "%2824 14 213" talk_to client 1 send "2825 90 213\n" simple_expect "%2825 14 213" talk_to client 2 send "2826 90 213\n" simple_expect "%2826 14 213" talk_to client 3 send "2827 90 213\n" simple_expect "=2827 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 213; adder 9 send "2828 30 213 10 15\n" talk_to client 1 simple_expect ":3 16 213 10 15" talk_to client 2 simple_expect ":3 16 213 10 15" talk_to client 3 simple_expect "=2828" talk_to client 0 send "2829 90 213\n" simple_expect "=2829 $any_time 9 0 8 0 3 { 15 10 6 24 9 $any_time } 0 \\\*" talk_to client 1 send "2830 90 213\n" simple_expect "=2830 $any_time 9 0 8 0 3 { 15 10 6 24 9 $any_time } 0 \\\*" talk_to client 2 send "2831 90 213\n" simple_expect "=2831 $any_time 9 0 8 0 3 { 15 10 6 24 9 $any_time } 0 \\\*" talk_to client 3 send "2832 90 213\n" simple_expect "=2832 $any_time 9 0 8 0 3 { 15 10 6 24 9 $any_time } 0 \\\*" # Deleting text 213; deleter 9 send "2833 29 213\n" talk_to client 1 simple_expect ":18 14 213 $any_time 9 0 8 0 3 { 15 10 6 24 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 213 $any_time 9 0 8 0 3 { 15 10 6 24 9 $any_time } 0 \\\*" talk_to client 3 simple_expect "=2833" # Creating text 214 by 9 send "2834 86 [holl "text 214"] 0 { } 0 { }\n" simple_expect "=2834 214" talk_to client 0 send "2835 90 214\n" simple_expect "%2835 14 214" talk_to client 1 send "2836 90 214\n" simple_expect "%2836 14 214" talk_to client 2 send "2837 90 214\n" simple_expect "%2837 14 214" talk_to client 3 send "2838 90 214\n" simple_expect "=2838 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 214; adder 9 send "2839 30 214 11 15\n" talk_to client 1 simple_expect ":3 16 214 11 15" talk_to client 2 simple_expect ":3 16 214 11 15" talk_to client 3 simple_expect "=2839" talk_to client 0 send "2840 90 214\n" simple_expect "%2840 14 214" talk_to client 1 send "2841 90 214\n" simple_expect "=2841 $any_time 9 0 8 0 3 { 15 11 6 24 9 $any_time } 0 \\\*" talk_to client 2 send "2842 90 214\n" simple_expect "=2842 $any_time 9 0 8 0 3 { 15 11 6 24 9 $any_time } 0 \\\*" talk_to client 3 send "2843 90 214\n" simple_expect "=2843 $any_time 9 0 8 0 3 { 15 11 6 24 9 $any_time } 0 \\\*" # Deleting text 214; deleter 9 send "2844 29 214\n" talk_to client 1 simple_expect ":18 14 214 $any_time 9 0 8 0 3 { 15 11 6 24 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 214 $any_time 9 0 8 0 3 { 15 11 6 24 9 $any_time } 0 \\\*" talk_to client 3 simple_expect "=2844" # Creating text 215 by 9 send "2845 86 [holl "text 215"] 0 { } 0 { }\n" simple_expect "=2845 215" talk_to client 0 send "2846 90 215\n" simple_expect "%2846 14 215" talk_to client 1 send "2847 90 215\n" simple_expect "%2847 14 215" talk_to client 2 send "2848 90 215\n" simple_expect "%2848 14 215" talk_to client 3 send "2849 90 215\n" simple_expect "=2849 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 215; adder 9 send "2850 30 215 13 15\n" talk_to client 1 simple_expect ":3 16 215 13 15" talk_to client 2 simple_expect ":3 16 215 13 15" talk_to client 3 simple_expect "=2850" talk_to client 0 send "2851 90 215\n" simple_expect "=2851 $any_time 9 0 8 0 3 { 15 13 6 24 9 $any_time } 0 \\\*" talk_to client 1 send "2852 90 215\n" simple_expect "=2852 $any_time 9 0 8 0 3 { 15 13 6 24 9 $any_time } 0 \\\*" talk_to client 2 send "2853 90 215\n" simple_expect "=2853 $any_time 9 0 8 0 3 { 15 13 6 24 9 $any_time } 0 \\\*" talk_to client 3 send "2854 90 215\n" simple_expect "=2854 $any_time 9 0 8 0 3 { 15 13 6 24 9 $any_time } 0 \\\*" # Deleting text 215; deleter 9 send "2855 29 215\n" talk_to client 1 simple_expect ":18 14 215 $any_time 9 0 8 0 3 { 15 13 6 24 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 215 $any_time 9 0 8 0 3 { 15 13 6 24 9 $any_time } 0 \\\*" talk_to client 3 simple_expect "=2855" # Creating text 216 by 9 send "2856 86 [holl "text 216"] 0 { } 0 { }\n" simple_expect "=2856 216" talk_to client 0 send "2857 90 216\n" simple_expect "%2857 14 216" talk_to client 1 send "2858 90 216\n" simple_expect "%2858 14 216" talk_to client 2 send "2859 90 216\n" simple_expect "%2859 14 216" talk_to client 3 send "2860 90 216\n" simple_expect "=2860 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 216; adder 9 send "2861 30 216 14 15\n" talk_to client 1 simple_expect ":3 16 216 14 15" talk_to client 2 simple_expect ":3 16 216 14 15" talk_to client 3 simple_expect "=2861" talk_to client 0 send "2862 90 216\n" simple_expect "%2862 14 216" talk_to client 1 send "2863 90 216\n" simple_expect "=2863 $any_time 9 0 8 0 3 { 15 14 6 24 9 $any_time } 0 \\\*" talk_to client 2 send "2864 90 216\n" simple_expect "=2864 $any_time 9 0 8 0 3 { 15 14 6 24 9 $any_time } 0 \\\*" talk_to client 3 send "2865 90 216\n" simple_expect "=2865 $any_time 9 0 8 0 3 { 15 14 6 24 9 $any_time } 0 \\\*" # Deleting text 216; deleter 9 send "2866 29 216\n" talk_to client 1 simple_expect ":18 14 216 $any_time 9 0 8 0 3 { 15 14 6 24 9 $any_time } 0 \\\*" talk_to client 2 simple_expect ":18 14 216 $any_time 9 0 8 0 3 { 15 14 6 24 9 $any_time } 0 \\\*" talk_to client 3 simple_expect "=2866" send_user "testing some special cases\n" talk_to client 1 # Creating text 217 by 7 send "2867 86 [holl "text 217"] 1 { 0 10 } 0 { }\n" simple_expect ":18 15 217 $any_time 7 0 8 0 2 { 0 10 6 25 } 0 \\\*" talk_to client 2 simple_expect ":18 15 217 $any_time 7 0 8 0 2 { 0 10 6 25 } 0 \\\*" talk_to client 1 simple_expect "=2867 217" talk_to client 0 send "2868 90 217\n" simple_expect "=2868 $any_time 7 0 8 0 2 { 0 10 6 25 } 0 \\\*" talk_to client 1 send "2869 90 217\n" simple_expect "=2869 $any_time 7 0 8 0 2 { 0 10 6 25 } 0 \\\*" talk_to client 2 send "2870 90 217\n" simple_expect "=2870 $any_time 7 0 8 0 2 { 0 10 6 25 } 0 \\\*" talk_to client 3 send "2871 90 217\n" simple_expect "=2871 $any_time 7 0 8 0 2 { 0 10 6 25 } 0 \\\*" talk_to client 0 # Adding recipient to text 217; adder 6 send "2872 30 217 8 15\n" talk_to client 1 simple_expect ":3 16 217 8 15" talk_to client 2 simple_expect ":3 16 217 8 15" talk_to client 0 simple_expect "=2872" send "2873 90 217\n" simple_expect "=2873 $any_time 7 0 8 0 6 { 0 10 6 25 15 8 6 25 8 6 9 $any_time } 0 \\\*" talk_to client 1 send "2874 90 217\n" simple_expect "=2874 $any_time 7 0 8 0 6 { 0 10 6 25 15 8 6 25 8 6 9 $any_time } 0 \\\*" talk_to client 2 send "2875 90 217\n" simple_expect "=2875 $any_time 7 0 8 0 6 { 0 10 6 25 15 8 6 25 8 6 9 $any_time } 0 \\\*" talk_to client 3 send "2876 90 217\n" simple_expect "=2876 $any_time 7 0 8 0 2 { 0 10 6 25 } 0 \\\*" talk_to client 1 # Removing recipient from text 217; remover 7 send "2877 31 217 10\n" simple_expect ":3 17 217 10 0" talk_to client 2 simple_expect ":3 17 217 10 0" talk_to client 1 simple_expect "=2877" talk_to client 0 send "2878 90 217\n" simple_expect "%2878 14 217" talk_to client 1 send "2879 90 217\n" simple_expect "=2879 $any_time 7 0 8 0 4 { 15 8 6 25 8 6 9 $any_time } 0 \\\*" talk_to client 2 send "2880 90 217\n" simple_expect "=2880 $any_time 7 0 8 0 4 { 15 8 6 25 8 6 9 $any_time } 0 \\\*" talk_to client 3 send "2881 90 217\n" simple_expect "%2881 14 217" talk_to client 1 # Deleting text 217; deleter 7 send "2882 29 217\n" talk_to client 2 simple_expect ":18 14 217 $any_time 7 0 8 0 4 { 15 8 6 25 8 6 9 $any_time } 0 \\\*" talk_to client 1 simple_expect "=2882" talk_to client 0 send "2883 55 0\n" simple_expect "=2883" client_death 0 talk_to client 1 send "2884 55 0\n" simple_expect "=2884" client_death 1 talk_to client 2 send "2885 55 0\n" simple_expect "=2885" client_death 2 talk_to client 3 send "2886 62 5 [holl "gazonk"] 1\n" simple_expect "=2886" send "2887 42 255\n" simple_expect "=2887" send "2888 44 0\n" simple_expect "=2888" client_death 3 lyskomd_death # Automatically generated by gen-15.py. Do not edit. lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/16.exp0000664000015100472110000000745707721716133016753 # Test suite for lyskomd. # Copyright (C) 1999-2000, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check if secret conference numbers can leak from the various # calls that get session information. # Several players are used: # client 0 person 6 member of 6 # client 1 person 7 member of 7, 8, creator of 8 # # Conferences: # 8 (secret) members: 7 creator: 7 proc assert_0 {conf msg} { # Fail if $conf is non-zero. if {$conf == 0} { pass "$msg" } else { fail "$msg" } } lyskomd_start # Establish the sessions, create persons, and log in. proc startup_16 {session person} { client_start $session talk_to client $session send "A3Hfoo\n" simple_expect "LysKOM" "connected" send "100 80 1 { 6 }\n" simple_expect "=100" send "101 89 [holl "Person $person"] [holl "foo"] 00000000 0 { }\n" simple_expect "=101 $person" send "102 62 $person [holl "foo"] 0\n" simple_expect "=102" } startup_16 0 6 startup_16 1 7 # Create the conference talk_to client 1 send "1000 88 [holl "conf 8"] 1010 0 { }\n" simple_expect "=1000 8" # Join the conference talk_to client 1 send "1001 100 8 7 100 1 00000000\n" simple_expect "=1001" # Person 7 goes to the secret conference. send "1002 2 8\n" simple_expect ":5 6 7 8 2 0H [idholl "foo"]" simple_expect "=1002" talk_to client 0 # Should this even be sent? Seen from the view-point of person 6, # person 7 goes from conference 0 to conference 0. extracting_expect ":5 6 7 (\[08\]) 2 0H [idholl "foo"]" conf 1 assert_0 $conf "async-i-am-on leaks secret info" # Person 6 tries to get information. # Assert that conference 8 is invisible to person 6. send "1003 91 8\n" simple_expect "%1003 9 8" send "1004 39\n" extracting_expect "=1004 2 { 7 (\[08\]) 0H 6 0 0H }" conf 1 assert_0 $conf "who-is-on-old leaks secret info" send "1005 51\n" extracting_expect "=1005 2 { 7 (\[08\]) 2 0H [idholl "foo"] 6 0 1 0H [idholl "foo"] }" conf 1 assert_0 $conf "who-is-on leaks secret info" send "1007 54 2\n" extracting_expect "=1007 7 (\[08\]) 2 0H [idholl "foo"] $any_num $any_time" conf 1 assert_0 $conf "get-session-info leaks secret info" send "1006 63\n" extracting_expect "=1006 2 { 7 (\[08\]) 2 0H 3Hfoo [holl "$lyskomd_host"] [holl "unknown"] 6 0 1 0H 3Hfoo [holl "$lyskomd_host"] [holl "unknown"] }" conf 1 assert_0 $conf "who-is-on-ident leaks secret info" send "1007 64 2\n" extracting_expect "=1007 7 (\[08\]) 2 0H 3Hfoo [holl "$lyskomd_host"] [holl "unknown"] $any_num $any_time" conf 1 assert_0 $conf "get-session-info-ident leaks secret info" send "1 83 1 1 0\n" extracting_expect "=1 2 { 2 7 (\[08\]) $any_num 00000000 0H 1 6 0 $any_num 00000000 0H }" conf 1 assert_0 $conf "who-is-on-dynamic leaks secret info" # Shut down the server. talk_to client 1 send "1008 55 0\n" simple_expect "=1008" client_death 1 talk_to client 0 send "1009 62 5 [holl "gazonk"] 1\n" simple_expect "=1009" send "1010 42 255\n" simple_expect "=1010" send "1011 44 0\n" simple_expect "=1011" client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/17.exp0000664000015100472110000000523407721716133016743 # Test suite for lyskomd. # Copyright (C) 1999-2000, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check the recommended-conf aux-item, especially the validate regexp. read_versions lyskomd_start client_start 0 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" "connected" send "1000 62 5 [holl "gazonk"] 1\n" simple_expect "=1000" send "1001 94\n" simple_expect "=1001 $server_compat_version 1 2 3 4 0 0 \\*" # We cannot modify the system info unless we enable our privileges. send "1002 95 0 { } 1 { 29 00000000 1 [holl "1"] }\n" simple_expect "%1002 12 0" send "1003 42 255\n" simple_expect "=1003" # Three valid items. send "1004 95 0 { } 1 { 29 00000000 1 [holl "1"] }\n" simple_expect "=1004" send "1005 94\n" simple_expect "=1005 $server_compat_version 1 2 3 4 0 1 { 1 29 5 $any_time 00000000 1 [holl "1"] }" send "1006 95 0 { } 1 { 29 00000000 1 [holl "2 250"] }\n" simple_expect "=1006" send "1007 95 0 { } 1 { 29 00000000 1 [holl "3 250 00000000"] }\n" simple_expect "=1007" # A few invalid values. send "1008 95 0 { } 1 { 29 00000000 1 [holl "4 250 00000000 4"] }\n" simple_expect "%1008 48 0" send "1009 95 0 { } 1 { 29 00000000 1 [holl "4 00000000"] }\n" simple_expect "%1009 48 0" send "1010 95 0 { } 1 { 29 00000000 1 [holl "4 2c0 00000000"] }\n" simple_expect "%1010 48 0" send "1011 95 0 { } 1 { 29 00000000 1 [holl "4 250 00200000"] }\n" simple_expect "%1011 48 0" # A fourth valid item. send "1012 95 0 { } 1 { 29 00000000 1 [holl "4 190 00000000"] }\n" simple_expect "=1012" send "1005 94\n" simple_expect "=1005 $server_compat_version 1 2 3 4 0 4 { 1 29 5 $any_time 00000000 1 [holl "1"] 2 29 5 $any_time 00000000 1 [holl "2 250"] 3 29 5 $any_time 00000000 1 [holl "3 250 00000000"] 4 29 5 $any_time 00000000 1 [holl "4 190 00000000"] }" send "1013 44 0\n" simple_expect "=1013" client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/18.exp0000664000015100472110000001016107721716133016737 # Test suite for lyskomd. # Copyright (C) 1999-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check that the server can re-read the aux-items file. read_versions set myaux "lyskomd.0/aux-items-18.conf" proc copy_aux {file} { global myaux system "rm -f $myaux" system "cp $file $myaux" } copy_aux $srcdir/lyskomd.0/aux-items.conf lyskomd_start "$myaux" client_start 0 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" "connected" send "1000 62 5 [holl "gazonk"] 1\n" simple_expect "=1000" send "1001 96\n" simple_expect "=1001 39 { 10003 10002 10001 10000 4000 3002 3001 3000 2007 2006 2005 2004 2003 2002 2001 2000 1022 1021 1020 1019 1018 1017 1016 1015 1014 1013 1012 1011 1010 1009 1008 1007 1006 1005 1004 1003 1002 1001 1000 }" copy_aux $aux_item_default_conf_file send "1002 96\n" simple_expect "=1002 39 { 10003 10002 10001 10000 4000 3002 3001 3000 2007 2006 2005 2004 2003 2002 2001 2000 1022 1021 1020 1019 1018 1017 1016 1015 1014 1013 1012 1011 1010 1009 1008 1007 1006 1005 1004 1003 1002 1001 1000 }" system "kill -WINCH $lyskomd_pid" lyskomd_expect "Signal WINCH received. aux definitions reloaded." send "1003 96\n" simple_expect "=1003 40 { 10104 10103 10102 10101 10100 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 }" send "1004 96\n" simple_expect "=1004 40 { 10104 10103 10102 10101 10100 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 }" copy_aux $srcdir/lyskomd.0/aux-items.conf system "kill -WINCH $lyskomd_pid" lyskomd_expect "Signal WINCH received. aux definitions reloaded." send "1005 96\n" simple_expect "=1005 39 { 10003 10002 10001 10000 4000 3002 3001 3000 2007 2006 2005 2004 2003 2002 2001 2000 1022 1021 1020 1019 1018 1017 1016 1015 1014 1013 1012 1011 1010 1009 1008 1007 1006 1005 1004 1003 1002 1001 1000 }" system "kill -WINCH $lyskomd_pid" lyskomd_expect "Signal WINCH received. aux definitions reloaded." send "1006 96\n" simple_expect "=1006 39 { 10003 10002 10001 10000 4000 3002 3001 3000 2007 2006 2005 2004 2003 2002 2001 2000 1022 1021 1020 1019 1018 1017 1016 1015 1014 1013 1012 1011 1010 1009 1008 1007 1006 1005 1004 1003 1002 1001 1000 }" system "kill -WINCH $lyskomd_pid" lyskomd_expect "Signal WINCH received. aux definitions reloaded." send "1007 96\n" simple_expect "=1007 39 { 10003 10002 10001 10000 4000 3002 3001 3000 2007 2006 2005 2004 2003 2002 2001 2000 1022 1021 1020 1019 1018 1017 1016 1015 1014 1013 1012 1011 1010 1009 1008 1007 1006 1005 1004 1003 1002 1001 1000 }" system "kill -WINCH $lyskomd_pid" lyskomd_expect "Signal WINCH received. aux definitions reloaded." send "1008 96\n" simple_expect "=1008 39 { 10003 10002 10001 10000 4000 3002 3001 3000 2007 2006 2005 2004 2003 2002 2001 2000 1022 1021 1020 1019 1018 1017 1016 1015 1014 1013 1012 1011 1010 1009 1008 1007 1006 1005 1004 1003 1002 1001 1000 }" copy_aux $aux_item_default_conf_file system "kill -WINCH $lyskomd_pid" lyskomd_expect "Signal WINCH received. aux definitions reloaded." send "1009 96\n" simple_expect "=1009 40 { 10104 10103 10102 10101 10100 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 }" send "1010 42 255\n" simple_expect "=1010" send "1011 44 0\n" simple_expect "=1011" client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/19.exp0000444000015100472110000072250307723710375016752 # Automatically generated by gen-19.py. Do not edit. lyskomd_start client_start 0 # talk to Person 6 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" "connected 6" send "1000 80 4 { 14 15 16 17 }\n" simple_expect "=1000" send "1001 89 [holl "Person 6"] [holl "foo"] 00000000 0 { }\n" simple_expect "=1001 6" send "1002 62 6 [holl "foo"] 0\n" simple_expect "=1002" client_start 1 # talk to Person 7 talk_to client 1 send "A3Hfoo\n" simple_expect "LysKOM" "connected 7" send "1003 80 4 { 14 15 16 17 }\n" simple_expect "=1003" send "1004 89 [holl "Person 7"] [holl "foo"] 00000000 0 { }\n" simple_expect "=1004 7" send "1005 62 7 [holl "foo"] 0\n" simple_expect "=1005" client_start 2 # talk to Person 8 talk_to client 2 send "A3Hfoo\n" simple_expect "LysKOM" "connected 8" send "1006 80 4 { 14 15 16 17 }\n" simple_expect "=1006" send "1007 89 [holl "Person 8"] [holl "foo"] 00000000 0 { }\n" simple_expect "=1007 8" send "1008 62 8 [holl "foo"] 0\n" simple_expect "=1008" client_start 3 # talk to Person 9 talk_to client 3 send "A3Hfoo\n" simple_expect "LysKOM" "connected 9" send "1009 80 4 { 14 15 16 17 }\n" simple_expect "=1009" send "1010 89 [holl "Person 9"] [holl "foo"] 00000000 0 { }\n" simple_expect "=1010 9" send "1011 62 9 [holl "foo"] 0\n" simple_expect "=1011" # talk to Person 7 talk_to client 1 send "1012 88 [holl "conf 10"] 0000 0 { }\n" simple_expect "=1012 10" send "1013 88 [holl "conf 11"] 1000 0 { }\n" simple_expect "=1013 11" send "1014 88 [holl "conf 12"] 1010 0 { }\n" simple_expect "=1014 12" # talk to Person 9 talk_to client 3 send "1015 88 [holl "conf 13"] 0000 0 { }\n" simple_expect "=1015 13" send "1016 88 [holl "conf 14"] 1000 0 { }\n" simple_expect "=1016 14" send "1017 88 [holl "conf 15"] 1010 0 { }\n" simple_expect "=1017 15" # talk to Person 7 talk_to client 1 send "1018 100 10 7 100 3 00000000\n" simple_expect "=1018" send "1019 100 10 8 100 3 01000000\n" simple_expect "=1019" send "1020 100 11 7 100 3 00000000\n" simple_expect "=1020" send "1021 100 11 8 100 3 01000000\n" simple_expect "=1021" send "1022 100 12 7 100 3 00000000\n" simple_expect "=1022" send "1023 100 12 8 100 3 01000000\n" simple_expect "=1023" # talk to Person 9 talk_to client 3 send "1024 100 13 7 100 6 01000000\n" simple_expect "=1024" send "1025 100 13 8 100 6 00000000\n" simple_expect "=1025" send "1026 100 14 7 100 6 01000000\n" simple_expect "=1026" send "1027 100 14 8 100 6 00000000\n" simple_expect "=1027" send "1028 100 15 7 100 6 01000000\n" simple_expect "=1028" send "1029 100 15 8 100 6 00000000\n" simple_expect "=1029" talk_to lyskomd simple_expect "Person 8 added to conference 10 by 7." simple_expect "Person 8 added to conference 11 by 7." simple_expect "Person 8 added to conference 12 by 7." simple_expect "Person 7 added to conference 13 by 9." simple_expect "Person 8 added to conference 13 by 9." simple_expect "Person 7 added to conference 14 by 9." simple_expect "Person 8 added to conference 14 by 9." simple_expect "Person 7 added to conference 15 by 9." simple_expect "Person 8 added to conference 15 by 9." # talk to Person 7 talk_to client 1 send "1030 15 7 7\n" simple_expect "=1030" send_user "testing simple create+delete\n" # talk to Person 6 talk_to client 0 # Creating text 1 by 6 send "1031 86 [holl "text 1"] 1 { 0 6 } 0 { }\n" simple_expect ":18 15 1 $any_time 6 0 6 0 2 { 0 6 6 1 } 0 \\\*" simple_expect "=1031 1" send "1032 90 1\n" simple_expect "=1032 $any_time 6 0 6 0 2 { 0 6 6 1 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1033 90 1\n" simple_expect "%1033 14 1" # talk to Person 8 talk_to client 2 send "1034 90 1\n" simple_expect "%1034 14 1" # talk to Person 9 talk_to client 3 send "1035 90 1\n" simple_expect "%1035 14 1" # talk to Person 6 talk_to client 0 # Deleting text 1; deleter 6 send "1036 29 1\n" simple_expect ":18 14 1 $any_time 6 0 6 0 2 { 0 6 6 1 } 0 \\\*" simple_expect "=1036" # Creating text 2 by 6 send "1037 86 [holl "text 2"] 1 { 0 7 } 0 { }\n" simple_expect "=1037 2" send "1038 90 2\n" simple_expect "=1038 $any_time 6 0 6 0 2 { 0 7 6 1 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1039 90 2\n" simple_expect "=1039 $any_time 6 0 6 0 2 { 0 7 6 1 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1040 90 2\n" simple_expect "%1040 14 2" # talk to Person 9 talk_to client 3 send "1041 90 2\n" simple_expect "%1041 14 2" # talk to Person 6 talk_to client 0 # Deleting text 2; deleter 6 send "1042 29 2\n" simple_expect "=1042" # Creating text 3 by 6 send "1043 86 [holl "text 3"] 1 { 0 8 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 3 $any_time 6 0 6 0 2 { 0 8 6 1 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1043 3" send "1044 90 3\n" simple_expect "=1044 $any_time 6 0 6 0 2 { 0 8 6 1 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1045 90 3\n" simple_expect "%1045 14 3" # talk to Person 8 talk_to client 2 send "1046 90 3\n" simple_expect "=1046 $any_time 6 0 6 0 2 { 0 8 6 1 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1047 90 3\n" simple_expect "%1047 14 3" # talk to Person 6 talk_to client 0 # Deleting text 3; deleter 6 send "1048 29 3\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 3 $any_time 6 0 6 0 2 { 0 8 6 1 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1048" # Creating text 4 by 6 send "1049 86 [holl "text 4"] 1 { 0 9 } 0 { }\n" # talk to Person 9 talk_to client 3 simple_expect ":18 15 4 $any_time 6 0 6 0 2 { 0 9 6 1 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1049 4" send "1050 90 4\n" simple_expect "=1050 $any_time 6 0 6 0 2 { 0 9 6 1 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1051 90 4\n" simple_expect "%1051 14 4" # talk to Person 8 talk_to client 2 send "1052 90 4\n" simple_expect "%1052 14 4" # talk to Person 9 talk_to client 3 send "1053 90 4\n" simple_expect "=1053 $any_time 6 0 6 0 2 { 0 9 6 1 } 0 \\\*" # talk to Person 6 talk_to client 0 # Deleting text 4; deleter 6 send "1054 29 4\n" # talk to Person 9 talk_to client 3 simple_expect ":18 14 4 $any_time 6 0 6 0 2 { 0 9 6 1 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1054" # Creating text 5 by 6 send "1055 86 [holl "text 5"] 1 { 0 10 } 0 { }\n" # talk to Person 7 talk_to client 1 simple_expect ":18 15 5 $any_time 6 0 6 0 2 { 0 10 6 1 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1055 5" send "1056 90 5\n" simple_expect "=1056 $any_time 6 0 6 0 2 { 0 10 6 1 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1057 90 5\n" simple_expect "=1057 $any_time 6 0 6 0 2 { 0 10 6 1 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1058 90 5\n" simple_expect "=1058 $any_time 6 0 6 0 2 { 0 10 6 1 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1059 90 5\n" simple_expect "=1059 $any_time 6 0 6 0 2 { 0 10 6 1 } 0 \\\*" # talk to Person 6 talk_to client 0 # Deleting text 5; deleter 6 send "1060 29 5\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 5 $any_time 6 0 6 0 2 { 0 10 6 1 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1060" # Creating text 6 by 6 send "1061 86 [holl "text 6"] 1 { 0 11 } 0 { }\n" # talk to Person 7 talk_to client 1 simple_expect ":18 15 6 $any_time 6 0 6 0 2 { 0 11 6 1 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1061 6" send "1062 90 6\n" simple_expect "=1062 $any_time 6 0 6 0 2 { 0 11 6 1 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1063 90 6\n" simple_expect "=1063 $any_time 6 0 6 0 2 { 0 11 6 1 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1064 90 6\n" simple_expect "=1064 $any_time 6 0 6 0 2 { 0 11 6 1 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1065 90 6\n" simple_expect "%1065 14 6" # talk to Person 6 talk_to client 0 # Deleting text 6; deleter 6 send "1066 29 6\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 6 $any_time 6 0 6 0 2 { 0 11 6 1 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1066" # Creating text 7 by 6 send "1067 86 [holl "text 7"] 1 { 0 13 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 7 $any_time 6 0 6 0 2 { 0 13 6 1 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1067 7" send "1068 90 7\n" simple_expect "=1068 $any_time 6 0 6 0 2 { 0 13 6 1 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1069 90 7\n" simple_expect "=1069 $any_time 6 0 6 0 2 { 0 13 6 1 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1070 90 7\n" simple_expect "=1070 $any_time 6 0 6 0 2 { 0 13 6 1 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1071 90 7\n" simple_expect "=1071 $any_time 6 0 6 0 2 { 0 13 6 1 } 0 \\\*" # talk to Person 6 talk_to client 0 # Deleting text 7; deleter 6 send "1072 29 7\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 7 $any_time 6 0 6 0 2 { 0 13 6 1 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1072" # Creating text 8 by 6 send "1073 86 [holl "text 8"] 1 { 0 14 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 8 $any_time 6 0 6 0 2 { 0 14 6 1 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1073 8" send "1074 90 8\n" simple_expect "=1074 $any_time 6 0 6 0 2 { 0 14 6 1 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1075 90 8\n" simple_expect "=1075 $any_time 6 0 6 0 2 { 0 14 6 1 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1076 90 8\n" simple_expect "=1076 $any_time 6 0 6 0 2 { 0 14 6 1 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1077 90 8\n" simple_expect "=1077 $any_time 6 0 6 0 2 { 0 14 6 1 } 0 \\\*" # talk to Person 6 talk_to client 0 # Deleting text 8; deleter 6 send "1078 29 8\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 8 $any_time 6 0 6 0 2 { 0 14 6 1 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1078" # Creating text 9 by 6 send "1079 86 [holl "text 9"] 1 { 1 6 } 0 { }\n" simple_expect ":18 15 9 $any_time 6 0 6 0 2 { 1 6 6 2 } 0 \\\*" simple_expect "=1079 9" send "1080 90 9\n" simple_expect "=1080 $any_time 6 0 6 0 2 { 1 6 6 2 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1081 90 9\n" simple_expect "%1081 14 9" # talk to Person 8 talk_to client 2 send "1082 90 9\n" simple_expect "%1082 14 9" # talk to Person 9 talk_to client 3 send "1083 90 9\n" simple_expect "%1083 14 9" # talk to Person 6 talk_to client 0 # Deleting text 9; deleter 6 send "1084 29 9\n" simple_expect ":18 14 9 $any_time 6 0 6 0 2 { 1 6 6 2 } 0 \\\*" simple_expect "=1084" # Creating text 10 by 6 send "1085 86 [holl "text 10"] 1 { 1 7 } 0 { }\n" simple_expect "=1085 10" send "1086 90 10\n" simple_expect "=1086 $any_time 6 0 7 0 2 { 1 7 6 2 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1087 90 10\n" simple_expect "=1087 $any_time 6 0 7 0 2 { 1 7 6 2 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1088 90 10\n" simple_expect "%1088 14 10" # talk to Person 9 talk_to client 3 send "1089 90 10\n" simple_expect "%1089 14 10" # talk to Person 6 talk_to client 0 # Deleting text 10; deleter 6 send "1090 29 10\n" simple_expect "=1090" # Creating text 11 by 6 send "1091 86 [holl "text 11"] 1 { 1 8 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 11 $any_time 6 0 7 0 2 { 1 8 6 2 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1091 11" send "1092 90 11\n" simple_expect "=1092 $any_time 6 0 7 0 2 { 1 8 6 2 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1093 90 11\n" simple_expect "%1093 14 11" # talk to Person 8 talk_to client 2 send "1094 90 11\n" simple_expect "=1094 $any_time 6 0 7 0 2 { 1 8 6 2 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1095 90 11\n" simple_expect "%1095 14 11" # talk to Person 6 talk_to client 0 # Deleting text 11; deleter 6 send "1096 29 11\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 11 $any_time 6 0 7 0 2 { 1 8 6 2 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1096" # Creating text 12 by 6 send "1097 86 [holl "text 12"] 1 { 1 9 } 0 { }\n" # talk to Person 9 talk_to client 3 simple_expect ":18 15 12 $any_time 6 0 7 0 2 { 1 9 6 2 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1097 12" send "1098 90 12\n" simple_expect "=1098 $any_time 6 0 7 0 2 { 1 9 6 2 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1099 90 12\n" simple_expect "%1099 14 12" # talk to Person 8 talk_to client 2 send "1100 90 12\n" simple_expect "%1100 14 12" # talk to Person 9 talk_to client 3 send "1101 90 12\n" simple_expect "=1101 $any_time 6 0 7 0 2 { 1 9 6 2 } 0 \\\*" # talk to Person 6 talk_to client 0 # Deleting text 12; deleter 6 send "1102 29 12\n" # talk to Person 9 talk_to client 3 simple_expect ":18 14 12 $any_time 6 0 7 0 2 { 1 9 6 2 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1102" # Creating text 13 by 6 send "1103 86 [holl "text 13"] 1 { 1 10 } 0 { }\n" # talk to Person 7 talk_to client 1 simple_expect ":18 15 13 $any_time 6 0 7 0 2 { 1 10 6 2 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1103 13" send "1104 90 13\n" simple_expect "=1104 $any_time 6 0 7 0 2 { 1 10 6 2 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1105 90 13\n" simple_expect "=1105 $any_time 6 0 7 0 2 { 1 10 6 2 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1106 90 13\n" simple_expect "=1106 $any_time 6 0 7 0 2 { 1 10 6 2 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1107 90 13\n" simple_expect "=1107 $any_time 6 0 7 0 2 { 1 10 6 2 } 0 \\\*" # talk to Person 6 talk_to client 0 # Deleting text 13; deleter 6 send "1108 29 13\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 13 $any_time 6 0 7 0 2 { 1 10 6 2 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1108" # Creating text 14 by 6 send "1109 86 [holl "text 14"] 1 { 1 11 } 0 { }\n" # talk to Person 7 talk_to client 1 simple_expect ":18 15 14 $any_time 6 0 7 0 2 { 1 11 6 2 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1109 14" send "1110 90 14\n" simple_expect "=1110 $any_time 6 0 7 0 2 { 1 11 6 2 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1111 90 14\n" simple_expect "=1111 $any_time 6 0 7 0 2 { 1 11 6 2 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1112 90 14\n" simple_expect "=1112 $any_time 6 0 7 0 2 { 1 11 6 2 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1113 90 14\n" simple_expect "%1113 14 14" # talk to Person 6 talk_to client 0 # Deleting text 14; deleter 6 send "1114 29 14\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 14 $any_time 6 0 7 0 2 { 1 11 6 2 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1114" # Creating text 15 by 6 send "1115 86 [holl "text 15"] 1 { 1 13 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 15 $any_time 6 0 7 0 2 { 1 13 6 2 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1115 15" send "1116 90 15\n" simple_expect "=1116 $any_time 6 0 7 0 2 { 1 13 6 2 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1117 90 15\n" simple_expect "=1117 $any_time 6 0 7 0 2 { 1 13 6 2 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1118 90 15\n" simple_expect "=1118 $any_time 6 0 7 0 2 { 1 13 6 2 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1119 90 15\n" simple_expect "=1119 $any_time 6 0 7 0 2 { 1 13 6 2 } 0 \\\*" # talk to Person 6 talk_to client 0 # Deleting text 15; deleter 6 send "1120 29 15\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 15 $any_time 6 0 7 0 2 { 1 13 6 2 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1120" # Creating text 16 by 6 send "1121 86 [holl "text 16"] 1 { 1 14 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 16 $any_time 6 0 7 0 2 { 1 14 6 2 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1121 16" send "1122 90 16\n" simple_expect "=1122 $any_time 6 0 7 0 2 { 1 14 6 2 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1123 90 16\n" simple_expect "=1123 $any_time 6 0 7 0 2 { 1 14 6 2 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1124 90 16\n" simple_expect "=1124 $any_time 6 0 7 0 2 { 1 14 6 2 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1125 90 16\n" simple_expect "=1125 $any_time 6 0 7 0 2 { 1 14 6 2 } 0 \\\*" # talk to Person 6 talk_to client 0 # Deleting text 16; deleter 6 send "1126 29 16\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 16 $any_time 6 0 7 0 2 { 1 14 6 2 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1126" # Creating text 17 by 6 send "1127 86 [holl "text 17"] 1 { 15 6 } 0 { }\n" simple_expect ":18 15 17 $any_time 6 0 7 0 2 { 15 6 6 3 } 0 \\\*" simple_expect "=1127 17" send "1128 90 17\n" simple_expect "=1128 $any_time 6 0 7 0 2 { 15 6 6 3 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1129 90 17\n" simple_expect "%1129 14 17" # talk to Person 8 talk_to client 2 send "1130 90 17\n" simple_expect "%1130 14 17" # talk to Person 9 talk_to client 3 send "1131 90 17\n" simple_expect "%1131 14 17" # talk to Person 6 talk_to client 0 # Deleting text 17; deleter 6 send "1132 29 17\n" simple_expect ":18 14 17 $any_time 6 0 7 0 2 { 15 6 6 3 } 0 \\\*" simple_expect "=1132" # Creating text 18 by 6 send "1133 86 [holl "text 18"] 1 { 15 7 } 0 { }\n" simple_expect "=1133 18" send "1134 90 18\n" simple_expect "=1134 $any_time 6 0 7 0 2 { 15 7 6 3 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1135 90 18\n" simple_expect "=1135 $any_time 6 0 7 0 2 { 15 7 6 3 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1136 90 18\n" simple_expect "%1136 14 18" # talk to Person 9 talk_to client 3 send "1137 90 18\n" simple_expect "%1137 14 18" # talk to Person 6 talk_to client 0 # Deleting text 18; deleter 6 send "1138 29 18\n" simple_expect "=1138" # Creating text 19 by 6 send "1139 86 [holl "text 19"] 1 { 15 8 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 19 $any_time 6 0 7 0 2 { 15 8 6 3 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1139 19" send "1140 90 19\n" simple_expect "=1140 $any_time 6 0 7 0 2 { 15 8 6 3 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1141 90 19\n" simple_expect "%1141 14 19" # talk to Person 8 talk_to client 2 send "1142 90 19\n" simple_expect "=1142 $any_time 6 0 7 0 2 { 15 8 6 3 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1143 90 19\n" simple_expect "%1143 14 19" # talk to Person 6 talk_to client 0 # Deleting text 19; deleter 6 send "1144 29 19\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 19 $any_time 6 0 7 0 2 { 15 8 6 3 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1144" # Creating text 20 by 6 send "1145 86 [holl "text 20"] 1 { 15 9 } 0 { }\n" # talk to Person 9 talk_to client 3 simple_expect ":18 15 20 $any_time 6 0 7 0 2 { 15 9 6 3 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1145 20" send "1146 90 20\n" simple_expect "=1146 $any_time 6 0 7 0 2 { 15 9 6 3 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1147 90 20\n" simple_expect "%1147 14 20" # talk to Person 8 talk_to client 2 send "1148 90 20\n" simple_expect "%1148 14 20" # talk to Person 9 talk_to client 3 send "1149 90 20\n" simple_expect "=1149 $any_time 6 0 7 0 2 { 15 9 6 3 } 0 \\\*" # talk to Person 6 talk_to client 0 # Deleting text 20; deleter 6 send "1150 29 20\n" # talk to Person 9 talk_to client 3 simple_expect ":18 14 20 $any_time 6 0 7 0 2 { 15 9 6 3 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1150" # Creating text 21 by 6 send "1151 86 [holl "text 21"] 1 { 15 10 } 0 { }\n" # talk to Person 7 talk_to client 1 simple_expect ":18 15 21 $any_time 6 0 7 0 2 { 15 10 6 3 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1151 21" send "1152 90 21\n" simple_expect "=1152 $any_time 6 0 7 0 2 { 15 10 6 3 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1153 90 21\n" simple_expect "=1153 $any_time 6 0 7 0 2 { 15 10 6 3 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1154 90 21\n" simple_expect "=1154 $any_time 6 0 7 0 2 { 15 10 6 3 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1155 90 21\n" simple_expect "=1155 $any_time 6 0 7 0 2 { 15 10 6 3 } 0 \\\*" # talk to Person 6 talk_to client 0 # Deleting text 21; deleter 6 send "1156 29 21\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 21 $any_time 6 0 7 0 2 { 15 10 6 3 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1156" # Creating text 22 by 6 send "1157 86 [holl "text 22"] 1 { 15 11 } 0 { }\n" # talk to Person 7 talk_to client 1 simple_expect ":18 15 22 $any_time 6 0 7 0 2 { 15 11 6 3 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1157 22" send "1158 90 22\n" simple_expect "=1158 $any_time 6 0 7 0 2 { 15 11 6 3 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1159 90 22\n" simple_expect "=1159 $any_time 6 0 7 0 2 { 15 11 6 3 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1160 90 22\n" simple_expect "=1160 $any_time 6 0 7 0 2 { 15 11 6 3 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1161 90 22\n" simple_expect "%1161 14 22" # talk to Person 6 talk_to client 0 # Deleting text 22; deleter 6 send "1162 29 22\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 22 $any_time 6 0 7 0 2 { 15 11 6 3 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1162" # Creating text 23 by 6 send "1163 86 [holl "text 23"] 1 { 15 13 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 23 $any_time 6 0 7 0 2 { 15 13 6 3 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1163 23" send "1164 90 23\n" simple_expect "=1164 $any_time 6 0 7 0 2 { 15 13 6 3 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1165 90 23\n" simple_expect "=1165 $any_time 6 0 7 0 2 { 15 13 6 3 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1166 90 23\n" simple_expect "=1166 $any_time 6 0 7 0 2 { 15 13 6 3 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1167 90 23\n" simple_expect "=1167 $any_time 6 0 7 0 2 { 15 13 6 3 } 0 \\\*" # talk to Person 6 talk_to client 0 # Deleting text 23; deleter 6 send "1168 29 23\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 23 $any_time 6 0 7 0 2 { 15 13 6 3 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1168" # Creating text 24 by 6 send "1169 86 [holl "text 24"] 1 { 15 14 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 24 $any_time 6 0 7 0 2 { 15 14 6 3 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1169 24" send "1170 90 24\n" simple_expect "=1170 $any_time 6 0 7 0 2 { 15 14 6 3 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1171 90 24\n" simple_expect "=1171 $any_time 6 0 7 0 2 { 15 14 6 3 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1172 90 24\n" simple_expect "=1172 $any_time 6 0 7 0 2 { 15 14 6 3 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1173 90 24\n" simple_expect "=1173 $any_time 6 0 7 0 2 { 15 14 6 3 } 0 \\\*" # talk to Person 6 talk_to client 0 # Deleting text 24; deleter 6 send "1174 29 24\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 24 $any_time 6 0 7 0 2 { 15 14 6 3 } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1174" # talk to Person 7 talk_to client 1 # Creating text 25 by 7 send "1175 86 [holl "text 25"] 1 { 0 6 } 0 { }\n" # talk to Person 6 talk_to client 0 simple_expect ":18 15 25 $any_time 7 0 7 0 2 { 0 6 6 4 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1175 25" # talk to Person 6 talk_to client 0 send "1176 90 25\n" simple_expect "=1176 $any_time 7 0 7 0 2 { 0 6 6 4 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1177 90 25\n" simple_expect "=1177 $any_time 7 0 7 0 2 { 0 6 6 4 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1178 90 25\n" simple_expect "%1178 14 25" # talk to Person 9 talk_to client 3 send "1179 90 25\n" simple_expect "%1179 14 25" # talk to Person 7 talk_to client 1 # Deleting text 25; deleter 7 send "1180 29 25\n" # talk to Person 6 talk_to client 0 simple_expect ":18 14 25 $any_time 7 0 7 0 2 { 0 6 6 4 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1180" # Creating text 26 by 7 send "1181 86 [holl "text 26"] 1 { 0 7 } 0 { }\n" simple_expect "=1181 26" # talk to Person 6 talk_to client 0 send "1182 90 26\n" simple_expect "%1182 14 26" # talk to Person 7 talk_to client 1 send "1183 90 26\n" simple_expect "=1183 $any_time 7 0 7 0 2 { 0 7 6 4 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1184 90 26\n" simple_expect "%1184 14 26" # talk to Person 9 talk_to client 3 send "1185 90 26\n" simple_expect "%1185 14 26" # talk to Person 7 talk_to client 1 # Deleting text 26; deleter 7 send "1186 29 26\n" simple_expect "=1186" # Creating text 27 by 7 send "1187 86 [holl "text 27"] 1 { 0 8 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 27 $any_time 7 0 7 0 2 { 0 8 6 4 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1187 27" # talk to Person 6 talk_to client 0 send "1188 90 27\n" simple_expect "%1188 14 27" # talk to Person 7 talk_to client 1 send "1189 90 27\n" simple_expect "=1189 $any_time 7 0 7 0 2 { 0 8 6 4 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1190 90 27\n" simple_expect "=1190 $any_time 7 0 7 0 2 { 0 8 6 4 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1191 90 27\n" simple_expect "%1191 14 27" # talk to Person 7 talk_to client 1 # Deleting text 27; deleter 7 send "1192 29 27\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 27 $any_time 7 0 7 0 2 { 0 8 6 4 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1192" # Creating text 28 by 7 send "1193 86 [holl "text 28"] 1 { 0 9 } 0 { }\n" # talk to Person 9 talk_to client 3 simple_expect ":18 15 28 $any_time 7 0 7 0 2 { 0 9 6 4 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1193 28" # talk to Person 6 talk_to client 0 send "1194 90 28\n" simple_expect "%1194 14 28" # talk to Person 7 talk_to client 1 send "1195 90 28\n" simple_expect "=1195 $any_time 7 0 7 0 2 { 0 9 6 4 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1196 90 28\n" simple_expect "%1196 14 28" # talk to Person 9 talk_to client 3 send "1197 90 28\n" simple_expect "=1197 $any_time 7 0 7 0 2 { 0 9 6 4 } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 28; deleter 7 send "1198 29 28\n" # talk to Person 9 talk_to client 3 simple_expect ":18 14 28 $any_time 7 0 7 0 2 { 0 9 6 4 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1198" # Creating text 29 by 7 send "1199 86 [holl "text 29"] 1 { 0 10 } 0 { }\n" simple_expect ":18 15 29 $any_time 7 0 7 0 2 { 0 10 6 4 } 0 \\\*" simple_expect "=1199 29" # talk to Person 6 talk_to client 0 send "1200 90 29\n" simple_expect "=1200 $any_time 7 0 7 0 2 { 0 10 6 4 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1201 90 29\n" simple_expect "=1201 $any_time 7 0 7 0 2 { 0 10 6 4 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1202 90 29\n" simple_expect "=1202 $any_time 7 0 7 0 2 { 0 10 6 4 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1203 90 29\n" simple_expect "=1203 $any_time 7 0 7 0 2 { 0 10 6 4 } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 29; deleter 7 send "1204 29 29\n" simple_expect ":18 14 29 $any_time 7 0 7 0 2 { 0 10 6 4 } 0 \\\*" simple_expect "=1204" # Creating text 30 by 7 send "1205 86 [holl "text 30"] 1 { 0 11 } 0 { }\n" simple_expect ":18 15 30 $any_time 7 0 7 0 2 { 0 11 6 4 } 0 \\\*" simple_expect "=1205 30" # talk to Person 6 talk_to client 0 send "1206 90 30\n" simple_expect "%1206 14 30" # talk to Person 7 talk_to client 1 send "1207 90 30\n" simple_expect "=1207 $any_time 7 0 7 0 2 { 0 11 6 4 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1208 90 30\n" simple_expect "=1208 $any_time 7 0 7 0 2 { 0 11 6 4 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1209 90 30\n" simple_expect "%1209 14 30" # talk to Person 7 talk_to client 1 # Deleting text 30; deleter 7 send "1210 29 30\n" simple_expect ":18 14 30 $any_time 7 0 7 0 2 { 0 11 6 4 } 0 \\\*" simple_expect "=1210" # Creating text 31 by 7 send "1211 86 [holl "text 31"] 1 { 0 12 } 0 { }\n" simple_expect ":18 15 31 $any_time 7 0 7 0 2 { 0 12 6 1 } 0 \\\*" simple_expect "=1211 31" # talk to Person 6 talk_to client 0 send "1212 90 31\n" simple_expect "%1212 14 31" # talk to Person 7 talk_to client 1 send "1213 90 31\n" simple_expect "=1213 $any_time 7 0 7 0 2 { 0 12 6 1 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1214 90 31\n" simple_expect "=1214 $any_time 7 0 7 0 2 { 0 12 6 1 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1215 90 31\n" simple_expect "%1215 14 31" # talk to Person 7 talk_to client 1 # Deleting text 31; deleter 7 send "1216 29 31\n" simple_expect ":18 14 31 $any_time 7 0 7 0 2 { 0 12 6 1 } 0 \\\*" simple_expect "=1216" # Creating text 32 by 7 send "1217 86 [holl "text 32"] 1 { 0 13 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 32 $any_time 7 0 7 0 2 { 0 13 6 4 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1217 32" # talk to Person 6 talk_to client 0 send "1218 90 32\n" simple_expect "=1218 $any_time 7 0 7 0 2 { 0 13 6 4 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1219 90 32\n" simple_expect "=1219 $any_time 7 0 7 0 2 { 0 13 6 4 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1220 90 32\n" simple_expect "=1220 $any_time 7 0 7 0 2 { 0 13 6 4 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1221 90 32\n" simple_expect "=1221 $any_time 7 0 7 0 2 { 0 13 6 4 } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 32; deleter 7 send "1222 29 32\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 32 $any_time 7 0 7 0 2 { 0 13 6 4 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1222" # Creating text 33 by 7 send "1223 86 [holl "text 33"] 1 { 0 14 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 33 $any_time 7 0 7 0 2 { 0 14 6 4 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1223 33" # talk to Person 6 talk_to client 0 send "1224 90 33\n" simple_expect "%1224 14 33" # talk to Person 7 talk_to client 1 send "1225 90 33\n" simple_expect "=1225 $any_time 7 0 7 0 2 { 0 14 6 4 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1226 90 33\n" simple_expect "=1226 $any_time 7 0 7 0 2 { 0 14 6 4 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1227 90 33\n" simple_expect "=1227 $any_time 7 0 7 0 2 { 0 14 6 4 } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 33; deleter 7 send "1228 29 33\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 33 $any_time 7 0 7 0 2 { 0 14 6 4 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1228" # Creating text 34 by 7 send "1229 86 [holl "text 34"] 1 { 0 15 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 34 $any_time 7 0 7 0 2 { 0 15 6 1 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1229 34" # talk to Person 6 talk_to client 0 send "1230 90 34\n" simple_expect "%1230 14 34" # talk to Person 7 talk_to client 1 send "1231 90 34\n" simple_expect "=1231 $any_time 7 0 7 0 2 { 0 15 6 1 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1232 90 34\n" simple_expect "=1232 $any_time 7 0 7 0 2 { 0 15 6 1 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1233 90 34\n" simple_expect "=1233 $any_time 7 0 7 0 2 { 0 15 6 1 } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 34; deleter 7 send "1234 29 34\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 34 $any_time 7 0 7 0 2 { 0 15 6 1 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1234" # Creating text 35 by 7 send "1235 86 [holl "text 35"] 1 { 1 6 } 0 { }\n" # talk to Person 6 talk_to client 0 simple_expect ":18 15 35 $any_time 7 0 7 0 2 { 1 6 6 5 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1235 35" # talk to Person 6 talk_to client 0 send "1236 90 35\n" simple_expect "=1236 $any_time 7 0 7 0 2 { 1 6 6 5 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1237 90 35\n" simple_expect "=1237 $any_time 7 0 7 0 2 { 1 6 6 5 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1238 90 35\n" simple_expect "%1238 14 35" # talk to Person 9 talk_to client 3 send "1239 90 35\n" simple_expect "%1239 14 35" # talk to Person 7 talk_to client 1 # Deleting text 35; deleter 7 send "1240 29 35\n" # talk to Person 6 talk_to client 0 simple_expect ":18 14 35 $any_time 7 0 7 0 2 { 1 6 6 5 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1240" # Creating text 36 by 7 send "1241 86 [holl "text 36"] 1 { 1 7 } 0 { }\n" simple_expect "=1241 36" # talk to Person 6 talk_to client 0 send "1242 90 36\n" simple_expect "%1242 14 36" # talk to Person 7 talk_to client 1 send "1243 90 36\n" simple_expect "=1243 $any_time 7 0 7 0 2 { 1 7 6 5 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1244 90 36\n" simple_expect "%1244 14 36" # talk to Person 9 talk_to client 3 send "1245 90 36\n" simple_expect "%1245 14 36" # talk to Person 7 talk_to client 1 # Deleting text 36; deleter 7 send "1246 29 36\n" simple_expect "=1246" # Creating text 37 by 7 send "1247 86 [holl "text 37"] 1 { 1 8 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 37 $any_time 7 0 7 0 2 { 1 8 6 5 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1247 37" # talk to Person 6 talk_to client 0 send "1248 90 37\n" simple_expect "%1248 14 37" # talk to Person 7 talk_to client 1 send "1249 90 37\n" simple_expect "=1249 $any_time 7 0 7 0 2 { 1 8 6 5 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1250 90 37\n" simple_expect "=1250 $any_time 7 0 7 0 2 { 1 8 6 5 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1251 90 37\n" simple_expect "%1251 14 37" # talk to Person 7 talk_to client 1 # Deleting text 37; deleter 7 send "1252 29 37\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 37 $any_time 7 0 7 0 2 { 1 8 6 5 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1252" # Creating text 38 by 7 send "1253 86 [holl "text 38"] 1 { 1 9 } 0 { }\n" # talk to Person 9 talk_to client 3 simple_expect ":18 15 38 $any_time 7 0 7 0 2 { 1 9 6 5 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1253 38" # talk to Person 6 talk_to client 0 send "1254 90 38\n" simple_expect "%1254 14 38" # talk to Person 7 talk_to client 1 send "1255 90 38\n" simple_expect "=1255 $any_time 7 0 7 0 2 { 1 9 6 5 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1256 90 38\n" simple_expect "%1256 14 38" # talk to Person 9 talk_to client 3 send "1257 90 38\n" simple_expect "=1257 $any_time 7 0 7 0 2 { 1 9 6 5 } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 38; deleter 7 send "1258 29 38\n" # talk to Person 9 talk_to client 3 simple_expect ":18 14 38 $any_time 7 0 7 0 2 { 1 9 6 5 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1258" # Creating text 39 by 7 send "1259 86 [holl "text 39"] 1 { 1 10 } 0 { }\n" simple_expect ":18 15 39 $any_time 7 0 7 0 2 { 1 10 6 5 } 0 \\\*" simple_expect "=1259 39" # talk to Person 6 talk_to client 0 send "1260 90 39\n" simple_expect "=1260 $any_time 7 0 7 0 2 { 1 10 6 5 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1261 90 39\n" simple_expect "=1261 $any_time 7 0 7 0 2 { 1 10 6 5 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1262 90 39\n" simple_expect "=1262 $any_time 7 0 7 0 2 { 1 10 6 5 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1263 90 39\n" simple_expect "=1263 $any_time 7 0 7 0 2 { 1 10 6 5 } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 39; deleter 7 send "1264 29 39\n" simple_expect ":18 14 39 $any_time 7 0 7 0 2 { 1 10 6 5 } 0 \\\*" simple_expect "=1264" # Creating text 40 by 7 send "1265 86 [holl "text 40"] 1 { 1 11 } 0 { }\n" simple_expect ":18 15 40 $any_time 7 0 7 0 2 { 1 11 6 5 } 0 \\\*" simple_expect "=1265 40" # talk to Person 6 talk_to client 0 send "1266 90 40\n" simple_expect "%1266 14 40" # talk to Person 7 talk_to client 1 send "1267 90 40\n" simple_expect "=1267 $any_time 7 0 7 0 2 { 1 11 6 5 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1268 90 40\n" simple_expect "=1268 $any_time 7 0 7 0 2 { 1 11 6 5 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1269 90 40\n" simple_expect "%1269 14 40" # talk to Person 7 talk_to client 1 # Deleting text 40; deleter 7 send "1270 29 40\n" simple_expect ":18 14 40 $any_time 7 0 7 0 2 { 1 11 6 5 } 0 \\\*" simple_expect "=1270" # Creating text 41 by 7 send "1271 86 [holl "text 41"] 1 { 1 12 } 0 { }\n" simple_expect ":18 15 41 $any_time 7 0 7 0 2 { 1 12 6 2 } 0 \\\*" simple_expect "=1271 41" # talk to Person 6 talk_to client 0 send "1272 90 41\n" simple_expect "%1272 14 41" # talk to Person 7 talk_to client 1 send "1273 90 41\n" simple_expect "=1273 $any_time 7 0 7 0 2 { 1 12 6 2 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1274 90 41\n" simple_expect "=1274 $any_time 7 0 7 0 2 { 1 12 6 2 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1275 90 41\n" simple_expect "%1275 14 41" # talk to Person 7 talk_to client 1 # Deleting text 41; deleter 7 send "1276 29 41\n" simple_expect ":18 14 41 $any_time 7 0 7 0 2 { 1 12 6 2 } 0 \\\*" simple_expect "=1276" # Creating text 42 by 7 send "1277 86 [holl "text 42"] 1 { 1 13 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 42 $any_time 7 0 7 0 2 { 1 13 6 5 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1277 42" # talk to Person 6 talk_to client 0 send "1278 90 42\n" simple_expect "=1278 $any_time 7 0 7 0 2 { 1 13 6 5 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1279 90 42\n" simple_expect "=1279 $any_time 7 0 7 0 2 { 1 13 6 5 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1280 90 42\n" simple_expect "=1280 $any_time 7 0 7 0 2 { 1 13 6 5 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1281 90 42\n" simple_expect "=1281 $any_time 7 0 7 0 2 { 1 13 6 5 } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 42; deleter 7 send "1282 29 42\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 42 $any_time 7 0 7 0 2 { 1 13 6 5 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1282" # Creating text 43 by 7 send "1283 86 [holl "text 43"] 1 { 1 14 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 43 $any_time 7 0 7 0 2 { 1 14 6 5 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1283 43" # talk to Person 6 talk_to client 0 send "1284 90 43\n" simple_expect "%1284 14 43" # talk to Person 7 talk_to client 1 send "1285 90 43\n" simple_expect "=1285 $any_time 7 0 7 0 2 { 1 14 6 5 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1286 90 43\n" simple_expect "=1286 $any_time 7 0 7 0 2 { 1 14 6 5 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1287 90 43\n" simple_expect "=1287 $any_time 7 0 7 0 2 { 1 14 6 5 } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 43; deleter 7 send "1288 29 43\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 43 $any_time 7 0 7 0 2 { 1 14 6 5 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1288" # Creating text 44 by 7 send "1289 86 [holl "text 44"] 1 { 1 15 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 44 $any_time 7 0 7 0 2 { 1 15 6 2 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1289 44" # talk to Person 6 talk_to client 0 send "1290 90 44\n" simple_expect "%1290 14 44" # talk to Person 7 talk_to client 1 send "1291 90 44\n" simple_expect "=1291 $any_time 7 0 7 0 2 { 1 15 6 2 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1292 90 44\n" simple_expect "=1292 $any_time 7 0 7 0 2 { 1 15 6 2 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1293 90 44\n" simple_expect "=1293 $any_time 7 0 7 0 2 { 1 15 6 2 } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 44; deleter 7 send "1294 29 44\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 44 $any_time 7 0 7 0 2 { 1 15 6 2 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1294" # Creating text 45 by 7 send "1295 86 [holl "text 45"] 1 { 15 6 } 0 { }\n" # talk to Person 6 talk_to client 0 simple_expect ":18 15 45 $any_time 7 0 7 0 2 { 15 6 6 6 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1295 45" # talk to Person 6 talk_to client 0 send "1296 90 45\n" simple_expect "=1296 $any_time 7 0 7 0 2 { 15 6 6 6 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1297 90 45\n" simple_expect "=1297 $any_time 7 0 7 0 2 { 15 6 6 6 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1298 90 45\n" simple_expect "%1298 14 45" # talk to Person 9 talk_to client 3 send "1299 90 45\n" simple_expect "%1299 14 45" # talk to Person 7 talk_to client 1 # Deleting text 45; deleter 7 send "1300 29 45\n" # talk to Person 6 talk_to client 0 simple_expect ":18 14 45 $any_time 7 0 7 0 2 { 15 6 6 6 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1300" # Creating text 46 by 7 send "1301 86 [holl "text 46"] 1 { 15 7 } 0 { }\n" simple_expect "=1301 46" # talk to Person 6 talk_to client 0 send "1302 90 46\n" simple_expect "%1302 14 46" # talk to Person 7 talk_to client 1 send "1303 90 46\n" simple_expect "=1303 $any_time 7 0 7 0 2 { 15 7 6 6 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1304 90 46\n" simple_expect "%1304 14 46" # talk to Person 9 talk_to client 3 send "1305 90 46\n" simple_expect "%1305 14 46" # talk to Person 7 talk_to client 1 # Deleting text 46; deleter 7 send "1306 29 46\n" simple_expect "=1306" # Creating text 47 by 7 send "1307 86 [holl "text 47"] 1 { 15 8 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 47 $any_time 7 0 7 0 2 { 15 8 6 6 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1307 47" # talk to Person 6 talk_to client 0 send "1308 90 47\n" simple_expect "%1308 14 47" # talk to Person 7 talk_to client 1 send "1309 90 47\n" simple_expect "=1309 $any_time 7 0 7 0 2 { 15 8 6 6 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1310 90 47\n" simple_expect "=1310 $any_time 7 0 7 0 2 { 15 8 6 6 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1311 90 47\n" simple_expect "%1311 14 47" # talk to Person 7 talk_to client 1 # Deleting text 47; deleter 7 send "1312 29 47\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 47 $any_time 7 0 7 0 2 { 15 8 6 6 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1312" # Creating text 48 by 7 send "1313 86 [holl "text 48"] 1 { 15 9 } 0 { }\n" # talk to Person 9 talk_to client 3 simple_expect ":18 15 48 $any_time 7 0 7 0 2 { 15 9 6 6 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1313 48" # talk to Person 6 talk_to client 0 send "1314 90 48\n" simple_expect "%1314 14 48" # talk to Person 7 talk_to client 1 send "1315 90 48\n" simple_expect "=1315 $any_time 7 0 7 0 2 { 15 9 6 6 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1316 90 48\n" simple_expect "%1316 14 48" # talk to Person 9 talk_to client 3 send "1317 90 48\n" simple_expect "=1317 $any_time 7 0 7 0 2 { 15 9 6 6 } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 48; deleter 7 send "1318 29 48\n" # talk to Person 9 talk_to client 3 simple_expect ":18 14 48 $any_time 7 0 7 0 2 { 15 9 6 6 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1318" # Creating text 49 by 7 send "1319 86 [holl "text 49"] 1 { 15 10 } 0 { }\n" simple_expect ":18 15 49 $any_time 7 0 7 0 2 { 15 10 6 6 } 0 \\\*" simple_expect "=1319 49" # talk to Person 6 talk_to client 0 send "1320 90 49\n" simple_expect "=1320 $any_time 7 0 7 0 2 { 15 10 6 6 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1321 90 49\n" simple_expect "=1321 $any_time 7 0 7 0 2 { 15 10 6 6 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1322 90 49\n" simple_expect "=1322 $any_time 7 0 7 0 2 { 15 10 6 6 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1323 90 49\n" simple_expect "=1323 $any_time 7 0 7 0 2 { 15 10 6 6 } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 49; deleter 7 send "1324 29 49\n" simple_expect ":18 14 49 $any_time 7 0 7 0 2 { 15 10 6 6 } 0 \\\*" simple_expect "=1324" # Creating text 50 by 7 send "1325 86 [holl "text 50"] 1 { 15 11 } 0 { }\n" simple_expect ":18 15 50 $any_time 7 0 7 0 2 { 15 11 6 6 } 0 \\\*" simple_expect "=1325 50" # talk to Person 6 talk_to client 0 send "1326 90 50\n" simple_expect "%1326 14 50" # talk to Person 7 talk_to client 1 send "1327 90 50\n" simple_expect "=1327 $any_time 7 0 7 0 2 { 15 11 6 6 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1328 90 50\n" simple_expect "=1328 $any_time 7 0 7 0 2 { 15 11 6 6 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1329 90 50\n" simple_expect "%1329 14 50" # talk to Person 7 talk_to client 1 # Deleting text 50; deleter 7 send "1330 29 50\n" simple_expect ":18 14 50 $any_time 7 0 7 0 2 { 15 11 6 6 } 0 \\\*" simple_expect "=1330" # Creating text 51 by 7 send "1331 86 [holl "text 51"] 1 { 15 12 } 0 { }\n" simple_expect ":18 15 51 $any_time 7 0 7 0 2 { 15 12 6 3 } 0 \\\*" simple_expect "=1331 51" # talk to Person 6 talk_to client 0 send "1332 90 51\n" simple_expect "%1332 14 51" # talk to Person 7 talk_to client 1 send "1333 90 51\n" simple_expect "=1333 $any_time 7 0 7 0 2 { 15 12 6 3 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1334 90 51\n" simple_expect "=1334 $any_time 7 0 7 0 2 { 15 12 6 3 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1335 90 51\n" simple_expect "%1335 14 51" # talk to Person 7 talk_to client 1 # Deleting text 51; deleter 7 send "1336 29 51\n" simple_expect ":18 14 51 $any_time 7 0 7 0 2 { 15 12 6 3 } 0 \\\*" simple_expect "=1336" # Creating text 52 by 7 send "1337 86 [holl "text 52"] 1 { 15 13 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 52 $any_time 7 0 7 0 2 { 15 13 6 6 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1337 52" # talk to Person 6 talk_to client 0 send "1338 90 52\n" simple_expect "=1338 $any_time 7 0 7 0 2 { 15 13 6 6 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1339 90 52\n" simple_expect "=1339 $any_time 7 0 7 0 2 { 15 13 6 6 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1340 90 52\n" simple_expect "=1340 $any_time 7 0 7 0 2 { 15 13 6 6 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1341 90 52\n" simple_expect "=1341 $any_time 7 0 7 0 2 { 15 13 6 6 } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 52; deleter 7 send "1342 29 52\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 52 $any_time 7 0 7 0 2 { 15 13 6 6 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1342" # Creating text 53 by 7 send "1343 86 [holl "text 53"] 1 { 15 14 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 53 $any_time 7 0 7 0 2 { 15 14 6 6 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1343 53" # talk to Person 6 talk_to client 0 send "1344 90 53\n" simple_expect "%1344 14 53" # talk to Person 7 talk_to client 1 send "1345 90 53\n" simple_expect "=1345 $any_time 7 0 7 0 2 { 15 14 6 6 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1346 90 53\n" simple_expect "=1346 $any_time 7 0 7 0 2 { 15 14 6 6 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1347 90 53\n" simple_expect "=1347 $any_time 7 0 7 0 2 { 15 14 6 6 } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 53; deleter 7 send "1348 29 53\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 53 $any_time 7 0 7 0 2 { 15 14 6 6 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1348" # Creating text 54 by 7 send "1349 86 [holl "text 54"] 1 { 15 15 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 54 $any_time 7 0 7 0 2 { 15 15 6 3 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1349 54" # talk to Person 6 talk_to client 0 send "1350 90 54\n" simple_expect "%1350 14 54" # talk to Person 7 talk_to client 1 send "1351 90 54\n" simple_expect "=1351 $any_time 7 0 7 0 2 { 15 15 6 3 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1352 90 54\n" simple_expect "=1352 $any_time 7 0 7 0 2 { 15 15 6 3 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1353 90 54\n" simple_expect "=1353 $any_time 7 0 7 0 2 { 15 15 6 3 } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 54; deleter 7 send "1354 29 54\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 54 $any_time 7 0 7 0 2 { 15 15 6 3 } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1354" # talk to Person 8 talk_to client 2 # Creating text 55 by 8 send "1355 86 [holl "text 55"] 1 { 0 6 } 0 { }\n" # talk to Person 6 talk_to client 0 simple_expect ":18 15 55 $any_time 8 0 7 0 2 { 0 6 6 7 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1355 55" # talk to Person 6 talk_to client 0 send "1356 90 55\n" simple_expect "=1356 $any_time 8 0 7 0 2 { 0 6 6 7 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1357 90 55\n" simple_expect "%1357 14 55" # talk to Person 8 talk_to client 2 send "1358 90 55\n" simple_expect "=1358 $any_time 8 0 7 0 2 { 0 6 6 7 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1359 90 55\n" simple_expect "%1359 14 55" # talk to Person 8 talk_to client 2 # Deleting text 55; deleter 8 send "1360 29 55\n" # talk to Person 6 talk_to client 0 simple_expect ":18 14 55 $any_time 8 0 7 0 2 { 0 6 6 7 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1360" # Creating text 56 by 8 send "1361 86 [holl "text 56"] 1 { 0 7 } 0 { }\n" simple_expect "=1361 56" # talk to Person 6 talk_to client 0 send "1362 90 56\n" simple_expect "%1362 14 56" # talk to Person 7 talk_to client 1 send "1363 90 56\n" simple_expect "=1363 $any_time 8 0 7 0 2 { 0 7 6 7 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1364 90 56\n" simple_expect "=1364 $any_time 8 0 7 0 2 { 0 7 6 7 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1365 90 56\n" simple_expect "%1365 14 56" # talk to Person 8 talk_to client 2 # Deleting text 56; deleter 8 send "1366 29 56\n" simple_expect "=1366" # Creating text 57 by 8 send "1367 86 [holl "text 57"] 1 { 0 8 } 0 { }\n" simple_expect ":18 15 57 $any_time 8 0 7 0 2 { 0 8 6 7 } 0 \\\*" simple_expect "=1367 57" # talk to Person 6 talk_to client 0 send "1368 90 57\n" simple_expect "%1368 14 57" # talk to Person 7 talk_to client 1 send "1369 90 57\n" simple_expect "%1369 14 57" # talk to Person 8 talk_to client 2 send "1370 90 57\n" simple_expect "=1370 $any_time 8 0 7 0 2 { 0 8 6 7 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1371 90 57\n" simple_expect "%1371 14 57" # talk to Person 8 talk_to client 2 # Deleting text 57; deleter 8 send "1372 29 57\n" simple_expect ":18 14 57 $any_time 8 0 7 0 2 { 0 8 6 7 } 0 \\\*" simple_expect "=1372" # Creating text 58 by 8 send "1373 86 [holl "text 58"] 1 { 0 9 } 0 { }\n" # talk to Person 9 talk_to client 3 simple_expect ":18 15 58 $any_time 8 0 7 0 2 { 0 9 6 7 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1373 58" # talk to Person 6 talk_to client 0 send "1374 90 58\n" simple_expect "%1374 14 58" # talk to Person 7 talk_to client 1 send "1375 90 58\n" simple_expect "%1375 14 58" # talk to Person 8 talk_to client 2 send "1376 90 58\n" simple_expect "=1376 $any_time 8 0 7 0 2 { 0 9 6 7 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1377 90 58\n" simple_expect "=1377 $any_time 8 0 7 0 2 { 0 9 6 7 } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 58; deleter 8 send "1378 29 58\n" # talk to Person 9 talk_to client 3 simple_expect ":18 14 58 $any_time 8 0 7 0 2 { 0 9 6 7 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1378" # Creating text 59 by 8 send "1379 86 [holl "text 59"] 1 { 0 10 } 0 { }\n" # talk to Person 7 talk_to client 1 simple_expect ":18 15 59 $any_time 8 0 7 0 2 { 0 10 6 7 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1379 59" # talk to Person 6 talk_to client 0 send "1380 90 59\n" simple_expect "=1380 $any_time 8 0 7 0 2 { 0 10 6 7 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1381 90 59\n" simple_expect "=1381 $any_time 8 0 7 0 2 { 0 10 6 7 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1382 90 59\n" simple_expect "=1382 $any_time 8 0 7 0 2 { 0 10 6 7 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1383 90 59\n" simple_expect "=1383 $any_time 8 0 7 0 2 { 0 10 6 7 } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 59; deleter 8 send "1384 29 59\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 59 $any_time 8 0 7 0 2 { 0 10 6 7 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1384" # Creating text 60 by 8 send "1385 86 [holl "text 60"] 1 { 0 11 } 0 { }\n" # talk to Person 7 talk_to client 1 simple_expect ":18 15 60 $any_time 8 0 7 0 2 { 0 11 6 7 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1385 60" # talk to Person 6 talk_to client 0 send "1386 90 60\n" simple_expect "%1386 14 60" # talk to Person 7 talk_to client 1 send "1387 90 60\n" simple_expect "=1387 $any_time 8 0 7 0 2 { 0 11 6 7 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1388 90 60\n" simple_expect "=1388 $any_time 8 0 7 0 2 { 0 11 6 7 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1389 90 60\n" simple_expect "%1389 14 60" # talk to Person 8 talk_to client 2 # Deleting text 60; deleter 8 send "1390 29 60\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 60 $any_time 8 0 7 0 2 { 0 11 6 7 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1390" # Creating text 61 by 8 send "1391 86 [holl "text 61"] 1 { 0 12 } 0 { }\n" # talk to Person 7 talk_to client 1 simple_expect ":18 15 61 $any_time 8 0 7 0 2 { 0 12 6 4 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1391 61" # talk to Person 6 talk_to client 0 send "1392 90 61\n" simple_expect "%1392 14 61" # talk to Person 7 talk_to client 1 send "1393 90 61\n" simple_expect "=1393 $any_time 8 0 7 0 2 { 0 12 6 4 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1394 90 61\n" simple_expect "=1394 $any_time 8 0 7 0 2 { 0 12 6 4 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1395 90 61\n" simple_expect "%1395 14 61" # talk to Person 8 talk_to client 2 # Deleting text 61; deleter 8 send "1396 29 61\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 61 $any_time 8 0 7 0 2 { 0 12 6 4 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1396" # Creating text 62 by 8 send "1397 86 [holl "text 62"] 1 { 0 13 } 0 { }\n" simple_expect ":18 15 62 $any_time 8 0 7 0 2 { 0 13 6 7 } 0 \\\*" simple_expect "=1397 62" # talk to Person 6 talk_to client 0 send "1398 90 62\n" simple_expect "=1398 $any_time 8 0 7 0 2 { 0 13 6 7 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1399 90 62\n" simple_expect "=1399 $any_time 8 0 7 0 2 { 0 13 6 7 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1400 90 62\n" simple_expect "=1400 $any_time 8 0 7 0 2 { 0 13 6 7 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1401 90 62\n" simple_expect "=1401 $any_time 8 0 7 0 2 { 0 13 6 7 } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 62; deleter 8 send "1402 29 62\n" simple_expect ":18 14 62 $any_time 8 0 7 0 2 { 0 13 6 7 } 0 \\\*" simple_expect "=1402" # Creating text 63 by 8 send "1403 86 [holl "text 63"] 1 { 0 14 } 0 { }\n" simple_expect ":18 15 63 $any_time 8 0 7 0 2 { 0 14 6 7 } 0 \\\*" simple_expect "=1403 63" # talk to Person 6 talk_to client 0 send "1404 90 63\n" simple_expect "%1404 14 63" # talk to Person 7 talk_to client 1 send "1405 90 63\n" simple_expect "=1405 $any_time 8 0 7 0 2 { 0 14 6 7 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1406 90 63\n" simple_expect "=1406 $any_time 8 0 7 0 2 { 0 14 6 7 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1407 90 63\n" simple_expect "=1407 $any_time 8 0 7 0 2 { 0 14 6 7 } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 63; deleter 8 send "1408 29 63\n" simple_expect ":18 14 63 $any_time 8 0 7 0 2 { 0 14 6 7 } 0 \\\*" simple_expect "=1408" # Creating text 64 by 8 send "1409 86 [holl "text 64"] 1 { 0 15 } 0 { }\n" simple_expect ":18 15 64 $any_time 8 0 7 0 2 { 0 15 6 4 } 0 \\\*" simple_expect "=1409 64" # talk to Person 6 talk_to client 0 send "1410 90 64\n" simple_expect "%1410 14 64" # talk to Person 7 talk_to client 1 send "1411 90 64\n" simple_expect "=1411 $any_time 8 0 7 0 2 { 0 15 6 4 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1412 90 64\n" simple_expect "=1412 $any_time 8 0 7 0 2 { 0 15 6 4 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1413 90 64\n" simple_expect "=1413 $any_time 8 0 7 0 2 { 0 15 6 4 } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 64; deleter 8 send "1414 29 64\n" simple_expect ":18 14 64 $any_time 8 0 7 0 2 { 0 15 6 4 } 0 \\\*" simple_expect "=1414" # Creating text 65 by 8 send "1415 86 [holl "text 65"] 1 { 1 6 } 0 { }\n" # talk to Person 6 talk_to client 0 simple_expect ":18 15 65 $any_time 8 0 7 0 2 { 1 6 6 8 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1415 65" # talk to Person 6 talk_to client 0 send "1416 90 65\n" simple_expect "=1416 $any_time 8 0 7 0 2 { 1 6 6 8 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1417 90 65\n" simple_expect "%1417 14 65" # talk to Person 8 talk_to client 2 send "1418 90 65\n" simple_expect "=1418 $any_time 8 0 7 0 2 { 1 6 6 8 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1419 90 65\n" simple_expect "%1419 14 65" # talk to Person 8 talk_to client 2 # Deleting text 65; deleter 8 send "1420 29 65\n" # talk to Person 6 talk_to client 0 simple_expect ":18 14 65 $any_time 8 0 7 0 2 { 1 6 6 8 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1420" # Creating text 66 by 8 send "1421 86 [holl "text 66"] 1 { 1 7 } 0 { }\n" simple_expect "=1421 66" # talk to Person 6 talk_to client 0 send "1422 90 66\n" simple_expect "%1422 14 66" # talk to Person 7 talk_to client 1 send "1423 90 66\n" simple_expect "=1423 $any_time 8 0 7 0 2 { 1 7 6 8 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1424 90 66\n" simple_expect "=1424 $any_time 8 0 7 0 2 { 1 7 6 8 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1425 90 66\n" simple_expect "%1425 14 66" # talk to Person 8 talk_to client 2 # Deleting text 66; deleter 8 send "1426 29 66\n" simple_expect "=1426" # Creating text 67 by 8 send "1427 86 [holl "text 67"] 1 { 1 8 } 0 { }\n" simple_expect ":18 15 67 $any_time 8 0 7 0 2 { 1 8 6 8 } 0 \\\*" simple_expect "=1427 67" # talk to Person 6 talk_to client 0 send "1428 90 67\n" simple_expect "%1428 14 67" # talk to Person 7 talk_to client 1 send "1429 90 67\n" simple_expect "%1429 14 67" # talk to Person 8 talk_to client 2 send "1430 90 67\n" simple_expect "=1430 $any_time 8 0 7 0 2 { 1 8 6 8 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1431 90 67\n" simple_expect "%1431 14 67" # talk to Person 8 talk_to client 2 # Deleting text 67; deleter 8 send "1432 29 67\n" simple_expect ":18 14 67 $any_time 8 0 7 0 2 { 1 8 6 8 } 0 \\\*" simple_expect "=1432" # Creating text 68 by 8 send "1433 86 [holl "text 68"] 1 { 1 9 } 0 { }\n" # talk to Person 9 talk_to client 3 simple_expect ":18 15 68 $any_time 8 0 7 0 2 { 1 9 6 8 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1433 68" # talk to Person 6 talk_to client 0 send "1434 90 68\n" simple_expect "%1434 14 68" # talk to Person 7 talk_to client 1 send "1435 90 68\n" simple_expect "%1435 14 68" # talk to Person 8 talk_to client 2 send "1436 90 68\n" simple_expect "=1436 $any_time 8 0 7 0 2 { 1 9 6 8 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1437 90 68\n" simple_expect "=1437 $any_time 8 0 7 0 2 { 1 9 6 8 } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 68; deleter 8 send "1438 29 68\n" # talk to Person 9 talk_to client 3 simple_expect ":18 14 68 $any_time 8 0 7 0 2 { 1 9 6 8 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1438" # Creating text 69 by 8 send "1439 86 [holl "text 69"] 1 { 1 10 } 0 { }\n" # talk to Person 7 talk_to client 1 simple_expect ":18 15 69 $any_time 8 0 7 0 2 { 1 10 6 8 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1439 69" # talk to Person 6 talk_to client 0 send "1440 90 69\n" simple_expect "=1440 $any_time 8 0 7 0 2 { 1 10 6 8 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1441 90 69\n" simple_expect "=1441 $any_time 8 0 7 0 2 { 1 10 6 8 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1442 90 69\n" simple_expect "=1442 $any_time 8 0 7 0 2 { 1 10 6 8 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1443 90 69\n" simple_expect "=1443 $any_time 8 0 7 0 2 { 1 10 6 8 } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 69; deleter 8 send "1444 29 69\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 69 $any_time 8 0 7 0 2 { 1 10 6 8 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1444" # Creating text 70 by 8 send "1445 86 [holl "text 70"] 1 { 1 11 } 0 { }\n" # talk to Person 7 talk_to client 1 simple_expect ":18 15 70 $any_time 8 0 7 0 2 { 1 11 6 8 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1445 70" # talk to Person 6 talk_to client 0 send "1446 90 70\n" simple_expect "%1446 14 70" # talk to Person 7 talk_to client 1 send "1447 90 70\n" simple_expect "=1447 $any_time 8 0 7 0 2 { 1 11 6 8 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1448 90 70\n" simple_expect "=1448 $any_time 8 0 7 0 2 { 1 11 6 8 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1449 90 70\n" simple_expect "%1449 14 70" # talk to Person 8 talk_to client 2 # Deleting text 70; deleter 8 send "1450 29 70\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 70 $any_time 8 0 7 0 2 { 1 11 6 8 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1450" # Creating text 71 by 8 send "1451 86 [holl "text 71"] 1 { 1 12 } 0 { }\n" # talk to Person 7 talk_to client 1 simple_expect ":18 15 71 $any_time 8 0 7 0 2 { 1 12 6 5 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1451 71" # talk to Person 6 talk_to client 0 send "1452 90 71\n" simple_expect "%1452 14 71" # talk to Person 7 talk_to client 1 send "1453 90 71\n" simple_expect "=1453 $any_time 8 0 7 0 2 { 1 12 6 5 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1454 90 71\n" simple_expect "=1454 $any_time 8 0 7 0 2 { 1 12 6 5 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1455 90 71\n" simple_expect "%1455 14 71" # talk to Person 8 talk_to client 2 # Deleting text 71; deleter 8 send "1456 29 71\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 71 $any_time 8 0 7 0 2 { 1 12 6 5 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1456" # Creating text 72 by 8 send "1457 86 [holl "text 72"] 1 { 1 13 } 0 { }\n" simple_expect ":18 15 72 $any_time 8 0 7 0 2 { 1 13 6 8 } 0 \\\*" simple_expect "=1457 72" # talk to Person 6 talk_to client 0 send "1458 90 72\n" simple_expect "=1458 $any_time 8 0 7 0 2 { 1 13 6 8 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1459 90 72\n" simple_expect "=1459 $any_time 8 0 7 0 2 { 1 13 6 8 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1460 90 72\n" simple_expect "=1460 $any_time 8 0 7 0 2 { 1 13 6 8 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1461 90 72\n" simple_expect "=1461 $any_time 8 0 7 0 2 { 1 13 6 8 } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 72; deleter 8 send "1462 29 72\n" simple_expect ":18 14 72 $any_time 8 0 7 0 2 { 1 13 6 8 } 0 \\\*" simple_expect "=1462" # Creating text 73 by 8 send "1463 86 [holl "text 73"] 1 { 1 14 } 0 { }\n" simple_expect ":18 15 73 $any_time 8 0 7 0 2 { 1 14 6 8 } 0 \\\*" simple_expect "=1463 73" # talk to Person 6 talk_to client 0 send "1464 90 73\n" simple_expect "%1464 14 73" # talk to Person 7 talk_to client 1 send "1465 90 73\n" simple_expect "=1465 $any_time 8 0 7 0 2 { 1 14 6 8 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1466 90 73\n" simple_expect "=1466 $any_time 8 0 7 0 2 { 1 14 6 8 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1467 90 73\n" simple_expect "=1467 $any_time 8 0 7 0 2 { 1 14 6 8 } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 73; deleter 8 send "1468 29 73\n" simple_expect ":18 14 73 $any_time 8 0 7 0 2 { 1 14 6 8 } 0 \\\*" simple_expect "=1468" # Creating text 74 by 8 send "1469 86 [holl "text 74"] 1 { 1 15 } 0 { }\n" simple_expect ":18 15 74 $any_time 8 0 7 0 2 { 1 15 6 5 } 0 \\\*" simple_expect "=1469 74" # talk to Person 6 talk_to client 0 send "1470 90 74\n" simple_expect "%1470 14 74" # talk to Person 7 talk_to client 1 send "1471 90 74\n" simple_expect "=1471 $any_time 8 0 7 0 2 { 1 15 6 5 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1472 90 74\n" simple_expect "=1472 $any_time 8 0 7 0 2 { 1 15 6 5 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1473 90 74\n" simple_expect "=1473 $any_time 8 0 7 0 2 { 1 15 6 5 } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 74; deleter 8 send "1474 29 74\n" simple_expect ":18 14 74 $any_time 8 0 7 0 2 { 1 15 6 5 } 0 \\\*" simple_expect "=1474" # Creating text 75 by 8 send "1475 86 [holl "text 75"] 1 { 15 6 } 0 { }\n" # talk to Person 6 talk_to client 0 simple_expect ":18 15 75 $any_time 8 0 7 0 2 { 15 6 6 9 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1475 75" # talk to Person 6 talk_to client 0 send "1476 90 75\n" simple_expect "=1476 $any_time 8 0 7 0 2 { 15 6 6 9 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1477 90 75\n" simple_expect "%1477 14 75" # talk to Person 8 talk_to client 2 send "1478 90 75\n" simple_expect "=1478 $any_time 8 0 7 0 2 { 15 6 6 9 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1479 90 75\n" simple_expect "%1479 14 75" # talk to Person 8 talk_to client 2 # Deleting text 75; deleter 8 send "1480 29 75\n" # talk to Person 6 talk_to client 0 simple_expect ":18 14 75 $any_time 8 0 7 0 2 { 15 6 6 9 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1480" # Creating text 76 by 8 send "1481 86 [holl "text 76"] 1 { 15 7 } 0 { }\n" simple_expect "=1481 76" # talk to Person 6 talk_to client 0 send "1482 90 76\n" simple_expect "%1482 14 76" # talk to Person 7 talk_to client 1 send "1483 90 76\n" simple_expect "=1483 $any_time 8 0 7 0 2 { 15 7 6 9 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1484 90 76\n" simple_expect "=1484 $any_time 8 0 7 0 2 { 15 7 6 9 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1485 90 76\n" simple_expect "%1485 14 76" # talk to Person 8 talk_to client 2 # Deleting text 76; deleter 8 send "1486 29 76\n" simple_expect "=1486" # Creating text 77 by 8 send "1487 86 [holl "text 77"] 1 { 15 8 } 0 { }\n" simple_expect ":18 15 77 $any_time 8 0 7 0 2 { 15 8 6 9 } 0 \\\*" simple_expect "=1487 77" # talk to Person 6 talk_to client 0 send "1488 90 77\n" simple_expect "%1488 14 77" # talk to Person 7 talk_to client 1 send "1489 90 77\n" simple_expect "%1489 14 77" # talk to Person 8 talk_to client 2 send "1490 90 77\n" simple_expect "=1490 $any_time 8 0 7 0 2 { 15 8 6 9 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1491 90 77\n" simple_expect "%1491 14 77" # talk to Person 8 talk_to client 2 # Deleting text 77; deleter 8 send "1492 29 77\n" simple_expect ":18 14 77 $any_time 8 0 7 0 2 { 15 8 6 9 } 0 \\\*" simple_expect "=1492" # Creating text 78 by 8 send "1493 86 [holl "text 78"] 1 { 15 9 } 0 { }\n" # talk to Person 9 talk_to client 3 simple_expect ":18 15 78 $any_time 8 0 7 0 2 { 15 9 6 9 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1493 78" # talk to Person 6 talk_to client 0 send "1494 90 78\n" simple_expect "%1494 14 78" # talk to Person 7 talk_to client 1 send "1495 90 78\n" simple_expect "%1495 14 78" # talk to Person 8 talk_to client 2 send "1496 90 78\n" simple_expect "=1496 $any_time 8 0 7 0 2 { 15 9 6 9 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1497 90 78\n" simple_expect "=1497 $any_time 8 0 7 0 2 { 15 9 6 9 } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 78; deleter 8 send "1498 29 78\n" # talk to Person 9 talk_to client 3 simple_expect ":18 14 78 $any_time 8 0 7 0 2 { 15 9 6 9 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1498" # Creating text 79 by 8 send "1499 86 [holl "text 79"] 1 { 15 10 } 0 { }\n" # talk to Person 7 talk_to client 1 simple_expect ":18 15 79 $any_time 8 0 7 0 2 { 15 10 6 9 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1499 79" # talk to Person 6 talk_to client 0 send "1500 90 79\n" simple_expect "=1500 $any_time 8 0 7 0 2 { 15 10 6 9 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1501 90 79\n" simple_expect "=1501 $any_time 8 0 7 0 2 { 15 10 6 9 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1502 90 79\n" simple_expect "=1502 $any_time 8 0 7 0 2 { 15 10 6 9 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1503 90 79\n" simple_expect "=1503 $any_time 8 0 7 0 2 { 15 10 6 9 } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 79; deleter 8 send "1504 29 79\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 79 $any_time 8 0 7 0 2 { 15 10 6 9 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1504" # Creating text 80 by 8 send "1505 86 [holl "text 80"] 1 { 15 11 } 0 { }\n" # talk to Person 7 talk_to client 1 simple_expect ":18 15 80 $any_time 8 0 7 0 2 { 15 11 6 9 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1505 80" # talk to Person 6 talk_to client 0 send "1506 90 80\n" simple_expect "%1506 14 80" # talk to Person 7 talk_to client 1 send "1507 90 80\n" simple_expect "=1507 $any_time 8 0 7 0 2 { 15 11 6 9 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1508 90 80\n" simple_expect "=1508 $any_time 8 0 7 0 2 { 15 11 6 9 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1509 90 80\n" simple_expect "%1509 14 80" # talk to Person 8 talk_to client 2 # Deleting text 80; deleter 8 send "1510 29 80\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 80 $any_time 8 0 7 0 2 { 15 11 6 9 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1510" # Creating text 81 by 8 send "1511 86 [holl "text 81"] 1 { 15 12 } 0 { }\n" # talk to Person 7 talk_to client 1 simple_expect ":18 15 81 $any_time 8 0 7 0 2 { 15 12 6 6 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1511 81" # talk to Person 6 talk_to client 0 send "1512 90 81\n" simple_expect "%1512 14 81" # talk to Person 7 talk_to client 1 send "1513 90 81\n" simple_expect "=1513 $any_time 8 0 7 0 2 { 15 12 6 6 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1514 90 81\n" simple_expect "=1514 $any_time 8 0 7 0 2 { 15 12 6 6 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1515 90 81\n" simple_expect "%1515 14 81" # talk to Person 8 talk_to client 2 # Deleting text 81; deleter 8 send "1516 29 81\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 81 $any_time 8 0 7 0 2 { 15 12 6 6 } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=1516" # Creating text 82 by 8 send "1517 86 [holl "text 82"] 1 { 15 13 } 0 { }\n" simple_expect ":18 15 82 $any_time 8 0 7 0 2 { 15 13 6 9 } 0 \\\*" simple_expect "=1517 82" # talk to Person 6 talk_to client 0 send "1518 90 82\n" simple_expect "=1518 $any_time 8 0 7 0 2 { 15 13 6 9 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1519 90 82\n" simple_expect "=1519 $any_time 8 0 7 0 2 { 15 13 6 9 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1520 90 82\n" simple_expect "=1520 $any_time 8 0 7 0 2 { 15 13 6 9 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1521 90 82\n" simple_expect "=1521 $any_time 8 0 7 0 2 { 15 13 6 9 } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 82; deleter 8 send "1522 29 82\n" simple_expect ":18 14 82 $any_time 8 0 7 0 2 { 15 13 6 9 } 0 \\\*" simple_expect "=1522" # Creating text 83 by 8 send "1523 86 [holl "text 83"] 1 { 15 14 } 0 { }\n" simple_expect ":18 15 83 $any_time 8 0 7 0 2 { 15 14 6 9 } 0 \\\*" simple_expect "=1523 83" # talk to Person 6 talk_to client 0 send "1524 90 83\n" simple_expect "%1524 14 83" # talk to Person 7 talk_to client 1 send "1525 90 83\n" simple_expect "=1525 $any_time 8 0 7 0 2 { 15 14 6 9 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1526 90 83\n" simple_expect "=1526 $any_time 8 0 7 0 2 { 15 14 6 9 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1527 90 83\n" simple_expect "=1527 $any_time 8 0 7 0 2 { 15 14 6 9 } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 83; deleter 8 send "1528 29 83\n" simple_expect ":18 14 83 $any_time 8 0 7 0 2 { 15 14 6 9 } 0 \\\*" simple_expect "=1528" # Creating text 84 by 8 send "1529 86 [holl "text 84"] 1 { 15 15 } 0 { }\n" simple_expect ":18 15 84 $any_time 8 0 7 0 2 { 15 15 6 6 } 0 \\\*" simple_expect "=1529 84" # talk to Person 6 talk_to client 0 send "1530 90 84\n" simple_expect "%1530 14 84" # talk to Person 7 talk_to client 1 send "1531 90 84\n" simple_expect "=1531 $any_time 8 0 7 0 2 { 15 15 6 6 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1532 90 84\n" simple_expect "=1532 $any_time 8 0 7 0 2 { 15 15 6 6 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1533 90 84\n" simple_expect "=1533 $any_time 8 0 7 0 2 { 15 15 6 6 } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 84; deleter 8 send "1534 29 84\n" simple_expect ":18 14 84 $any_time 8 0 7 0 2 { 15 15 6 6 } 0 \\\*" simple_expect "=1534" # talk to Person 9 talk_to client 3 # Creating text 85 by 9 send "1535 86 [holl "text 85"] 1 { 0 6 } 0 { }\n" # talk to Person 6 talk_to client 0 simple_expect ":18 15 85 $any_time 9 0 7 0 2 { 0 6 6 10 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1535 85" # talk to Person 6 talk_to client 0 send "1536 90 85\n" simple_expect "=1536 $any_time 9 0 7 0 2 { 0 6 6 10 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1537 90 85\n" simple_expect "%1537 14 85" # talk to Person 8 talk_to client 2 send "1538 90 85\n" simple_expect "%1538 14 85" # talk to Person 9 talk_to client 3 send "1539 90 85\n" simple_expect "=1539 $any_time 9 0 7 0 2 { 0 6 6 10 } 0 \\\*" # Deleting text 85; deleter 9 send "1540 29 85\n" # talk to Person 6 talk_to client 0 simple_expect ":18 14 85 $any_time 9 0 7 0 2 { 0 6 6 10 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1540" # Creating text 86 by 9 send "1541 86 [holl "text 86"] 1 { 0 7 } 0 { }\n" simple_expect "=1541 86" # talk to Person 6 talk_to client 0 send "1542 90 86\n" simple_expect "%1542 14 86" # talk to Person 7 talk_to client 1 send "1543 90 86\n" simple_expect "=1543 $any_time 9 0 7 0 2 { 0 7 6 10 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1544 90 86\n" simple_expect "%1544 14 86" # talk to Person 9 talk_to client 3 send "1545 90 86\n" simple_expect "=1545 $any_time 9 0 7 0 2 { 0 7 6 10 } 0 \\\*" # Deleting text 86; deleter 9 send "1546 29 86\n" simple_expect "=1546" # Creating text 87 by 9 send "1547 86 [holl "text 87"] 1 { 0 8 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 87 $any_time 9 0 7 0 2 { 0 8 6 10 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1547 87" # talk to Person 6 talk_to client 0 send "1548 90 87\n" simple_expect "%1548 14 87" # talk to Person 7 talk_to client 1 send "1549 90 87\n" simple_expect "%1549 14 87" # talk to Person 8 talk_to client 2 send "1550 90 87\n" simple_expect "=1550 $any_time 9 0 7 0 2 { 0 8 6 10 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1551 90 87\n" simple_expect "=1551 $any_time 9 0 7 0 2 { 0 8 6 10 } 0 \\\*" # Deleting text 87; deleter 9 send "1552 29 87\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 87 $any_time 9 0 7 0 2 { 0 8 6 10 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1552" # Creating text 88 by 9 send "1553 86 [holl "text 88"] 1 { 0 9 } 0 { }\n" simple_expect ":18 15 88 $any_time 9 0 7 0 2 { 0 9 6 10 } 0 \\\*" simple_expect "=1553 88" # talk to Person 6 talk_to client 0 send "1554 90 88\n" simple_expect "%1554 14 88" # talk to Person 7 talk_to client 1 send "1555 90 88\n" simple_expect "%1555 14 88" # talk to Person 8 talk_to client 2 send "1556 90 88\n" simple_expect "%1556 14 88" # talk to Person 9 talk_to client 3 send "1557 90 88\n" simple_expect "=1557 $any_time 9 0 7 0 2 { 0 9 6 10 } 0 \\\*" # Deleting text 88; deleter 9 send "1558 29 88\n" simple_expect ":18 14 88 $any_time 9 0 7 0 2 { 0 9 6 10 } 0 \\\*" simple_expect "=1558" # Creating text 89 by 9 send "1559 86 [holl "text 89"] 1 { 0 10 } 0 { }\n" # talk to Person 7 talk_to client 1 simple_expect ":18 15 89 $any_time 9 0 7 0 2 { 0 10 6 10 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1559 89" # talk to Person 6 talk_to client 0 send "1560 90 89\n" simple_expect "=1560 $any_time 9 0 7 0 2 { 0 10 6 10 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1561 90 89\n" simple_expect "=1561 $any_time 9 0 7 0 2 { 0 10 6 10 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1562 90 89\n" simple_expect "=1562 $any_time 9 0 7 0 2 { 0 10 6 10 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1563 90 89\n" simple_expect "=1563 $any_time 9 0 7 0 2 { 0 10 6 10 } 0 \\\*" # Deleting text 89; deleter 9 send "1564 29 89\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 89 $any_time 9 0 7 0 2 { 0 10 6 10 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1564" # Creating text 90 by 9 send "1565 86 [holl "text 90"] 1 { 0 11 } 0 { }\n" # talk to Person 7 talk_to client 1 simple_expect ":18 15 90 $any_time 9 0 7 0 2 { 0 11 6 10 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1565 90" # talk to Person 6 talk_to client 0 send "1566 90 90\n" simple_expect "%1566 14 90" # talk to Person 7 talk_to client 1 send "1567 90 90\n" simple_expect "=1567 $any_time 9 0 7 0 2 { 0 11 6 10 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1568 90 90\n" simple_expect "=1568 $any_time 9 0 7 0 2 { 0 11 6 10 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1569 90 90\n" simple_expect "=1569 $any_time 9 0 7 0 2 { 0 11 6 10 } 0 \\\*" # Deleting text 90; deleter 9 send "1570 29 90\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 90 $any_time 9 0 7 0 2 { 0 11 6 10 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1570" # Creating text 91 by 9 send "1571 86 [holl "text 91"] 1 { 0 13 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 91 $any_time 9 0 7 0 2 { 0 13 6 10 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1571 91" # talk to Person 6 talk_to client 0 send "1572 90 91\n" simple_expect "=1572 $any_time 9 0 7 0 2 { 0 13 6 10 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1573 90 91\n" simple_expect "=1573 $any_time 9 0 7 0 2 { 0 13 6 10 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1574 90 91\n" simple_expect "=1574 $any_time 9 0 7 0 2 { 0 13 6 10 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1575 90 91\n" simple_expect "=1575 $any_time 9 0 7 0 2 { 0 13 6 10 } 0 \\\*" # Deleting text 91; deleter 9 send "1576 29 91\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 91 $any_time 9 0 7 0 2 { 0 13 6 10 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1576" # Creating text 92 by 9 send "1577 86 [holl "text 92"] 1 { 0 14 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 92 $any_time 9 0 7 0 2 { 0 14 6 10 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1577 92" # talk to Person 6 talk_to client 0 send "1578 90 92\n" simple_expect "%1578 14 92" # talk to Person 7 talk_to client 1 send "1579 90 92\n" simple_expect "=1579 $any_time 9 0 7 0 2 { 0 14 6 10 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1580 90 92\n" simple_expect "=1580 $any_time 9 0 7 0 2 { 0 14 6 10 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1581 90 92\n" simple_expect "=1581 $any_time 9 0 7 0 2 { 0 14 6 10 } 0 \\\*" # Deleting text 92; deleter 9 send "1582 29 92\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 92 $any_time 9 0 7 0 2 { 0 14 6 10 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1582" # Creating text 93 by 9 send "1583 86 [holl "text 93"] 1 { 1 6 } 0 { }\n" # talk to Person 6 talk_to client 0 simple_expect ":18 15 93 $any_time 9 0 7 0 2 { 1 6 6 11 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1583 93" # talk to Person 6 talk_to client 0 send "1584 90 93\n" simple_expect "=1584 $any_time 9 0 7 0 2 { 1 6 6 11 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1585 90 93\n" simple_expect "%1585 14 93" # talk to Person 8 talk_to client 2 send "1586 90 93\n" simple_expect "%1586 14 93" # talk to Person 9 talk_to client 3 send "1587 90 93\n" simple_expect "=1587 $any_time 9 0 7 0 2 { 1 6 6 11 } 0 \\\*" # Deleting text 93; deleter 9 send "1588 29 93\n" # talk to Person 6 talk_to client 0 simple_expect ":18 14 93 $any_time 9 0 7 0 2 { 1 6 6 11 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1588" # Creating text 94 by 9 send "1589 86 [holl "text 94"] 1 { 1 7 } 0 { }\n" simple_expect "=1589 94" # talk to Person 6 talk_to client 0 send "1590 90 94\n" simple_expect "%1590 14 94" # talk to Person 7 talk_to client 1 send "1591 90 94\n" simple_expect "=1591 $any_time 9 0 7 0 2 { 1 7 6 11 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1592 90 94\n" simple_expect "%1592 14 94" # talk to Person 9 talk_to client 3 send "1593 90 94\n" simple_expect "=1593 $any_time 9 0 7 0 2 { 1 7 6 11 } 0 \\\*" # Deleting text 94; deleter 9 send "1594 29 94\n" simple_expect "=1594" # Creating text 95 by 9 send "1595 86 [holl "text 95"] 1 { 1 8 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 95 $any_time 9 0 7 0 2 { 1 8 6 11 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1595 95" # talk to Person 6 talk_to client 0 send "1596 90 95\n" simple_expect "%1596 14 95" # talk to Person 7 talk_to client 1 send "1597 90 95\n" simple_expect "%1597 14 95" # talk to Person 8 talk_to client 2 send "1598 90 95\n" simple_expect "=1598 $any_time 9 0 7 0 2 { 1 8 6 11 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1599 90 95\n" simple_expect "=1599 $any_time 9 0 7 0 2 { 1 8 6 11 } 0 \\\*" # Deleting text 95; deleter 9 send "1600 29 95\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 95 $any_time 9 0 7 0 2 { 1 8 6 11 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1600" # Creating text 96 by 9 send "1601 86 [holl "text 96"] 1 { 1 9 } 0 { }\n" simple_expect ":18 15 96 $any_time 9 0 7 0 2 { 1 9 6 11 } 0 \\\*" simple_expect "=1601 96" # talk to Person 6 talk_to client 0 send "1602 90 96\n" simple_expect "%1602 14 96" # talk to Person 7 talk_to client 1 send "1603 90 96\n" simple_expect "%1603 14 96" # talk to Person 8 talk_to client 2 send "1604 90 96\n" simple_expect "%1604 14 96" # talk to Person 9 talk_to client 3 send "1605 90 96\n" simple_expect "=1605 $any_time 9 0 7 0 2 { 1 9 6 11 } 0 \\\*" # Deleting text 96; deleter 9 send "1606 29 96\n" simple_expect ":18 14 96 $any_time 9 0 7 0 2 { 1 9 6 11 } 0 \\\*" simple_expect "=1606" # Creating text 97 by 9 send "1607 86 [holl "text 97"] 1 { 1 10 } 0 { }\n" # talk to Person 7 talk_to client 1 simple_expect ":18 15 97 $any_time 9 0 7 0 2 { 1 10 6 11 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1607 97" # talk to Person 6 talk_to client 0 send "1608 90 97\n" simple_expect "=1608 $any_time 9 0 7 0 2 { 1 10 6 11 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1609 90 97\n" simple_expect "=1609 $any_time 9 0 7 0 2 { 1 10 6 11 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1610 90 97\n" simple_expect "=1610 $any_time 9 0 7 0 2 { 1 10 6 11 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1611 90 97\n" simple_expect "=1611 $any_time 9 0 7 0 2 { 1 10 6 11 } 0 \\\*" # Deleting text 97; deleter 9 send "1612 29 97\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 97 $any_time 9 0 7 0 2 { 1 10 6 11 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1612" # Creating text 98 by 9 send "1613 86 [holl "text 98"] 1 { 1 11 } 0 { }\n" # talk to Person 7 talk_to client 1 simple_expect ":18 15 98 $any_time 9 0 7 0 2 { 1 11 6 11 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1613 98" # talk to Person 6 talk_to client 0 send "1614 90 98\n" simple_expect "%1614 14 98" # talk to Person 7 talk_to client 1 send "1615 90 98\n" simple_expect "=1615 $any_time 9 0 7 0 2 { 1 11 6 11 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1616 90 98\n" simple_expect "=1616 $any_time 9 0 7 0 2 { 1 11 6 11 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1617 90 98\n" simple_expect "=1617 $any_time 9 0 7 0 2 { 1 11 6 11 } 0 \\\*" # Deleting text 98; deleter 9 send "1618 29 98\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 98 $any_time 9 0 7 0 2 { 1 11 6 11 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1618" # Creating text 99 by 9 send "1619 86 [holl "text 99"] 1 { 1 13 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 99 $any_time 9 0 7 0 2 { 1 13 6 11 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1619 99" # talk to Person 6 talk_to client 0 send "1620 90 99\n" simple_expect "=1620 $any_time 9 0 7 0 2 { 1 13 6 11 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1621 90 99\n" simple_expect "=1621 $any_time 9 0 7 0 2 { 1 13 6 11 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1622 90 99\n" simple_expect "=1622 $any_time 9 0 7 0 2 { 1 13 6 11 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1623 90 99\n" simple_expect "=1623 $any_time 9 0 7 0 2 { 1 13 6 11 } 0 \\\*" # Deleting text 99; deleter 9 send "1624 29 99\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 99 $any_time 9 0 7 0 2 { 1 13 6 11 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1624" # Creating text 100 by 9 send "1625 86 [holl "text 100"] 1 { 1 14 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 100 $any_time 9 0 8 0 2 { 1 14 6 11 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1625 100" # talk to Person 6 talk_to client 0 send "1626 90 100\n" simple_expect "%1626 14 100" # talk to Person 7 talk_to client 1 send "1627 90 100\n" simple_expect "=1627 $any_time 9 0 8 0 2 { 1 14 6 11 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1628 90 100\n" simple_expect "=1628 $any_time 9 0 8 0 2 { 1 14 6 11 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1629 90 100\n" simple_expect "=1629 $any_time 9 0 8 0 2 { 1 14 6 11 } 0 \\\*" # Deleting text 100; deleter 9 send "1630 29 100\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 100 $any_time 9 0 8 0 2 { 1 14 6 11 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1630" # Creating text 101 by 9 send "1631 86 [holl "text 101"] 1 { 15 6 } 0 { }\n" # talk to Person 6 talk_to client 0 simple_expect ":18 15 101 $any_time 9 0 8 0 2 { 15 6 6 12 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1631 101" # talk to Person 6 talk_to client 0 send "1632 90 101\n" simple_expect "=1632 $any_time 9 0 8 0 2 { 15 6 6 12 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1633 90 101\n" simple_expect "%1633 14 101" # talk to Person 8 talk_to client 2 send "1634 90 101\n" simple_expect "%1634 14 101" # talk to Person 9 talk_to client 3 send "1635 90 101\n" simple_expect "=1635 $any_time 9 0 8 0 2 { 15 6 6 12 } 0 \\\*" # Deleting text 101; deleter 9 send "1636 29 101\n" # talk to Person 6 talk_to client 0 simple_expect ":18 14 101 $any_time 9 0 8 0 2 { 15 6 6 12 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1636" # Creating text 102 by 9 send "1637 86 [holl "text 102"] 1 { 15 7 } 0 { }\n" simple_expect "=1637 102" # talk to Person 6 talk_to client 0 send "1638 90 102\n" simple_expect "%1638 14 102" # talk to Person 7 talk_to client 1 send "1639 90 102\n" simple_expect "=1639 $any_time 9 0 8 0 2 { 15 7 6 12 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1640 90 102\n" simple_expect "%1640 14 102" # talk to Person 9 talk_to client 3 send "1641 90 102\n" simple_expect "=1641 $any_time 9 0 8 0 2 { 15 7 6 12 } 0 \\\*" # Deleting text 102; deleter 9 send "1642 29 102\n" simple_expect "=1642" # Creating text 103 by 9 send "1643 86 [holl "text 103"] 1 { 15 8 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 103 $any_time 9 0 8 0 2 { 15 8 6 12 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1643 103" # talk to Person 6 talk_to client 0 send "1644 90 103\n" simple_expect "%1644 14 103" # talk to Person 7 talk_to client 1 send "1645 90 103\n" simple_expect "%1645 14 103" # talk to Person 8 talk_to client 2 send "1646 90 103\n" simple_expect "=1646 $any_time 9 0 8 0 2 { 15 8 6 12 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1647 90 103\n" simple_expect "=1647 $any_time 9 0 8 0 2 { 15 8 6 12 } 0 \\\*" # Deleting text 103; deleter 9 send "1648 29 103\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 103 $any_time 9 0 8 0 2 { 15 8 6 12 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1648" # Creating text 104 by 9 send "1649 86 [holl "text 104"] 1 { 15 9 } 0 { }\n" simple_expect ":18 15 104 $any_time 9 0 8 0 2 { 15 9 6 12 } 0 \\\*" simple_expect "=1649 104" # talk to Person 6 talk_to client 0 send "1650 90 104\n" simple_expect "%1650 14 104" # talk to Person 7 talk_to client 1 send "1651 90 104\n" simple_expect "%1651 14 104" # talk to Person 8 talk_to client 2 send "1652 90 104\n" simple_expect "%1652 14 104" # talk to Person 9 talk_to client 3 send "1653 90 104\n" simple_expect "=1653 $any_time 9 0 8 0 2 { 15 9 6 12 } 0 \\\*" # Deleting text 104; deleter 9 send "1654 29 104\n" simple_expect ":18 14 104 $any_time 9 0 8 0 2 { 15 9 6 12 } 0 \\\*" simple_expect "=1654" # Creating text 105 by 9 send "1655 86 [holl "text 105"] 1 { 15 10 } 0 { }\n" # talk to Person 7 talk_to client 1 simple_expect ":18 15 105 $any_time 9 0 8 0 2 { 15 10 6 12 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1655 105" # talk to Person 6 talk_to client 0 send "1656 90 105\n" simple_expect "=1656 $any_time 9 0 8 0 2 { 15 10 6 12 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1657 90 105\n" simple_expect "=1657 $any_time 9 0 8 0 2 { 15 10 6 12 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1658 90 105\n" simple_expect "=1658 $any_time 9 0 8 0 2 { 15 10 6 12 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1659 90 105\n" simple_expect "=1659 $any_time 9 0 8 0 2 { 15 10 6 12 } 0 \\\*" # Deleting text 105; deleter 9 send "1660 29 105\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 105 $any_time 9 0 8 0 2 { 15 10 6 12 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1660" # Creating text 106 by 9 send "1661 86 [holl "text 106"] 1 { 15 11 } 0 { }\n" # talk to Person 7 talk_to client 1 simple_expect ":18 15 106 $any_time 9 0 8 0 2 { 15 11 6 12 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1661 106" # talk to Person 6 talk_to client 0 send "1662 90 106\n" simple_expect "%1662 14 106" # talk to Person 7 talk_to client 1 send "1663 90 106\n" simple_expect "=1663 $any_time 9 0 8 0 2 { 15 11 6 12 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1664 90 106\n" simple_expect "=1664 $any_time 9 0 8 0 2 { 15 11 6 12 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1665 90 106\n" simple_expect "=1665 $any_time 9 0 8 0 2 { 15 11 6 12 } 0 \\\*" # Deleting text 106; deleter 9 send "1666 29 106\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 106 $any_time 9 0 8 0 2 { 15 11 6 12 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1666" # Creating text 107 by 9 send "1667 86 [holl "text 107"] 1 { 15 13 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 107 $any_time 9 0 8 0 2 { 15 13 6 12 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1667 107" # talk to Person 6 talk_to client 0 send "1668 90 107\n" simple_expect "=1668 $any_time 9 0 8 0 2 { 15 13 6 12 } 0 \\\*" # talk to Person 7 talk_to client 1 send "1669 90 107\n" simple_expect "=1669 $any_time 9 0 8 0 2 { 15 13 6 12 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1670 90 107\n" simple_expect "=1670 $any_time 9 0 8 0 2 { 15 13 6 12 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1671 90 107\n" simple_expect "=1671 $any_time 9 0 8 0 2 { 15 13 6 12 } 0 \\\*" # Deleting text 107; deleter 9 send "1672 29 107\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 107 $any_time 9 0 8 0 2 { 15 13 6 12 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1672" # Creating text 108 by 9 send "1673 86 [holl "text 108"] 1 { 15 14 } 0 { }\n" # talk to Person 8 talk_to client 2 simple_expect ":18 15 108 $any_time 9 0 8 0 2 { 15 14 6 12 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1673 108" # talk to Person 6 talk_to client 0 send "1674 90 108\n" simple_expect "%1674 14 108" # talk to Person 7 talk_to client 1 send "1675 90 108\n" simple_expect "=1675 $any_time 9 0 8 0 2 { 15 14 6 12 } 0 \\\*" # talk to Person 8 talk_to client 2 send "1676 90 108\n" simple_expect "=1676 $any_time 9 0 8 0 2 { 15 14 6 12 } 0 \\\*" # talk to Person 9 talk_to client 3 send "1677 90 108\n" simple_expect "=1677 $any_time 9 0 8 0 2 { 15 14 6 12 } 0 \\\*" # Deleting text 108; deleter 9 send "1678 29 108\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 108 $any_time 9 0 8 0 2 { 15 14 6 12 } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=1678" send_user "testing simple create+add+delete\n" # talk to Person 6 talk_to client 0 # Creating text 109 by 6 send "1679 86 [holl "text 109"] 0 { } 0 { }\n" simple_expect "=1679 109" send "1680 90 109\n" simple_expect "=1680 $any_time 6 0 8 0 0 \\\* 0 \\\*" # talk to Person 7 talk_to client 1 send "1681 90 109\n" simple_expect "%1681 14 109" # talk to Person 8 talk_to client 2 send "1682 90 109\n" simple_expect "%1682 14 109" # talk to Person 9 talk_to client 3 send "1683 90 109\n" simple_expect "%1683 14 109" # talk to Person 6 talk_to client 0 # Adding recipient to text 109; adder 6 send "1684 30 109 6 0\n" simple_expect ":3 16 109 6 0" simple_expect "=1684" send "1685 90 109\n" simple_expect "=1685 $any_time 6 0 8 0 3 { 0 6 6 13 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "1686 90 109\n" simple_expect "%1686 14 109" # talk to Person 8 talk_to client 2 send "1687 90 109\n" simple_expect "%1687 14 109" # talk to Person 9 talk_to client 3 send "1688 90 109\n" simple_expect "%1688 14 109" # talk to Person 6 talk_to client 0 # Deleting text 109; deleter 6 send "1689 29 109\n" simple_expect ":18 14 109 $any_time 6 0 8 0 3 { 0 6 6 13 9 $any_time } 0 \\\*" simple_expect "=1689" # Creating text 110 by 6 send "1690 86 [holl "text 110"] 0 { } 0 { }\n" simple_expect "=1690 110" send "1691 90 110\n" simple_expect "=1691 $any_time 6 0 8 0 0 \\\* 0 \\\*" # talk to Person 7 talk_to client 1 send "1692 90 110\n" simple_expect "%1692 14 110" # talk to Person 8 talk_to client 2 send "1693 90 110\n" simple_expect "%1693 14 110" # talk to Person 9 talk_to client 3 send "1694 90 110\n" simple_expect "%1694 14 110" # talk to Person 6 talk_to client 0 # Adding recipient to text 110; adder 6 send "1695 30 110 7 0\n" simple_expect "=1695" send "1696 90 110\n" simple_expect "=1696 $any_time 6 0 8 0 3 { 0 7 6 13 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "1697 90 110\n" simple_expect "=1697 $any_time 6 0 8 0 3 { 0 7 6 13 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "1698 90 110\n" simple_expect "%1698 14 110" # talk to Person 9 talk_to client 3 send "1699 90 110\n" simple_expect "%1699 14 110" # talk to Person 6 talk_to client 0 # Deleting text 110; deleter 6 send "1700 29 110\n" simple_expect "=1700" # Creating text 111 by 6 send "1701 86 [holl "text 111"] 0 { } 0 { }\n" simple_expect "=1701 111" send "1702 90 111\n" simple_expect "=1702 $any_time 6 0 8 0 0 \\\* 0 \\\*" # talk to Person 7 talk_to client 1 send "1703 90 111\n" simple_expect "%1703 14 111" # talk to Person 8 talk_to client 2 send "1704 90 111\n" simple_expect "%1704 14 111" # talk to Person 9 talk_to client 3 send "1705 90 111\n" simple_expect "%1705 14 111" # talk to Person 6 talk_to client 0 # Adding recipient to text 111; adder 6 send "1706 30 111 8 0\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 111 8 0" # talk to Person 6 talk_to client 0 simple_expect "=1706" send "1707 90 111\n" simple_expect "=1707 $any_time 6 0 8 0 3 { 0 8 6 13 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "1708 90 111\n" simple_expect "%1708 14 111" # talk to Person 8 talk_to client 2 send "1709 90 111\n" simple_expect "=1709 $any_time 6 0 8 0 3 { 0 8 6 13 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "1710 90 111\n" simple_expect "%1710 14 111" # talk to Person 6 talk_to client 0 # Deleting text 111; deleter 6 send "1711 29 111\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 111 $any_time 6 0 8 0 3 { 0 8 6 13 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1711" # Creating text 112 by 6 send "1712 86 [holl "text 112"] 0 { } 0 { }\n" simple_expect "=1712 112" send "1713 90 112\n" simple_expect "=1713 $any_time 6 0 8 0 0 \\\* 0 \\\*" # talk to Person 7 talk_to client 1 send "1714 90 112\n" simple_expect "%1714 14 112" # talk to Person 8 talk_to client 2 send "1715 90 112\n" simple_expect "%1715 14 112" # talk to Person 9 talk_to client 3 send "1716 90 112\n" simple_expect "%1716 14 112" # talk to Person 6 talk_to client 0 # Adding recipient to text 112; adder 6 send "1717 30 112 9 0\n" # talk to Person 9 talk_to client 3 simple_expect ":3 16 112 9 0" # talk to Person 6 talk_to client 0 simple_expect "=1717" send "1718 90 112\n" simple_expect "=1718 $any_time 6 0 8 0 3 { 0 9 6 13 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "1719 90 112\n" simple_expect "%1719 14 112" # talk to Person 8 talk_to client 2 send "1720 90 112\n" simple_expect "%1720 14 112" # talk to Person 9 talk_to client 3 send "1721 90 112\n" simple_expect "=1721 $any_time 6 0 8 0 3 { 0 9 6 13 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 # Deleting text 112; deleter 6 send "1722 29 112\n" # talk to Person 9 talk_to client 3 simple_expect ":18 14 112 $any_time 6 0 8 0 3 { 0 9 6 13 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1722" # Creating text 113 by 6 send "1723 86 [holl "text 113"] 0 { } 0 { }\n" simple_expect "=1723 113" send "1724 90 113\n" simple_expect "=1724 $any_time 6 0 8 0 0 \\\* 0 \\\*" # talk to Person 7 talk_to client 1 send "1725 90 113\n" simple_expect "%1725 14 113" # talk to Person 8 talk_to client 2 send "1726 90 113\n" simple_expect "%1726 14 113" # talk to Person 9 talk_to client 3 send "1727 90 113\n" simple_expect "%1727 14 113" # talk to Person 6 talk_to client 0 # Adding recipient to text 113; adder 6 send "1728 30 113 10 0\n" # talk to Person 7 talk_to client 1 simple_expect ":3 16 113 10 0" # talk to Person 6 talk_to client 0 simple_expect "=1728" send "1729 90 113\n" simple_expect "=1729 $any_time 6 0 8 0 3 { 0 10 6 13 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "1730 90 113\n" simple_expect "=1730 $any_time 6 0 8 0 3 { 0 10 6 13 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "1731 90 113\n" simple_expect "=1731 $any_time 6 0 8 0 3 { 0 10 6 13 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "1732 90 113\n" simple_expect "=1732 $any_time 6 0 8 0 3 { 0 10 6 13 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 # Deleting text 113; deleter 6 send "1733 29 113\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 113 $any_time 6 0 8 0 3 { 0 10 6 13 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1733" # Creating text 114 by 6 send "1734 86 [holl "text 114"] 0 { } 0 { }\n" simple_expect "=1734 114" send "1735 90 114\n" simple_expect "=1735 $any_time 6 0 8 0 0 \\\* 0 \\\*" # talk to Person 7 talk_to client 1 send "1736 90 114\n" simple_expect "%1736 14 114" # talk to Person 8 talk_to client 2 send "1737 90 114\n" simple_expect "%1737 14 114" # talk to Person 9 talk_to client 3 send "1738 90 114\n" simple_expect "%1738 14 114" # talk to Person 6 talk_to client 0 # Adding recipient to text 114; adder 6 send "1739 30 114 11 0\n" # talk to Person 7 talk_to client 1 simple_expect ":3 16 114 11 0" # talk to Person 6 talk_to client 0 simple_expect "=1739" send "1740 90 114\n" simple_expect "=1740 $any_time 6 0 8 0 3 { 0 11 6 13 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "1741 90 114\n" simple_expect "=1741 $any_time 6 0 8 0 3 { 0 11 6 13 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "1742 90 114\n" simple_expect "=1742 $any_time 6 0 8 0 3 { 0 11 6 13 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "1743 90 114\n" simple_expect "%1743 14 114" # talk to Person 6 talk_to client 0 # Deleting text 114; deleter 6 send "1744 29 114\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 114 $any_time 6 0 8 0 3 { 0 11 6 13 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1744" # Creating text 115 by 6 send "1745 86 [holl "text 115"] 0 { } 0 { }\n" simple_expect "=1745 115" send "1746 90 115\n" simple_expect "=1746 $any_time 6 0 8 0 0 \\\* 0 \\\*" # talk to Person 7 talk_to client 1 send "1747 90 115\n" simple_expect "%1747 14 115" # talk to Person 8 talk_to client 2 send "1748 90 115\n" simple_expect "%1748 14 115" # talk to Person 9 talk_to client 3 send "1749 90 115\n" simple_expect "%1749 14 115" # talk to Person 6 talk_to client 0 # Adding recipient to text 115; adder 6 send "1750 30 115 13 0\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 115 13 0" # talk to Person 6 talk_to client 0 simple_expect "=1750" send "1751 90 115\n" simple_expect "=1751 $any_time 6 0 8 0 3 { 0 13 6 13 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "1752 90 115\n" simple_expect "=1752 $any_time 6 0 8 0 3 { 0 13 6 13 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "1753 90 115\n" simple_expect "=1753 $any_time 6 0 8 0 3 { 0 13 6 13 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "1754 90 115\n" simple_expect "=1754 $any_time 6 0 8 0 3 { 0 13 6 13 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 # Deleting text 115; deleter 6 send "1755 29 115\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 115 $any_time 6 0 8 0 3 { 0 13 6 13 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1755" # Creating text 116 by 6 send "1756 86 [holl "text 116"] 0 { } 0 { }\n" simple_expect "=1756 116" send "1757 90 116\n" simple_expect "=1757 $any_time 6 0 8 0 0 \\\* 0 \\\*" # talk to Person 7 talk_to client 1 send "1758 90 116\n" simple_expect "%1758 14 116" # talk to Person 8 talk_to client 2 send "1759 90 116\n" simple_expect "%1759 14 116" # talk to Person 9 talk_to client 3 send "1760 90 116\n" simple_expect "%1760 14 116" # talk to Person 6 talk_to client 0 # Adding recipient to text 116; adder 6 send "1761 30 116 14 0\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 116 14 0" # talk to Person 6 talk_to client 0 simple_expect "=1761" send "1762 90 116\n" simple_expect "=1762 $any_time 6 0 8 0 3 { 0 14 6 13 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "1763 90 116\n" simple_expect "=1763 $any_time 6 0 8 0 3 { 0 14 6 13 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "1764 90 116\n" simple_expect "=1764 $any_time 6 0 8 0 3 { 0 14 6 13 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "1765 90 116\n" simple_expect "=1765 $any_time 6 0 8 0 3 { 0 14 6 13 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 # Deleting text 116; deleter 6 send "1766 29 116\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 116 $any_time 6 0 8 0 3 { 0 14 6 13 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1766" # Creating text 117 by 6 send "1767 86 [holl "text 117"] 0 { } 0 { }\n" simple_expect "=1767 117" send "1768 90 117\n" simple_expect "=1768 $any_time 6 0 8 0 0 \\\* 0 \\\*" # talk to Person 7 talk_to client 1 send "1769 90 117\n" simple_expect "%1769 14 117" # talk to Person 8 talk_to client 2 send "1770 90 117\n" simple_expect "%1770 14 117" # talk to Person 9 talk_to client 3 send "1771 90 117\n" simple_expect "%1771 14 117" # talk to Person 6 talk_to client 0 # Adding recipient to text 117; adder 6 send "1772 30 117 6 1\n" simple_expect ":3 16 117 6 1" simple_expect "=1772" send "1773 90 117\n" simple_expect "=1773 $any_time 6 0 8 0 3 { 1 6 6 14 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "1774 90 117\n" simple_expect "%1774 14 117" # talk to Person 8 talk_to client 2 send "1775 90 117\n" simple_expect "%1775 14 117" # talk to Person 9 talk_to client 3 send "1776 90 117\n" simple_expect "%1776 14 117" # talk to Person 6 talk_to client 0 # Deleting text 117; deleter 6 send "1777 29 117\n" simple_expect ":18 14 117 $any_time 6 0 8 0 3 { 1 6 6 14 9 $any_time } 0 \\\*" simple_expect "=1777" # Creating text 118 by 6 send "1778 86 [holl "text 118"] 0 { } 0 { }\n" simple_expect "=1778 118" send "1779 90 118\n" simple_expect "=1779 $any_time 6 0 8 0 0 \\\* 0 \\\*" # talk to Person 7 talk_to client 1 send "1780 90 118\n" simple_expect "%1780 14 118" # talk to Person 8 talk_to client 2 send "1781 90 118\n" simple_expect "%1781 14 118" # talk to Person 9 talk_to client 3 send "1782 90 118\n" simple_expect "%1782 14 118" # talk to Person 6 talk_to client 0 # Adding recipient to text 118; adder 6 send "1783 30 118 7 1\n" simple_expect "=1783" send "1784 90 118\n" simple_expect "=1784 $any_time 6 0 8 0 3 { 1 7 6 14 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "1785 90 118\n" simple_expect "=1785 $any_time 6 0 8 0 3 { 1 7 6 14 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "1786 90 118\n" simple_expect "%1786 14 118" # talk to Person 9 talk_to client 3 send "1787 90 118\n" simple_expect "%1787 14 118" # talk to Person 6 talk_to client 0 # Deleting text 118; deleter 6 send "1788 29 118\n" simple_expect "=1788" # Creating text 119 by 6 send "1789 86 [holl "text 119"] 0 { } 0 { }\n" simple_expect "=1789 119" send "1790 90 119\n" simple_expect "=1790 $any_time 6 0 8 0 0 \\\* 0 \\\*" # talk to Person 7 talk_to client 1 send "1791 90 119\n" simple_expect "%1791 14 119" # talk to Person 8 talk_to client 2 send "1792 90 119\n" simple_expect "%1792 14 119" # talk to Person 9 talk_to client 3 send "1793 90 119\n" simple_expect "%1793 14 119" # talk to Person 6 talk_to client 0 # Adding recipient to text 119; adder 6 send "1794 30 119 8 1\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 119 8 1" # talk to Person 6 talk_to client 0 simple_expect "=1794" send "1795 90 119\n" simple_expect "=1795 $any_time 6 0 8 0 3 { 1 8 6 14 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "1796 90 119\n" simple_expect "%1796 14 119" # talk to Person 8 talk_to client 2 send "1797 90 119\n" simple_expect "=1797 $any_time 6 0 8 0 3 { 1 8 6 14 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "1798 90 119\n" simple_expect "%1798 14 119" # talk to Person 6 talk_to client 0 # Deleting text 119; deleter 6 send "1799 29 119\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 119 $any_time 6 0 8 0 3 { 1 8 6 14 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1799" # Creating text 120 by 6 send "1800 86 [holl "text 120"] 0 { } 0 { }\n" simple_expect "=1800 120" send "1801 90 120\n" simple_expect "=1801 $any_time 6 0 8 0 0 \\\* 0 \\\*" # talk to Person 7 talk_to client 1 send "1802 90 120\n" simple_expect "%1802 14 120" # talk to Person 8 talk_to client 2 send "1803 90 120\n" simple_expect "%1803 14 120" # talk to Person 9 talk_to client 3 send "1804 90 120\n" simple_expect "%1804 14 120" # talk to Person 6 talk_to client 0 # Adding recipient to text 120; adder 6 send "1805 30 120 9 1\n" # talk to Person 9 talk_to client 3 simple_expect ":3 16 120 9 1" # talk to Person 6 talk_to client 0 simple_expect "=1805" send "1806 90 120\n" simple_expect "=1806 $any_time 6 0 8 0 3 { 1 9 6 14 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "1807 90 120\n" simple_expect "%1807 14 120" # talk to Person 8 talk_to client 2 send "1808 90 120\n" simple_expect "%1808 14 120" # talk to Person 9 talk_to client 3 send "1809 90 120\n" simple_expect "=1809 $any_time 6 0 8 0 3 { 1 9 6 14 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 # Deleting text 120; deleter 6 send "1810 29 120\n" # talk to Person 9 talk_to client 3 simple_expect ":18 14 120 $any_time 6 0 8 0 3 { 1 9 6 14 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1810" # Creating text 121 by 6 send "1811 86 [holl "text 121"] 0 { } 0 { }\n" simple_expect "=1811 121" send "1812 90 121\n" simple_expect "=1812 $any_time 6 0 8 0 0 \\\* 0 \\\*" # talk to Person 7 talk_to client 1 send "1813 90 121\n" simple_expect "%1813 14 121" # talk to Person 8 talk_to client 2 send "1814 90 121\n" simple_expect "%1814 14 121" # talk to Person 9 talk_to client 3 send "1815 90 121\n" simple_expect "%1815 14 121" # talk to Person 6 talk_to client 0 # Adding recipient to text 121; adder 6 send "1816 30 121 10 1\n" # talk to Person 7 talk_to client 1 simple_expect ":3 16 121 10 1" # talk to Person 6 talk_to client 0 simple_expect "=1816" send "1817 90 121\n" simple_expect "=1817 $any_time 6 0 8 0 3 { 1 10 6 14 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "1818 90 121\n" simple_expect "=1818 $any_time 6 0 8 0 3 { 1 10 6 14 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "1819 90 121\n" simple_expect "=1819 $any_time 6 0 8 0 3 { 1 10 6 14 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "1820 90 121\n" simple_expect "=1820 $any_time 6 0 8 0 3 { 1 10 6 14 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 # Deleting text 121; deleter 6 send "1821 29 121\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 121 $any_time 6 0 8 0 3 { 1 10 6 14 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1821" # Creating text 122 by 6 send "1822 86 [holl "text 122"] 0 { } 0 { }\n" simple_expect "=1822 122" send "1823 90 122\n" simple_expect "=1823 $any_time 6 0 8 0 0 \\\* 0 \\\*" # talk to Person 7 talk_to client 1 send "1824 90 122\n" simple_expect "%1824 14 122" # talk to Person 8 talk_to client 2 send "1825 90 122\n" simple_expect "%1825 14 122" # talk to Person 9 talk_to client 3 send "1826 90 122\n" simple_expect "%1826 14 122" # talk to Person 6 talk_to client 0 # Adding recipient to text 122; adder 6 send "1827 30 122 11 1\n" # talk to Person 7 talk_to client 1 simple_expect ":3 16 122 11 1" # talk to Person 6 talk_to client 0 simple_expect "=1827" send "1828 90 122\n" simple_expect "=1828 $any_time 6 0 8 0 3 { 1 11 6 14 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "1829 90 122\n" simple_expect "=1829 $any_time 6 0 8 0 3 { 1 11 6 14 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "1830 90 122\n" simple_expect "=1830 $any_time 6 0 8 0 3 { 1 11 6 14 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "1831 90 122\n" simple_expect "%1831 14 122" # talk to Person 6 talk_to client 0 # Deleting text 122; deleter 6 send "1832 29 122\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 122 $any_time 6 0 8 0 3 { 1 11 6 14 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1832" # Creating text 123 by 6 send "1833 86 [holl "text 123"] 0 { } 0 { }\n" simple_expect "=1833 123" send "1834 90 123\n" simple_expect "=1834 $any_time 6 0 8 0 0 \\\* 0 \\\*" # talk to Person 7 talk_to client 1 send "1835 90 123\n" simple_expect "%1835 14 123" # talk to Person 8 talk_to client 2 send "1836 90 123\n" simple_expect "%1836 14 123" # talk to Person 9 talk_to client 3 send "1837 90 123\n" simple_expect "%1837 14 123" # talk to Person 6 talk_to client 0 # Adding recipient to text 123; adder 6 send "1838 30 123 13 1\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 123 13 1" # talk to Person 6 talk_to client 0 simple_expect "=1838" send "1839 90 123\n" simple_expect "=1839 $any_time 6 0 8 0 3 { 1 13 6 14 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "1840 90 123\n" simple_expect "=1840 $any_time 6 0 8 0 3 { 1 13 6 14 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "1841 90 123\n" simple_expect "=1841 $any_time 6 0 8 0 3 { 1 13 6 14 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "1842 90 123\n" simple_expect "=1842 $any_time 6 0 8 0 3 { 1 13 6 14 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 # Deleting text 123; deleter 6 send "1843 29 123\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 123 $any_time 6 0 8 0 3 { 1 13 6 14 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1843" # Creating text 124 by 6 send "1844 86 [holl "text 124"] 0 { } 0 { }\n" simple_expect "=1844 124" send "1845 90 124\n" simple_expect "=1845 $any_time 6 0 8 0 0 \\\* 0 \\\*" # talk to Person 7 talk_to client 1 send "1846 90 124\n" simple_expect "%1846 14 124" # talk to Person 8 talk_to client 2 send "1847 90 124\n" simple_expect "%1847 14 124" # talk to Person 9 talk_to client 3 send "1848 90 124\n" simple_expect "%1848 14 124" # talk to Person 6 talk_to client 0 # Adding recipient to text 124; adder 6 send "1849 30 124 14 1\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 124 14 1" # talk to Person 6 talk_to client 0 simple_expect "=1849" send "1850 90 124\n" simple_expect "=1850 $any_time 6 0 8 0 3 { 1 14 6 14 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "1851 90 124\n" simple_expect "=1851 $any_time 6 0 8 0 3 { 1 14 6 14 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "1852 90 124\n" simple_expect "=1852 $any_time 6 0 8 0 3 { 1 14 6 14 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "1853 90 124\n" simple_expect "=1853 $any_time 6 0 8 0 3 { 1 14 6 14 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 # Deleting text 124; deleter 6 send "1854 29 124\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 124 $any_time 6 0 8 0 3 { 1 14 6 14 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1854" # Creating text 125 by 6 send "1855 86 [holl "text 125"] 0 { } 0 { }\n" simple_expect "=1855 125" send "1856 90 125\n" simple_expect "=1856 $any_time 6 0 8 0 0 \\\* 0 \\\*" # talk to Person 7 talk_to client 1 send "1857 90 125\n" simple_expect "%1857 14 125" # talk to Person 8 talk_to client 2 send "1858 90 125\n" simple_expect "%1858 14 125" # talk to Person 9 talk_to client 3 send "1859 90 125\n" simple_expect "%1859 14 125" # talk to Person 6 talk_to client 0 # Adding recipient to text 125; adder 6 send "1860 30 125 6 15\n" simple_expect ":3 16 125 6 15" simple_expect "=1860" send "1861 90 125\n" simple_expect "=1861 $any_time 6 0 8 0 3 { 15 6 6 15 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "1862 90 125\n" simple_expect "%1862 14 125" # talk to Person 8 talk_to client 2 send "1863 90 125\n" simple_expect "%1863 14 125" # talk to Person 9 talk_to client 3 send "1864 90 125\n" simple_expect "%1864 14 125" # talk to Person 6 talk_to client 0 # Deleting text 125; deleter 6 send "1865 29 125\n" simple_expect ":18 14 125 $any_time 6 0 8 0 3 { 15 6 6 15 9 $any_time } 0 \\\*" simple_expect "=1865" # Creating text 126 by 6 send "1866 86 [holl "text 126"] 0 { } 0 { }\n" simple_expect "=1866 126" send "1867 90 126\n" simple_expect "=1867 $any_time 6 0 8 0 0 \\\* 0 \\\*" # talk to Person 7 talk_to client 1 send "1868 90 126\n" simple_expect "%1868 14 126" # talk to Person 8 talk_to client 2 send "1869 90 126\n" simple_expect "%1869 14 126" # talk to Person 9 talk_to client 3 send "1870 90 126\n" simple_expect "%1870 14 126" # talk to Person 6 talk_to client 0 # Adding recipient to text 126; adder 6 send "1871 30 126 7 15\n" simple_expect "=1871" send "1872 90 126\n" simple_expect "=1872 $any_time 6 0 8 0 3 { 15 7 6 15 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "1873 90 126\n" simple_expect "=1873 $any_time 6 0 8 0 3 { 15 7 6 15 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "1874 90 126\n" simple_expect "%1874 14 126" # talk to Person 9 talk_to client 3 send "1875 90 126\n" simple_expect "%1875 14 126" # talk to Person 6 talk_to client 0 # Deleting text 126; deleter 6 send "1876 29 126\n" simple_expect "=1876" # Creating text 127 by 6 send "1877 86 [holl "text 127"] 0 { } 0 { }\n" simple_expect "=1877 127" send "1878 90 127\n" simple_expect "=1878 $any_time 6 0 8 0 0 \\\* 0 \\\*" # talk to Person 7 talk_to client 1 send "1879 90 127\n" simple_expect "%1879 14 127" # talk to Person 8 talk_to client 2 send "1880 90 127\n" simple_expect "%1880 14 127" # talk to Person 9 talk_to client 3 send "1881 90 127\n" simple_expect "%1881 14 127" # talk to Person 6 talk_to client 0 # Adding recipient to text 127; adder 6 send "1882 30 127 8 15\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 127 8 15" # talk to Person 6 talk_to client 0 simple_expect "=1882" send "1883 90 127\n" simple_expect "=1883 $any_time 6 0 8 0 3 { 15 8 6 15 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "1884 90 127\n" simple_expect "%1884 14 127" # talk to Person 8 talk_to client 2 send "1885 90 127\n" simple_expect "=1885 $any_time 6 0 8 0 3 { 15 8 6 15 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "1886 90 127\n" simple_expect "%1886 14 127" # talk to Person 6 talk_to client 0 # Deleting text 127; deleter 6 send "1887 29 127\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 127 $any_time 6 0 8 0 3 { 15 8 6 15 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1887" # Creating text 128 by 6 send "1888 86 [holl "text 128"] 0 { } 0 { }\n" simple_expect "=1888 128" send "1889 90 128\n" simple_expect "=1889 $any_time 6 0 8 0 0 \\\* 0 \\\*" # talk to Person 7 talk_to client 1 send "1890 90 128\n" simple_expect "%1890 14 128" # talk to Person 8 talk_to client 2 send "1891 90 128\n" simple_expect "%1891 14 128" # talk to Person 9 talk_to client 3 send "1892 90 128\n" simple_expect "%1892 14 128" # talk to Person 6 talk_to client 0 # Adding recipient to text 128; adder 6 send "1893 30 128 9 15\n" # talk to Person 9 talk_to client 3 simple_expect ":3 16 128 9 15" # talk to Person 6 talk_to client 0 simple_expect "=1893" send "1894 90 128\n" simple_expect "=1894 $any_time 6 0 8 0 3 { 15 9 6 15 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "1895 90 128\n" simple_expect "%1895 14 128" # talk to Person 8 talk_to client 2 send "1896 90 128\n" simple_expect "%1896 14 128" # talk to Person 9 talk_to client 3 send "1897 90 128\n" simple_expect "=1897 $any_time 6 0 8 0 3 { 15 9 6 15 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 # Deleting text 128; deleter 6 send "1898 29 128\n" # talk to Person 9 talk_to client 3 simple_expect ":18 14 128 $any_time 6 0 8 0 3 { 15 9 6 15 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1898" # Creating text 129 by 6 send "1899 86 [holl "text 129"] 0 { } 0 { }\n" simple_expect "=1899 129" send "1900 90 129\n" simple_expect "=1900 $any_time 6 0 8 0 0 \\\* 0 \\\*" # talk to Person 7 talk_to client 1 send "1901 90 129\n" simple_expect "%1901 14 129" # talk to Person 8 talk_to client 2 send "1902 90 129\n" simple_expect "%1902 14 129" # talk to Person 9 talk_to client 3 send "1903 90 129\n" simple_expect "%1903 14 129" # talk to Person 6 talk_to client 0 # Adding recipient to text 129; adder 6 send "1904 30 129 10 15\n" # talk to Person 7 talk_to client 1 simple_expect ":3 16 129 10 15" # talk to Person 6 talk_to client 0 simple_expect "=1904" send "1905 90 129\n" simple_expect "=1905 $any_time 6 0 8 0 3 { 15 10 6 15 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "1906 90 129\n" simple_expect "=1906 $any_time 6 0 8 0 3 { 15 10 6 15 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "1907 90 129\n" simple_expect "=1907 $any_time 6 0 8 0 3 { 15 10 6 15 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "1908 90 129\n" simple_expect "=1908 $any_time 6 0 8 0 3 { 15 10 6 15 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 # Deleting text 129; deleter 6 send "1909 29 129\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 129 $any_time 6 0 8 0 3 { 15 10 6 15 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1909" # Creating text 130 by 6 send "1910 86 [holl "text 130"] 0 { } 0 { }\n" simple_expect "=1910 130" send "1911 90 130\n" simple_expect "=1911 $any_time 6 0 8 0 0 \\\* 0 \\\*" # talk to Person 7 talk_to client 1 send "1912 90 130\n" simple_expect "%1912 14 130" # talk to Person 8 talk_to client 2 send "1913 90 130\n" simple_expect "%1913 14 130" # talk to Person 9 talk_to client 3 send "1914 90 130\n" simple_expect "%1914 14 130" # talk to Person 6 talk_to client 0 # Adding recipient to text 130; adder 6 send "1915 30 130 11 15\n" # talk to Person 7 talk_to client 1 simple_expect ":3 16 130 11 15" # talk to Person 6 talk_to client 0 simple_expect "=1915" send "1916 90 130\n" simple_expect "=1916 $any_time 6 0 8 0 3 { 15 11 6 15 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "1917 90 130\n" simple_expect "=1917 $any_time 6 0 8 0 3 { 15 11 6 15 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "1918 90 130\n" simple_expect "=1918 $any_time 6 0 8 0 3 { 15 11 6 15 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "1919 90 130\n" simple_expect "%1919 14 130" # talk to Person 6 talk_to client 0 # Deleting text 130; deleter 6 send "1920 29 130\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 130 $any_time 6 0 8 0 3 { 15 11 6 15 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1920" # Creating text 131 by 6 send "1921 86 [holl "text 131"] 0 { } 0 { }\n" simple_expect "=1921 131" send "1922 90 131\n" simple_expect "=1922 $any_time 6 0 8 0 0 \\\* 0 \\\*" # talk to Person 7 talk_to client 1 send "1923 90 131\n" simple_expect "%1923 14 131" # talk to Person 8 talk_to client 2 send "1924 90 131\n" simple_expect "%1924 14 131" # talk to Person 9 talk_to client 3 send "1925 90 131\n" simple_expect "%1925 14 131" # talk to Person 6 talk_to client 0 # Adding recipient to text 131; adder 6 send "1926 30 131 13 15\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 131 13 15" # talk to Person 6 talk_to client 0 simple_expect "=1926" send "1927 90 131\n" simple_expect "=1927 $any_time 6 0 8 0 3 { 15 13 6 15 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "1928 90 131\n" simple_expect "=1928 $any_time 6 0 8 0 3 { 15 13 6 15 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "1929 90 131\n" simple_expect "=1929 $any_time 6 0 8 0 3 { 15 13 6 15 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "1930 90 131\n" simple_expect "=1930 $any_time 6 0 8 0 3 { 15 13 6 15 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 # Deleting text 131; deleter 6 send "1931 29 131\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 131 $any_time 6 0 8 0 3 { 15 13 6 15 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1931" # Creating text 132 by 6 send "1932 86 [holl "text 132"] 0 { } 0 { }\n" simple_expect "=1932 132" send "1933 90 132\n" simple_expect "=1933 $any_time 6 0 8 0 0 \\\* 0 \\\*" # talk to Person 7 talk_to client 1 send "1934 90 132\n" simple_expect "%1934 14 132" # talk to Person 8 talk_to client 2 send "1935 90 132\n" simple_expect "%1935 14 132" # talk to Person 9 talk_to client 3 send "1936 90 132\n" simple_expect "%1936 14 132" # talk to Person 6 talk_to client 0 # Adding recipient to text 132; adder 6 send "1937 30 132 14 15\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 132 14 15" # talk to Person 6 talk_to client 0 simple_expect "=1937" send "1938 90 132\n" simple_expect "=1938 $any_time 6 0 8 0 3 { 15 14 6 15 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "1939 90 132\n" simple_expect "=1939 $any_time 6 0 8 0 3 { 15 14 6 15 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "1940 90 132\n" simple_expect "=1940 $any_time 6 0 8 0 3 { 15 14 6 15 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "1941 90 132\n" simple_expect "=1941 $any_time 6 0 8 0 3 { 15 14 6 15 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 # Deleting text 132; deleter 6 send "1942 29 132\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 132 $any_time 6 0 8 0 3 { 15 14 6 15 9 $any_time } 0 \\\*" # talk to Person 6 talk_to client 0 simple_expect "=1942" # talk to Person 7 talk_to client 1 # Creating text 133 by 7 send "1943 86 [holl "text 133"] 0 { } 0 { }\n" simple_expect "=1943 133" # talk to Person 6 talk_to client 0 send "1944 90 133\n" simple_expect "%1944 14 133" # talk to Person 7 talk_to client 1 send "1945 90 133\n" simple_expect "=1945 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "1946 90 133\n" simple_expect "%1946 14 133" # talk to Person 9 talk_to client 3 send "1947 90 133\n" simple_expect "%1947 14 133" # talk to Person 7 talk_to client 1 # Adding recipient to text 133; adder 7 send "1948 30 133 6 0\n" # talk to Person 6 talk_to client 0 simple_expect ":3 16 133 6 0" # talk to Person 7 talk_to client 1 simple_expect "=1948" # talk to Person 6 talk_to client 0 send "1949 90 133\n" simple_expect "=1949 $any_time 7 0 8 0 3 { 0 6 6 16 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "1950 90 133\n" simple_expect "=1950 $any_time 7 0 8 0 3 { 0 6 6 16 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "1951 90 133\n" simple_expect "%1951 14 133" # talk to Person 9 talk_to client 3 send "1952 90 133\n" simple_expect "%1952 14 133" # talk to Person 7 talk_to client 1 # Deleting text 133; deleter 7 send "1953 29 133\n" # talk to Person 6 talk_to client 0 simple_expect ":18 14 133 $any_time 7 0 8 0 3 { 0 6 6 16 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1953" # Creating text 134 by 7 send "1954 86 [holl "text 134"] 0 { } 0 { }\n" simple_expect "=1954 134" # talk to Person 6 talk_to client 0 send "1955 90 134\n" simple_expect "%1955 14 134" # talk to Person 7 talk_to client 1 send "1956 90 134\n" simple_expect "=1956 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "1957 90 134\n" simple_expect "%1957 14 134" # talk to Person 9 talk_to client 3 send "1958 90 134\n" simple_expect "%1958 14 134" # talk to Person 7 talk_to client 1 # Adding recipient to text 134; adder 7 send "1959 30 134 7 0\n" simple_expect "=1959" # talk to Person 6 talk_to client 0 send "1960 90 134\n" simple_expect "%1960 14 134" # talk to Person 7 talk_to client 1 send "1961 90 134\n" simple_expect "=1961 $any_time 7 0 8 0 3 { 0 7 6 16 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "1962 90 134\n" simple_expect "%1962 14 134" # talk to Person 9 talk_to client 3 send "1963 90 134\n" simple_expect "%1963 14 134" # talk to Person 7 talk_to client 1 # Deleting text 134; deleter 7 send "1964 29 134\n" simple_expect "=1964" # Creating text 135 by 7 send "1965 86 [holl "text 135"] 0 { } 0 { }\n" simple_expect "=1965 135" # talk to Person 6 talk_to client 0 send "1966 90 135\n" simple_expect "%1966 14 135" # talk to Person 7 talk_to client 1 send "1967 90 135\n" simple_expect "=1967 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "1968 90 135\n" simple_expect "%1968 14 135" # talk to Person 9 talk_to client 3 send "1969 90 135\n" simple_expect "%1969 14 135" # talk to Person 7 talk_to client 1 # Adding recipient to text 135; adder 7 send "1970 30 135 8 0\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 135 8 0" # talk to Person 7 talk_to client 1 simple_expect "=1970" # talk to Person 6 talk_to client 0 send "1971 90 135\n" simple_expect "%1971 14 135" # talk to Person 7 talk_to client 1 send "1972 90 135\n" simple_expect "=1972 $any_time 7 0 8 0 3 { 0 8 6 16 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "1973 90 135\n" simple_expect "=1973 $any_time 7 0 8 0 3 { 0 8 6 16 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "1974 90 135\n" simple_expect "%1974 14 135" # talk to Person 7 talk_to client 1 # Deleting text 135; deleter 7 send "1975 29 135\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 135 $any_time 7 0 8 0 3 { 0 8 6 16 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1975" # Creating text 136 by 7 send "1976 86 [holl "text 136"] 0 { } 0 { }\n" simple_expect "=1976 136" # talk to Person 6 talk_to client 0 send "1977 90 136\n" simple_expect "%1977 14 136" # talk to Person 7 talk_to client 1 send "1978 90 136\n" simple_expect "=1978 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "1979 90 136\n" simple_expect "%1979 14 136" # talk to Person 9 talk_to client 3 send "1980 90 136\n" simple_expect "%1980 14 136" # talk to Person 7 talk_to client 1 # Adding recipient to text 136; adder 7 send "1981 30 136 9 0\n" # talk to Person 9 talk_to client 3 simple_expect ":3 16 136 9 0" # talk to Person 7 talk_to client 1 simple_expect "=1981" # talk to Person 6 talk_to client 0 send "1982 90 136\n" simple_expect "%1982 14 136" # talk to Person 7 talk_to client 1 send "1983 90 136\n" simple_expect "=1983 $any_time 7 0 8 0 3 { 0 9 6 16 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "1984 90 136\n" simple_expect "%1984 14 136" # talk to Person 9 talk_to client 3 send "1985 90 136\n" simple_expect "=1985 $any_time 7 0 8 0 3 { 0 9 6 16 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 136; deleter 7 send "1986 29 136\n" # talk to Person 9 talk_to client 3 simple_expect ":18 14 136 $any_time 7 0 8 0 3 { 0 9 6 16 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=1986" # Creating text 137 by 7 send "1987 86 [holl "text 137"] 0 { } 0 { }\n" simple_expect "=1987 137" # talk to Person 6 talk_to client 0 send "1988 90 137\n" simple_expect "%1988 14 137" # talk to Person 7 talk_to client 1 send "1989 90 137\n" simple_expect "=1989 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "1990 90 137\n" simple_expect "%1990 14 137" # talk to Person 9 talk_to client 3 send "1991 90 137\n" simple_expect "%1991 14 137" # talk to Person 7 talk_to client 1 # Adding recipient to text 137; adder 7 send "1992 30 137 10 0\n" simple_expect ":3 16 137 10 0" simple_expect "=1992" # talk to Person 6 talk_to client 0 send "1993 90 137\n" simple_expect "=1993 $any_time 7 0 8 0 3 { 0 10 6 16 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "1994 90 137\n" simple_expect "=1994 $any_time 7 0 8 0 3 { 0 10 6 16 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "1995 90 137\n" simple_expect "=1995 $any_time 7 0 8 0 3 { 0 10 6 16 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "1996 90 137\n" simple_expect "=1996 $any_time 7 0 8 0 3 { 0 10 6 16 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 137; deleter 7 send "1997 29 137\n" simple_expect ":18 14 137 $any_time 7 0 8 0 3 { 0 10 6 16 9 $any_time } 0 \\\*" simple_expect "=1997" # Creating text 138 by 7 send "1998 86 [holl "text 138"] 0 { } 0 { }\n" simple_expect "=1998 138" # talk to Person 6 talk_to client 0 send "1999 90 138\n" simple_expect "%1999 14 138" # talk to Person 7 talk_to client 1 send "2000 90 138\n" simple_expect "=2000 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "2001 90 138\n" simple_expect "%2001 14 138" # talk to Person 9 talk_to client 3 send "2002 90 138\n" simple_expect "%2002 14 138" # talk to Person 7 talk_to client 1 # Adding recipient to text 138; adder 7 send "2003 30 138 11 0\n" simple_expect ":3 16 138 11 0" simple_expect "=2003" # talk to Person 6 talk_to client 0 send "2004 90 138\n" simple_expect "%2004 14 138" # talk to Person 7 talk_to client 1 send "2005 90 138\n" simple_expect "=2005 $any_time 7 0 8 0 3 { 0 11 6 16 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2006 90 138\n" simple_expect "=2006 $any_time 7 0 8 0 3 { 0 11 6 16 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2007 90 138\n" simple_expect "%2007 14 138" # talk to Person 7 talk_to client 1 # Deleting text 138; deleter 7 send "2008 29 138\n" simple_expect ":18 14 138 $any_time 7 0 8 0 3 { 0 11 6 16 9 $any_time } 0 \\\*" simple_expect "=2008" # Creating text 139 by 7 send "2009 86 [holl "text 139"] 0 { } 0 { }\n" simple_expect "=2009 139" # talk to Person 6 talk_to client 0 send "2010 90 139\n" simple_expect "%2010 14 139" # talk to Person 7 talk_to client 1 send "2011 90 139\n" simple_expect "=2011 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "2012 90 139\n" simple_expect "%2012 14 139" # talk to Person 9 talk_to client 3 send "2013 90 139\n" simple_expect "%2013 14 139" # talk to Person 7 talk_to client 1 # Adding recipient to text 139; adder 7 send "2014 30 139 12 0\n" simple_expect ":3 16 139 12 0" simple_expect "=2014" # talk to Person 6 talk_to client 0 send "2015 90 139\n" simple_expect "%2015 14 139" # talk to Person 7 talk_to client 1 send "2016 90 139\n" simple_expect "=2016 $any_time 7 0 8 0 3 { 0 12 6 7 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2017 90 139\n" simple_expect "=2017 $any_time 7 0 8 0 3 { 0 12 6 7 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2018 90 139\n" simple_expect "%2018 14 139" # talk to Person 7 talk_to client 1 # Deleting text 139; deleter 7 send "2019 29 139\n" simple_expect ":18 14 139 $any_time 7 0 8 0 3 { 0 12 6 7 9 $any_time } 0 \\\*" simple_expect "=2019" # Creating text 140 by 7 send "2020 86 [holl "text 140"] 0 { } 0 { }\n" simple_expect "=2020 140" # talk to Person 6 talk_to client 0 send "2021 90 140\n" simple_expect "%2021 14 140" # talk to Person 7 talk_to client 1 send "2022 90 140\n" simple_expect "=2022 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "2023 90 140\n" simple_expect "%2023 14 140" # talk to Person 9 talk_to client 3 send "2024 90 140\n" simple_expect "%2024 14 140" # talk to Person 7 talk_to client 1 # Adding recipient to text 140; adder 7 send "2025 30 140 13 0\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 140 13 0" # talk to Person 7 talk_to client 1 simple_expect "=2025" # talk to Person 6 talk_to client 0 send "2026 90 140\n" simple_expect "=2026 $any_time 7 0 8 0 3 { 0 13 6 16 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "2027 90 140\n" simple_expect "=2027 $any_time 7 0 8 0 3 { 0 13 6 16 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2028 90 140\n" simple_expect "=2028 $any_time 7 0 8 0 3 { 0 13 6 16 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2029 90 140\n" simple_expect "=2029 $any_time 7 0 8 0 3 { 0 13 6 16 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 140; deleter 7 send "2030 29 140\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 140 $any_time 7 0 8 0 3 { 0 13 6 16 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=2030" # Creating text 141 by 7 send "2031 86 [holl "text 141"] 0 { } 0 { }\n" simple_expect "=2031 141" # talk to Person 6 talk_to client 0 send "2032 90 141\n" simple_expect "%2032 14 141" # talk to Person 7 talk_to client 1 send "2033 90 141\n" simple_expect "=2033 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "2034 90 141\n" simple_expect "%2034 14 141" # talk to Person 9 talk_to client 3 send "2035 90 141\n" simple_expect "%2035 14 141" # talk to Person 7 talk_to client 1 # Adding recipient to text 141; adder 7 send "2036 30 141 14 0\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 141 14 0" # talk to Person 7 talk_to client 1 simple_expect "=2036" # talk to Person 6 talk_to client 0 send "2037 90 141\n" simple_expect "%2037 14 141" # talk to Person 7 talk_to client 1 send "2038 90 141\n" simple_expect "=2038 $any_time 7 0 8 0 3 { 0 14 6 16 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2039 90 141\n" simple_expect "=2039 $any_time 7 0 8 0 3 { 0 14 6 16 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2040 90 141\n" simple_expect "=2040 $any_time 7 0 8 0 3 { 0 14 6 16 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 141; deleter 7 send "2041 29 141\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 141 $any_time 7 0 8 0 3 { 0 14 6 16 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=2041" # Creating text 142 by 7 send "2042 86 [holl "text 142"] 0 { } 0 { }\n" simple_expect "=2042 142" # talk to Person 6 talk_to client 0 send "2043 90 142\n" simple_expect "%2043 14 142" # talk to Person 7 talk_to client 1 send "2044 90 142\n" simple_expect "=2044 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "2045 90 142\n" simple_expect "%2045 14 142" # talk to Person 9 talk_to client 3 send "2046 90 142\n" simple_expect "%2046 14 142" # talk to Person 7 talk_to client 1 # Adding recipient to text 142; adder 7 send "2047 30 142 15 0\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 142 15 0" # talk to Person 7 talk_to client 1 simple_expect "=2047" # talk to Person 6 talk_to client 0 send "2048 90 142\n" simple_expect "%2048 14 142" # talk to Person 7 talk_to client 1 send "2049 90 142\n" simple_expect "=2049 $any_time 7 0 8 0 3 { 0 15 6 7 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2050 90 142\n" simple_expect "=2050 $any_time 7 0 8 0 3 { 0 15 6 7 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2051 90 142\n" simple_expect "=2051 $any_time 7 0 8 0 3 { 0 15 6 7 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 142; deleter 7 send "2052 29 142\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 142 $any_time 7 0 8 0 3 { 0 15 6 7 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=2052" # Creating text 143 by 7 send "2053 86 [holl "text 143"] 0 { } 0 { }\n" simple_expect "=2053 143" # talk to Person 6 talk_to client 0 send "2054 90 143\n" simple_expect "%2054 14 143" # talk to Person 7 talk_to client 1 send "2055 90 143\n" simple_expect "=2055 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "2056 90 143\n" simple_expect "%2056 14 143" # talk to Person 9 talk_to client 3 send "2057 90 143\n" simple_expect "%2057 14 143" # talk to Person 7 talk_to client 1 # Adding recipient to text 143; adder 7 send "2058 30 143 6 1\n" # talk to Person 6 talk_to client 0 simple_expect ":3 16 143 6 1" # talk to Person 7 talk_to client 1 simple_expect "=2058" # talk to Person 6 talk_to client 0 send "2059 90 143\n" simple_expect "=2059 $any_time 7 0 8 0 3 { 1 6 6 17 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "2060 90 143\n" simple_expect "=2060 $any_time 7 0 8 0 3 { 1 6 6 17 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2061 90 143\n" simple_expect "%2061 14 143" # talk to Person 9 talk_to client 3 send "2062 90 143\n" simple_expect "%2062 14 143" # talk to Person 7 talk_to client 1 # Deleting text 143; deleter 7 send "2063 29 143\n" # talk to Person 6 talk_to client 0 simple_expect ":18 14 143 $any_time 7 0 8 0 3 { 1 6 6 17 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=2063" # Creating text 144 by 7 send "2064 86 [holl "text 144"] 0 { } 0 { }\n" simple_expect "=2064 144" # talk to Person 6 talk_to client 0 send "2065 90 144\n" simple_expect "%2065 14 144" # talk to Person 7 talk_to client 1 send "2066 90 144\n" simple_expect "=2066 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "2067 90 144\n" simple_expect "%2067 14 144" # talk to Person 9 talk_to client 3 send "2068 90 144\n" simple_expect "%2068 14 144" # talk to Person 7 talk_to client 1 # Adding recipient to text 144; adder 7 send "2069 30 144 7 1\n" simple_expect "=2069" # talk to Person 6 talk_to client 0 send "2070 90 144\n" simple_expect "%2070 14 144" # talk to Person 7 talk_to client 1 send "2071 90 144\n" simple_expect "=2071 $any_time 7 0 8 0 3 { 1 7 6 17 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2072 90 144\n" simple_expect "%2072 14 144" # talk to Person 9 talk_to client 3 send "2073 90 144\n" simple_expect "%2073 14 144" # talk to Person 7 talk_to client 1 # Deleting text 144; deleter 7 send "2074 29 144\n" simple_expect "=2074" # Creating text 145 by 7 send "2075 86 [holl "text 145"] 0 { } 0 { }\n" simple_expect "=2075 145" # talk to Person 6 talk_to client 0 send "2076 90 145\n" simple_expect "%2076 14 145" # talk to Person 7 talk_to client 1 send "2077 90 145\n" simple_expect "=2077 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "2078 90 145\n" simple_expect "%2078 14 145" # talk to Person 9 talk_to client 3 send "2079 90 145\n" simple_expect "%2079 14 145" # talk to Person 7 talk_to client 1 # Adding recipient to text 145; adder 7 send "2080 30 145 8 1\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 145 8 1" # talk to Person 7 talk_to client 1 simple_expect "=2080" # talk to Person 6 talk_to client 0 send "2081 90 145\n" simple_expect "%2081 14 145" # talk to Person 7 talk_to client 1 send "2082 90 145\n" simple_expect "=2082 $any_time 7 0 8 0 3 { 1 8 6 17 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2083 90 145\n" simple_expect "=2083 $any_time 7 0 8 0 3 { 1 8 6 17 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2084 90 145\n" simple_expect "%2084 14 145" # talk to Person 7 talk_to client 1 # Deleting text 145; deleter 7 send "2085 29 145\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 145 $any_time 7 0 8 0 3 { 1 8 6 17 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=2085" # Creating text 146 by 7 send "2086 86 [holl "text 146"] 0 { } 0 { }\n" simple_expect "=2086 146" # talk to Person 6 talk_to client 0 send "2087 90 146\n" simple_expect "%2087 14 146" # talk to Person 7 talk_to client 1 send "2088 90 146\n" simple_expect "=2088 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "2089 90 146\n" simple_expect "%2089 14 146" # talk to Person 9 talk_to client 3 send "2090 90 146\n" simple_expect "%2090 14 146" # talk to Person 7 talk_to client 1 # Adding recipient to text 146; adder 7 send "2091 30 146 9 1\n" # talk to Person 9 talk_to client 3 simple_expect ":3 16 146 9 1" # talk to Person 7 talk_to client 1 simple_expect "=2091" # talk to Person 6 talk_to client 0 send "2092 90 146\n" simple_expect "%2092 14 146" # talk to Person 7 talk_to client 1 send "2093 90 146\n" simple_expect "=2093 $any_time 7 0 8 0 3 { 1 9 6 17 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2094 90 146\n" simple_expect "%2094 14 146" # talk to Person 9 talk_to client 3 send "2095 90 146\n" simple_expect "=2095 $any_time 7 0 8 0 3 { 1 9 6 17 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 146; deleter 7 send "2096 29 146\n" # talk to Person 9 talk_to client 3 simple_expect ":18 14 146 $any_time 7 0 8 0 3 { 1 9 6 17 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=2096" # Creating text 147 by 7 send "2097 86 [holl "text 147"] 0 { } 0 { }\n" simple_expect "=2097 147" # talk to Person 6 talk_to client 0 send "2098 90 147\n" simple_expect "%2098 14 147" # talk to Person 7 talk_to client 1 send "2099 90 147\n" simple_expect "=2099 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "2100 90 147\n" simple_expect "%2100 14 147" # talk to Person 9 talk_to client 3 send "2101 90 147\n" simple_expect "%2101 14 147" # talk to Person 7 talk_to client 1 # Adding recipient to text 147; adder 7 send "2102 30 147 10 1\n" simple_expect ":3 16 147 10 1" simple_expect "=2102" # talk to Person 6 talk_to client 0 send "2103 90 147\n" simple_expect "=2103 $any_time 7 0 8 0 3 { 1 10 6 17 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "2104 90 147\n" simple_expect "=2104 $any_time 7 0 8 0 3 { 1 10 6 17 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2105 90 147\n" simple_expect "=2105 $any_time 7 0 8 0 3 { 1 10 6 17 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2106 90 147\n" simple_expect "=2106 $any_time 7 0 8 0 3 { 1 10 6 17 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 147; deleter 7 send "2107 29 147\n" simple_expect ":18 14 147 $any_time 7 0 8 0 3 { 1 10 6 17 9 $any_time } 0 \\\*" simple_expect "=2107" # Creating text 148 by 7 send "2108 86 [holl "text 148"] 0 { } 0 { }\n" simple_expect "=2108 148" # talk to Person 6 talk_to client 0 send "2109 90 148\n" simple_expect "%2109 14 148" # talk to Person 7 talk_to client 1 send "2110 90 148\n" simple_expect "=2110 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "2111 90 148\n" simple_expect "%2111 14 148" # talk to Person 9 talk_to client 3 send "2112 90 148\n" simple_expect "%2112 14 148" # talk to Person 7 talk_to client 1 # Adding recipient to text 148; adder 7 send "2113 30 148 11 1\n" simple_expect ":3 16 148 11 1" simple_expect "=2113" # talk to Person 6 talk_to client 0 send "2114 90 148\n" simple_expect "%2114 14 148" # talk to Person 7 talk_to client 1 send "2115 90 148\n" simple_expect "=2115 $any_time 7 0 8 0 3 { 1 11 6 17 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2116 90 148\n" simple_expect "=2116 $any_time 7 0 8 0 3 { 1 11 6 17 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2117 90 148\n" simple_expect "%2117 14 148" # talk to Person 7 talk_to client 1 # Deleting text 148; deleter 7 send "2118 29 148\n" simple_expect ":18 14 148 $any_time 7 0 8 0 3 { 1 11 6 17 9 $any_time } 0 \\\*" simple_expect "=2118" # Creating text 149 by 7 send "2119 86 [holl "text 149"] 0 { } 0 { }\n" simple_expect "=2119 149" # talk to Person 6 talk_to client 0 send "2120 90 149\n" simple_expect "%2120 14 149" # talk to Person 7 talk_to client 1 send "2121 90 149\n" simple_expect "=2121 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "2122 90 149\n" simple_expect "%2122 14 149" # talk to Person 9 talk_to client 3 send "2123 90 149\n" simple_expect "%2123 14 149" # talk to Person 7 talk_to client 1 # Adding recipient to text 149; adder 7 send "2124 30 149 12 1\n" simple_expect ":3 16 149 12 1" simple_expect "=2124" # talk to Person 6 talk_to client 0 send "2125 90 149\n" simple_expect "%2125 14 149" # talk to Person 7 talk_to client 1 send "2126 90 149\n" simple_expect "=2126 $any_time 7 0 8 0 3 { 1 12 6 8 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2127 90 149\n" simple_expect "=2127 $any_time 7 0 8 0 3 { 1 12 6 8 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2128 90 149\n" simple_expect "%2128 14 149" # talk to Person 7 talk_to client 1 # Deleting text 149; deleter 7 send "2129 29 149\n" simple_expect ":18 14 149 $any_time 7 0 8 0 3 { 1 12 6 8 9 $any_time } 0 \\\*" simple_expect "=2129" # Creating text 150 by 7 send "2130 86 [holl "text 150"] 0 { } 0 { }\n" simple_expect "=2130 150" # talk to Person 6 talk_to client 0 send "2131 90 150\n" simple_expect "%2131 14 150" # talk to Person 7 talk_to client 1 send "2132 90 150\n" simple_expect "=2132 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "2133 90 150\n" simple_expect "%2133 14 150" # talk to Person 9 talk_to client 3 send "2134 90 150\n" simple_expect "%2134 14 150" # talk to Person 7 talk_to client 1 # Adding recipient to text 150; adder 7 send "2135 30 150 13 1\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 150 13 1" # talk to Person 7 talk_to client 1 simple_expect "=2135" # talk to Person 6 talk_to client 0 send "2136 90 150\n" simple_expect "=2136 $any_time 7 0 8 0 3 { 1 13 6 17 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "2137 90 150\n" simple_expect "=2137 $any_time 7 0 8 0 3 { 1 13 6 17 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2138 90 150\n" simple_expect "=2138 $any_time 7 0 8 0 3 { 1 13 6 17 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2139 90 150\n" simple_expect "=2139 $any_time 7 0 8 0 3 { 1 13 6 17 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 150; deleter 7 send "2140 29 150\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 150 $any_time 7 0 8 0 3 { 1 13 6 17 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=2140" # Creating text 151 by 7 send "2141 86 [holl "text 151"] 0 { } 0 { }\n" simple_expect "=2141 151" # talk to Person 6 talk_to client 0 send "2142 90 151\n" simple_expect "%2142 14 151" # talk to Person 7 talk_to client 1 send "2143 90 151\n" simple_expect "=2143 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "2144 90 151\n" simple_expect "%2144 14 151" # talk to Person 9 talk_to client 3 send "2145 90 151\n" simple_expect "%2145 14 151" # talk to Person 7 talk_to client 1 # Adding recipient to text 151; adder 7 send "2146 30 151 14 1\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 151 14 1" # talk to Person 7 talk_to client 1 simple_expect "=2146" # talk to Person 6 talk_to client 0 send "2147 90 151\n" simple_expect "%2147 14 151" # talk to Person 7 talk_to client 1 send "2148 90 151\n" simple_expect "=2148 $any_time 7 0 8 0 3 { 1 14 6 17 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2149 90 151\n" simple_expect "=2149 $any_time 7 0 8 0 3 { 1 14 6 17 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2150 90 151\n" simple_expect "=2150 $any_time 7 0 8 0 3 { 1 14 6 17 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 151; deleter 7 send "2151 29 151\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 151 $any_time 7 0 8 0 3 { 1 14 6 17 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=2151" # Creating text 152 by 7 send "2152 86 [holl "text 152"] 0 { } 0 { }\n" simple_expect "=2152 152" # talk to Person 6 talk_to client 0 send "2153 90 152\n" simple_expect "%2153 14 152" # talk to Person 7 talk_to client 1 send "2154 90 152\n" simple_expect "=2154 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "2155 90 152\n" simple_expect "%2155 14 152" # talk to Person 9 talk_to client 3 send "2156 90 152\n" simple_expect "%2156 14 152" # talk to Person 7 talk_to client 1 # Adding recipient to text 152; adder 7 send "2157 30 152 15 1\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 152 15 1" # talk to Person 7 talk_to client 1 simple_expect "=2157" # talk to Person 6 talk_to client 0 send "2158 90 152\n" simple_expect "%2158 14 152" # talk to Person 7 talk_to client 1 send "2159 90 152\n" simple_expect "=2159 $any_time 7 0 8 0 3 { 1 15 6 8 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2160 90 152\n" simple_expect "=2160 $any_time 7 0 8 0 3 { 1 15 6 8 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2161 90 152\n" simple_expect "=2161 $any_time 7 0 8 0 3 { 1 15 6 8 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 152; deleter 7 send "2162 29 152\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 152 $any_time 7 0 8 0 3 { 1 15 6 8 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=2162" # Creating text 153 by 7 send "2163 86 [holl "text 153"] 0 { } 0 { }\n" simple_expect "=2163 153" # talk to Person 6 talk_to client 0 send "2164 90 153\n" simple_expect "%2164 14 153" # talk to Person 7 talk_to client 1 send "2165 90 153\n" simple_expect "=2165 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "2166 90 153\n" simple_expect "%2166 14 153" # talk to Person 9 talk_to client 3 send "2167 90 153\n" simple_expect "%2167 14 153" # talk to Person 7 talk_to client 1 # Adding recipient to text 153; adder 7 send "2168 30 153 6 15\n" # talk to Person 6 talk_to client 0 simple_expect ":3 16 153 6 15" # talk to Person 7 talk_to client 1 simple_expect "=2168" # talk to Person 6 talk_to client 0 send "2169 90 153\n" simple_expect "=2169 $any_time 7 0 8 0 3 { 15 6 6 18 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "2170 90 153\n" simple_expect "=2170 $any_time 7 0 8 0 3 { 15 6 6 18 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2171 90 153\n" simple_expect "%2171 14 153" # talk to Person 9 talk_to client 3 send "2172 90 153\n" simple_expect "%2172 14 153" # talk to Person 7 talk_to client 1 # Deleting text 153; deleter 7 send "2173 29 153\n" # talk to Person 6 talk_to client 0 simple_expect ":18 14 153 $any_time 7 0 8 0 3 { 15 6 6 18 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=2173" # Creating text 154 by 7 send "2174 86 [holl "text 154"] 0 { } 0 { }\n" simple_expect "=2174 154" # talk to Person 6 talk_to client 0 send "2175 90 154\n" simple_expect "%2175 14 154" # talk to Person 7 talk_to client 1 send "2176 90 154\n" simple_expect "=2176 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "2177 90 154\n" simple_expect "%2177 14 154" # talk to Person 9 talk_to client 3 send "2178 90 154\n" simple_expect "%2178 14 154" # talk to Person 7 talk_to client 1 # Adding recipient to text 154; adder 7 send "2179 30 154 7 15\n" simple_expect "=2179" # talk to Person 6 talk_to client 0 send "2180 90 154\n" simple_expect "%2180 14 154" # talk to Person 7 talk_to client 1 send "2181 90 154\n" simple_expect "=2181 $any_time 7 0 8 0 3 { 15 7 6 18 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2182 90 154\n" simple_expect "%2182 14 154" # talk to Person 9 talk_to client 3 send "2183 90 154\n" simple_expect "%2183 14 154" # talk to Person 7 talk_to client 1 # Deleting text 154; deleter 7 send "2184 29 154\n" simple_expect "=2184" # Creating text 155 by 7 send "2185 86 [holl "text 155"] 0 { } 0 { }\n" simple_expect "=2185 155" # talk to Person 6 talk_to client 0 send "2186 90 155\n" simple_expect "%2186 14 155" # talk to Person 7 talk_to client 1 send "2187 90 155\n" simple_expect "=2187 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "2188 90 155\n" simple_expect "%2188 14 155" # talk to Person 9 talk_to client 3 send "2189 90 155\n" simple_expect "%2189 14 155" # talk to Person 7 talk_to client 1 # Adding recipient to text 155; adder 7 send "2190 30 155 8 15\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 155 8 15" # talk to Person 7 talk_to client 1 simple_expect "=2190" # talk to Person 6 talk_to client 0 send "2191 90 155\n" simple_expect "%2191 14 155" # talk to Person 7 talk_to client 1 send "2192 90 155\n" simple_expect "=2192 $any_time 7 0 8 0 3 { 15 8 6 18 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2193 90 155\n" simple_expect "=2193 $any_time 7 0 8 0 3 { 15 8 6 18 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2194 90 155\n" simple_expect "%2194 14 155" # talk to Person 7 talk_to client 1 # Deleting text 155; deleter 7 send "2195 29 155\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 155 $any_time 7 0 8 0 3 { 15 8 6 18 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=2195" # Creating text 156 by 7 send "2196 86 [holl "text 156"] 0 { } 0 { }\n" simple_expect "=2196 156" # talk to Person 6 talk_to client 0 send "2197 90 156\n" simple_expect "%2197 14 156" # talk to Person 7 talk_to client 1 send "2198 90 156\n" simple_expect "=2198 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "2199 90 156\n" simple_expect "%2199 14 156" # talk to Person 9 talk_to client 3 send "2200 90 156\n" simple_expect "%2200 14 156" # talk to Person 7 talk_to client 1 # Adding recipient to text 156; adder 7 send "2201 30 156 9 15\n" # talk to Person 9 talk_to client 3 simple_expect ":3 16 156 9 15" # talk to Person 7 talk_to client 1 simple_expect "=2201" # talk to Person 6 talk_to client 0 send "2202 90 156\n" simple_expect "%2202 14 156" # talk to Person 7 talk_to client 1 send "2203 90 156\n" simple_expect "=2203 $any_time 7 0 8 0 3 { 15 9 6 18 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2204 90 156\n" simple_expect "%2204 14 156" # talk to Person 9 talk_to client 3 send "2205 90 156\n" simple_expect "=2205 $any_time 7 0 8 0 3 { 15 9 6 18 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 156; deleter 7 send "2206 29 156\n" # talk to Person 9 talk_to client 3 simple_expect ":18 14 156 $any_time 7 0 8 0 3 { 15 9 6 18 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=2206" # Creating text 157 by 7 send "2207 86 [holl "text 157"] 0 { } 0 { }\n" simple_expect "=2207 157" # talk to Person 6 talk_to client 0 send "2208 90 157\n" simple_expect "%2208 14 157" # talk to Person 7 talk_to client 1 send "2209 90 157\n" simple_expect "=2209 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "2210 90 157\n" simple_expect "%2210 14 157" # talk to Person 9 talk_to client 3 send "2211 90 157\n" simple_expect "%2211 14 157" # talk to Person 7 talk_to client 1 # Adding recipient to text 157; adder 7 send "2212 30 157 10 15\n" simple_expect ":3 16 157 10 15" simple_expect "=2212" # talk to Person 6 talk_to client 0 send "2213 90 157\n" simple_expect "=2213 $any_time 7 0 8 0 3 { 15 10 6 18 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "2214 90 157\n" simple_expect "=2214 $any_time 7 0 8 0 3 { 15 10 6 18 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2215 90 157\n" simple_expect "=2215 $any_time 7 0 8 0 3 { 15 10 6 18 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2216 90 157\n" simple_expect "=2216 $any_time 7 0 8 0 3 { 15 10 6 18 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 157; deleter 7 send "2217 29 157\n" simple_expect ":18 14 157 $any_time 7 0 8 0 3 { 15 10 6 18 9 $any_time } 0 \\\*" simple_expect "=2217" # Creating text 158 by 7 send "2218 86 [holl "text 158"] 0 { } 0 { }\n" simple_expect "=2218 158" # talk to Person 6 talk_to client 0 send "2219 90 158\n" simple_expect "%2219 14 158" # talk to Person 7 talk_to client 1 send "2220 90 158\n" simple_expect "=2220 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "2221 90 158\n" simple_expect "%2221 14 158" # talk to Person 9 talk_to client 3 send "2222 90 158\n" simple_expect "%2222 14 158" # talk to Person 7 talk_to client 1 # Adding recipient to text 158; adder 7 send "2223 30 158 11 15\n" simple_expect ":3 16 158 11 15" simple_expect "=2223" # talk to Person 6 talk_to client 0 send "2224 90 158\n" simple_expect "%2224 14 158" # talk to Person 7 talk_to client 1 send "2225 90 158\n" simple_expect "=2225 $any_time 7 0 8 0 3 { 15 11 6 18 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2226 90 158\n" simple_expect "=2226 $any_time 7 0 8 0 3 { 15 11 6 18 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2227 90 158\n" simple_expect "%2227 14 158" # talk to Person 7 talk_to client 1 # Deleting text 158; deleter 7 send "2228 29 158\n" simple_expect ":18 14 158 $any_time 7 0 8 0 3 { 15 11 6 18 9 $any_time } 0 \\\*" simple_expect "=2228" # Creating text 159 by 7 send "2229 86 [holl "text 159"] 0 { } 0 { }\n" simple_expect "=2229 159" # talk to Person 6 talk_to client 0 send "2230 90 159\n" simple_expect "%2230 14 159" # talk to Person 7 talk_to client 1 send "2231 90 159\n" simple_expect "=2231 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "2232 90 159\n" simple_expect "%2232 14 159" # talk to Person 9 talk_to client 3 send "2233 90 159\n" simple_expect "%2233 14 159" # talk to Person 7 talk_to client 1 # Adding recipient to text 159; adder 7 send "2234 30 159 12 15\n" simple_expect ":3 16 159 12 15" simple_expect "=2234" # talk to Person 6 talk_to client 0 send "2235 90 159\n" simple_expect "%2235 14 159" # talk to Person 7 talk_to client 1 send "2236 90 159\n" simple_expect "=2236 $any_time 7 0 8 0 3 { 15 12 6 9 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2237 90 159\n" simple_expect "=2237 $any_time 7 0 8 0 3 { 15 12 6 9 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2238 90 159\n" simple_expect "%2238 14 159" # talk to Person 7 talk_to client 1 # Deleting text 159; deleter 7 send "2239 29 159\n" simple_expect ":18 14 159 $any_time 7 0 8 0 3 { 15 12 6 9 9 $any_time } 0 \\\*" simple_expect "=2239" # Creating text 160 by 7 send "2240 86 [holl "text 160"] 0 { } 0 { }\n" simple_expect "=2240 160" # talk to Person 6 talk_to client 0 send "2241 90 160\n" simple_expect "%2241 14 160" # talk to Person 7 talk_to client 1 send "2242 90 160\n" simple_expect "=2242 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "2243 90 160\n" simple_expect "%2243 14 160" # talk to Person 9 talk_to client 3 send "2244 90 160\n" simple_expect "%2244 14 160" # talk to Person 7 talk_to client 1 # Adding recipient to text 160; adder 7 send "2245 30 160 13 15\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 160 13 15" # talk to Person 7 talk_to client 1 simple_expect "=2245" # talk to Person 6 talk_to client 0 send "2246 90 160\n" simple_expect "=2246 $any_time 7 0 8 0 3 { 15 13 6 18 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "2247 90 160\n" simple_expect "=2247 $any_time 7 0 8 0 3 { 15 13 6 18 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2248 90 160\n" simple_expect "=2248 $any_time 7 0 8 0 3 { 15 13 6 18 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2249 90 160\n" simple_expect "=2249 $any_time 7 0 8 0 3 { 15 13 6 18 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 160; deleter 7 send "2250 29 160\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 160 $any_time 7 0 8 0 3 { 15 13 6 18 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=2250" # Creating text 161 by 7 send "2251 86 [holl "text 161"] 0 { } 0 { }\n" simple_expect "=2251 161" # talk to Person 6 talk_to client 0 send "2252 90 161\n" simple_expect "%2252 14 161" # talk to Person 7 talk_to client 1 send "2253 90 161\n" simple_expect "=2253 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "2254 90 161\n" simple_expect "%2254 14 161" # talk to Person 9 talk_to client 3 send "2255 90 161\n" simple_expect "%2255 14 161" # talk to Person 7 talk_to client 1 # Adding recipient to text 161; adder 7 send "2256 30 161 14 15\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 161 14 15" # talk to Person 7 talk_to client 1 simple_expect "=2256" # talk to Person 6 talk_to client 0 send "2257 90 161\n" simple_expect "%2257 14 161" # talk to Person 7 talk_to client 1 send "2258 90 161\n" simple_expect "=2258 $any_time 7 0 8 0 3 { 15 14 6 18 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2259 90 161\n" simple_expect "=2259 $any_time 7 0 8 0 3 { 15 14 6 18 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2260 90 161\n" simple_expect "=2260 $any_time 7 0 8 0 3 { 15 14 6 18 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 161; deleter 7 send "2261 29 161\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 161 $any_time 7 0 8 0 3 { 15 14 6 18 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=2261" # Creating text 162 by 7 send "2262 86 [holl "text 162"] 0 { } 0 { }\n" simple_expect "=2262 162" # talk to Person 6 talk_to client 0 send "2263 90 162\n" simple_expect "%2263 14 162" # talk to Person 7 talk_to client 1 send "2264 90 162\n" simple_expect "=2264 $any_time 7 0 8 0 0 \\\* 0 \\\*" # talk to Person 8 talk_to client 2 send "2265 90 162\n" simple_expect "%2265 14 162" # talk to Person 9 talk_to client 3 send "2266 90 162\n" simple_expect "%2266 14 162" # talk to Person 7 talk_to client 1 # Adding recipient to text 162; adder 7 send "2267 30 162 15 15\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 162 15 15" # talk to Person 7 talk_to client 1 simple_expect "=2267" # talk to Person 6 talk_to client 0 send "2268 90 162\n" simple_expect "%2268 14 162" # talk to Person 7 talk_to client 1 send "2269 90 162\n" simple_expect "=2269 $any_time 7 0 8 0 3 { 15 15 6 9 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2270 90 162\n" simple_expect "=2270 $any_time 7 0 8 0 3 { 15 15 6 9 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2271 90 162\n" simple_expect "=2271 $any_time 7 0 8 0 3 { 15 15 6 9 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 # Deleting text 162; deleter 7 send "2272 29 162\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 162 $any_time 7 0 8 0 3 { 15 15 6 9 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=2272" # talk to Person 8 talk_to client 2 # Creating text 163 by 8 send "2273 86 [holl "text 163"] 0 { } 0 { }\n" simple_expect "=2273 163" # talk to Person 6 talk_to client 0 send "2274 90 163\n" simple_expect "%2274 14 163" # talk to Person 7 talk_to client 1 send "2275 90 163\n" simple_expect "%2275 14 163" # talk to Person 8 talk_to client 2 send "2276 90 163\n" simple_expect "=2276 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2277 90 163\n" simple_expect "%2277 14 163" # talk to Person 8 talk_to client 2 # Adding recipient to text 163; adder 8 send "2278 30 163 6 0\n" # talk to Person 6 talk_to client 0 simple_expect ":3 16 163 6 0" # talk to Person 8 talk_to client 2 simple_expect "=2278" # talk to Person 6 talk_to client 0 send "2279 90 163\n" simple_expect "=2279 $any_time 8 0 8 0 3 { 0 6 6 19 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "2280 90 163\n" simple_expect "%2280 14 163" # talk to Person 8 talk_to client 2 send "2281 90 163\n" simple_expect "=2281 $any_time 8 0 8 0 3 { 0 6 6 19 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2282 90 163\n" simple_expect "%2282 14 163" # talk to Person 8 talk_to client 2 # Deleting text 163; deleter 8 send "2283 29 163\n" # talk to Person 6 talk_to client 0 simple_expect ":18 14 163 $any_time 8 0 8 0 3 { 0 6 6 19 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=2283" # Creating text 164 by 8 send "2284 86 [holl "text 164"] 0 { } 0 { }\n" simple_expect "=2284 164" # talk to Person 6 talk_to client 0 send "2285 90 164\n" simple_expect "%2285 14 164" # talk to Person 7 talk_to client 1 send "2286 90 164\n" simple_expect "%2286 14 164" # talk to Person 8 talk_to client 2 send "2287 90 164\n" simple_expect "=2287 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2288 90 164\n" simple_expect "%2288 14 164" # talk to Person 8 talk_to client 2 # Adding recipient to text 164; adder 8 send "2289 30 164 7 0\n" simple_expect "=2289" # talk to Person 6 talk_to client 0 send "2290 90 164\n" simple_expect "%2290 14 164" # talk to Person 7 talk_to client 1 send "2291 90 164\n" simple_expect "=2291 $any_time 8 0 8 0 3 { 0 7 6 19 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2292 90 164\n" simple_expect "=2292 $any_time 8 0 8 0 3 { 0 7 6 19 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2293 90 164\n" simple_expect "%2293 14 164" # talk to Person 8 talk_to client 2 # Deleting text 164; deleter 8 send "2294 29 164\n" simple_expect "=2294" # Creating text 165 by 8 send "2295 86 [holl "text 165"] 0 { } 0 { }\n" simple_expect "=2295 165" # talk to Person 6 talk_to client 0 send "2296 90 165\n" simple_expect "%2296 14 165" # talk to Person 7 talk_to client 1 send "2297 90 165\n" simple_expect "%2297 14 165" # talk to Person 8 talk_to client 2 send "2298 90 165\n" simple_expect "=2298 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2299 90 165\n" simple_expect "%2299 14 165" # talk to Person 8 talk_to client 2 # Adding recipient to text 165; adder 8 send "2300 30 165 8 0\n" simple_expect ":3 16 165 8 0" simple_expect "=2300" # talk to Person 6 talk_to client 0 send "2301 90 165\n" simple_expect "%2301 14 165" # talk to Person 7 talk_to client 1 send "2302 90 165\n" simple_expect "%2302 14 165" # talk to Person 8 talk_to client 2 send "2303 90 165\n" simple_expect "=2303 $any_time 8 0 8 0 3 { 0 8 6 19 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2304 90 165\n" simple_expect "%2304 14 165" # talk to Person 8 talk_to client 2 # Deleting text 165; deleter 8 send "2305 29 165\n" simple_expect ":18 14 165 $any_time 8 0 8 0 3 { 0 8 6 19 9 $any_time } 0 \\\*" simple_expect "=2305" # Creating text 166 by 8 send "2306 86 [holl "text 166"] 0 { } 0 { }\n" simple_expect "=2306 166" # talk to Person 6 talk_to client 0 send "2307 90 166\n" simple_expect "%2307 14 166" # talk to Person 7 talk_to client 1 send "2308 90 166\n" simple_expect "%2308 14 166" # talk to Person 8 talk_to client 2 send "2309 90 166\n" simple_expect "=2309 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2310 90 166\n" simple_expect "%2310 14 166" # talk to Person 8 talk_to client 2 # Adding recipient to text 166; adder 8 send "2311 30 166 9 0\n" # talk to Person 9 talk_to client 3 simple_expect ":3 16 166 9 0" # talk to Person 8 talk_to client 2 simple_expect "=2311" # talk to Person 6 talk_to client 0 send "2312 90 166\n" simple_expect "%2312 14 166" # talk to Person 7 talk_to client 1 send "2313 90 166\n" simple_expect "%2313 14 166" # talk to Person 8 talk_to client 2 send "2314 90 166\n" simple_expect "=2314 $any_time 8 0 8 0 3 { 0 9 6 19 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2315 90 166\n" simple_expect "=2315 $any_time 8 0 8 0 3 { 0 9 6 19 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 166; deleter 8 send "2316 29 166\n" # talk to Person 9 talk_to client 3 simple_expect ":18 14 166 $any_time 8 0 8 0 3 { 0 9 6 19 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=2316" # Creating text 167 by 8 send "2317 86 [holl "text 167"] 0 { } 0 { }\n" simple_expect "=2317 167" # talk to Person 6 talk_to client 0 send "2318 90 167\n" simple_expect "%2318 14 167" # talk to Person 7 talk_to client 1 send "2319 90 167\n" simple_expect "%2319 14 167" # talk to Person 8 talk_to client 2 send "2320 90 167\n" simple_expect "=2320 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2321 90 167\n" simple_expect "%2321 14 167" # talk to Person 8 talk_to client 2 # Adding recipient to text 167; adder 8 send "2322 30 167 10 0\n" # talk to Person 7 talk_to client 1 simple_expect ":3 16 167 10 0" # talk to Person 8 talk_to client 2 simple_expect "=2322" # talk to Person 6 talk_to client 0 send "2323 90 167\n" simple_expect "=2323 $any_time 8 0 8 0 3 { 0 10 6 19 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "2324 90 167\n" simple_expect "=2324 $any_time 8 0 8 0 3 { 0 10 6 19 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2325 90 167\n" simple_expect "=2325 $any_time 8 0 8 0 3 { 0 10 6 19 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2326 90 167\n" simple_expect "=2326 $any_time 8 0 8 0 3 { 0 10 6 19 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 167; deleter 8 send "2327 29 167\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 167 $any_time 8 0 8 0 3 { 0 10 6 19 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=2327" # Creating text 168 by 8 send "2328 86 [holl "text 168"] 0 { } 0 { }\n" simple_expect "=2328 168" # talk to Person 6 talk_to client 0 send "2329 90 168\n" simple_expect "%2329 14 168" # talk to Person 7 talk_to client 1 send "2330 90 168\n" simple_expect "%2330 14 168" # talk to Person 8 talk_to client 2 send "2331 90 168\n" simple_expect "=2331 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2332 90 168\n" simple_expect "%2332 14 168" # talk to Person 8 talk_to client 2 # Adding recipient to text 168; adder 8 send "2333 30 168 11 0\n" # talk to Person 7 talk_to client 1 simple_expect ":3 16 168 11 0" # talk to Person 8 talk_to client 2 simple_expect "=2333" # talk to Person 6 talk_to client 0 send "2334 90 168\n" simple_expect "%2334 14 168" # talk to Person 7 talk_to client 1 send "2335 90 168\n" simple_expect "=2335 $any_time 8 0 8 0 3 { 0 11 6 19 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2336 90 168\n" simple_expect "=2336 $any_time 8 0 8 0 3 { 0 11 6 19 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2337 90 168\n" simple_expect "%2337 14 168" # talk to Person 8 talk_to client 2 # Deleting text 168; deleter 8 send "2338 29 168\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 168 $any_time 8 0 8 0 3 { 0 11 6 19 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=2338" # Creating text 169 by 8 send "2339 86 [holl "text 169"] 0 { } 0 { }\n" simple_expect "=2339 169" # talk to Person 6 talk_to client 0 send "2340 90 169\n" simple_expect "%2340 14 169" # talk to Person 7 talk_to client 1 send "2341 90 169\n" simple_expect "%2341 14 169" # talk to Person 8 talk_to client 2 send "2342 90 169\n" simple_expect "=2342 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2343 90 169\n" simple_expect "%2343 14 169" # talk to Person 8 talk_to client 2 # Adding recipient to text 169; adder 8 send "2344 30 169 12 0\n" # talk to Person 7 talk_to client 1 simple_expect ":3 16 169 12 0" # talk to Person 8 talk_to client 2 simple_expect "=2344" # talk to Person 6 talk_to client 0 send "2345 90 169\n" simple_expect "%2345 14 169" # talk to Person 7 talk_to client 1 send "2346 90 169\n" simple_expect "=2346 $any_time 8 0 8 0 3 { 0 12 6 10 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2347 90 169\n" simple_expect "=2347 $any_time 8 0 8 0 3 { 0 12 6 10 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2348 90 169\n" simple_expect "%2348 14 169" # talk to Person 8 talk_to client 2 # Deleting text 169; deleter 8 send "2349 29 169\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 169 $any_time 8 0 8 0 3 { 0 12 6 10 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=2349" # Creating text 170 by 8 send "2350 86 [holl "text 170"] 0 { } 0 { }\n" simple_expect "=2350 170" # talk to Person 6 talk_to client 0 send "2351 90 170\n" simple_expect "%2351 14 170" # talk to Person 7 talk_to client 1 send "2352 90 170\n" simple_expect "%2352 14 170" # talk to Person 8 talk_to client 2 send "2353 90 170\n" simple_expect "=2353 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2354 90 170\n" simple_expect "%2354 14 170" # talk to Person 8 talk_to client 2 # Adding recipient to text 170; adder 8 send "2355 30 170 13 0\n" simple_expect ":3 16 170 13 0" simple_expect "=2355" # talk to Person 6 talk_to client 0 send "2356 90 170\n" simple_expect "=2356 $any_time 8 0 8 0 3 { 0 13 6 19 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "2357 90 170\n" simple_expect "=2357 $any_time 8 0 8 0 3 { 0 13 6 19 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2358 90 170\n" simple_expect "=2358 $any_time 8 0 8 0 3 { 0 13 6 19 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2359 90 170\n" simple_expect "=2359 $any_time 8 0 8 0 3 { 0 13 6 19 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 170; deleter 8 send "2360 29 170\n" simple_expect ":18 14 170 $any_time 8 0 8 0 3 { 0 13 6 19 9 $any_time } 0 \\\*" simple_expect "=2360" # Creating text 171 by 8 send "2361 86 [holl "text 171"] 0 { } 0 { }\n" simple_expect "=2361 171" # talk to Person 6 talk_to client 0 send "2362 90 171\n" simple_expect "%2362 14 171" # talk to Person 7 talk_to client 1 send "2363 90 171\n" simple_expect "%2363 14 171" # talk to Person 8 talk_to client 2 send "2364 90 171\n" simple_expect "=2364 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2365 90 171\n" simple_expect "%2365 14 171" # talk to Person 8 talk_to client 2 # Adding recipient to text 171; adder 8 send "2366 30 171 14 0\n" simple_expect ":3 16 171 14 0" simple_expect "=2366" # talk to Person 6 talk_to client 0 send "2367 90 171\n" simple_expect "%2367 14 171" # talk to Person 7 talk_to client 1 send "2368 90 171\n" simple_expect "=2368 $any_time 8 0 8 0 3 { 0 14 6 19 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2369 90 171\n" simple_expect "=2369 $any_time 8 0 8 0 3 { 0 14 6 19 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2370 90 171\n" simple_expect "=2370 $any_time 8 0 8 0 3 { 0 14 6 19 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 171; deleter 8 send "2371 29 171\n" simple_expect ":18 14 171 $any_time 8 0 8 0 3 { 0 14 6 19 9 $any_time } 0 \\\*" simple_expect "=2371" # Creating text 172 by 8 send "2372 86 [holl "text 172"] 0 { } 0 { }\n" simple_expect "=2372 172" # talk to Person 6 talk_to client 0 send "2373 90 172\n" simple_expect "%2373 14 172" # talk to Person 7 talk_to client 1 send "2374 90 172\n" simple_expect "%2374 14 172" # talk to Person 8 talk_to client 2 send "2375 90 172\n" simple_expect "=2375 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2376 90 172\n" simple_expect "%2376 14 172" # talk to Person 8 talk_to client 2 # Adding recipient to text 172; adder 8 send "2377 30 172 15 0\n" simple_expect ":3 16 172 15 0" simple_expect "=2377" # talk to Person 6 talk_to client 0 send "2378 90 172\n" simple_expect "%2378 14 172" # talk to Person 7 talk_to client 1 send "2379 90 172\n" simple_expect "=2379 $any_time 8 0 8 0 3 { 0 15 6 10 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2380 90 172\n" simple_expect "=2380 $any_time 8 0 8 0 3 { 0 15 6 10 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2381 90 172\n" simple_expect "=2381 $any_time 8 0 8 0 3 { 0 15 6 10 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 172; deleter 8 send "2382 29 172\n" simple_expect ":18 14 172 $any_time 8 0 8 0 3 { 0 15 6 10 9 $any_time } 0 \\\*" simple_expect "=2382" # Creating text 173 by 8 send "2383 86 [holl "text 173"] 0 { } 0 { }\n" simple_expect "=2383 173" # talk to Person 6 talk_to client 0 send "2384 90 173\n" simple_expect "%2384 14 173" # talk to Person 7 talk_to client 1 send "2385 90 173\n" simple_expect "%2385 14 173" # talk to Person 8 talk_to client 2 send "2386 90 173\n" simple_expect "=2386 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2387 90 173\n" simple_expect "%2387 14 173" # talk to Person 8 talk_to client 2 # Adding recipient to text 173; adder 8 send "2388 30 173 6 1\n" # talk to Person 6 talk_to client 0 simple_expect ":3 16 173 6 1" # talk to Person 8 talk_to client 2 simple_expect "=2388" # talk to Person 6 talk_to client 0 send "2389 90 173\n" simple_expect "=2389 $any_time 8 0 8 0 3 { 1 6 6 20 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "2390 90 173\n" simple_expect "%2390 14 173" # talk to Person 8 talk_to client 2 send "2391 90 173\n" simple_expect "=2391 $any_time 8 0 8 0 3 { 1 6 6 20 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2392 90 173\n" simple_expect "%2392 14 173" # talk to Person 8 talk_to client 2 # Deleting text 173; deleter 8 send "2393 29 173\n" # talk to Person 6 talk_to client 0 simple_expect ":18 14 173 $any_time 8 0 8 0 3 { 1 6 6 20 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=2393" # Creating text 174 by 8 send "2394 86 [holl "text 174"] 0 { } 0 { }\n" simple_expect "=2394 174" # talk to Person 6 talk_to client 0 send "2395 90 174\n" simple_expect "%2395 14 174" # talk to Person 7 talk_to client 1 send "2396 90 174\n" simple_expect "%2396 14 174" # talk to Person 8 talk_to client 2 send "2397 90 174\n" simple_expect "=2397 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2398 90 174\n" simple_expect "%2398 14 174" # talk to Person 8 talk_to client 2 # Adding recipient to text 174; adder 8 send "2399 30 174 7 1\n" simple_expect "=2399" # talk to Person 6 talk_to client 0 send "2400 90 174\n" simple_expect "%2400 14 174" # talk to Person 7 talk_to client 1 send "2401 90 174\n" simple_expect "=2401 $any_time 8 0 8 0 3 { 1 7 6 20 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2402 90 174\n" simple_expect "=2402 $any_time 8 0 8 0 3 { 1 7 6 20 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2403 90 174\n" simple_expect "%2403 14 174" # talk to Person 8 talk_to client 2 # Deleting text 174; deleter 8 send "2404 29 174\n" simple_expect "=2404" # Creating text 175 by 8 send "2405 86 [holl "text 175"] 0 { } 0 { }\n" simple_expect "=2405 175" # talk to Person 6 talk_to client 0 send "2406 90 175\n" simple_expect "%2406 14 175" # talk to Person 7 talk_to client 1 send "2407 90 175\n" simple_expect "%2407 14 175" # talk to Person 8 talk_to client 2 send "2408 90 175\n" simple_expect "=2408 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2409 90 175\n" simple_expect "%2409 14 175" # talk to Person 8 talk_to client 2 # Adding recipient to text 175; adder 8 send "2410 30 175 8 1\n" simple_expect ":3 16 175 8 1" simple_expect "=2410" # talk to Person 6 talk_to client 0 send "2411 90 175\n" simple_expect "%2411 14 175" # talk to Person 7 talk_to client 1 send "2412 90 175\n" simple_expect "%2412 14 175" # talk to Person 8 talk_to client 2 send "2413 90 175\n" simple_expect "=2413 $any_time 8 0 8 0 3 { 1 8 6 20 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2414 90 175\n" simple_expect "%2414 14 175" # talk to Person 8 talk_to client 2 # Deleting text 175; deleter 8 send "2415 29 175\n" simple_expect ":18 14 175 $any_time 8 0 8 0 3 { 1 8 6 20 9 $any_time } 0 \\\*" simple_expect "=2415" # Creating text 176 by 8 send "2416 86 [holl "text 176"] 0 { } 0 { }\n" simple_expect "=2416 176" # talk to Person 6 talk_to client 0 send "2417 90 176\n" simple_expect "%2417 14 176" # talk to Person 7 talk_to client 1 send "2418 90 176\n" simple_expect "%2418 14 176" # talk to Person 8 talk_to client 2 send "2419 90 176\n" simple_expect "=2419 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2420 90 176\n" simple_expect "%2420 14 176" # talk to Person 8 talk_to client 2 # Adding recipient to text 176; adder 8 send "2421 30 176 9 1\n" # talk to Person 9 talk_to client 3 simple_expect ":3 16 176 9 1" # talk to Person 8 talk_to client 2 simple_expect "=2421" # talk to Person 6 talk_to client 0 send "2422 90 176\n" simple_expect "%2422 14 176" # talk to Person 7 talk_to client 1 send "2423 90 176\n" simple_expect "%2423 14 176" # talk to Person 8 talk_to client 2 send "2424 90 176\n" simple_expect "=2424 $any_time 8 0 8 0 3 { 1 9 6 20 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2425 90 176\n" simple_expect "=2425 $any_time 8 0 8 0 3 { 1 9 6 20 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 176; deleter 8 send "2426 29 176\n" # talk to Person 9 talk_to client 3 simple_expect ":18 14 176 $any_time 8 0 8 0 3 { 1 9 6 20 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=2426" # Creating text 177 by 8 send "2427 86 [holl "text 177"] 0 { } 0 { }\n" simple_expect "=2427 177" # talk to Person 6 talk_to client 0 send "2428 90 177\n" simple_expect "%2428 14 177" # talk to Person 7 talk_to client 1 send "2429 90 177\n" simple_expect "%2429 14 177" # talk to Person 8 talk_to client 2 send "2430 90 177\n" simple_expect "=2430 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2431 90 177\n" simple_expect "%2431 14 177" # talk to Person 8 talk_to client 2 # Adding recipient to text 177; adder 8 send "2432 30 177 10 1\n" # talk to Person 7 talk_to client 1 simple_expect ":3 16 177 10 1" # talk to Person 8 talk_to client 2 simple_expect "=2432" # talk to Person 6 talk_to client 0 send "2433 90 177\n" simple_expect "=2433 $any_time 8 0 8 0 3 { 1 10 6 20 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "2434 90 177\n" simple_expect "=2434 $any_time 8 0 8 0 3 { 1 10 6 20 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2435 90 177\n" simple_expect "=2435 $any_time 8 0 8 0 3 { 1 10 6 20 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2436 90 177\n" simple_expect "=2436 $any_time 8 0 8 0 3 { 1 10 6 20 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 177; deleter 8 send "2437 29 177\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 177 $any_time 8 0 8 0 3 { 1 10 6 20 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=2437" # Creating text 178 by 8 send "2438 86 [holl "text 178"] 0 { } 0 { }\n" simple_expect "=2438 178" # talk to Person 6 talk_to client 0 send "2439 90 178\n" simple_expect "%2439 14 178" # talk to Person 7 talk_to client 1 send "2440 90 178\n" simple_expect "%2440 14 178" # talk to Person 8 talk_to client 2 send "2441 90 178\n" simple_expect "=2441 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2442 90 178\n" simple_expect "%2442 14 178" # talk to Person 8 talk_to client 2 # Adding recipient to text 178; adder 8 send "2443 30 178 11 1\n" # talk to Person 7 talk_to client 1 simple_expect ":3 16 178 11 1" # talk to Person 8 talk_to client 2 simple_expect "=2443" # talk to Person 6 talk_to client 0 send "2444 90 178\n" simple_expect "%2444 14 178" # talk to Person 7 talk_to client 1 send "2445 90 178\n" simple_expect "=2445 $any_time 8 0 8 0 3 { 1 11 6 20 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2446 90 178\n" simple_expect "=2446 $any_time 8 0 8 0 3 { 1 11 6 20 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2447 90 178\n" simple_expect "%2447 14 178" # talk to Person 8 talk_to client 2 # Deleting text 178; deleter 8 send "2448 29 178\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 178 $any_time 8 0 8 0 3 { 1 11 6 20 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=2448" # Creating text 179 by 8 send "2449 86 [holl "text 179"] 0 { } 0 { }\n" simple_expect "=2449 179" # talk to Person 6 talk_to client 0 send "2450 90 179\n" simple_expect "%2450 14 179" # talk to Person 7 talk_to client 1 send "2451 90 179\n" simple_expect "%2451 14 179" # talk to Person 8 talk_to client 2 send "2452 90 179\n" simple_expect "=2452 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2453 90 179\n" simple_expect "%2453 14 179" # talk to Person 8 talk_to client 2 # Adding recipient to text 179; adder 8 send "2454 30 179 12 1\n" # talk to Person 7 talk_to client 1 simple_expect ":3 16 179 12 1" # talk to Person 8 talk_to client 2 simple_expect "=2454" # talk to Person 6 talk_to client 0 send "2455 90 179\n" simple_expect "%2455 14 179" # talk to Person 7 talk_to client 1 send "2456 90 179\n" simple_expect "=2456 $any_time 8 0 8 0 3 { 1 12 6 11 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2457 90 179\n" simple_expect "=2457 $any_time 8 0 8 0 3 { 1 12 6 11 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2458 90 179\n" simple_expect "%2458 14 179" # talk to Person 8 talk_to client 2 # Deleting text 179; deleter 8 send "2459 29 179\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 179 $any_time 8 0 8 0 3 { 1 12 6 11 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=2459" # Creating text 180 by 8 send "2460 86 [holl "text 180"] 0 { } 0 { }\n" simple_expect "=2460 180" # talk to Person 6 talk_to client 0 send "2461 90 180\n" simple_expect "%2461 14 180" # talk to Person 7 talk_to client 1 send "2462 90 180\n" simple_expect "%2462 14 180" # talk to Person 8 talk_to client 2 send "2463 90 180\n" simple_expect "=2463 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2464 90 180\n" simple_expect "%2464 14 180" # talk to Person 8 talk_to client 2 # Adding recipient to text 180; adder 8 send "2465 30 180 13 1\n" simple_expect ":3 16 180 13 1" simple_expect "=2465" # talk to Person 6 talk_to client 0 send "2466 90 180\n" simple_expect "=2466 $any_time 8 0 8 0 3 { 1 13 6 20 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "2467 90 180\n" simple_expect "=2467 $any_time 8 0 8 0 3 { 1 13 6 20 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2468 90 180\n" simple_expect "=2468 $any_time 8 0 8 0 3 { 1 13 6 20 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2469 90 180\n" simple_expect "=2469 $any_time 8 0 8 0 3 { 1 13 6 20 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 180; deleter 8 send "2470 29 180\n" simple_expect ":18 14 180 $any_time 8 0 8 0 3 { 1 13 6 20 9 $any_time } 0 \\\*" simple_expect "=2470" # Creating text 181 by 8 send "2471 86 [holl "text 181"] 0 { } 0 { }\n" simple_expect "=2471 181" # talk to Person 6 talk_to client 0 send "2472 90 181\n" simple_expect "%2472 14 181" # talk to Person 7 talk_to client 1 send "2473 90 181\n" simple_expect "%2473 14 181" # talk to Person 8 talk_to client 2 send "2474 90 181\n" simple_expect "=2474 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2475 90 181\n" simple_expect "%2475 14 181" # talk to Person 8 talk_to client 2 # Adding recipient to text 181; adder 8 send "2476 30 181 14 1\n" simple_expect ":3 16 181 14 1" simple_expect "=2476" # talk to Person 6 talk_to client 0 send "2477 90 181\n" simple_expect "%2477 14 181" # talk to Person 7 talk_to client 1 send "2478 90 181\n" simple_expect "=2478 $any_time 8 0 8 0 3 { 1 14 6 20 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2479 90 181\n" simple_expect "=2479 $any_time 8 0 8 0 3 { 1 14 6 20 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2480 90 181\n" simple_expect "=2480 $any_time 8 0 8 0 3 { 1 14 6 20 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 181; deleter 8 send "2481 29 181\n" simple_expect ":18 14 181 $any_time 8 0 8 0 3 { 1 14 6 20 9 $any_time } 0 \\\*" simple_expect "=2481" # Creating text 182 by 8 send "2482 86 [holl "text 182"] 0 { } 0 { }\n" simple_expect "=2482 182" # talk to Person 6 talk_to client 0 send "2483 90 182\n" simple_expect "%2483 14 182" # talk to Person 7 talk_to client 1 send "2484 90 182\n" simple_expect "%2484 14 182" # talk to Person 8 talk_to client 2 send "2485 90 182\n" simple_expect "=2485 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2486 90 182\n" simple_expect "%2486 14 182" # talk to Person 8 talk_to client 2 # Adding recipient to text 182; adder 8 send "2487 30 182 15 1\n" simple_expect ":3 16 182 15 1" simple_expect "=2487" # talk to Person 6 talk_to client 0 send "2488 90 182\n" simple_expect "%2488 14 182" # talk to Person 7 talk_to client 1 send "2489 90 182\n" simple_expect "=2489 $any_time 8 0 8 0 3 { 1 15 6 11 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2490 90 182\n" simple_expect "=2490 $any_time 8 0 8 0 3 { 1 15 6 11 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2491 90 182\n" simple_expect "=2491 $any_time 8 0 8 0 3 { 1 15 6 11 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 182; deleter 8 send "2492 29 182\n" simple_expect ":18 14 182 $any_time 8 0 8 0 3 { 1 15 6 11 9 $any_time } 0 \\\*" simple_expect "=2492" # Creating text 183 by 8 send "2493 86 [holl "text 183"] 0 { } 0 { }\n" simple_expect "=2493 183" # talk to Person 6 talk_to client 0 send "2494 90 183\n" simple_expect "%2494 14 183" # talk to Person 7 talk_to client 1 send "2495 90 183\n" simple_expect "%2495 14 183" # talk to Person 8 talk_to client 2 send "2496 90 183\n" simple_expect "=2496 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2497 90 183\n" simple_expect "%2497 14 183" # talk to Person 8 talk_to client 2 # Adding recipient to text 183; adder 8 send "2498 30 183 6 15\n" # talk to Person 6 talk_to client 0 simple_expect ":3 16 183 6 15" # talk to Person 8 talk_to client 2 simple_expect "=2498" # talk to Person 6 talk_to client 0 send "2499 90 183\n" simple_expect "=2499 $any_time 8 0 8 0 3 { 15 6 6 21 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "2500 90 183\n" simple_expect "%2500 14 183" # talk to Person 8 talk_to client 2 send "2501 90 183\n" simple_expect "=2501 $any_time 8 0 8 0 3 { 15 6 6 21 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2502 90 183\n" simple_expect "%2502 14 183" # talk to Person 8 talk_to client 2 # Deleting text 183; deleter 8 send "2503 29 183\n" # talk to Person 6 talk_to client 0 simple_expect ":18 14 183 $any_time 8 0 8 0 3 { 15 6 6 21 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=2503" # Creating text 184 by 8 send "2504 86 [holl "text 184"] 0 { } 0 { }\n" simple_expect "=2504 184" # talk to Person 6 talk_to client 0 send "2505 90 184\n" simple_expect "%2505 14 184" # talk to Person 7 talk_to client 1 send "2506 90 184\n" simple_expect "%2506 14 184" # talk to Person 8 talk_to client 2 send "2507 90 184\n" simple_expect "=2507 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2508 90 184\n" simple_expect "%2508 14 184" # talk to Person 8 talk_to client 2 # Adding recipient to text 184; adder 8 send "2509 30 184 7 15\n" simple_expect "=2509" # talk to Person 6 talk_to client 0 send "2510 90 184\n" simple_expect "%2510 14 184" # talk to Person 7 talk_to client 1 send "2511 90 184\n" simple_expect "=2511 $any_time 8 0 8 0 3 { 15 7 6 21 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2512 90 184\n" simple_expect "=2512 $any_time 8 0 8 0 3 { 15 7 6 21 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2513 90 184\n" simple_expect "%2513 14 184" # talk to Person 8 talk_to client 2 # Deleting text 184; deleter 8 send "2514 29 184\n" simple_expect "=2514" # Creating text 185 by 8 send "2515 86 [holl "text 185"] 0 { } 0 { }\n" simple_expect "=2515 185" # talk to Person 6 talk_to client 0 send "2516 90 185\n" simple_expect "%2516 14 185" # talk to Person 7 talk_to client 1 send "2517 90 185\n" simple_expect "%2517 14 185" # talk to Person 8 talk_to client 2 send "2518 90 185\n" simple_expect "=2518 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2519 90 185\n" simple_expect "%2519 14 185" # talk to Person 8 talk_to client 2 # Adding recipient to text 185; adder 8 send "2520 30 185 8 15\n" simple_expect ":3 16 185 8 15" simple_expect "=2520" # talk to Person 6 talk_to client 0 send "2521 90 185\n" simple_expect "%2521 14 185" # talk to Person 7 talk_to client 1 send "2522 90 185\n" simple_expect "%2522 14 185" # talk to Person 8 talk_to client 2 send "2523 90 185\n" simple_expect "=2523 $any_time 8 0 8 0 3 { 15 8 6 21 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2524 90 185\n" simple_expect "%2524 14 185" # talk to Person 8 talk_to client 2 # Deleting text 185; deleter 8 send "2525 29 185\n" simple_expect ":18 14 185 $any_time 8 0 8 0 3 { 15 8 6 21 9 $any_time } 0 \\\*" simple_expect "=2525" # Creating text 186 by 8 send "2526 86 [holl "text 186"] 0 { } 0 { }\n" simple_expect "=2526 186" # talk to Person 6 talk_to client 0 send "2527 90 186\n" simple_expect "%2527 14 186" # talk to Person 7 talk_to client 1 send "2528 90 186\n" simple_expect "%2528 14 186" # talk to Person 8 talk_to client 2 send "2529 90 186\n" simple_expect "=2529 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2530 90 186\n" simple_expect "%2530 14 186" # talk to Person 8 talk_to client 2 # Adding recipient to text 186; adder 8 send "2531 30 186 9 15\n" # talk to Person 9 talk_to client 3 simple_expect ":3 16 186 9 15" # talk to Person 8 talk_to client 2 simple_expect "=2531" # talk to Person 6 talk_to client 0 send "2532 90 186\n" simple_expect "%2532 14 186" # talk to Person 7 talk_to client 1 send "2533 90 186\n" simple_expect "%2533 14 186" # talk to Person 8 talk_to client 2 send "2534 90 186\n" simple_expect "=2534 $any_time 8 0 8 0 3 { 15 9 6 21 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2535 90 186\n" simple_expect "=2535 $any_time 8 0 8 0 3 { 15 9 6 21 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 186; deleter 8 send "2536 29 186\n" # talk to Person 9 talk_to client 3 simple_expect ":18 14 186 $any_time 8 0 8 0 3 { 15 9 6 21 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=2536" # Creating text 187 by 8 send "2537 86 [holl "text 187"] 0 { } 0 { }\n" simple_expect "=2537 187" # talk to Person 6 talk_to client 0 send "2538 90 187\n" simple_expect "%2538 14 187" # talk to Person 7 talk_to client 1 send "2539 90 187\n" simple_expect "%2539 14 187" # talk to Person 8 talk_to client 2 send "2540 90 187\n" simple_expect "=2540 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2541 90 187\n" simple_expect "%2541 14 187" # talk to Person 8 talk_to client 2 # Adding recipient to text 187; adder 8 send "2542 30 187 10 15\n" # talk to Person 7 talk_to client 1 simple_expect ":3 16 187 10 15" # talk to Person 8 talk_to client 2 simple_expect "=2542" # talk to Person 6 talk_to client 0 send "2543 90 187\n" simple_expect "=2543 $any_time 8 0 8 0 3 { 15 10 6 21 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "2544 90 187\n" simple_expect "=2544 $any_time 8 0 8 0 3 { 15 10 6 21 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2545 90 187\n" simple_expect "=2545 $any_time 8 0 8 0 3 { 15 10 6 21 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2546 90 187\n" simple_expect "=2546 $any_time 8 0 8 0 3 { 15 10 6 21 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 187; deleter 8 send "2547 29 187\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 187 $any_time 8 0 8 0 3 { 15 10 6 21 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=2547" # Creating text 188 by 8 send "2548 86 [holl "text 188"] 0 { } 0 { }\n" simple_expect "=2548 188" # talk to Person 6 talk_to client 0 send "2549 90 188\n" simple_expect "%2549 14 188" # talk to Person 7 talk_to client 1 send "2550 90 188\n" simple_expect "%2550 14 188" # talk to Person 8 talk_to client 2 send "2551 90 188\n" simple_expect "=2551 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2552 90 188\n" simple_expect "%2552 14 188" # talk to Person 8 talk_to client 2 # Adding recipient to text 188; adder 8 send "2553 30 188 11 15\n" # talk to Person 7 talk_to client 1 simple_expect ":3 16 188 11 15" # talk to Person 8 talk_to client 2 simple_expect "=2553" # talk to Person 6 talk_to client 0 send "2554 90 188\n" simple_expect "%2554 14 188" # talk to Person 7 talk_to client 1 send "2555 90 188\n" simple_expect "=2555 $any_time 8 0 8 0 3 { 15 11 6 21 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2556 90 188\n" simple_expect "=2556 $any_time 8 0 8 0 3 { 15 11 6 21 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2557 90 188\n" simple_expect "%2557 14 188" # talk to Person 8 talk_to client 2 # Deleting text 188; deleter 8 send "2558 29 188\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 188 $any_time 8 0 8 0 3 { 15 11 6 21 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=2558" # Creating text 189 by 8 send "2559 86 [holl "text 189"] 0 { } 0 { }\n" simple_expect "=2559 189" # talk to Person 6 talk_to client 0 send "2560 90 189\n" simple_expect "%2560 14 189" # talk to Person 7 talk_to client 1 send "2561 90 189\n" simple_expect "%2561 14 189" # talk to Person 8 talk_to client 2 send "2562 90 189\n" simple_expect "=2562 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2563 90 189\n" simple_expect "%2563 14 189" # talk to Person 8 talk_to client 2 # Adding recipient to text 189; adder 8 send "2564 30 189 12 15\n" # talk to Person 7 talk_to client 1 simple_expect ":3 16 189 12 15" # talk to Person 8 talk_to client 2 simple_expect "=2564" # talk to Person 6 talk_to client 0 send "2565 90 189\n" simple_expect "%2565 14 189" # talk to Person 7 talk_to client 1 send "2566 90 189\n" simple_expect "=2566 $any_time 8 0 8 0 3 { 15 12 6 12 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2567 90 189\n" simple_expect "=2567 $any_time 8 0 8 0 3 { 15 12 6 12 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2568 90 189\n" simple_expect "%2568 14 189" # talk to Person 8 talk_to client 2 # Deleting text 189; deleter 8 send "2569 29 189\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 189 $any_time 8 0 8 0 3 { 15 12 6 12 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 simple_expect "=2569" # Creating text 190 by 8 send "2570 86 [holl "text 190"] 0 { } 0 { }\n" simple_expect "=2570 190" # talk to Person 6 talk_to client 0 send "2571 90 190\n" simple_expect "%2571 14 190" # talk to Person 7 talk_to client 1 send "2572 90 190\n" simple_expect "%2572 14 190" # talk to Person 8 talk_to client 2 send "2573 90 190\n" simple_expect "=2573 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2574 90 190\n" simple_expect "%2574 14 190" # talk to Person 8 talk_to client 2 # Adding recipient to text 190; adder 8 send "2575 30 190 13 15\n" simple_expect ":3 16 190 13 15" simple_expect "=2575" # talk to Person 6 talk_to client 0 send "2576 90 190\n" simple_expect "=2576 $any_time 8 0 8 0 3 { 15 13 6 21 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "2577 90 190\n" simple_expect "=2577 $any_time 8 0 8 0 3 { 15 13 6 21 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2578 90 190\n" simple_expect "=2578 $any_time 8 0 8 0 3 { 15 13 6 21 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2579 90 190\n" simple_expect "=2579 $any_time 8 0 8 0 3 { 15 13 6 21 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 190; deleter 8 send "2580 29 190\n" simple_expect ":18 14 190 $any_time 8 0 8 0 3 { 15 13 6 21 9 $any_time } 0 \\\*" simple_expect "=2580" # Creating text 191 by 8 send "2581 86 [holl "text 191"] 0 { } 0 { }\n" simple_expect "=2581 191" # talk to Person 6 talk_to client 0 send "2582 90 191\n" simple_expect "%2582 14 191" # talk to Person 7 talk_to client 1 send "2583 90 191\n" simple_expect "%2583 14 191" # talk to Person 8 talk_to client 2 send "2584 90 191\n" simple_expect "=2584 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2585 90 191\n" simple_expect "%2585 14 191" # talk to Person 8 talk_to client 2 # Adding recipient to text 191; adder 8 send "2586 30 191 14 15\n" simple_expect ":3 16 191 14 15" simple_expect "=2586" # talk to Person 6 talk_to client 0 send "2587 90 191\n" simple_expect "%2587 14 191" # talk to Person 7 talk_to client 1 send "2588 90 191\n" simple_expect "=2588 $any_time 8 0 8 0 3 { 15 14 6 21 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2589 90 191\n" simple_expect "=2589 $any_time 8 0 8 0 3 { 15 14 6 21 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2590 90 191\n" simple_expect "=2590 $any_time 8 0 8 0 3 { 15 14 6 21 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 191; deleter 8 send "2591 29 191\n" simple_expect ":18 14 191 $any_time 8 0 8 0 3 { 15 14 6 21 9 $any_time } 0 \\\*" simple_expect "=2591" # Creating text 192 by 8 send "2592 86 [holl "text 192"] 0 { } 0 { }\n" simple_expect "=2592 192" # talk to Person 6 talk_to client 0 send "2593 90 192\n" simple_expect "%2593 14 192" # talk to Person 7 talk_to client 1 send "2594 90 192\n" simple_expect "%2594 14 192" # talk to Person 8 talk_to client 2 send "2595 90 192\n" simple_expect "=2595 $any_time 8 0 8 0 0 \\\* 0 \\\*" # talk to Person 9 talk_to client 3 send "2596 90 192\n" simple_expect "%2596 14 192" # talk to Person 8 talk_to client 2 # Adding recipient to text 192; adder 8 send "2597 30 192 15 15\n" simple_expect ":3 16 192 15 15" simple_expect "=2597" # talk to Person 6 talk_to client 0 send "2598 90 192\n" simple_expect "%2598 14 192" # talk to Person 7 talk_to client 1 send "2599 90 192\n" simple_expect "=2599 $any_time 8 0 8 0 3 { 15 15 6 12 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2600 90 192\n" simple_expect "=2600 $any_time 8 0 8 0 3 { 15 15 6 12 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2601 90 192\n" simple_expect "=2601 $any_time 8 0 8 0 3 { 15 15 6 12 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 # Deleting text 192; deleter 8 send "2602 29 192\n" simple_expect ":18 14 192 $any_time 8 0 8 0 3 { 15 15 6 12 9 $any_time } 0 \\\*" simple_expect "=2602" # talk to Person 9 talk_to client 3 # Creating text 193 by 9 send "2603 86 [holl "text 193"] 0 { } 0 { }\n" simple_expect "=2603 193" # talk to Person 6 talk_to client 0 send "2604 90 193\n" simple_expect "%2604 14 193" # talk to Person 7 talk_to client 1 send "2605 90 193\n" simple_expect "%2605 14 193" # talk to Person 8 talk_to client 2 send "2606 90 193\n" simple_expect "%2606 14 193" # talk to Person 9 talk_to client 3 send "2607 90 193\n" simple_expect "=2607 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 193; adder 9 send "2608 30 193 6 0\n" # talk to Person 6 talk_to client 0 simple_expect ":3 16 193 6 0" # talk to Person 9 talk_to client 3 simple_expect "=2608" # talk to Person 6 talk_to client 0 send "2609 90 193\n" simple_expect "=2609 $any_time 9 0 8 0 3 { 0 6 6 22 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "2610 90 193\n" simple_expect "%2610 14 193" # talk to Person 8 talk_to client 2 send "2611 90 193\n" simple_expect "%2611 14 193" # talk to Person 9 talk_to client 3 send "2612 90 193\n" simple_expect "=2612 $any_time 9 0 8 0 3 { 0 6 6 22 9 $any_time } 0 \\\*" # Deleting text 193; deleter 9 send "2613 29 193\n" # talk to Person 6 talk_to client 0 simple_expect ":18 14 193 $any_time 9 0 8 0 3 { 0 6 6 22 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=2613" # Creating text 194 by 9 send "2614 86 [holl "text 194"] 0 { } 0 { }\n" simple_expect "=2614 194" # talk to Person 6 talk_to client 0 send "2615 90 194\n" simple_expect "%2615 14 194" # talk to Person 7 talk_to client 1 send "2616 90 194\n" simple_expect "%2616 14 194" # talk to Person 8 talk_to client 2 send "2617 90 194\n" simple_expect "%2617 14 194" # talk to Person 9 talk_to client 3 send "2618 90 194\n" simple_expect "=2618 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 194; adder 9 send "2619 30 194 7 0\n" simple_expect "=2619" # talk to Person 6 talk_to client 0 send "2620 90 194\n" simple_expect "%2620 14 194" # talk to Person 7 talk_to client 1 send "2621 90 194\n" simple_expect "=2621 $any_time 9 0 8 0 3 { 0 7 6 22 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2622 90 194\n" simple_expect "%2622 14 194" # talk to Person 9 talk_to client 3 send "2623 90 194\n" simple_expect "=2623 $any_time 9 0 8 0 3 { 0 7 6 22 9 $any_time } 0 \\\*" # Deleting text 194; deleter 9 send "2624 29 194\n" simple_expect "=2624" # Creating text 195 by 9 send "2625 86 [holl "text 195"] 0 { } 0 { }\n" simple_expect "=2625 195" # talk to Person 6 talk_to client 0 send "2626 90 195\n" simple_expect "%2626 14 195" # talk to Person 7 talk_to client 1 send "2627 90 195\n" simple_expect "%2627 14 195" # talk to Person 8 talk_to client 2 send "2628 90 195\n" simple_expect "%2628 14 195" # talk to Person 9 talk_to client 3 send "2629 90 195\n" simple_expect "=2629 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 195; adder 9 send "2630 30 195 8 0\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 195 8 0" # talk to Person 9 talk_to client 3 simple_expect "=2630" # talk to Person 6 talk_to client 0 send "2631 90 195\n" simple_expect "%2631 14 195" # talk to Person 7 talk_to client 1 send "2632 90 195\n" simple_expect "%2632 14 195" # talk to Person 8 talk_to client 2 send "2633 90 195\n" simple_expect "=2633 $any_time 9 0 8 0 3 { 0 8 6 22 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2634 90 195\n" simple_expect "=2634 $any_time 9 0 8 0 3 { 0 8 6 22 9 $any_time } 0 \\\*" # Deleting text 195; deleter 9 send "2635 29 195\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 195 $any_time 9 0 8 0 3 { 0 8 6 22 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=2635" # Creating text 196 by 9 send "2636 86 [holl "text 196"] 0 { } 0 { }\n" simple_expect "=2636 196" # talk to Person 6 talk_to client 0 send "2637 90 196\n" simple_expect "%2637 14 196" # talk to Person 7 talk_to client 1 send "2638 90 196\n" simple_expect "%2638 14 196" # talk to Person 8 talk_to client 2 send "2639 90 196\n" simple_expect "%2639 14 196" # talk to Person 9 talk_to client 3 send "2640 90 196\n" simple_expect "=2640 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 196; adder 9 send "2641 30 196 9 0\n" simple_expect ":3 16 196 9 0" simple_expect "=2641" # talk to Person 6 talk_to client 0 send "2642 90 196\n" simple_expect "%2642 14 196" # talk to Person 7 talk_to client 1 send "2643 90 196\n" simple_expect "%2643 14 196" # talk to Person 8 talk_to client 2 send "2644 90 196\n" simple_expect "%2644 14 196" # talk to Person 9 talk_to client 3 send "2645 90 196\n" simple_expect "=2645 $any_time 9 0 8 0 3 { 0 9 6 22 9 $any_time } 0 \\\*" # Deleting text 196; deleter 9 send "2646 29 196\n" simple_expect ":18 14 196 $any_time 9 0 8 0 3 { 0 9 6 22 9 $any_time } 0 \\\*" simple_expect "=2646" # Creating text 197 by 9 send "2647 86 [holl "text 197"] 0 { } 0 { }\n" simple_expect "=2647 197" # talk to Person 6 talk_to client 0 send "2648 90 197\n" simple_expect "%2648 14 197" # talk to Person 7 talk_to client 1 send "2649 90 197\n" simple_expect "%2649 14 197" # talk to Person 8 talk_to client 2 send "2650 90 197\n" simple_expect "%2650 14 197" # talk to Person 9 talk_to client 3 send "2651 90 197\n" simple_expect "=2651 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 197; adder 9 send "2652 30 197 10 0\n" # talk to Person 7 talk_to client 1 simple_expect ":3 16 197 10 0" # talk to Person 9 talk_to client 3 simple_expect "=2652" # talk to Person 6 talk_to client 0 send "2653 90 197\n" simple_expect "=2653 $any_time 9 0 8 0 3 { 0 10 6 22 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "2654 90 197\n" simple_expect "=2654 $any_time 9 0 8 0 3 { 0 10 6 22 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2655 90 197\n" simple_expect "=2655 $any_time 9 0 8 0 3 { 0 10 6 22 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2656 90 197\n" simple_expect "=2656 $any_time 9 0 8 0 3 { 0 10 6 22 9 $any_time } 0 \\\*" # Deleting text 197; deleter 9 send "2657 29 197\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 197 $any_time 9 0 8 0 3 { 0 10 6 22 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=2657" # Creating text 198 by 9 send "2658 86 [holl "text 198"] 0 { } 0 { }\n" simple_expect "=2658 198" # talk to Person 6 talk_to client 0 send "2659 90 198\n" simple_expect "%2659 14 198" # talk to Person 7 talk_to client 1 send "2660 90 198\n" simple_expect "%2660 14 198" # talk to Person 8 talk_to client 2 send "2661 90 198\n" simple_expect "%2661 14 198" # talk to Person 9 talk_to client 3 send "2662 90 198\n" simple_expect "=2662 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 198; adder 9 send "2663 30 198 11 0\n" # talk to Person 7 talk_to client 1 simple_expect ":3 16 198 11 0" # talk to Person 9 talk_to client 3 simple_expect "=2663" # talk to Person 6 talk_to client 0 send "2664 90 198\n" simple_expect "%2664 14 198" # talk to Person 7 talk_to client 1 send "2665 90 198\n" simple_expect "=2665 $any_time 9 0 8 0 3 { 0 11 6 22 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2666 90 198\n" simple_expect "=2666 $any_time 9 0 8 0 3 { 0 11 6 22 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2667 90 198\n" simple_expect "=2667 $any_time 9 0 8 0 3 { 0 11 6 22 9 $any_time } 0 \\\*" # Deleting text 198; deleter 9 send "2668 29 198\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 198 $any_time 9 0 8 0 3 { 0 11 6 22 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=2668" # Creating text 199 by 9 send "2669 86 [holl "text 199"] 0 { } 0 { }\n" simple_expect "=2669 199" # talk to Person 6 talk_to client 0 send "2670 90 199\n" simple_expect "%2670 14 199" # talk to Person 7 talk_to client 1 send "2671 90 199\n" simple_expect "%2671 14 199" # talk to Person 8 talk_to client 2 send "2672 90 199\n" simple_expect "%2672 14 199" # talk to Person 9 talk_to client 3 send "2673 90 199\n" simple_expect "=2673 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 199; adder 9 send "2674 30 199 13 0\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 199 13 0" # talk to Person 9 talk_to client 3 simple_expect "=2674" # talk to Person 6 talk_to client 0 send "2675 90 199\n" simple_expect "=2675 $any_time 9 0 8 0 3 { 0 13 6 22 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "2676 90 199\n" simple_expect "=2676 $any_time 9 0 8 0 3 { 0 13 6 22 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2677 90 199\n" simple_expect "=2677 $any_time 9 0 8 0 3 { 0 13 6 22 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2678 90 199\n" simple_expect "=2678 $any_time 9 0 8 0 3 { 0 13 6 22 9 $any_time } 0 \\\*" # Deleting text 199; deleter 9 send "2679 29 199\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 199 $any_time 9 0 8 0 3 { 0 13 6 22 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=2679" # Creating text 200 by 9 send "2680 86 [holl "text 200"] 0 { } 0 { }\n" simple_expect "=2680 200" # talk to Person 6 talk_to client 0 send "2681 90 200\n" simple_expect "%2681 14 200" # talk to Person 7 talk_to client 1 send "2682 90 200\n" simple_expect "%2682 14 200" # talk to Person 8 talk_to client 2 send "2683 90 200\n" simple_expect "%2683 14 200" # talk to Person 9 talk_to client 3 send "2684 90 200\n" simple_expect "=2684 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 200; adder 9 send "2685 30 200 14 0\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 200 14 0" # talk to Person 9 talk_to client 3 simple_expect "=2685" # talk to Person 6 talk_to client 0 send "2686 90 200\n" simple_expect "%2686 14 200" # talk to Person 7 talk_to client 1 send "2687 90 200\n" simple_expect "=2687 $any_time 9 0 8 0 3 { 0 14 6 22 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2688 90 200\n" simple_expect "=2688 $any_time 9 0 8 0 3 { 0 14 6 22 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2689 90 200\n" simple_expect "=2689 $any_time 9 0 8 0 3 { 0 14 6 22 9 $any_time } 0 \\\*" # Deleting text 200; deleter 9 send "2690 29 200\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 200 $any_time 9 0 8 0 3 { 0 14 6 22 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=2690" # Creating text 201 by 9 send "2691 86 [holl "text 201"] 0 { } 0 { }\n" simple_expect "=2691 201" # talk to Person 6 talk_to client 0 send "2692 90 201\n" simple_expect "%2692 14 201" # talk to Person 7 talk_to client 1 send "2693 90 201\n" simple_expect "%2693 14 201" # talk to Person 8 talk_to client 2 send "2694 90 201\n" simple_expect "%2694 14 201" # talk to Person 9 talk_to client 3 send "2695 90 201\n" simple_expect "=2695 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 201; adder 9 send "2696 30 201 6 1\n" # talk to Person 6 talk_to client 0 simple_expect ":3 16 201 6 1" # talk to Person 9 talk_to client 3 simple_expect "=2696" # talk to Person 6 talk_to client 0 send "2697 90 201\n" simple_expect "=2697 $any_time 9 0 8 0 3 { 1 6 6 23 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "2698 90 201\n" simple_expect "%2698 14 201" # talk to Person 8 talk_to client 2 send "2699 90 201\n" simple_expect "%2699 14 201" # talk to Person 9 talk_to client 3 send "2700 90 201\n" simple_expect "=2700 $any_time 9 0 8 0 3 { 1 6 6 23 9 $any_time } 0 \\\*" # Deleting text 201; deleter 9 send "2701 29 201\n" # talk to Person 6 talk_to client 0 simple_expect ":18 14 201 $any_time 9 0 8 0 3 { 1 6 6 23 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=2701" # Creating text 202 by 9 send "2702 86 [holl "text 202"] 0 { } 0 { }\n" simple_expect "=2702 202" # talk to Person 6 talk_to client 0 send "2703 90 202\n" simple_expect "%2703 14 202" # talk to Person 7 talk_to client 1 send "2704 90 202\n" simple_expect "%2704 14 202" # talk to Person 8 talk_to client 2 send "2705 90 202\n" simple_expect "%2705 14 202" # talk to Person 9 talk_to client 3 send "2706 90 202\n" simple_expect "=2706 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 202; adder 9 send "2707 30 202 7 1\n" simple_expect "=2707" # talk to Person 6 talk_to client 0 send "2708 90 202\n" simple_expect "%2708 14 202" # talk to Person 7 talk_to client 1 send "2709 90 202\n" simple_expect "=2709 $any_time 9 0 8 0 3 { 1 7 6 23 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2710 90 202\n" simple_expect "%2710 14 202" # talk to Person 9 talk_to client 3 send "2711 90 202\n" simple_expect "=2711 $any_time 9 0 8 0 3 { 1 7 6 23 9 $any_time } 0 \\\*" # Deleting text 202; deleter 9 send "2712 29 202\n" simple_expect "=2712" # Creating text 203 by 9 send "2713 86 [holl "text 203"] 0 { } 0 { }\n" simple_expect "=2713 203" # talk to Person 6 talk_to client 0 send "2714 90 203\n" simple_expect "%2714 14 203" # talk to Person 7 talk_to client 1 send "2715 90 203\n" simple_expect "%2715 14 203" # talk to Person 8 talk_to client 2 send "2716 90 203\n" simple_expect "%2716 14 203" # talk to Person 9 talk_to client 3 send "2717 90 203\n" simple_expect "=2717 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 203; adder 9 send "2718 30 203 8 1\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 203 8 1" # talk to Person 9 talk_to client 3 simple_expect "=2718" # talk to Person 6 talk_to client 0 send "2719 90 203\n" simple_expect "%2719 14 203" # talk to Person 7 talk_to client 1 send "2720 90 203\n" simple_expect "%2720 14 203" # talk to Person 8 talk_to client 2 send "2721 90 203\n" simple_expect "=2721 $any_time 9 0 8 0 3 { 1 8 6 23 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2722 90 203\n" simple_expect "=2722 $any_time 9 0 8 0 3 { 1 8 6 23 9 $any_time } 0 \\\*" # Deleting text 203; deleter 9 send "2723 29 203\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 203 $any_time 9 0 8 0 3 { 1 8 6 23 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=2723" # Creating text 204 by 9 send "2724 86 [holl "text 204"] 0 { } 0 { }\n" simple_expect "=2724 204" # talk to Person 6 talk_to client 0 send "2725 90 204\n" simple_expect "%2725 14 204" # talk to Person 7 talk_to client 1 send "2726 90 204\n" simple_expect "%2726 14 204" # talk to Person 8 talk_to client 2 send "2727 90 204\n" simple_expect "%2727 14 204" # talk to Person 9 talk_to client 3 send "2728 90 204\n" simple_expect "=2728 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 204; adder 9 send "2729 30 204 9 1\n" simple_expect ":3 16 204 9 1" simple_expect "=2729" # talk to Person 6 talk_to client 0 send "2730 90 204\n" simple_expect "%2730 14 204" # talk to Person 7 talk_to client 1 send "2731 90 204\n" simple_expect "%2731 14 204" # talk to Person 8 talk_to client 2 send "2732 90 204\n" simple_expect "%2732 14 204" # talk to Person 9 talk_to client 3 send "2733 90 204\n" simple_expect "=2733 $any_time 9 0 8 0 3 { 1 9 6 23 9 $any_time } 0 \\\*" # Deleting text 204; deleter 9 send "2734 29 204\n" simple_expect ":18 14 204 $any_time 9 0 8 0 3 { 1 9 6 23 9 $any_time } 0 \\\*" simple_expect "=2734" # Creating text 205 by 9 send "2735 86 [holl "text 205"] 0 { } 0 { }\n" simple_expect "=2735 205" # talk to Person 6 talk_to client 0 send "2736 90 205\n" simple_expect "%2736 14 205" # talk to Person 7 talk_to client 1 send "2737 90 205\n" simple_expect "%2737 14 205" # talk to Person 8 talk_to client 2 send "2738 90 205\n" simple_expect "%2738 14 205" # talk to Person 9 talk_to client 3 send "2739 90 205\n" simple_expect "=2739 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 205; adder 9 send "2740 30 205 10 1\n" # talk to Person 7 talk_to client 1 simple_expect ":3 16 205 10 1" # talk to Person 9 talk_to client 3 simple_expect "=2740" # talk to Person 6 talk_to client 0 send "2741 90 205\n" simple_expect "=2741 $any_time 9 0 8 0 3 { 1 10 6 23 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "2742 90 205\n" simple_expect "=2742 $any_time 9 0 8 0 3 { 1 10 6 23 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2743 90 205\n" simple_expect "=2743 $any_time 9 0 8 0 3 { 1 10 6 23 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2744 90 205\n" simple_expect "=2744 $any_time 9 0 8 0 3 { 1 10 6 23 9 $any_time } 0 \\\*" # Deleting text 205; deleter 9 send "2745 29 205\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 205 $any_time 9 0 8 0 3 { 1 10 6 23 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=2745" # Creating text 206 by 9 send "2746 86 [holl "text 206"] 0 { } 0 { }\n" simple_expect "=2746 206" # talk to Person 6 talk_to client 0 send "2747 90 206\n" simple_expect "%2747 14 206" # talk to Person 7 talk_to client 1 send "2748 90 206\n" simple_expect "%2748 14 206" # talk to Person 8 talk_to client 2 send "2749 90 206\n" simple_expect "%2749 14 206" # talk to Person 9 talk_to client 3 send "2750 90 206\n" simple_expect "=2750 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 206; adder 9 send "2751 30 206 11 1\n" # talk to Person 7 talk_to client 1 simple_expect ":3 16 206 11 1" # talk to Person 9 talk_to client 3 simple_expect "=2751" # talk to Person 6 talk_to client 0 send "2752 90 206\n" simple_expect "%2752 14 206" # talk to Person 7 talk_to client 1 send "2753 90 206\n" simple_expect "=2753 $any_time 9 0 8 0 3 { 1 11 6 23 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2754 90 206\n" simple_expect "=2754 $any_time 9 0 8 0 3 { 1 11 6 23 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2755 90 206\n" simple_expect "=2755 $any_time 9 0 8 0 3 { 1 11 6 23 9 $any_time } 0 \\\*" # Deleting text 206; deleter 9 send "2756 29 206\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 206 $any_time 9 0 8 0 3 { 1 11 6 23 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=2756" # Creating text 207 by 9 send "2757 86 [holl "text 207"] 0 { } 0 { }\n" simple_expect "=2757 207" # talk to Person 6 talk_to client 0 send "2758 90 207\n" simple_expect "%2758 14 207" # talk to Person 7 talk_to client 1 send "2759 90 207\n" simple_expect "%2759 14 207" # talk to Person 8 talk_to client 2 send "2760 90 207\n" simple_expect "%2760 14 207" # talk to Person 9 talk_to client 3 send "2761 90 207\n" simple_expect "=2761 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 207; adder 9 send "2762 30 207 13 1\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 207 13 1" # talk to Person 9 talk_to client 3 simple_expect "=2762" # talk to Person 6 talk_to client 0 send "2763 90 207\n" simple_expect "=2763 $any_time 9 0 8 0 3 { 1 13 6 23 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "2764 90 207\n" simple_expect "=2764 $any_time 9 0 8 0 3 { 1 13 6 23 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2765 90 207\n" simple_expect "=2765 $any_time 9 0 8 0 3 { 1 13 6 23 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2766 90 207\n" simple_expect "=2766 $any_time 9 0 8 0 3 { 1 13 6 23 9 $any_time } 0 \\\*" # Deleting text 207; deleter 9 send "2767 29 207\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 207 $any_time 9 0 8 0 3 { 1 13 6 23 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=2767" # Creating text 208 by 9 send "2768 86 [holl "text 208"] 0 { } 0 { }\n" simple_expect "=2768 208" # talk to Person 6 talk_to client 0 send "2769 90 208\n" simple_expect "%2769 14 208" # talk to Person 7 talk_to client 1 send "2770 90 208\n" simple_expect "%2770 14 208" # talk to Person 8 talk_to client 2 send "2771 90 208\n" simple_expect "%2771 14 208" # talk to Person 9 talk_to client 3 send "2772 90 208\n" simple_expect "=2772 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 208; adder 9 send "2773 30 208 14 1\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 208 14 1" # talk to Person 9 talk_to client 3 simple_expect "=2773" # talk to Person 6 talk_to client 0 send "2774 90 208\n" simple_expect "%2774 14 208" # talk to Person 7 talk_to client 1 send "2775 90 208\n" simple_expect "=2775 $any_time 9 0 8 0 3 { 1 14 6 23 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2776 90 208\n" simple_expect "=2776 $any_time 9 0 8 0 3 { 1 14 6 23 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2777 90 208\n" simple_expect "=2777 $any_time 9 0 8 0 3 { 1 14 6 23 9 $any_time } 0 \\\*" # Deleting text 208; deleter 9 send "2778 29 208\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 208 $any_time 9 0 8 0 3 { 1 14 6 23 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=2778" # Creating text 209 by 9 send "2779 86 [holl "text 209"] 0 { } 0 { }\n" simple_expect "=2779 209" # talk to Person 6 talk_to client 0 send "2780 90 209\n" simple_expect "%2780 14 209" # talk to Person 7 talk_to client 1 send "2781 90 209\n" simple_expect "%2781 14 209" # talk to Person 8 talk_to client 2 send "2782 90 209\n" simple_expect "%2782 14 209" # talk to Person 9 talk_to client 3 send "2783 90 209\n" simple_expect "=2783 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 209; adder 9 send "2784 30 209 6 15\n" # talk to Person 6 talk_to client 0 simple_expect ":3 16 209 6 15" # talk to Person 9 talk_to client 3 simple_expect "=2784" # talk to Person 6 talk_to client 0 send "2785 90 209\n" simple_expect "=2785 $any_time 9 0 8 0 3 { 15 6 6 24 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "2786 90 209\n" simple_expect "%2786 14 209" # talk to Person 8 talk_to client 2 send "2787 90 209\n" simple_expect "%2787 14 209" # talk to Person 9 talk_to client 3 send "2788 90 209\n" simple_expect "=2788 $any_time 9 0 8 0 3 { 15 6 6 24 9 $any_time } 0 \\\*" # Deleting text 209; deleter 9 send "2789 29 209\n" # talk to Person 6 talk_to client 0 simple_expect ":18 14 209 $any_time 9 0 8 0 3 { 15 6 6 24 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=2789" # Creating text 210 by 9 send "2790 86 [holl "text 210"] 0 { } 0 { }\n" simple_expect "=2790 210" # talk to Person 6 talk_to client 0 send "2791 90 210\n" simple_expect "%2791 14 210" # talk to Person 7 talk_to client 1 send "2792 90 210\n" simple_expect "%2792 14 210" # talk to Person 8 talk_to client 2 send "2793 90 210\n" simple_expect "%2793 14 210" # talk to Person 9 talk_to client 3 send "2794 90 210\n" simple_expect "=2794 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 210; adder 9 send "2795 30 210 7 15\n" simple_expect "=2795" # talk to Person 6 talk_to client 0 send "2796 90 210\n" simple_expect "%2796 14 210" # talk to Person 7 talk_to client 1 send "2797 90 210\n" simple_expect "=2797 $any_time 9 0 8 0 3 { 15 7 6 24 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2798 90 210\n" simple_expect "%2798 14 210" # talk to Person 9 talk_to client 3 send "2799 90 210\n" simple_expect "=2799 $any_time 9 0 8 0 3 { 15 7 6 24 9 $any_time } 0 \\\*" # Deleting text 210; deleter 9 send "2800 29 210\n" simple_expect "=2800" # Creating text 211 by 9 send "2801 86 [holl "text 211"] 0 { } 0 { }\n" simple_expect "=2801 211" # talk to Person 6 talk_to client 0 send "2802 90 211\n" simple_expect "%2802 14 211" # talk to Person 7 talk_to client 1 send "2803 90 211\n" simple_expect "%2803 14 211" # talk to Person 8 talk_to client 2 send "2804 90 211\n" simple_expect "%2804 14 211" # talk to Person 9 talk_to client 3 send "2805 90 211\n" simple_expect "=2805 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 211; adder 9 send "2806 30 211 8 15\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 211 8 15" # talk to Person 9 talk_to client 3 simple_expect "=2806" # talk to Person 6 talk_to client 0 send "2807 90 211\n" simple_expect "%2807 14 211" # talk to Person 7 talk_to client 1 send "2808 90 211\n" simple_expect "%2808 14 211" # talk to Person 8 talk_to client 2 send "2809 90 211\n" simple_expect "=2809 $any_time 9 0 8 0 3 { 15 8 6 24 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2810 90 211\n" simple_expect "=2810 $any_time 9 0 8 0 3 { 15 8 6 24 9 $any_time } 0 \\\*" # Deleting text 211; deleter 9 send "2811 29 211\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 211 $any_time 9 0 8 0 3 { 15 8 6 24 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=2811" # Creating text 212 by 9 send "2812 86 [holl "text 212"] 0 { } 0 { }\n" simple_expect "=2812 212" # talk to Person 6 talk_to client 0 send "2813 90 212\n" simple_expect "%2813 14 212" # talk to Person 7 talk_to client 1 send "2814 90 212\n" simple_expect "%2814 14 212" # talk to Person 8 talk_to client 2 send "2815 90 212\n" simple_expect "%2815 14 212" # talk to Person 9 talk_to client 3 send "2816 90 212\n" simple_expect "=2816 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 212; adder 9 send "2817 30 212 9 15\n" simple_expect ":3 16 212 9 15" simple_expect "=2817" # talk to Person 6 talk_to client 0 send "2818 90 212\n" simple_expect "%2818 14 212" # talk to Person 7 talk_to client 1 send "2819 90 212\n" simple_expect "%2819 14 212" # talk to Person 8 talk_to client 2 send "2820 90 212\n" simple_expect "%2820 14 212" # talk to Person 9 talk_to client 3 send "2821 90 212\n" simple_expect "=2821 $any_time 9 0 8 0 3 { 15 9 6 24 9 $any_time } 0 \\\*" # Deleting text 212; deleter 9 send "2822 29 212\n" simple_expect ":18 14 212 $any_time 9 0 8 0 3 { 15 9 6 24 9 $any_time } 0 \\\*" simple_expect "=2822" # Creating text 213 by 9 send "2823 86 [holl "text 213"] 0 { } 0 { }\n" simple_expect "=2823 213" # talk to Person 6 talk_to client 0 send "2824 90 213\n" simple_expect "%2824 14 213" # talk to Person 7 talk_to client 1 send "2825 90 213\n" simple_expect "%2825 14 213" # talk to Person 8 talk_to client 2 send "2826 90 213\n" simple_expect "%2826 14 213" # talk to Person 9 talk_to client 3 send "2827 90 213\n" simple_expect "=2827 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 213; adder 9 send "2828 30 213 10 15\n" # talk to Person 7 talk_to client 1 simple_expect ":3 16 213 10 15" # talk to Person 9 talk_to client 3 simple_expect "=2828" # talk to Person 6 talk_to client 0 send "2829 90 213\n" simple_expect "=2829 $any_time 9 0 8 0 3 { 15 10 6 24 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "2830 90 213\n" simple_expect "=2830 $any_time 9 0 8 0 3 { 15 10 6 24 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2831 90 213\n" simple_expect "=2831 $any_time 9 0 8 0 3 { 15 10 6 24 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2832 90 213\n" simple_expect "=2832 $any_time 9 0 8 0 3 { 15 10 6 24 9 $any_time } 0 \\\*" # Deleting text 213; deleter 9 send "2833 29 213\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 213 $any_time 9 0 8 0 3 { 15 10 6 24 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=2833" # Creating text 214 by 9 send "2834 86 [holl "text 214"] 0 { } 0 { }\n" simple_expect "=2834 214" # talk to Person 6 talk_to client 0 send "2835 90 214\n" simple_expect "%2835 14 214" # talk to Person 7 talk_to client 1 send "2836 90 214\n" simple_expect "%2836 14 214" # talk to Person 8 talk_to client 2 send "2837 90 214\n" simple_expect "%2837 14 214" # talk to Person 9 talk_to client 3 send "2838 90 214\n" simple_expect "=2838 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 214; adder 9 send "2839 30 214 11 15\n" # talk to Person 7 talk_to client 1 simple_expect ":3 16 214 11 15" # talk to Person 9 talk_to client 3 simple_expect "=2839" # talk to Person 6 talk_to client 0 send "2840 90 214\n" simple_expect "%2840 14 214" # talk to Person 7 talk_to client 1 send "2841 90 214\n" simple_expect "=2841 $any_time 9 0 8 0 3 { 15 11 6 24 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2842 90 214\n" simple_expect "=2842 $any_time 9 0 8 0 3 { 15 11 6 24 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2843 90 214\n" simple_expect "=2843 $any_time 9 0 8 0 3 { 15 11 6 24 9 $any_time } 0 \\\*" # Deleting text 214; deleter 9 send "2844 29 214\n" # talk to Person 7 talk_to client 1 simple_expect ":18 14 214 $any_time 9 0 8 0 3 { 15 11 6 24 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=2844" # Creating text 215 by 9 send "2845 86 [holl "text 215"] 0 { } 0 { }\n" simple_expect "=2845 215" # talk to Person 6 talk_to client 0 send "2846 90 215\n" simple_expect "%2846 14 215" # talk to Person 7 talk_to client 1 send "2847 90 215\n" simple_expect "%2847 14 215" # talk to Person 8 talk_to client 2 send "2848 90 215\n" simple_expect "%2848 14 215" # talk to Person 9 talk_to client 3 send "2849 90 215\n" simple_expect "=2849 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 215; adder 9 send "2850 30 215 13 15\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 215 13 15" # talk to Person 9 talk_to client 3 simple_expect "=2850" # talk to Person 6 talk_to client 0 send "2851 90 215\n" simple_expect "=2851 $any_time 9 0 8 0 3 { 15 13 6 24 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "2852 90 215\n" simple_expect "=2852 $any_time 9 0 8 0 3 { 15 13 6 24 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2853 90 215\n" simple_expect "=2853 $any_time 9 0 8 0 3 { 15 13 6 24 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2854 90 215\n" simple_expect "=2854 $any_time 9 0 8 0 3 { 15 13 6 24 9 $any_time } 0 \\\*" # Deleting text 215; deleter 9 send "2855 29 215\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 215 $any_time 9 0 8 0 3 { 15 13 6 24 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=2855" # Creating text 216 by 9 send "2856 86 [holl "text 216"] 0 { } 0 { }\n" simple_expect "=2856 216" # talk to Person 6 talk_to client 0 send "2857 90 216\n" simple_expect "%2857 14 216" # talk to Person 7 talk_to client 1 send "2858 90 216\n" simple_expect "%2858 14 216" # talk to Person 8 talk_to client 2 send "2859 90 216\n" simple_expect "%2859 14 216" # talk to Person 9 talk_to client 3 send "2860 90 216\n" simple_expect "=2860 $any_time 9 0 8 0 0 \\\* 0 \\\*" # Adding recipient to text 216; adder 9 send "2861 30 216 14 15\n" # talk to Person 8 talk_to client 2 simple_expect ":3 16 216 14 15" # talk to Person 9 talk_to client 3 simple_expect "=2861" # talk to Person 6 talk_to client 0 send "2862 90 216\n" simple_expect "%2862 14 216" # talk to Person 7 talk_to client 1 send "2863 90 216\n" simple_expect "=2863 $any_time 9 0 8 0 3 { 15 14 6 24 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2864 90 216\n" simple_expect "=2864 $any_time 9 0 8 0 3 { 15 14 6 24 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2865 90 216\n" simple_expect "=2865 $any_time 9 0 8 0 3 { 15 14 6 24 9 $any_time } 0 \\\*" # Deleting text 216; deleter 9 send "2866 29 216\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 216 $any_time 9 0 8 0 3 { 15 14 6 24 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 simple_expect "=2866" send_user "testing some special cases\n" # talk to Person 7 talk_to client 1 # Creating text 217 by 7 send "2867 86 [holl "text 217"] 1 { 0 10 } 0 { }\n" simple_expect ":18 15 217 $any_time 7 0 8 0 2 { 0 10 6 25 } 0 \\\*" simple_expect "=2867 217" # talk to Person 6 talk_to client 0 send "2868 90 217\n" simple_expect "=2868 $any_time 7 0 8 0 2 { 0 10 6 25 } 0 \\\*" # talk to Person 7 talk_to client 1 send "2869 90 217\n" simple_expect "=2869 $any_time 7 0 8 0 2 { 0 10 6 25 } 0 \\\*" # talk to Person 8 talk_to client 2 send "2870 90 217\n" simple_expect "=2870 $any_time 7 0 8 0 2 { 0 10 6 25 } 0 \\\*" # talk to Person 9 talk_to client 3 send "2871 90 217\n" simple_expect "=2871 $any_time 7 0 8 0 2 { 0 10 6 25 } 0 \\\*" # talk to Person 6 talk_to client 0 # Adding recipient to text 217; adder 6 send "2872 30 217 8 15\n" # talk to Person 7 talk_to client 1 simple_expect ":3 16 217 8 15" # talk to Person 8 talk_to client 2 simple_expect ":3 16 217 8 15" # talk to Person 6 talk_to client 0 simple_expect "=2872" send "2873 90 217\n" simple_expect "=2873 $any_time 7 0 8 0 6 { 0 10 6 25 15 8 6 25 8 6 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 send "2874 90 217\n" simple_expect "=2874 $any_time 7 0 8 0 6 { 0 10 6 25 15 8 6 25 8 6 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2875 90 217\n" simple_expect "=2875 $any_time 7 0 8 0 6 { 0 10 6 25 15 8 6 25 8 6 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2876 90 217\n" simple_expect "=2876 $any_time 7 0 8 0 2 { 0 10 6 25 } 0 \\\*" # talk to Person 7 talk_to client 1 # Removing recipient from text 217; remover 7 send "2877 31 217 10\n" simple_expect ":3 17 217 10 0" # talk to Person 8 talk_to client 2 simple_expect ":3 17 217 10 0" # talk to Person 7 talk_to client 1 simple_expect "=2877" # talk to Person 6 talk_to client 0 send "2878 90 217\n" simple_expect "%2878 14 217" # talk to Person 7 talk_to client 1 send "2879 90 217\n" simple_expect "=2879 $any_time 7 0 8 0 4 { 15 8 6 25 8 6 9 $any_time } 0 \\\*" # talk to Person 8 talk_to client 2 send "2880 90 217\n" simple_expect "=2880 $any_time 7 0 8 0 4 { 15 8 6 25 8 6 9 $any_time } 0 \\\*" # talk to Person 9 talk_to client 3 send "2881 90 217\n" simple_expect "%2881 14 217" # talk to Person 7 talk_to client 1 # Deleting text 217; deleter 7 send "2882 29 217\n" # talk to Person 8 talk_to client 2 simple_expect ":18 14 217 $any_time 7 0 8 0 4 { 15 8 6 25 8 6 9 $any_time } 0 \\\*" # talk to Person 7 talk_to client 1 simple_expect "=2882" # talk to Person 6 talk_to client 0 send "2883 55 0\n" simple_expect "=2883" client_death 0 # talk to Person 7 talk_to client 1 send "2884 55 0\n" simple_expect "=2884" client_death 1 # talk to Person 8 talk_to client 2 send "2885 55 0\n" simple_expect "=2885" client_death 2 # talk to Person 9 talk_to client 3 send "2886 62 5 [holl "gazonk"] 1\n" simple_expect "=2886" send "2887 42 255\n" simple_expect "=2887" send "2888 44 0\n" simple_expect "=2888" client_death 3 lyskomd_death # Automatically generated by gen-19.py. Do not edit. lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/20.exp0000664000015100472110000003056107721716133016736 # Test suite for lyskomd. # Copyright (C) 2001, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check the aux-items added in lyskomd 2.0.5 (31, 32, 10100-10104). # Check the syntax of mx-date (21). # We currently get aux-item-permission (49) instead of illegal-aux-item (48) # in several places. proc want_illegal_aux_item {tst} { global test global errorcode set test "$tst" setup_xfail "*-*-*" "Bug 192" if {$errorcode == 48} { pass "$test" } else { fail "$test" } unset test } proc enable {} { send "990 42 255\n" simple_expect "=990" } proc disable {} { send "991 42 0\n" simple_expect "=991" } read_versions lyskomd_start client_start 0 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" "connected" send "1000 62 5 [holl "gazonk"] 1\n" simple_expect "=1000" send "1001 94\n" simple_expect "=1001 $server_compat_version 1 2 3 4 0 0 \\*" # # Test canonical-name (31). # # We cannot modify the system info unless we enable our privileges. send "1002 95 0 { } 1 { 31 00000000 1 [holl "foo.bar.gazonk"] }\n" simple_expect "%1002 12 0" enable # Set the canonical-name. send "1003 95 0 { } 1 { 31 00000000 1 [holl "foo.bar.gazonk"] }\n" simple_expect "=1003" send "1004 94\n" simple_expect "=1004 $server_compat_version 1 2 3 4 0 1 { 1 31 5 $any_time 00000000 1 [holl "foo.bar.gazonk"] }" # Check that we cannot have more than one canonical-name. send "1005 95 0 { } 1 { 31 00000000 1 [holl "foo.bar.se"] }\n" extracting_expect "%1005 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for duplicate canonical-name" send "1006 94\n" simple_expect "=1006 $server_compat_version 1 2 3 4 0 1 { 1 31 5 $any_time 00000000 1 [holl "foo.bar.gazonk"] }" send "1007 95 1 { 1 } 1 { 31 00000000 1 [holl "foo.bar.gazonk:942"] }\n" simple_expect "=1007" send "1008 94\n" simple_expect "=1008 $server_compat_version 1 2 3 4 0 1 { 2 31 5 $any_time 00000000 1 [holl "foo.bar.gazonk:942"] }" # Attempt to set a few malformed canonical names, and make sure that # the name set above remains in effect. proc set_bad_canonical_name {tag} { global server_compat_version global any_time send "998 95 1 { 2 } 1 { 31 00000000 1 [holl "$tag"] }\n" simple_expect "%998 48 0" send "999 94\n" simple_expect "=999 $server_compat_version 1 2 3 4 0 1 { 2 31 5 $any_time 00000000 1 [holl "foo.bar.gazonk:942"] }" } set_bad_canonical_name "foo.bar.gazonk:942:18" set_bad_canonical_name "foo.bar:4711z" set_bad_canonical_name "foo_bar.ingate.se:4711" set_bad_canonical_name "foo_bar.ingate.se" set_bad_canonical_name "" set_bad_canonical_name ":4711" # Check that certain bits are cleared. send "1009 95 1 { 2 } 1 { 31 01111111 8 [holl "kom.lysator.liu.se"] }\n" simple_expect "=1009" send "1010 94\n" simple_expect "=1010 $server_compat_version 1 2 3 4 0 1 { 3 31 5 $any_time 00000111 8 [holl "kom.lysator.liu.se"] }" # Check that we cannot use canonical-name on texts or persons. disable send "1011 86 [holl "foo"] 0 { } 1 { 31 00000000 1 [holl "kom.liu.se"] }\n" extracting_expect "%1011 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for canonical-name on text" send "1012 89 [holl "person foo"] [holl "password"] 00000000 1 { 31 00000000 1 [holl "kom.liu.se"] }\n" extracting_expect "%1012 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for canonical-name on person" send "1013 88 [holl "conference foo"] 00000000 1 { 31 00000000 1 [holl "kom.liu.se"] }\n" extracting_expect "%1013 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for canonical-name on conference" # # Test mx-list-name (32). # # Not on system. enable send "1014 95 0 { } 1 { 32 00000000 1 [holl "foo@bar.com"] }\n" extracting_expect "%1014 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for mx-list-name on system." disable # Not on text. send "1015 86 [holl "foo"] 0 { } 1 { 32 00000000 1 [holl "foo@bar.com"] }\n" extracting_expect "%1015 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for mx-list-name on text" # Not on person. send "1016 89 [holl "person 6"] [holl "password"] 00000000 1 { 32 00000000 1 [holl "foo@bar.com"] }\n" extracting_expect "%1016 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for mx-list-name on person" # On conference. send "1017 88 [holl "conference 6"] 00000000 1 { 32 00000000 1 [holl "foo@bar.com"] }\n" extracting_expect "=1017 (6|9)" aconf 1 # The above conference should be conference 6, but is conference 9, # because the three failed attempts above to create persons or # conferences consumes conference numbers. See FIXME-comments in # do_create_conf() in conference.c, and create_person_generic in # person.c. set test "Attempting to create a conference preserves the next Conf_no" setup_xfail "*-*-*" "Bug 146 and Bug 160" if {$aconf == 6} { pass "$test" } else { fail "$test" } unset test # Test a few bad values proc set_bad_list_name {item} { global aconf global any_time send "992 93 $aconf 1 { 1 } 1 { 32 00000000 1 [holl "$item"] }\n" simple_expect "%992 48 0" send "993 91 $aconf\n" simple_expect "=993 [holl "conference 6"] 00000000 $any_time $any_time 5 0 5 0 5 0 77 77 0 1 0 0 1 { 1 32 5 $any_time 00000000 1 [holl "foo@bar.com"] }" } set_bad_list_name "foo@bar@gazonk" set_bad_list_name "foo@" set_bad_list_name "@bar" set_bad_list_name "@" set_bad_list_name "" # # Test mx-mime-belongs-to (10100) and mx-mime-part-in (10101). # # Set up a "reverse" link: the subpart is entered first. send "1018 86 [holl "part"] 1 { 0 $aconf } 1 { 10100 00000000 1 [holl "1"] }\n" simple_expect "%1018 48 0" send "1019 86 [holl "part"] 1 { 0 $aconf } 0 { }\n" simple_expect "=1019 1" send "1020 86 [holl "root"] 1 { 0 $aconf } 1 { 10101 00000000 1 [holl "1"] }\n" simple_expect "=1020 2" send "1021 92 1 0 { } 1 { 10100 00000000 1 [holl "2"] }\n" simple_expect "=1021" # Set up a "forward" link: the root is entered first. send "1022 86 [holl "root"] 1 { 0 $aconf } 1 { 10101 00000000 1 [holl "4"] }\n" simple_expect "%1022 48 0" send "1023 86 [holl "root"] 1 { 0 $aconf } 0 { }\n" simple_expect "=1023 3" send "1024 86 [holl "part"] 1 { 0 $aconf } 1 { 10101 00000000 1 [holl "3"] }\n" simple_expect "=1024 4" send "1025 92 3 0 { } 1 { 10100 00000000 1 [holl "4"] }\n" simple_expect "=1025" # Try a few broken text numbers. send "1026 86 [holl "t"] 1 { 0 $aconf } 1 { 10101 00000000 1 [holl "99"] }\n" simple_expect "%1026 48 0" send "1027 86 [holl "t"] 1 { 0 $aconf } 1 { 10101 00000000 1 [holl "t"] }\n" simple_expect "%1027 48 0" send "1028 86 [holl "t"] 1 { 0 $aconf } 1 { 10101 00000000 1 [holl ""] }\n" simple_expect "%1028 48 0" send "1029 86 [holl "t"] 1 { 0 $aconf } 1 { 10101 00000000 1 [holl "0"] }\n" simple_expect "%1029 48 0" send "1030 86 [holl "t"] 1 { 0 $aconf } 1 { 10101 00000000 1 [holl "-4711"] }\n" simple_expect "%1030 48 0" send "1031 86 [holl "t"] 1 { 0 $aconf } 1 { 10101 00000000 1 [holl "-1"] }\n" simple_expect "%1031 48 0" send "1032 86 [holl "t"] 1 { 0 $aconf } 1 { 10101 00000000 1 [holl "+1"] }\n" simple_expect "%1032 48 0" send "1033 86 [holl "t"] 1 { 0 $aconf } 1 { 10101 00000000 1 [holl " 1"] }\n" simple_expect "%1033 48 0" send "1034 86 [holl "t"] 1 { 0 $aconf } 1 { 10101 00000000 1 [holl "1 "] }\n" simple_expect "%1034 48 0" # Not on conferences. send "1035 88 [holl "badconf 1"] 00000000 1 { 10100 00000000 1 [holl "1"] }\n" extracting_expect "%1035 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for mx-mime-belongs-to on conference" send "1036 88 [holl "badconf 2"] 00000000 1 { 10101 00000000 1 [holl "1"] }\n" extracting_expect "%1036 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for mx-mime-part-in on conference" # Not on persons. send "1037 89 [holl "badperson 1"] [holl "password"] 00000000 1 { 10100 00000000 1 [holl "1"] }\n" extracting_expect "%1037 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for mx-mime-belongs-to on person" send "1038 89 [holl "badperson 1"] [holl "password"] 00000000 1 { 10101 00000000 1 [holl "1"] }\n" extracting_expect "%1038 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for mx-mime-part-in on person" # # Test mx-mime-misc (10102), mx-envelope-sender (10103) and # mx-mime-file-name (10104). # send "1039 86 [holl "y"] 1 { 0 $aconf } 3 { 10102 00000000 1 [holl "header"] 10103 00000000 1 [holl "foo@bar"] 10104 00000000 1 [holl "readme.exe"] }\n" simple_expect "=1039 5" # Not on conferences. send "1040 88 [holl "badconf 1"] 00000000 1 { 10102 00000000 1 [holl "header"] }\n" extracting_expect "%1040 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for mx-mime-belongs-to on conference" send "1041 88 [holl "badconf 1"] 00000000 1 { 10103 00000000 1 [holl "1"] }\n" extracting_expect "%1041 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for mx-mime-belongs-to on conference" send "1042 88 [holl "badconf 2"] 00000000 1 { 10104 00000000 1 [holl "1"] }\n" extracting_expect "%1042 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for mx-mime-part-in on conference" # Not on persons. send "1043 89 [holl "badperson 1"] [holl "password"] 00000000 1 { 10102 00000000 1 [holl "header"] }\n" extracting_expect "%1043 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for mx-mime-belongs-to on person" send "1044 89 [holl "badperson 1"] [holl "password"] 00000000 1 { 10103 00000000 1 [holl "1"] }\n" extracting_expect "%1044 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for mx-mime-belongs-to on person" send "1045 89 [holl "badperson 1"] [holl "password"] 00000000 1 { 10104 00000000 1 [holl "1"] }\n" extracting_expect "%1045 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for mx-mime-part-in on person" # # Test the syntax of mx-date (21). # send "1046 86 [holl "imported mail"] 1 { 0 $aconf } 1 { 21 11111111 99 [holl "2001-09-30 13:52:37"] }\n" simple_expect "=1046 6" send "1047 90 6\n" simple_expect "=1047 $any_time 5 0 13 0 2 { 0 $aconf 6 6 } 1 { 1 21 5 $any_time 00000111 99 [holl "2001-09-30 13:52:37"] }" send "1048 86 [holl "imported mail"] 1 { 0 $aconf } 1 { 21 11111111 99 [holl " 2001-09-30 13:52:37"] }\n" simple_expect "%1048 48 0" send "1049 86 [holl "imported mail"] 1 { 0 $aconf } 1 { 21 11111111 99 [holl "2001-09-30 13:52:37 "] }\n" simple_expect "%1049 48 0" send "1050 86 [holl "imported mail"] 1 { 0 $aconf } 1 { 21 00000000 1 [holl "2001-09-30 13:52:37 +0200"] }\n" simple_expect "=1050 7" send "1051 90 7\n" simple_expect "=1051 $any_time 5 0 13 0 2 { 0 $aconf 6 7 } 1 { 1 21 5 $any_time 00000000 1 25H2001-09-30 13:52:37 \\+0200 }" send "1052 86 [holl "imported mail"] 1 { 0 $aconf } 1 { 21 00000000 1 [holl "2001-09-30 13:52:37 -1150"] }\n" simple_expect "=1052 8" send "1053 90 8\n" simple_expect "=1053 $any_time 5 0 13 0 2 { 0 $aconf 6 8 } 1 { 1 21 5 $any_time 00000000 1 [holl "2001-09-30 13:52:37 -1150"] }" send "1054 86 [holl "imported mail"] 1 { 0 $aconf } 1 { 21 11111111 99 [holl "2001-09-30 13:52:37 GMT"] }\n" simple_expect "%1054 48 0" send "1055 86 [holl "imported mail"] 1 { 0 $aconf } 1 { 21 11111111 99 [holl "2001-09-30 13:52:37 +0200 "] }\n" simple_expect "%1055 48 0" send "1056 86 [holl "imported mail"] 1 { 0 $aconf } 1 { 21 11111111 99 [holl "2001-09-30 13:52:37 +0200"] }\n" simple_expect "%1056 48 0" send "1057 86 [holl "imported mail"] 1 { 0 $aconf } 1 { 21 11111111 99 [holl "2001-09-30 13:52 +0200"] }\n" simple_expect "%1057 48 0" send "1058 86 [holl "imported mail"] 1 { 0 $aconf } 1 { 21 11111111 99 [holl "2001-09-30 13:52"] }\n" simple_expect "%1058 48 0" # # Shut down # enable send "1059 44 0\n" simple_expect "=1059" client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/21.exp0000664000015100472110000003741007721716133016737 # Test suite for lyskomd. # Copyright (C) 2001, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check the owner-delete feature of aux-items. # Note: there is currently no aux-item with owner-delete that can be # used on texts, so that functionality is not tested. # Database setup. # # Persons: # 0: person 5: administrator. # 1: person 6: supervisor of 7. # 2: person 7: owner of aux-items: creator of conf 12, text 1, person 8. # 3: person 8: subpersona of person 7. # 4: person 9: innocent bystander. # 5: person 10: supervisor of person 11. # 6: person 11: creator of aux-items: subpersona of 10. # # Conferences: # conference 12: created by 7. # # Texts: # text 1: created by 7. read_versions lyskomd_start # Start client 0: person 5 (administrator), enabled. client_start 0 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" "connected" send "1000 80 0 { }\n" simple_expect "=1000" send "1001 62 5 [holl "gazonk"] 1\n" simple_expect "=1001" send "1002 42 255\n" simple_expect "=1002" # Start client 1: person 6. client_start 1 talk_to client 1 send "A3Hbar\n" simple_expect "LysKOM" send "1003 80 0 { }\n" simple_expect "=1003" send "1004 89 [holl "Person 6"] [holl "password"] 00000000 0 { }\n" simple_expect "=1004 6" send "1005 62 6 [holl "password"] 0\n" simple_expect "=1005" # Create person 7. send "1006 89 [holl "Person 7"] [holl "password"] 00000000 0 { }\n" simple_expect "=1006 7" send "1007 91 7\n" simple_expect "=1007 [holl "Person 7"] 10011000 $any_time $any_time 6 0 6 0 6 0 77 77 1 1 0 0 0 \\*" # Start client 2: person 7. client_start 2 talk_to client 2 send "A3Hbar\n" simple_expect "LysKOM" send "1008 80 0 { }\n" simple_expect "=1008" send "1009 62 7 [holl "password"] 0\n" simple_expect "=1009" # Create person 8. send "1010 89 [holl "Person 8"] [holl "password"] 00000000 0 { }\n" simple_expect "=1010 8" send "1011 91 8\n" simple_expect "=1011 [holl "Person 8"] 10011000 $any_time $any_time 7 0 7 0 7 0 77 77 1 1 0 0 0 \\*" # Start client 3: person 8. client_start 3 talk_to client 3 send "A3Hbar\n" simple_expect "LysKOM" send "1012 80 0 { }\n" simple_expect "=1012" send "1013 62 8 [holl "password"] 0\n" simple_expect "=1013" # Start client 4: person 9. client_start 4 talk_to client 4 send "A3Hfoo\n" simple_expect "LysKOM" send "1014 80 0 { }\n" simple_expect "=1014" send "1015 89 [holl "Person 9"] [holl "password"] 00000000 0 { }\n" simple_expect "=1015 9" send "1016 62 9 [holl "password"] 0\n" simple_expect "=1016" # Start client 5: person 10. client_start 5 talk_to client 5 send "A3Hbar\n" simple_expect "LysKOM" send "1017 80 0 { }\n" simple_expect "=1017" send "1018 89 [holl "Person 10"] [holl "password"] 00000000 0 { }\n" simple_expect "=1018 10" send "1019 62 10 [holl "password"] 0\n" simple_expect "=1019" # Create person 11. send "1020 89 [holl "Person 11"] [holl "password"] 00000000 0 { }\n" simple_expect "=1020 11" send "1021 91 11\n" simple_expect "=1021 [holl "Person 11"] 10011000 $any_time $any_time 10 0 10 0 10 0 77 77 1 1 0 0 0 \\*" # Start client 6: person 11. client_start 6 talk_to client 6 send "A3Hbar\n" simple_expect "LysKOM" send "1022 80 0 { }\n" simple_expect "=1022" send "1023 62 11 [holl "password"] 0\n" simple_expect "=1023" # Create conference 12 and text 1. talk_to client 2 send "1024 88 [holl "Conference 12"] 00000000 0 { }\n" simple_expect "=1024 12" send "1025 86 [holl "Text 1"] 1 { 0 12 } 0 { }\n" simple_expect "=1025 1" # # Now that the database is set up, perform some real tests. # # # Test 8: redirect. # # Delete aux-item with owner-delete when creator. talk_to client 6 # Check that conference 12 and text 1 are devoid of aux-items. send "1026 90 1\n" simple_expect "=1026 $any_time 7 0 6 0 2 { 0 12 6 1 } 0 \\*" send "1027 91 12\n" simple_expect "=1027 [holl "Conference 12"] 00000000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 1 0 0 \\*" # Set supervisor of 12 to 11. talk_to client 2 send "1028 18 12 11\n" simple_expect "=1028" talk_to client 6 send "1029 93 12 0 { } 1 { 8 00000000 1 [holl "E-mail:ceder@lysator.liu.se"] }\n" simple_expect "=1029" # Reset supervisor of 12 to 7. send "1030 18 12 7\n" simple_expect "=1030" send "1031 91 12\n" simple_expect "=1031 [holl "Conference 12"] 00000000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 1 0 1 { 1 8 11 $any_time 00000000 1 [holl "E-mail:ceder@lysator.liu.se"] }" send "1032 93 12 1 { 1 } 0 { }\n" simple_expect "=1032" # Delete aux-item with owner-delete when owner. talk_to client 6 # Check that conference 12 and text 1 are devoid of aux-items. send "1033 90 1\n" simple_expect "=1033 $any_time 7 0 6 0 2 { 0 12 6 1 } 0 \\*" send "1034 91 12\n" simple_expect "=1034 [holl "Conference 12"] 00000000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 1 0 0 \\*" # Set supervisor of 12 to 11. talk_to client 2 send "1035 18 12 11\n" simple_expect "=1035" talk_to client 6 send "1036 93 12 0 { } 1 { 8 00000000 1 [holl "E-mail:ceder@lysator.liu.se"] }\n" simple_expect "=1036" # Reset supervisor of 12 to 7. send "1037 18 12 7\n" simple_expect "=1037" send "1038 91 12\n" simple_expect "=1038 [holl "Conference 12"] 00000000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 1 0 1 { 2 8 11 $any_time 00000000 1 [holl "E-mail:ceder@lysator.liu.se"] }" talk_to client 2 send "1039 93 12 1 { 2 } 0 { }\n" simple_expect "=1039" # Delete aux-item with owner-delete when supervisor of creator. talk_to client 6 # Check that conference 12 and text 1 are devoid of aux-items. send "1040 90 1\n" simple_expect "=1040 $any_time 7 0 6 0 2 { 0 12 6 1 } 0 \\*" send "1041 91 12\n" simple_expect "=1041 [holl "Conference 12"] 00000000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 1 0 0 \\*" # Set supervisor of 12 to 11. talk_to client 2 send "1042 18 12 11\n" simple_expect "=1042" talk_to client 6 send "1043 93 12 0 { } 1 { 8 00000000 1 [holl "E-mail:ceder@lysator.liu.se"] }\n" simple_expect "=1043" # Reset supervisor of 12 to 7. send "1044 18 12 7\n" simple_expect "=1044" send "1045 91 12\n" simple_expect "=1045 [holl "Conference 12"] 00000000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 1 0 1 { 3 8 11 $any_time 00000000 1 [holl "E-mail:ceder@lysator.liu.se"] }" talk_to client 5 send "1046 93 12 1 { 3 } 0 { }\n" simple_expect "=1046" # Delete aux-item with owner-delete when supervisor of owner. talk_to client 6 # Check that conference 12 and text 1 are devoid of aux-items. send "1047 90 1\n" simple_expect "=1047 $any_time 7 0 6 0 2 { 0 12 6 1 } 0 \\*" send "1048 91 12\n" simple_expect "=1048 [holl "Conference 12"] 00000000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 1 0 0 \\*" # Set supervisor of 12 to 11. talk_to client 2 send "1049 18 12 11\n" simple_expect "=1049" talk_to client 6 send "1050 93 12 0 { } 1 { 8 00000000 1 [holl "E-mail:ceder@lysator.liu.se"] }\n" simple_expect "=1050" # Reset supervisor of 12 to 7. send "1051 18 12 7\n" simple_expect "=1051" send "1052 91 12\n" simple_expect "=1052 [holl "Conference 12"] 00000000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 1 0 1 { 4 8 11 $any_time 00000000 1 [holl "E-mail:ceder@lysator.liu.se"] }" talk_to client 6 send "1053 93 12 1 { 4 } 0 { }\n" simple_expect "=1053" # Delete aux-item with owner-delete when ENA. talk_to client 6 # Check that conference 12 and text 1 are devoid of aux-items. send "1054 90 1\n" simple_expect "=1054 $any_time 7 0 6 0 2 { 0 12 6 1 } 0 \\*" send "1055 91 12\n" simple_expect "=1055 [holl "Conference 12"] 00000000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 1 0 0 \\*" # Set supervisor of 12 to 11. talk_to client 2 send "1056 18 12 11\n" simple_expect "=1056" talk_to client 6 send "1057 93 12 0 { } 1 { 8 00000000 1 [holl "E-mail:ceder@lysator.liu.se"] }\n" simple_expect "=1057" # Reset supervisor of 12 to 7. send "1058 18 12 7\n" simple_expect "=1058" send "1059 91 12\n" simple_expect "=1059 [holl "Conference 12"] 00000000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 1 0 1 { 5 8 11 $any_time 00000000 1 [holl "E-mail:ceder@lysator.liu.se"] }" talk_to client 0 send "1060 93 12 1 { 5 } 0 { }\n" simple_expect "=1060" # Delete aux-item with owner-delete when someone else. talk_to client 6 # Check that conference 12 and text 1 are devoid of aux-items. send "1061 90 1\n" simple_expect "=1061 $any_time 7 0 6 0 2 { 0 12 6 1 } 0 \\*" send "1062 91 12\n" simple_expect "=1062 [holl "Conference 12"] 00000000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 1 0 0 \\*" # Set supervisor of 12 to 11. talk_to client 2 send "1063 18 12 11\n" simple_expect "=1063" talk_to client 6 send "1064 93 12 0 { } 1 { 8 00000000 1 [holl "E-mail:ceder@lysator.liu.se"] }\n" simple_expect "=1064" # Reset supervisor of 12 to 7. send "1065 18 12 7\n" simple_expect "=1065" send "1066 91 12\n" simple_expect "=1066 [holl "Conference 12"] 00000000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 1 0 1 { 6 8 11 $any_time 00000000 1 [holl "E-mail:ceder@lysator.liu.se"] }" talk_to client 4 send "1067 93 12 1 { 6 } 0 { }\n" simple_expect "%1067 49 0" # Check that Conference 12 looks OK. send "1068 91 12\n" simple_expect "=1068 [holl "Conference 12"] 00000000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 1 0 1 { 6 8 11 $any_time 00000000 1 [holl "E-mail:ceder@lysator.liu.se"] }" # # Test 14: faq-text # # Delete aux-item with owner-delete when creator. talk_to client 6 # Ensure that conference 12 and text 1 are devoid of aux-items. send "1069 93 12 1 { 6 } 0 { }\n" simple_expect "=1069" send "1070 90 1\n" simple_expect "=1070 $any_time 7 0 6 0 2 { 0 12 6 1 } 0 \\*" send "1071 91 12\n" simple_expect "=1071 [holl "Conference 12"] 00000000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 1 0 0 \\*" # Set supervisor of 12 to 11. talk_to client 2 send "1072 18 12 11\n" simple_expect "=1072" talk_to client 6 send "1073 93 12 0 { } 1 { 14 00000000 1 [holl "1"] }\n" simple_expect "=1073" # Reset supervisor of 12 to 7. send "1074 18 12 7\n" simple_expect "=1074" send "1075 91 12\n" simple_expect "=1075 [holl "Conference 12"] 00000000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 1 0 1 { 7 14 11 $any_time 00000000 1 [holl "1"] }" send "1076 93 12 1 { 7 } 0 { }\n" simple_expect "=1076" # Delete aux-item with owner-delete when owner. talk_to client 6 # Check that conference 12 and text 1 are devoid of aux-items. send "1077 90 1\n" simple_expect "=1077 $any_time 7 0 6 0 2 { 0 12 6 1 } 0 \\*" send "1078 91 12\n" simple_expect "=1078 [holl "Conference 12"] 00000000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 1 0 0 \\*" # Set supervisor of 12 to 11. talk_to client 2 send "1079 18 12 11\n" simple_expect "=1079" talk_to client 6 send "1080 93 12 0 { } 1 { 14 00000000 1 [holl "1"] }\n" simple_expect "=1080" # Reset supervisor of 12 to 7. send "1081 18 12 7\n" simple_expect "=1081" send "1082 91 12\n" simple_expect "=1082 [holl "Conference 12"] 00000000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 1 0 1 { 8 14 11 $any_time 00000000 1 [holl "1"] }" talk_to client 2 send "1083 93 12 1 { 8 } 0 { }\n" simple_expect "=1083" # Delete aux-item with owner-delete when supervisor of creator. talk_to client 6 # Check that conference 12 and text 1 are devoid of aux-items. send "1084 90 1\n" simple_expect "=1084 $any_time 7 0 6 0 2 { 0 12 6 1 } 0 \\*" send "1085 91 12\n" simple_expect "=1085 [holl "Conference 12"] 00000000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 1 0 0 \\*" # Set supervisor of 12 to 11. talk_to client 2 send "1086 18 12 11\n" simple_expect "=1086" talk_to client 6 send "1087 93 12 0 { } 1 { 14 00000000 1 [holl "1"] }\n" simple_expect "=1087" # Reset supervisor of 12 to 7. send "1088 18 12 7\n" simple_expect "=1088" send "1089 91 12\n" simple_expect "=1089 [holl "Conference 12"] 00000000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 1 0 1 { 9 14 11 $any_time 00000000 1 [holl "1"] }" talk_to client 5 send "1090 93 12 1 { 9 } 0 { }\n" simple_expect "=1090" # Delete aux-item with owner-delete when supervisor of owner. talk_to client 6 # Check that conference 12 and text 1 are devoid of aux-items. send "1091 90 1\n" simple_expect "=1091 $any_time 7 0 6 0 2 { 0 12 6 1 } 0 \\*" send "1092 91 12\n" simple_expect "=1092 [holl "Conference 12"] 00000000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 1 0 0 \\*" # Set supervisor of 12 to 11. talk_to client 2 send "1093 18 12 11\n" simple_expect "=1093" talk_to client 6 send "1094 93 12 0 { } 1 { 14 00000000 1 [holl "1"] }\n" simple_expect "=1094" # Reset supervisor of 12 to 7. send "1095 18 12 7\n" simple_expect "=1095" send "1096 91 12\n" simple_expect "=1096 [holl "Conference 12"] 00000000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 1 0 1 { 10 14 11 $any_time 00000000 1 [holl "1"] }" talk_to client 6 send "1097 93 12 1 { 10 } 0 { }\n" simple_expect "=1097" # Delete aux-item with owner-delete when ENA. talk_to client 6 # Check that conference 12 and text 1 are devoid of aux-items. send "1098 90 1\n" simple_expect "=1098 $any_time 7 0 6 0 2 { 0 12 6 1 } 0 \\*" send "1099 91 12\n" simple_expect "=1099 [holl "Conference 12"] 00000000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 1 0 0 \\*" # Set supervisor of 12 to 11. talk_to client 2 send "1100 18 12 11\n" simple_expect "=1100" talk_to client 6 send "1101 93 12 0 { } 1 { 14 00000000 1 [holl "1"] }\n" simple_expect "=1101" # Reset supervisor of 12 to 7. send "1102 18 12 7\n" simple_expect "=1102" send "1103 91 12\n" simple_expect "=1103 [holl "Conference 12"] 00000000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 1 0 1 { 11 14 11 $any_time 00000000 1 [holl "1"] }" talk_to client 0 send "1104 93 12 1 { 11 } 0 { }\n" simple_expect "=1104" # Delete aux-item with owner-delete when someone else. talk_to client 6 # Check that conference 12 and text 1 are devoid of aux-items. send "1105 90 1\n" simple_expect "=1105 $any_time 7 0 6 0 2 { 0 12 6 1 } 0 \\*" send "1106 91 12\n" simple_expect "=1106 [holl "Conference 12"] 00000000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 1 0 0 \\*" # Set supervisor of 12 to 11. talk_to client 2 send "1107 18 12 11\n" simple_expect "=1107" talk_to client 6 send "1108 93 12 0 { } 1 { 14 00000000 1 [holl "1"] }\n" simple_expect "=1108" # Reset supervisor of 12 to 7. send "1109 18 12 7\n" simple_expect "=1109" send "1110 91 12\n" simple_expect "=1110 [holl "Conference 12"] 00000000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 1 0 1 { 12 14 11 $any_time 00000000 1 [holl "1"] }" talk_to client 4 send "1111 93 12 1 { 12 } 0 { }\n" simple_expect "%1111 49 0" # Check that Conference 12 and text 1 looks OK. send "1112 91 12\n" simple_expect "=1112 [holl "Conference 12"] 00000000 $any_time $any_time 7 0 7 0 7 0 77 77 0 1 1 0 1 { 12 14 11 $any_time 00000000 1 [holl "1"] }" send "1105 90 1\n" simple_expect "=1105 $any_time 7 0 6 0 2 { 0 12 6 1 } 1 { 6 28 11 $any_time 00001000 0 [holl "12"] }" # # Shut down # talk_to client 6 send "1113 55 0\n" simple_expect "=1113" client_death 6 talk_to client 5 send "1114 55 0\n" simple_expect "=1114" client_death 5 talk_to client 4 send "1115 55 0\n" simple_expect "=1115" client_death 4 talk_to client 3 send "1116 55 0\n" simple_expect "=1116" client_death 3 talk_to client 2 send "1117 55 0\n" simple_expect "=1117" client_death 2 talk_to client 1 send "1118 55 0\n" simple_expect "=1118" client_death 1 talk_to client 0 send "1119 42 255\n" simple_expect "=1119" send "1120 44 0\n" simple_expect "=1120" client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/22.exp0000664000015100472110000000255107721716133016736 # Test suite for lyskomd. # Copyright (C) 2001, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check that the default English database is loadable. lyskomd_start "" "" "" "" "-en" # Start client 0: person 5 (administrator), enable him. client_start 0 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" "connected" send "1001 62 5 [holl "gazonk"] 1\n" simple_expect "=1001" send "1119 42 255\n" simple_expect "=1119" # Shut down the server. send "1120 44 0\n" simple_expect "=1120" client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/23.exp0000664000015100472110000005047207721716133016744 # Test suite for lyskomd. # Copyright (C) 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check the aux-item send-comments-to (33). # This file checks the variant of send-comments-to that omits the # recipient type. See 28.exp for tests that includes the recipient # type. # FIXME (bug 314): When a mirror aux-item is implemented, this test # should be extended with get-conf-stat calls that checks that the # mirroring aux-item is set and removed appropriately. # There are three major players: # # 5. (client 0) The administrator. # 6. (client 1) # 7. (client 2) # # There are a few major conferences: # # 8. Created by 6. Public. Members: 6. # 9. Created by 6. Rd-prot. Members: 6. # 10. Created by 6. Secret. Members: 6. # # Some texts: # # 1. Created by 6. Recipients: 8. # 2. Created by 6. Recipients: 9. # 3. Created by 6. Recipients: 10. # We currently get aux-item-permission (49) instead of illegal-aux-item (48) # in several places. proc want_illegal_aux_item {tst} { global test global errorcode set test "$tst" setup_xfail "*-*-*" "Bug 192" if {$errorcode == 48} { pass "$test" } else { fail "$test" } unset test } proc enable {} { send "990 42 255\n" simple_expect "=990" } proc disable {} { send "991 42 0\n" simple_expect "=991" } read_versions lyskomd_start client_start 0 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" "connected" send "1000 94\n" simple_expect "=1000 $server_compat_version 1 2 3 4 0 0 \\*" send "1001 62 5 [holl "gazonk"] 1\n" simple_expect "=1001" # Populate the database. client_start 1 talk_to client 1 send "A3Hbar\n" simple_expect "LysKOM" send "1002 89 [holl "Person 6"] [holl "pswd6"] 00 0 { }\n" simple_expect "=1002 6" send "1003 62 6 [holl "pswd6"] 1\n" simple_expect "=1003" client_start 2 talk_to client 2 send "A 10Hfoo@bar.se\n" simple_expect "LysKOM" send "1004 89 [holl "Person 7"] [holl "pswd7"] 00 0 { }\n" simple_expect "=1004 7" send "1005 62 7 [holl "pswd7"] 1\n" simple_expect "=1005" talk_to client 1 send "1006 88 [holl "conf 8"] 0000 0 { }\n" simple_expect "=1006 8" send "1007 88 [holl "conf 9"] 1000 0 { }\n" simple_expect "=1007 9" send "1008 88 [holl "conf 10"] 1010 0 { }\n" simple_expect "=1008 10" # (Test to create a public-secret conf with four-bit conference type.) send "1009 88 [holl "conf 11"] 0010 0 { }\n" simple_expect "%1009 22 0" # (Test to create a public-secret conf using create-conf-old.) send "1010 10 [holl "conf 11"] 0010\n" simple_expect "%1010 22 0" send "1011 86 [holl "text 1"] 1 { 0 8 } 0 { }\n" simple_expect "=1011 1" send "1012 86 [holl "text 2"] 1 { 0 9 } 0 { }\n" simple_expect "=1012 2" send "1013 86 [holl "text 3"] 1 { 0 10 } 0 { }\n" simple_expect "=1013 3" # # Test send-comments-to # set next_conf 11 # Attempt to set "0" while creating a conference. # Should fail, since we can only set send-comments-to on letterboxes. talk_to client 1 send "1014 88 [holl "conf $next_conf I"] 00000000 1 { 33 00000000 1 [holl "0"] }\n" extracting_expect "%1014 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on conference" # Attempt to set "1" while creating a conference. # Should fail, since we can only set send-comments-to on letterboxes. send "1015 88 [holl "conf $next_conf II"] 00000000 1 { 33 00000000 1 [holl "1"] }\n" extracting_expect "%1015 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on conference" # Attempt to set "0" while creating a text. # Should fail, since we can only set send-comments-to on letterboxes. send "1016 86 [holl "text N"] 1 { 0 1 } 1 { 33 00000000 1 [holl "0"] }\n" extracting_expect "%1016 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on texts" # Attempt to set "1" while creating a text. # Should fail, since we can only set send-comments-to on letterboxes. send "1017 86 [holl "text N"] 1 { 0 1 } 1 { 33 00000000 1 [holl "1"] }\n" extracting_expect "%1017 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on texts" # Attempt to set "0" on system while enabled. # Should fail, since we can only set send-comments-to on letterboxes. talk_to client 0 enable send "1018 95 0 { } 1 { 33 00000000 1 [holl "0"] }\n" extracting_expect "%1018 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on system" # Attempt to set "1" on system while enabled. # Should fail, since we can only set send-comments-to on letterboxes. send "1019 95 0 { } 1 { 33 00000000 1 [holl "1"] }\n" extracting_expect "%1019 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on system" # Attempt to set "0" on an existing conference. # Should fail, since we can only set send-comments-to on letterboxes. talk_to client 1 send "1020 93 10 0 { } 1 { 33 00000000 1 [holl "0"] }\n" extracting_expect "%1020 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on conference" # Attempt to set "1" on an existing conference. # Should fail, since we can only set send-comments-to on letterboxes. send "1021 93 10 0 { } 1 { 33 00000000 1 [holl "1"] }\n" extracting_expect "%1021 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on conference" # Attempt to set "0" on an existing text. # Should fail, since we can only set send-comments-to on letterboxes. send "1022 92 3 0 { } 1 { 33 00000000 1 [holl "0"] }\n" extracting_expect "%1022 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on text" # Attempt to set "1" on an existing text. # Should fail, since we can only set send-comments-to on letterboxes. send "1023 92 3 0 { } 1 { 33 00000000 1 [holl "1"] }\n" extracting_expect "%1023 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on text" # Attempt to set "0" while creating a person. # Should work. client_start 3 talk_to client 3 send "A4Hheja\n" simple_expect "LysKOM" send "1024 89 [holl "person $next_conf III"] [holl "pwd"] 00000000 1 { 33 00000000 1 [holl "0"] }\n" extracting_expect "=1024 (\[0-9\]*)" conf_no 1 setup_xfail "*-*-*" "Bug 146" if {$conf_no == $next_conf} { pass set next_conf [expr {1 + $next_conf}] } else { fail "got wrong person number" set next_conf [expr {1 + $conf_no}] } # Attempt to set "1" while creating a person. # Should work. send "1025 89 [holl "person $next_conf IV"] [holl "pwd"] 00000000 1 { 33 00000000 1 [holl "1"] }\n" simple_expect "=1025 $next_conf" set conf_IV $next_conf set next_conf [expr {1 + $next_conf}] # Attempt to set "99" while creating a person. # Should fail, because no such conference exists, but because there is # no mirror aux item (bug 314) this will work. send "1026 89 [holl "person $next_conf V"] [holl "pwd"] 00000000 1 { 33 00000000 1 [holl "99"] }\n" # We need a version of simple_expect with a list of expected errors... setup_xfail "*-*-*" "Bug 314" if {0} { pass "Creation of person with send-comments-to to nonexisting conference forbidden" simple_expect "%1026 49 0" } else { fail "Creation of person with send-comments-to to nonexisting conference forbidden" simple_expect "=1026 $next_conf" set next_conf [expr {1 + $next_conf}] } # Attempt to set "10", a secret conference, while creating a person. # Should fail, because no such conference exists, but because there is # no mirror aux item (bug 314) this will work. send "1027 89 [holl "person $next_conf VI"] [holl "pwd"] 00000000 1 { 33 00000000 1 [holl "10"] }\n" setup_xfail "*-*-*" "Bug 314" if {0} { pass "Creation of person with send-comments-to to secret conference forbidden" simple_expect "=1027 49 0" } else { fail "Creation of person with send-comments-to to secret conference forbidden" simple_expect "=1027 $next_conf" set next_conf [expr {1 + $next_conf}] } # Attempt to set "9", an rd-prot conference, while creating a person. # Should work. send "1028 89 [holl "person $next_conf VII"] [holl "pwd"] 00000000 1 { 33 00000000 1 [holl "9"] }\n" simple_expect "=1028 $next_conf" set created_person $next_conf set next_conf [expr {1 + $next_conf}] # Set "9", an rd-prot conference, on person 6. # Should work. talk_to client 1 send "1029 93 6 0 { } 1 { 33 00000000 1 [holl "9"] }\n" simple_expect "=1029" # Set "10", a secret conference that is visible to the administrator, # on person 6. Should fail -- there can be only one send-comments-to. talk_to client 0 enable send "1030 93 6 0 { } 1 { 33 00000000 1 [holl "10"] }\n" setup_xfail "*-*-*" "Bug 327" if {0} { simple_expect "%1029 49 0" } else { fail "unique dosen't mean globally unique" simple_expect "=1030" # Remove the send-comments-to. send "900 93 6 1 { 2 } 0 { }\n" simple_expect "=900" } # Remove the send-comments-to. send "1031 93 6 1 { 1 } 0 { }\n" simple_expect "=1031" # Set "10", a secret conference that is visible to the # administrator and to person 6. Should work. send "1032 93 6 0 { } 1 { 33 00000000 1 [holl "10"] }\n" simple_expect "=1032" # Fetch the conference status of person 6. The aux-item should be # visible. send "1033 91 6\n" extracting_expect "=1033 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 1 { (2|3) 33 5 $any_time 00000000 1 [holl "10"] }" auxno 1 setup_xfail "*-*-*" "Bug 327" if {$auxno == 2} { pass "Correct aux-no" } else { # We were able to create an aux-item above that should have failed, # so the numbers are now wrong. fail "Correct aux-no" } # Fetch the conference status of person 6. The aux-item should be # visible. talk_to client 1 send "1034 91 6\n" simple_expect "=1034 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 1 { $auxno 33 5 $any_time 00000000 1 [holl "10"] }" # Fetch the conference status of person 6. The aux-item should not be # visible, because conference 10 is secret and person 7 isn't allowed # to see it. talk_to client 2 # (Check that the various get-conf-stat* calls really fail.) send "1035 13 10 0\n" simple_expect "%1035 9 10" send "1036 13 10 1\n" simple_expect "%1036 9 10" send "1037 50 10\n" simple_expect "%1037 9 10" send "1038 91 10\n" simple_expect "%1038 9 10" send "1039 91 6\n" setup_xfail "*-*-*" "Bug 314" if {0} { pass "Person 7 cannot see conference 10" simple_expect "=1039 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 0 { }" } else { fail "Person 7 cannot see conference 10" simple_expect "=1039 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 1 { $auxno 33 5 $any_time 00000000 1 [holl "10"] }" } # Remove the aux-item. talk_to client 0 send "1040 93 6 1 { $auxno } 0 { }\n" simple_expect "=1040" # Attempt to set some bad values, including the empty string, negative # numbers, hexadecimal numbers, whitespace-separated digits, et c. # They should all fail. talk_to client 1 send "1041 93 6 0 { } 1 { 33 00000000 1 [holl ""] }\n" simple_expect "%1041 48 0" send "1042 93 6 0 { } 1 { 33 00000000 1 [holl " "] }\n" simple_expect "%1042 48 0" send "1043 93 6 0 { } 1 { 33 00000000 1 [holl "-1"] }\n" simple_expect "%1043 48 0" send "1044 93 6 0 { } 1 { 33 00000000 1 [holl "-6"] }\n" simple_expect "%1044 48 0" send "1045 93 6 0 { } 1 { 33 00000000 1 [holl "a"] }\n" simple_expect "%1045 48 0" send "1046 93 6 0 { } 1 { 33 00000000 1 [holl "0a"] }\n" simple_expect "%1046 48 0" send "1047 93 6 0 { } 1 { 33 00000000 1 [holl "0x0a"] }\n" simple_expect "%1047 48 0" send "1048 93 6 0 { } 1 { 33 00000000 1 [holl "06"] }\n" simple_expect "%1048 48 0" send "1049 93 6 0 { } 1 { 33 00000000 1 [holl "5 2"] }\n" simple_expect "%1049 48 0" send "1050 93 6 0 { } 1 { 33 00000000 1 [holl "5 5"] }\n" simple_expect "%1050 48 0" send "1051 93 6 0 { } 1 { 33 00000000 1 [holl "5 "] }\n" simple_expect "%1051 48 0" send "1052 93 6 0 { } 1 { 33 00000000 1 [holl " 5 "] }\n" simple_expect "%1052 48 0" send "1053 93 6 0 { } 1 { 33 00000000 1 [holl " 5"] }\n" simple_expect "%1053 48 0" send "1054 93 6 0 { } 1 { 33 00000000 1 [holl "0 "] }\n" simple_expect "%1054 48 0" send "1055 93 6 0 { } 1 { 33 00000000 1 [holl " 0 "] }\n" simple_expect "%1055 48 0" send "1056 93 6 0 { } 1 { 33 00000000 1 [holl " 0"] }\n" simple_expect "%1056 48 0" # Set to "0". send "1057 94\n" simple_expect "=1057 $server_compat_version 1 2 3 4 0 0 \\*" send "1058 93 6 0 { } 1 { 33 00000000 1 [holl "0"] }\n" simple_expect "=1058" send "1059 94\n" simple_expect "=1059 $server_compat_version 1 2 3 4 0 0 \\*" # Check visibility for person 6. send "1060 91 6\n" extracting_expect "=1060 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 1 { (\[0-9\]*) 33 6 $any_time 00000000 1 [holl "0"] }" zeroauxno 1 if {$zeroauxno == $auxno + 1} { pass "Correct aux-no II" } else { fail "Correct aux-no II" } # Check visibility for person 7. talk_to client 2 send "1061 91 6\n" simple_expect "=1061 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 1 { $zeroauxno 33 6 $any_time 00000000 1 [holl "0"] }" # Remove "0" and set to "6". talk_to client 1 send "1062 93 6 1 { $zeroauxno } 1 { 33 00000000 1 [holl "6"] }\n" simple_expect "=1062" send "1063 94\n" simple_expect "=1063 $server_compat_version 1 2 3 4 0 0 \\*" # Check visibility for person 6. send "1064 91 6\n" extracting_expect "=1064 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 1 { (\[0-9\]*) 33 6 $any_time 00000000 1 [holl "6"] }" sixauxno 1 if {$sixauxno == $zeroauxno + 1} { pass "Correct aux-no III" } else { fail "Correct aux-no III" } # Check visibility for person 7. talk_to client 2 send "1065 91 6\n" simple_expect "=1065 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 1 { $sixauxno 33 6 $any_time 00000000 1 [holl "6"] }" # Remove "6". talk_to client 0 send "1066 93 6 1 { $sixauxno } 0 { }\n" simple_expect "=1066" # Set to "10". talk_to client 1 send "1067 93 6 0 { } 1 { 33 00000000 1 [holl "10"] }\n" simple_expect "=1067" # Check visibility for person 6. send "1068 91 6\n" extracting_expect "=1068 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 1 { (\[0-9\]*) 33 6 $any_time 00000000 1 [holl "10"] }" tenauxno 1 if {$tenauxno == $sixauxno + 1} { pass "Correct aux-no IV" } else { fail "Correct aux-no IV" } # Check visibility for person 7. Should not be visible. talk_to client 2 send "1069 91 6\n" setup_xfail "*-*-*" "Bug 314" if {0} { pass "Person 7 cannot see conference 10" simple_expect "=1069 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 0 { }" } else { fail "Person 7 cannot see conference 10" simple_expect "=1069 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 1 { $tenauxno 33 6 $any_time 00000000 1 [holl "10"] }" } # Remove "10". talk_to client 1 send "1070 93 6 1 { $tenauxno } 0 { }\n" simple_expect "=1070" # Change "10" to "9". Should fail, since "10" is already removed. # FIXME (bug 328): What error code should be returned? Currently, # 49=aux-item-permission is returned, but is that really proper? send "1071 93 6 1 { $tenauxno } 1 { 33 00000000 1 [holl "9"] }\n" simple_expect "%1071 49 0" # Set to "9". send "1072 93 6 0 { } 1 { 33 00000000 1 [holl "9"] }\n" simple_expect "=1072" # Check visibility for person 6. send "1073 91 6\n" extracting_expect "=1073 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 1 { (\[0-9\]*) 33 6 $any_time 00000000 1 [holl "9"] }" nineauxno 1 if {$nineauxno == $tenauxno + 1} { pass "Correct aux-no V" } else { fail "Correct aux-no V" } # Check visibility for person 7. talk_to client 2 send "1074 91 6\n" simple_expect "=1074 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 1 { $nineauxno 33 6 $any_time 00000000 1 [holl "9"] }" # Remove "9". talk_to client 1 send "1075 93 6 1 { $nineauxno } 0 { }\n" simple_expect "=1075" # Set to "8". send "1076 93 6 0 { } 1 { 33 00000000 2 [holl "8"] }\n" simple_expect "=1076" # Check visibility for person 6. send "1077 91 6\n" extracting_expect "=1077 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 1 { (\[0-9\]*) 33 6 $any_time 00000000 2 [holl "8"] }" eightauxno 1 if {$eightauxno == $nineauxno + 1} { pass "Correct aux-no VI" } else { fail "Correct aux-no VI" } # Check visibility for person 7. talk_to client 2 send "1078 91 6\n" simple_expect "=1078 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 1 { $eightauxno 33 6 $any_time 00000000 2 [holl "8"] }" # Remove "8". talk_to client 1 send "1079 93 6 1 { $eightauxno } 0 { }\n" simple_expect "=1079" # Attempt to set to "10" on person 7. Should fail, because this is a # unique aux-item, and person 7 isn't allowed to see conference 10. # See the 2001-12-12 00:30 entry on bug 25 for more info. # This will work, due to bug 314. talk_to client 0 send "1080 93 7 0 { } 1 { 33 00000000 1 [holl "10"] }\n" setup_xfail "*-*-*" "Bug 314" if {0} { pass "Cannot create global-unique link to object that the owner cannot see" simple_expect "%1080 49 0" } else { fail "Cannot create global-unique link to object that the owner cannot see" simple_expect "=1080" send "901 93 7 1 { 1 } 0 { }\n" simple_expect "=901" } # Finally, let the administrator fetch everything, to make sure # that no stray aux-items (or mirror aux-items) remain. send "1081 93 $conf_no 1 { 1 } 0 { }\n" simple_expect "=1081" send "1082 93 $conf_IV 1 { 1 } 0 { }\n" simple_expect "=1082" send "1083 93 $created_person 1 { 1 } 0 { }\n" simple_expect "=1083" send "1084 94\n" simple_expect "=1084 $server_compat_version 1 2 3 4 0 0 \\*" send "1085 91 1\n" simple_expect "=1085 [holl "Presentation .av nya. möten"] 00001000 $any_time $any_time 0 0 0 0 0 0 77 77 0 1 0 0 0 \\*" send "1086 91 2\n" simple_expect "=1086 [holl "Presentation .av nya. medlemmar"] 00001000 $any_time $any_time 0 0 0 0 0 0 77 77 0 1 0 0 0 \\*" send "1087 91 3\n" simple_expect "=1087 [holl "Lappar .på. dörren"] 00001000 $any_time $any_time 0 0 0 0 0 0 77 77 0 1 0 0 0 \\*" send "1088 91 4\n" simple_expect "=1088 [holl "Nyheter om LysKOM"] 00001000 $any_time $any_time 0 0 0 0 0 0 77 77 0 1 0 0 0 \\*" send "1089 91 5\n" simple_expect "=1089 [holl "Administratör .för. LysKOM"] 10011000 $any_time $any_time 5 0 5 0 0 0 77 77 1 1 0 0 0 \\*" send "1090 91 6\n" simple_expect "=1090 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 0 \\*" send "1091 91 7\n" simple_expect "=1091 [holl "Person 7"] 10011000 $any_time $any_time 7 0 7 0 0 0 77 77 1 1 0 0 0 \\*" send "1092 91 8\n" simple_expect "=1092 [holl "conf 8"] 00001000 $any_time $any_time 6 0 6 0 6 0 77 77 0 1 1 0 0 \\*" send "1093 91 9\n" simple_expect "=1093 [holl "conf 9"] 10001000 $any_time $any_time 6 0 6 0 6 0 77 77 0 1 1 0 0 \\*" send "1094 91 10\n" simple_expect "=1094 [holl "conf 10"] 10101000 $any_time $any_time 6 0 6 0 6 0 77 77 0 1 1 0 0 \\*" send "1095 91 $conf_no\n" simple_expect "=1095 [holl "person 11 III"] 10011000 $any_time $any_time $conf_no 0 $conf_no 0 0 0 77 77 1 1 0 0 0 \\*" send "1096 91 $conf_IV\n" simple_expect "=1096 [holl "person $conf_IV IV"] 10011000 $any_time $any_time $conf_IV 0 $conf_IV 0 0 0 77 77 1 1 0 0 0 \\*" send "1097 91 $created_person\n" simple_expect "=1097 [holl "person $created_person VII"] 10011000 $any_time $any_time $created_person 0 $created_person 0 0 0 77 77 1 1 0 0 0 \\*" send "1098 90 1\n" simple_expect "=1098 $any_time 6 0 6 0 2 { 0 8 6 1 } 0 \\*" send "1098 90 2\n" simple_expect "=1098 $any_time 6 0 6 0 2 { 0 9 6 1 } 0 \\*" send "1098 90 3\n" simple_expect "=1098 $any_time 6 0 6 0 2 { 0 10 6 1 } 0 \\*" # # Shut down # talk_to client 0 enable send "1099 44 0\n" simple_expect "=1099" client_death 0 client_death 1 client_death 2 client_death 3 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/24.exp0000664000015100472110000002316107721716133016740 # Test suite for lyskomd. # Copyright (C) 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check that the server handles super_conf and supervisor correctly, # especially when aux-items are removed. # There are three major players: # # 5. (client 0) The administrator. # 6. (client 1) # 7. (client 2) # # There are a few conferences: # # 8. Created by 5. rd-prot. Members: 7. Supervisor: 6. Super-conf: 6. # 9. Created by 5. Public. Members: 5. Supervisor: 5. Super-conf: 7. # 10. Created by 5. Public. Members: 5. Supervisor: 7. Super-conf: 5. # 11. Created by 5. Public. Members: 5. Supervisor: 5. Super-conf: 13. # 12. Created by 5. Public. Members: 5. Supervisor: 8. Super-conf: 8. # 13. Created by 6. Public. Members: 6, 7. Supervisor: 6. Super-conf: 7. proc enable {} { send "990 42 255\n" simple_expect "=990" } proc disable {} { send "991 42 0\n" simple_expect "=991" } read_versions lyskomd_start client_start 0 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" send "1000 62 5 [holl "gazonk"] 1\n" simple_expect "=1000" # Populate the database. client_start 1 talk_to client 1 send "A3Hbar\n" simple_expect "LysKOM" send "1001 89 [holl "Person 6"] [holl "pswd6"] 00 0 { }\n" simple_expect "=1001 6" send "1002 62 6 [holl "pswd6"] 1\n" simple_expect "=1002" client_start 2 talk_to client 2 send "A 10Hfoo@bar.se\n" simple_expect "LysKOM" send "1003 89 [holl "Person 7"] [holl "pswd7"] 00 0 { }\n" simple_expect "=1003 7" send "1004 62 7 [holl "pswd7"] 1\n" simple_expect "=1004" # Create the conferences. talk_to client 0 send "1005 88 [holl "conf 8"] 1000 0 { }\n" simple_expect "=1005 8" send "1006 88 [holl "conf 9"] 0000 0 { }\n" simple_expect "=1006 9" send "1007 88 [holl "conf 10"] 0000 000 { }\n" simple_expect "=1007 10" send "1008 88 [holl "conf 11"] 0000 0 { }\n" simple_expect "=1008 11" send "1009 88 [holl "conf 12"] 0000 0 { }\n" simple_expect "=1009 12" talk_to client 1 send "1010 88 [holl "conf 13"] 0000 0 { }\n" simple_expect "=1010 13" # Invite 7 to 8. talk_to client 2 send "1011 100 8 7 200 200 00000000\n" simple_expect "%1011 11 8" talk_to client 0 send "1012 100 8 7 200 200 10000000\n" lyskomd_expect "Person 7 added to conference 8 by 5." simple_expect "=1012" talk_to client 2 send "1013 100 8 7 200 200 00000000\n" simple_expect "=1013" # Let person 5 join several conferences. talk_to client 0 send "1014 100 9 5 200 200 00000000\n" simple_expect "=1014" send "1015 100 10 5 200 200 00000000\n" simple_expect "=1015" send "1016 100 11 5 200 200 00000000\n" simple_expect "=1016" send "1017 100 12 5 200 200 00000000\n" simple_expect "=1017" # Let person 6 join. talk_to client 1 send "1018 100 13 6 200 200 00000000\n" simple_expect "=1018" # Let person 7 join. talk_to client 2 send "1019 100 13 7 200 200 00000000\n" simple_expect "=1019" # Set supervisor and super-conf. talk_to client 0 send "1020 20 8 6\n" simple_expect "=1020" send "1021 18 8 6\n" simple_expect "=1021" send "1022 20 9 7\n" simple_expect "=1022" send "1023 18 10 7\n" simple_expect "=1023" send "1024 20 11 13\n" simple_expect "=1024" send "1025 20 12 8\n" simple_expect "=1025" send "1026 18 12 8\n" simple_expect "=1026" talk_to client 1 send "1027 20 13 7\n" simple_expect "=1027" # Let person 5 create six aux-items on conference 8-13, # two of type alternate-name, two of type redirect (which has # owner-delete set) and two from the experimental range. talk_to client 0 enable send "1028 93 8 0 { } 1 { 10 00000000 1 3Hfoo }\n" simple_expect "=1028" send "1029 93 9 0 { } 1 { 10 00000000 1 3Hfoo }\n" simple_expect "=1029" send "1030 93 10 0 { } 1 { 10 00000000 1 3Hfoo }\n" simple_expect "=1030" send "1031 93 11 0 { } 1 { 10 00000000 1 3Hfoo }\n" simple_expect "=1031" send "1032 93 12 0 { } 1 { 10 00000000 1 3Hfoo }\n" simple_expect "=1032" send "1033 93 13 0 { } 1 { 10 00000000 1 3Hfoo }\n" simple_expect "=1033" send "1034 93 8 0 { } 1 { 10 00000000 1 3Hfoo }\n" simple_expect "=1034" send "1035 93 9 0 { } 1 { 10 00000000 1 3Hfoo }\n" simple_expect "=1035" send "1036 93 10 0 { } 1 { 10 00000000 1 3Hfoo }\n" simple_expect "=1036" send "1037 93 11 0 { } 1 { 10 00000000 1 3Hfoo }\n" simple_expect "=1037" send "1038 93 12 0 { } 1 { 10 00000000 1 3Hfoo }\n" simple_expect "=1038" send "1039 93 13 0 { } 1 { 10 00000000 1 3Hfoo }\n" simple_expect "=1039" send "1040 93 8 0 { } 1 { 8 00000000 1 [holl "E-mail:foo@example.com"] }\n" simple_expect "=1040" send "1041 93 9 0 { } 1 { 8 00000000 1 [holl "E-mail:foo@example.com"] }\n" simple_expect "=1041" send "1042 93 10 0 { } 1 { 8 00000000 1 [holl "E-mail:foo@example.com"] }\n" simple_expect "=1042" send "1043 93 11 0 { } 1 { 8 00000000 1 [holl "E-mail:foo@example.com"] }\n" simple_expect "=1043" send "1044 93 12 0 { } 1 { 8 00000000 1 [holl "E-mail:foo@example.com"] }\n" simple_expect "=1044" send "1045 93 13 0 { } 1 { 8 00000000 1 [holl "E-mail:foo@example.com"] }\n" simple_expect "=1045" send "1046 93 8 0 { } 1 { 8 00000000 1 [holl "E-mail:foo@example.com"] }\n" simple_expect "=1046" send "1047 93 9 0 { } 1 { 8 00000000 1 [holl "E-mail:foo@example.com"] }\n" simple_expect "=1047" send "1048 93 10 0 { } 1 { 8 00000000 1 [holl "E-mail:foo@example.com"] }\n" simple_expect "=1048" send "1049 93 11 0 { } 1 { 8 00000000 1 [holl "E-mail:foo@example.com"] }\n" simple_expect "=1049" send "1050 93 12 0 { } 1 { 8 00000000 1 [holl "E-mail:foo@example.com"] }\n" simple_expect "=1050" send "1051 93 13 0 { } 1 { 8 00000000 1 [holl "E-mail:foo@example.com"] }\n" simple_expect "=1051" send "1052 93 8 0 { } 1 { 20000 00000000 1 0H }\n" simple_expect "=1052" send "1053 93 9 0 { } 1 { 20000 00000000 1 0H }\n" simple_expect "=1053" send "1054 93 10 0 { } 1 { 20000 00000000 1 0H }\n" simple_expect "=1054" send "1055 93 11 0 { } 1 { 20000 00000000 1 0H }\n" simple_expect "=1055" send "1056 93 12 0 { } 1 { 20000 00000000 1 0H }\n" simple_expect "=1056" send "1057 93 13 0 { } 1 { 20000 00000000 1 0H }\n" simple_expect "=1057" send "1058 93 8 0 { } 1 { 20000 00000000 1 0H }\n" simple_expect "=1058" send "1059 93 9 0 { } 1 { 20000 00000000 1 0H }\n" simple_expect "=1059" send "1060 93 10 0 { } 1 { 20000 00000000 1 0H }\n" simple_expect "=1060" send "1061 93 11 0 { } 1 { 20000 00000000 1 0H }\n" simple_expect "=1061" send "1062 93 12 0 { } 1 { 20000 00000000 1 0H }\n" simple_expect "=1062" send "1063 93 13 0 { } 1 { 20000 00000000 1 0H }\n" simple_expect "=1063" # Let person 6 attempt to remove the first, third and fifth aux-items. talk_to client 1 enable send "1064 93 8 1 { 1 } 0 { }\n" simple_expect "%1064 49 0" send "1065 93 9 1 { 1 } 0 { }\n" simple_expect "%1065 49 0" send "1066 93 10 1 { 1 } 0 { }\n" simple_expect "%1066 49 0" send "1067 93 11 1 { 1 } 0 { }\n" simple_expect "%1067 49 0" send "1068 93 12 1 { 1 } 0 { }\n" simple_expect "%1068 49 0" send "1069 93 13 1 { 1 } 0 { }\n" simple_expect "%1069 49 0" send "1070 93 8 1 { 3 } 0 { }\n" simple_expect "=1070" send "1071 93 9 1 { 3 } 0 { }\n" simple_expect "%1071 49 0" send "1072 93 10 1 { 3 } 0 { }\n" simple_expect "%1072 49 0" send "1073 93 11 1 { 3 } 0 { }\n" simple_expect "%1073 49 0" send "1074 93 12 1 { 3 } 0 { }\n" simple_expect "%1074 49 0" send "1075 93 13 1 { 3 } 0 { }\n" simple_expect "=1075" send "1076 93 8 1 { 5 } 0 { }\n" simple_expect "%1076 49 0" send "1077 93 9 1 { 5 } 0 { }\n" simple_expect "%1077 49 0" send "1078 93 10 1 { 5 } 0 { }\n" simple_expect "%1078 49 0" send "1079 93 11 1 { 5 } 0 { }\n" simple_expect "%1079 49 0" send "1080 93 12 1 { 5 } 0 { }\n" simple_expect "%1080 49 0" send "1081 93 13 1 { 5 } 0 { }\n" simple_expect "%1081 49 0" # Let person 7 attempt to remove the other aux-items. talk_to client 2 enable send "1082 93 8 1 { 2 } 0 { }\n" simple_expect "%1082 49 0" send "1083 93 9 1 { 2 } 0 { }\n" simple_expect "%1083 49 0" send "1084 93 10 1 { 2 } 0 { }\n" simple_expect "%1084 49 0" send "1085 93 11 1 { 2 } 0 { }\n" simple_expect "%1085 49 0" send "1086 93 12 1 { 2 } 0 { }\n" simple_expect "%1086 49 0" send "1087 93 13 1 { 2 } 0 { }\n" simple_expect "%1087 49 0" send "1088 93 8 1 { 4 } 0 { }\n" simple_expect "%1088 49 0" send "1089 93 9 1 { 4 } 0 { }\n" simple_expect "%1089 49 0" send "1090 93 10 1 { 4 } 0 { }\n" simple_expect "=1090" send "1091 93 11 1 { 4 } 0 { }\n" simple_expect "%1091 49 0" send "1092 93 12 1 { 4 } 0 { }\n" # Check that the supervisor check is correct. good_bad_expect "=1092" "%49 0" send "1093 93 13 1 { 4 } 0 { }\n" simple_expect "%1093 49 0" send "1094 93 8 1 { 6 } 0 { }\n" simple_expect "%1094 49 0" send "1095 93 9 1 { 6 } 0 { }\n" simple_expect "%1095 49 0" send "1096 93 10 1 { 6 } 0 { }\n" simple_expect "%1096 49 0" send "1097 93 11 1 { 6 } 0 { }\n" simple_expect "%1097 49 0" send "1098 93 12 1 { 6 } 0 { }\n" simple_expect "%1098 49 0" send "1099 93 13 1 { 6 } 0 { }\n" simple_expect "%1099 49 0" # # Shut down # talk_to client 0 enable send "1100 44 0\n" simple_expect "=1100" client_death 0 client_death 1 client_death 2 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/25.exp0000664000015100472110000000655607721716133016752 # Test suite for lyskomd. # Copyright (C) 1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test the "Jubel: public" crap. lyskomd_start "" "\ Jubel: public 0 1 Jubel: public 0 2 0" client_start 0 talk_to client 0 send "A[holl "foo"]\n" simple_expect "LysKOM" send "1000 0 5 [holl "gazonk"]\n" simple_expect ":2 9 5 1" simple_expect "=1000" send "1001 28 [holl "none"] 0 { }\n" talk_to lyskomd simple_expect "Granted jubel 1 to person 5, pending public check." simple_expect "Jubel stopped because no public recipient was found." talk_to client 0 simple_expect "%1001 45 0" send "1002 28 [holl "private"] 1 { 0 5 }\n" talk_to lyskomd simple_expect "Granted jubel 1 to person 5, pending public check." simple_expect "Jubel stopped because no public recipient was found." talk_to client 0 simple_expect "%1002 45 0" send "1003 28 [holl "public"] 1 { 0 4 }\n" talk_to lyskomd simple_expect "Granted jubel 1 to person 5, pending public check." talk_to client 0 simple_expect "=1003 1" send "1004 28 [holl "none"] 0 { }\n" talk_to lyskomd simple_expect "Granted jubel 2 to person 5, pending public check." simple_expect "Jubel stopped because no public recipient was found." talk_to client 0 simple_expect "%1004 45 0" send "1005 28 [holl "private"] 1 { 0 5 }\n" talk_to lyskomd simple_expect "Granted jubel 2 to person 5, pending public check." simple_expect "Jubel stopped because no public recipient was found." talk_to client 0 simple_expect "%1005 45 0" send "1006 28 [holl "public"] 1 { 0 4 }\n" talk_to lyskomd simple_expect "Granted jubel 2 to person 5, pending public check." talk_to client 0 simple_expect "=1006 2" send "1007 28 [holl "none"] 0 { }\n" simple_expect "=1007 3" send "1008 28 [holl "none"] 0 { }\n" talk_to lyskomd simple_expect "Granted jubel 4 to person 5, pending public check." simple_expect "Jubel stopped because no public recipient was found." talk_to client 0 simple_expect "%1008 45 0" send "1009 28 [holl "private"] 1 { 0 5 }\n" talk_to lyskomd simple_expect "Granted jubel 4 to person 5, pending public check." simple_expect "Jubel stopped because no public recipient was found." talk_to client 0 simple_expect "%1009 45 0" send "1010 28 [holl "public"] 1 { 0 4 }\n" talk_to lyskomd simple_expect "Granted jubel 4 to person 5, pending public check." talk_to client 0 simple_expect "=1010 4" send "1011 28 [holl "private"] 1 { 0 5 }\n" simple_expect ":16 0 5 $any_time 5 0 7 0 2 { 0 5 6 1 }" simple_expect "=1011 5" send "1012 42 255\n" simple_expect "=1012" send "1013 44 0\n" simple_expect "=1013" client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/26.exp0000664000015100472110000001774107721716133016751 # Test suite for lyskomd. # Copyright (C) 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check the world-readable (33) aux-items. # We currently get aux-item-permission (49) instead of illegal-aux-item (48) # in several places. proc want_illegal_aux_item {tst} { global test global errorcode set test "$tst" setup_xfail "*-*-*" "Bug 192" if {$errorcode == 48} { pass "$test" } else { fail "$test" } unset test } lyskomd_start # Client 0, person 5, logged in as admin. client_start 0 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" "connected" send "1000 80 0 { }\n" simple_expect "=1000" send "1001 62 5 [holl "gazonk"] 1\n" simple_expect "=1001" # Client 1, person 6, logged in, creates several texts. client_start 1 talk_to client 1 send "A3Hfoo\n" simple_expect "LysKOM" "client 1 connected" send "1002 80 0 { }\n" simple_expect "=1002" send "1003 89 [holl "Opriviligerad"] [holl "hemligt"] 10000000 0 { }\n" simple_expect "=1003 6" send "1004 62 6 [holl "hemligt"] 0\n" simple_expect "=1004" send "1005 86 [holl "text 1"] 1 { 0 1 } 0 { }\n" simple_expect "=1005 1" send "1006 86 [holl "text 2"] 1 { 0 1 } 1 { 34 01111000 20 [holl ""] }\n" simple_expect "=1006 2" send "1007 86 [holl "failed"] 1 { 0 1 } 1 { 34 01111000 20 [holl " "] }\n" simple_expect "%1007 48 0" send "1008 86 [holl "failed"] 1 { 0 1 } 1 { 34 01111000 20 [holl "^$"] }\n" simple_expect "%1008 48 0" send "1009 86 [holl "failed"] 1 { 0 1 } 1 { 34 01111000 20 [holl "^"] }\n" simple_expect "%1009 48 0" send "1010 86 [holl "failed"] 1 { 0 1 } 1 { 34 01111000 20 [holl "$"] }\n" simple_expect "%1010 48 0" send "1011 86 [holl "failed"] 1 { 0 1 } 1 { 34 01111000 20 [holl "@"] }\n" simple_expect "%1011 48 0" send "1012 86 [holl "failed"] 1 { 0 1 } 1 { 34 01111000 20 [holl "."] }\n" simple_expect "%1012 48 0" send "1013 86 [holl "failed"] 1 { 0 1 } 1 { 34 01111000 20 [holl ".*"] }\n" simple_expect "%1013 48 0" send "1014 86 [holl "failed"] 1 { 0 1 } 1 { 34 01111000 20 [holl "1"] }\n" simple_expect "%1014 48 0" send "1015 86 [holl "failed"] 1 { 0 1 } 1 { 34 01111000 20 [holl "xyzzy"] }\n" simple_expect "%1015 48 0" send "1016 86 [holl "text 3"] 0 { } 1 { 34 00000000 1 [holl ""] }\n" simple_expect "=1016 3" send "1017 86 [holl "text 4"] 1 { 0 1 } 0 { }\n" simple_expect "=1017 4" send "1018 86 [holl "text 5"] 0 { } 0 { }\n" simple_expect "=1018 5" # Client 2, not logged in, attempts to read all texts. client_start 2 talk_to client 2 send "A3Hfoo\n" simple_expect "LysKOM" "client 2 connected" send "1019 80 0 { }\n" simple_expect "=1019" send "1020 25 1 0 20\n" simple_expect "%1020 14 1" send "1021 26 1\n" simple_expect "%1021 14 1" send "1022 90 1\n" simple_expect "%1022 14 1" send "1023 25 2 0 20\n" simple_expect "=1023 [holl "text 2"]" send "1024 26 2\n" simple_expect "=1024 $any_time 6 0 6 0 2 { 0 1 6 2 }" send "1025 90 2\n" simple_expect "=1025 $any_time 6 0 6 0 2 { 0 1 6 2 } 1 { 1 34 6 $any_time 00000000 1 [holl ""] }" send "1026 25 3 0 20\n" simple_expect "=1026 [holl "text 3"]" send "1027 26 3\n" simple_expect "=1027 $any_time 6 0 6 0 0 \\*" send "1028 90 3\n" simple_expect "=1028 $any_time 6 0 6 0 0 \\* 1 { 1 34 6 $any_time 00000000 1 [holl ""] }" send "1029 25 4 0 20\n" simple_expect "%1029 14 4" send "1030 26 4\n" simple_expect "%1030 14 4" send "1031 90 4\n" simple_expect "%1031 14 4" send "1032 25 5 0 20\n" simple_expect "%1032 14 5" send "1033 26 5\n" simple_expect "%1033 14 5" send "1034 90 5\n" simple_expect "%1034 14 5" # Attempt by person 5 to add the world-readable aux item. talk_to client 0 send "1035 92 3 0 { } 1 { 34 00000000 1 [holl ""] }\n" simple_expect "%1035 49 0" send "1036 92 3 0 { } 1 { 34 00000000 1 [holl "1"] }\n" simple_expect "%1036 49 0" send "1037 92 4 0 { } 1 { 34 00000000 1 [holl ""] }\n" simple_expect "%1037 49 0" send "1038 92 4 0 { } 1 { 34 00000000 1 [holl "1"] }\n" simple_expect "%1038 49 0" send "1039 92 5 0 { } 1 { 34 00000000 1 [holl ""] }\n" simple_expect "%1039 14 5" send "1040 92 5 0 { } 1 { 34 00000000 1 [holl "1"] }\n" simple_expect "%1040 14 5" # Make sure the above didn't affect what client 2 can access. talk_to client 2 send "1041 25 1 0 20\n" simple_expect "%1041 14 1" send "1042 26 1\n" simple_expect "%1042 14 1" send "1043 90 1\n" simple_expect "%1043 14 1" send "1044 25 2 0 20\n" simple_expect "=1044 [holl "text 2"]" send "1045 26 2\n" simple_expect "=1045 $any_time 6 0 6 0 2 { 0 1 6 2 }" send "1046 90 2\n" simple_expect "=1046 $any_time 6 0 6 0 2 { 0 1 6 2 } 1 { 1 34 6 $any_time 00000000 1 [holl ""] }" send "1047 25 3 0 20\n" simple_expect "=1047 [holl "text 3"]" send "1048 26 3\n" simple_expect "=1048 $any_time 6 0 6 0 0 \\*" send "1049 90 3\n" simple_expect "=1049 $any_time 6 0 6 0 0 \\* 1 { 1 34 6 $any_time 00000000 1 [holl ""] }" send "1050 25 4 0 20\n" simple_expect "%1050 14 4" send "1051 26 4\n" simple_expect "%1051 14 4" send "1052 90 4\n" simple_expect "%1052 14 4" send "1053 25 5 0 20\n" simple_expect "%1053 14 5" send "1054 26 5\n" simple_expect "%1054 14 5" send "1055 90 5\n" simple_expect "%1055 14 5" # Add world-readable to a few texts talk_to client 1 # world-readable is already set, and unique, so this fails. send "1056 92 3 0 { } 1 { 34 00000000 1 [holl ""] }\n" extracting_expect "%1056 (48|49) 0" errorcode 1 want_illegal_aux_item "Attempt to add duplicate world-readable, wich is unique" send "1057 92 4 0 { } 1 { 34 00000000 1 [holl ""] }\n" simple_expect "=1057" send "1058 92 5 0 { } 1 { 34 00000000 1 [holl ""] }\n" simple_expect "=1058" # Make sure the above affects what client 2 can access. talk_to client 2 send "1059 25 1 0 20\n" simple_expect "%1059 14 1" send "1060 26 1\n" simple_expect "%1060 14 1" send "1061 90 1\n" simple_expect "%1061 14 1" send "1062 25 2 0 20\n" simple_expect "=1062 [holl "text 2"]" send "1063 26 2\n" simple_expect "=1063 $any_time 6 0 6 0 2 { 0 1 6 2 }" send "1064 90 2\n" simple_expect "=1064 $any_time 6 0 6 0 2 { 0 1 6 2 } 1 { 1 34 6 $any_time 00000000 1 [holl ""] }" send "1065 25 3 0 20\n" simple_expect "=1065 [holl "text 3"]" send "1066 26 3\n" simple_expect "=1066 $any_time 6 0 6 0 0 \\*" send "1067 90 3\n" simple_expect "=1067 $any_time 6 0 6 0 0 \\* 1 { 1 34 6 $any_time 00000000 1 [holl ""] }" send "1068 25 4 0 20\n" simple_expect "=1068 [holl "text 4"]" send "1069 26 4\n" simple_expect "=1069 $any_time 6 0 6 0 2 { 0 1 6 3 }" send "1070 90 4\n" simple_expect "=1070 $any_time 6 0 6 0 2 { 0 1 6 3 } 1 { 1 34 6 $any_time 00000000 1 [holl ""] }" send "" send "1071 25 5 0 20\n" simple_expect "=1071 [holl "text 5"]" send "1072 26 5\n" simple_expect "=1072 $any_time 6 0 6 0 0 \\*" send "1073 90 5\n" simple_expect "=1073 $any_time 6 0 6 0 0 \\* 1 { 1 34 6 $any_time 00000000 1 [holl ""] }" # Check that world-readable really isn't inherited. talk_to client 1 send "1074 86 [holl "text 6"] 2 { 0 1 2 2 } 0 { }\n" simple_expect "=1074 6" send "1075 90 6\n" simple_expect "=1075 $any_time 6 0 6 0 3 { 0 1 6 4 2 2 } 0 \\*" talk_to client 2 send "1076 25 6 0 20\n" simple_expect "%1076 14 6" send "1077 26 6\n" simple_expect "%1077 14 6" send "1078 90 6\n" simple_expect "%1078 14 6" # Shut down. talk_to client 0 send "1079 42 255\n" simple_expect "=1079" send "1080 44 0\n" simple_expect "=1080" client_death 0 client_death 1 client_death 2 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/27.exp0000664000015100472110000001525707721716133016752 # Test suite for lyskomd. # Copyright (C) 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # We have a secret conference (8), a member of that conference (7), # and a supervisor of the member (6). The supervisor is neither member # of the secret conference, nor supervisor of it. How much can the # supervisor find out about the secret conference? lyskomd_start # Client 0, person 5, logged in as admin. client_start 0 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" "connected" send "1000 80 0 { }\n" simple_expect "=1000" send "1001 62 5 [holl "gazonk"] 1\n" simple_expect "=1001" # Client 1, person 6, logged as "supervisor". client_start 1 talk_to client 1 send "A3Hfoo\n" simple_expect "LysKOM" "client 1 connected" send "1002 80 0 { }\n" simple_expect "=1002" send "1003 89 [holl "supervisor"] [holl "supersecret"] 00000000 0 { }\n" simple_expect "=1003 6" send "1004 62 6 [holl "supersecret"] 0\n" simple_expect "=1004" # Create the member. send "1005 89 [holl "member"] [holl "subsecret"] 00000000 0 { }\n" simple_expect "=1005 7" # Person 5 creates the secret conference, adds the member to it, and # writes a text in it. talk_to client 0 send "1006 88 [holl "secret"] 10101000 0 { }\n" simple_expect "=1006 8" send "1007 100 8 7 100 100 10000000\n" lyskomd_expect "Person 7 added to conference 8 by 5." simple_expect "=1007" send "1008 87 [holl "demo"] 1 { 0 8 } 0 { }\n" simple_expect "=1008 1" # Client 2, person 7, loggs in and accepts the invitation. client_start 2 talk_to client 2 send "A3Hfoo\n" simple_expect "LysKOM" "client 2 connected" send "1009 80 0 { }\n" simple_expect "=1009" send "1010 62 7 [holl "subsecret"] 0\n" simple_expect "=1010" send "1011 98 7 8\n" simple_expect "=1011 1 $any_time 8 100 0 0 \\* 5 $any_time 10000000" send "1012 100 8 7 100 100 00000000\n" simple_expect "=1012" send "1013 98 7 8\n" simple_expect "=1013 1 $any_time 8 100 0 0 \\* 5 $any_time 00000000" # # Base case: everything should be visible for person 7. Ensure that # it is, just to make certain that everything actually exists. # # query-read-texts-old send "1014 9 7 8\n" simple_expect "=1014 $any_time 8 100 0 0 \\*" # lookup-name send "1015 12 [holl "secret"]\n" simple_expect "=1015 1 { 8 } { 1010 }" # get-conf-stat-older send "1016 13 8 1\n" simple_expect "=1016 [holl "secret"] 1010 $any_time $any_time 5 0 5 0 5 0 77 1 1 1" send "1017 13 8 0\n" simple_expect "=1017 [holl ""] 1010 $any_time $any_time 5 0 5 0 5 0 77 1 1 1" # get-membership-old send "1018 46 7 0 10 1\n" simple_expect "=1018 2 { $any_time 7 255 0 0 \\* $any_time 8 100 0 0 \\* }" # get-member-old send "1019 48 8 0 10\n" simple_expect "=1019 1 { 7 }" # get-person-stat send "1020 49 7\n" simple_expect "=1020 [idholl "foo.unknown."] 0000010000000000 00000000 $any_time 0 0 1 0 0 0 0 0 0 1 0 0 2" # get-conf-stat-old send "1021 50 8\n" simple_expect "=1021 [holl "secret"] 1010 $any_time $any_time 5 0 5 0 5 0 77 1 1 1" # get-unread-confs send "1022 52 7\n" simple_expect "=1022 1 { 8 }" # re-lookup-conf send "1023 66 [holl "sec"]\n" simple_expect "=1023 1 { 8 }" # lookup-conf send "1024 68 [holl "sec"]\n" simple_expect "=1024 1 { 8 }" # re-z-lookup send "1025 74 [holl "sec"] 0 1\n" simple_expect "=1025 1 { [holl "secret"] 1010 8 }" # lookup-z-name send "1026 76 [holl "sec"] 0 1\n" simple_expect "=1026 1 { [holl "secret"] 1010 8 }" # get-uconf-stat send "1027 78 8\n" simple_expect "=1027 [holl "secret"] 10101000 1 77" # get-conf-stat send "1028 91 8\n" simple_expect "=1028 [holl "secret"] 10101000 $any_time $any_time 5 0 5 0 5 0 77 77 1 1 1 0 0 \\*" # query-read-texts send "1029 98 7 8\n" simple_expect "=1029 1 $any_time 8 100 0 0 \\* 5 $any_time 00000000" # get-membership send "1030 99 7 0 10 1\n" simple_expect "=1030 2 { 0 $any_time 7 255 0 0 \\* 6 $any_time 00000000 1 $any_time 8 100 0 0 \\* 5 $any_time 00000000 }" # get-members send "1031 101 8 0 10\n" simple_expect "=1031 1 { 7 5 $any_time 00000000 }" # # Test case: Ensure that the supervisor only sees what it should. # talk_to client 1 # query-read-texts-old: Note: secret conf VISIBLE. send "1032 9 7 8\n" good_bad_expect "=1032 $any_time 8 100 0 0 \\*" "%9 8" # lookup-name send "1033 12 [holl "secret"]\n" simple_expect "=1033 0 \\* \\*" # get-conf-stat-older send "1034 13 8 1\n" simple_expect "%1034 9 8" send "1035 13 8 0\n" simple_expect "%1035 9 8" # get-membership-old. Note: secret conf VISIBLE. send "1036 46 7 0 10 1\n" simple_expect "=1036 2 { $any_time 7 255 0 0 \\* $any_time 8 100 0 0 \\* }" # get-member-old. Note: secret conf NOT visible. send "1037 48 8 0 10\n" simple_expect "%1037 9 8" # get-person-stat send "1038 49 7\n" simple_expect "=1038 [idholl "foo.unknown."] 0000010000000000 00000000 $any_time 0 0 1 0 0 0 0 0 0 1 0 0 2" # get-conf-stat-old send "1039 50 8\n" simple_expect "%1039 9 8" # get-unread-confs. Note: secret conf visible. send "1040 52 7\n" simple_expect "=1040 1 { 8 }" # re-lookup-conf send "1041 66 [holl "sec"]\n" simple_expect "=1041 0 \\*" # lookup-conf send "1042 68 [holl "sec"]\n" simple_expect "=1042 0 \\*" # re-z-lookup send "1043 74 [holl "sec"] 0 1\n" simple_expect "=1043 0 \\*" # lookup-z-name send "1044 76 [holl "sec"] 0 1\n" simple_expect "=1044 0 \\*" # get-uconf-stat send "1045 78 8\n" simple_expect "%1045 9 8" # get-conf-stat send "1046 91 8\n" simple_expect "%1046 9 8" # query-read-texts. Note: secret conf VISIBLE. send "1047 98 7 8\n" good_bad_expect "=1047 1 $any_time 8 100 0 0 \\* 5 $any_time 00000000" "%9 8" # get-membership. Note: secret conf VISIBLE. send "1048 99 7 0 10 1\n" simple_expect "=1048 2 { 0 $any_time 7 255 0 0 \\* 6 $any_time 00000000 1 $any_time 8 100 0 0 \\* 5 $any_time 00000000 }" # get-members. Note: secret conf NOT visible. send "1049 101 8 0 10\n" simple_expect "%1049 9 8" # Shut down. talk_to client 0 send "1050 42 255\n" simple_expect "=1050" send "1051 44 0\n" simple_expect "=1051" client_death 0 client_death 1 client_death 2 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/28.exp0000664000015100472110000006225407721716133016752 # Test suite for lyskomd. # Copyright (C) 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check the aux-item send-comments-to (33). # This file checks the variant of send-comments-to that includes the # recipient type. See 23.exp for tests that omits the recipient # type. # FIXME (bug 314): When a mirror aux-item is implemented, this test # should be extended with get-conf-stat calls that checks that the # mirroring aux-item is set and removed appropriately. # There are three major players: # # 5. (client 0) The administrator. # 6. (client 1) # 7. (client 2) # # There are a few major conferences: # # 8. Created by 6. Public. Members: 6. # 9. Created by 6. Rd-prot. Members: 6. # 10. Created by 6. Secret. Members: 6. # # Some texts: # # 1. Created by 6. Recipients: 8. # 2. Created by 6. Recipients: 9. # 3. Created by 6. Recipients: 10. # We currently get aux-item-permission (49) instead of illegal-aux-item (48) # in several places. proc want_illegal_aux_item {tst} { global test global errorcode set test "$tst" setup_xfail "*-*-*" "Bug 192" if {$errorcode == 48} { pass "$test" } else { fail "$test" } unset test } proc enable {} { send "990 42 255\n" simple_expect "=990" } proc disable {} { send "991 42 0\n" simple_expect "=991" } read_versions lyskomd_start client_start 0 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" "connected" send "1000 94\n" simple_expect "=1000 $server_compat_version 1 2 3 4 0 0 \\*" send "1001 62 5 [holl "gazonk"] 1\n" simple_expect "=1001" # Populate the database. client_start 1 talk_to client 1 send "A3Hbar\n" simple_expect "LysKOM" send "1002 89 [holl "Person 6"] [holl "pswd6"] 00 0 { }\n" simple_expect "=1002 6" send "1003 62 6 [holl "pswd6"] 1\n" simple_expect "=1003" client_start 2 talk_to client 2 send "A 10Hfoo@bar.se\n" simple_expect "LysKOM" send "1004 89 [holl "Person 7"] [holl "pswd7"] 00 0 { }\n" simple_expect "=1004 7" send "1005 62 7 [holl "pswd7"] 1\n" simple_expect "=1005" talk_to client 1 send "1006 88 [holl "conf 8"] 0000 0 { }\n" simple_expect "=1006 8" send "1007 88 [holl "conf 9"] 1000 0 { }\n" simple_expect "=1007 9" send "1008 88 [holl "conf 10"] 1010 0 { }\n" simple_expect "=1008 10" # (Test to create a public-secret conf with four-bit conference type.) send "1009 88 [holl "conf 11"] 0010 0 { }\n" simple_expect "%1009 22 0" # (Test to create a public-secret conf using create-conf-old.) send "1010 10 [holl "conf 11"] 0010\n" simple_expect "%1010 22 0" send "1011 86 [holl "text 1"] 1 { 0 8 } 0 { }\n" simple_expect "=1011 1" send "1012 86 [holl "text 2"] 1 { 0 9 } 0 { }\n" simple_expect "=1012 2" send "1013 86 [holl "text 3"] 1 { 0 10 } 0 { }\n" simple_expect "=1013 3" # # Test send-comments-to # set next_conf 11 # Attempt to set "0" while creating a conference. # Should fail, since we can only set send-comments-to on letterboxes. talk_to client 1 send "1014 88 [holl "conf $next_conf I"] 00000000 1 { 33 00000000 1 [holl "0 0"] }\n" extracting_expect "%1014 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on conference" send "1015 88 [holl "conf $next_conf I"] 00000000 1 { 33 00000000 1 [holl "0 1"] }\n" extracting_expect "%1015 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on conference" send "1016 88 [holl "conf $next_conf I"] 00000000 1 { 33 00000000 1 [holl "0 15"] }\n" extracting_expect "%1016 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on conference" send "1017 88 [holl "conf $next_conf I"] 00000000 1 { 33 00000000 1 [holl "0 2"] }\n" simple_expect "%1017 48 0" # Attempt to set "1" while creating a conference. # Should fail, since we can only set send-comments-to on letterboxes. send "1018 88 [holl "conf $next_conf II"] 00000000 1 { 33 00000000 1 [holl "1 0"] }\n" extracting_expect "%1018 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on conference" send "1019 88 [holl "conf $next_conf II"] 00000000 1 { 33 00000000 1 [holl "1 1"] }\n" extracting_expect "%1019 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on conference" send "1020 88 [holl "conf $next_conf II"] 00000000 1 { 33 00000000 1 [holl "1 15"] }\n" extracting_expect "%1020 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on conference" send "1021 88 [holl "conf $next_conf II"] 00000000 1 { 33 00000000 1 [holl "1 13"] }\n" simple_expect "%1021 48 0" # Attempt to set "0" while creating a text. # Should fail, since we can only set send-comments-to on letterboxes. send "1022 86 [holl "text N"] 1 { 0 1 } 1 { 33 00000000 1 [holl "0 0"] }\n" extracting_expect "%1022 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on texts" send "1023 86 [holl "text N"] 1 { 0 1 } 1 { 33 00000000 1 [holl "0 1"] }\n" extracting_expect "%1023 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on texts" send "1024 86 [holl "text N"] 1 { 0 1 } 1 { 33 00000000 1 [holl "0 15"] }\n" extracting_expect "%1024 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on texts" send "1025 86 [holl "text N"] 1 { 0 1 } 1 { 33 00000000 1 [holl "0 7"] }\n" simple_expect "%1025 48 0" # Attempt to set "1" while creating a text. # Should fail, since we can only set send-comments-to on letterboxes. send "1026 86 [holl "text N"] 1 { 0 1 } 1 { 33 00000000 1 [holl "1 0"] }\n" extracting_expect "%1026 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on texts" send "1027 86 [holl "text N"] 1 { 0 1 } 1 { 33 00000000 1 [holl "1 1"] }\n" extracting_expect "%1027 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on texts" send "1028 86 [holl "text N"] 1 { 0 1 } 1 { 33 00000000 1 [holl "1 15"] }\n" extracting_expect "%1028 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on texts" send "1029 86 [holl "text N"] 1 { 0 1 } 1 { 33 00000000 1 [holl "1 16"] }\n" simple_expect "%1029 48 0" errorcode 1 # Attempt to set "0" on system while enabled. # Should fail, since we can only set send-comments-to on letterboxes. talk_to client 0 enable send "1030 95 0 { } 1 { 33 00000000 1 [holl "0 0"] }\n" extracting_expect "%1030 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on system" send "1031 95 0 { } 1 { 33 00000000 1 [holl "0 1"] }\n" extracting_expect "%1031 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on system" send "1032 95 0 { } 1 { 33 00000000 1 [holl "0 15"] }\n" extracting_expect "%1032 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on system" send "1033 95 0 { } 1 { 33 00000000 1 [holl "0 3"] }\n" simple_expect "%1033 48 0" errorcode 1 # Attempt to set "1" on system while enabled. # Should fail, since we can only set send-comments-to on letterboxes. send "1034 95 0 { } 1 { 33 00000000 1 [holl "1 0"] }\n" extracting_expect "%1034 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on system" send "1035 95 0 { } 1 { 33 00000000 1 [holl "1 1"] }\n" extracting_expect "%1035 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on system" send "1036 95 0 { } 1 { 33 00000000 1 [holl "1 15"] }\n" extracting_expect "%1036 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on system" send "1037 95 0 { } 1 { 33 00000000 1 [holl "1 4"] }\n" simple_expect "%1037 48 0" # Attempt to set "0" on an existing conference. # Should fail, since we can only set send-comments-to on letterboxes. talk_to client 1 send "1038 93 10 0 { } 1 { 33 00000000 1 [holl "0 0"] }\n" extracting_expect "%1038 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on conference" send "1039 93 10 0 { } 1 { 33 00000000 1 [holl "0 1"] }\n" extracting_expect "%1039 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on conference" send "1040 93 10 0 { } 1 { 33 00000000 1 [holl "0 15"] }\n" extracting_expect "%1040 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on conference" send "1041 93 10 0 { } 1 { 33 00000000 1 [holl "0 5"] }\n" simple_expect "%1041 48 0" # Attempt to set "1" on an existing conference. # Should fail, since we can only set send-comments-to on letterboxes. send "1042 93 10 0 { } 1 { 33 00000000 1 [holl "1 0"] }\n" extracting_expect "%1042 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on conference" send "1043 93 10 0 { } 1 { 33 00000000 1 [holl "1 1"] }\n" extracting_expect "%1043 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on conference" send "1044 93 10 0 { } 1 { 33 00000000 1 [holl "1 15"] }\n" extracting_expect "%1044 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on conference" send "1045 93 10 0 { } 1 { 33 00000000 1 [holl "1 6"] }\n" simple_expect "%1045 48 0" # Attempt to set "0" on an existing text. # Should fail, since we can only set send-comments-to on letterboxes. send "1046 92 3 0 { } 1 { 33 00000000 1 [holl "0 0"] }\n" extracting_expect "%1046 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on text" send "1047 92 3 0 { } 1 { 33 00000000 1 [holl "0 1"] }\n" extracting_expect "%1047 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on text" send "1048 92 3 0 { } 1 { 33 00000000 1 [holl "0 15"] }\n" extracting_expect "%1048 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on text" send "1049 92 3 0 { } 1 { 33 00000000 1 [holl "0 8"] }\n" simple_expect "%1049 48 0" # Attempt to set "1" on an existing text. # Should fail, since we can only set send-comments-to on letterboxes. send "1050 92 3 0 { } 1 { 33 00000000 1 [holl "1 0"] }\n" extracting_expect "%1050 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on text" send "1051 92 3 0 { } 1 { 33 00000000 1 [holl "1 1"] }\n" extracting_expect "%1051 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on text" send "1052 92 3 0 { } 1 { 33 00000000 1 [holl "1 15"] }\n" extracting_expect "%1052 (48|49) 0" errorcode 1 want_illegal_aux_item "Correct error code for send-comments-to on text" send "1053 92 3 0 { } 1 { 33 00000000 1 [holl "1 9"] }\n" simple_expect "%1053 48 0" # Attempt to set "0" while creating a person. # Should work. client_start 3 talk_to client 3 send "A4Hheja\n" simple_expect "LysKOM" send "1054 89 [holl "person $next_conf III"] [holl "pwd"] 00000000 1 { 33 00000000 1 [holl "0 0"] }\n" extracting_expect "=1054 (\[0-9\]*)" conf_no 1 setup_xfail "*-*-*" "Bug 146" if {$conf_no == $next_conf} { pass set next_conf [expr {1 + $next_conf}] } else { fail "got wrong person number" set next_conf [expr {1 + $conf_no}] } # Attempt to set "1" while creating a person. # Should work. send "1055 89 [holl "person $next_conf IV"] [holl "pwd"] 00000000 1 { 33 00000000 1 [holl "1 15"] }\n" simple_expect "=1055 $next_conf" set conf_IV $next_conf set next_conf [expr {1 + $next_conf}] # Attempt to set "99" while creating a person. # Should fail, because no such conference exists, but because there is # no mirror aux item (bug 314) this will work. send "1056 89 [holl "person $next_conf V"] [holl "pwd"] 00000000 1 { 33 00000000 1 [holl "99 1"] }\n" # We need a version of simple_expect with a list of expected errors... setup_xfail "*-*-*" "Bug 314" if {0} { pass "Creation of person with send-comments-to to nonexisting conference forbidden" simple_expect "%1056 49 0" } else { fail "Creation of person with send-comments-to to nonexisting conference forbidden" simple_expect "=1056 $next_conf" set next_conf [expr {1 + $next_conf}] } # Attempt to set "10", a secret conference, while creating a person. # Should fail, because no such conference exists, but because there is # no mirror aux item (bug 314) this will work. send "1057 89 [holl "person $next_conf VI"] [holl "pwd"] 00000000 1 { 33 00000000 1 [holl "10 1"] }\n" setup_xfail "*-*-*" "Bug 314" if {0} { pass "Creation of person with send-comments-to to secret conference forbidden" simple_expect "=1057 49 0" } else { fail "Creation of person with send-comments-to to secret conference forbidden" simple_expect "=1057 $next_conf" set next_conf [expr {1 + $next_conf}] } # Attempt to set "9", an rd-prot conference, while creating a person. # Should work. send "1058 89 [holl "person $next_conf VII"] [holl "pwd"] 00000000 1 { 33 00000000 1 [holl "9 1"] }\n" simple_expect "=1058 $next_conf" set created_person $next_conf set next_conf [expr {1 + $next_conf}] # Set "9", an rd-prot conference, on person 6. # Should work. talk_to client 1 send "1059 93 6 0 { } 1 { 33 00000000 1 [holl "9 15"] }\n" simple_expect "=1059" # Set "10", a secret conference that is visible to the administrator, # on person 6. Should fail -- there can be only one send-comments-to. talk_to client 0 enable send "1060 93 6 0 { } 1 { 33 00000000 1 [holl "10 0"] }\n" setup_xfail "*-*-*" "Bug 327" if {0} { simple_expect "%1060 49 0" } else { fail "unique dosen't mean globally unique" simple_expect "=1060" # Remove the send-comments-to. send "900 93 6 1 { 2 } 0 { }\n" simple_expect "=900" } # Remove the send-comments-to. send "1061 93 6 1 { 1 } 0 { }\n" simple_expect "=1061" # Set "10", a secret conference that is visible to the # administrator and to person 6. Should work. send "1062 93 6 0 { } 1 { 33 00000000 1 [holl "10 2"] }\n" simple_expect "%1062 48 0" send "1063 93 6 0 { } 1 { 33 00000000 1 [holl "10 0"] }\n" simple_expect "=1063" # Fetch the conference status of person 6. The aux-item should be # visible. send "1064 91 6\n" extracting_expect "=1064 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 1 { (2|3) 33 5 $any_time 00000000 1 [holl "10 0"] }" auxno 1 setup_xfail "*-*-*" "Bug 327" if {$auxno == 2} { pass "Correct aux-no" } else { # We were able to create an aux-item above that should have failed, # so the numbers are now wrong. fail "Correct aux-no" } # Fetch the conference status of person 6. The aux-item should be # visible. talk_to client 1 send "1065 91 6\n" simple_expect "=1065 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 1 { $auxno 33 5 $any_time 00000000 1 [holl "10 0"] }" # Fetch the conference status of person 6. The aux-item should not be # visible, because conference 10 is secret and person 7 isn't allowed # to see it. talk_to client 2 # (Check that the various get-conf-stat* calls really fail.) send "1066 13 10 0\n" simple_expect "%1066 9 10" send "1067 13 10 1\n" simple_expect "%1067 9 10" send "1068 50 10\n" simple_expect "%1068 9 10" send "1069 91 10\n" simple_expect "%1069 9 10" send "1070 91 6\n" setup_xfail "*-*-*" "Bug 314" if {0} { pass "Person 7 cannot see conference 10" simple_expect "=1070 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 0 { }" } else { fail "Person 7 cannot see conference 10" simple_expect "=1070 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 1 { $auxno 33 5 $any_time 00000000 1 [holl "10 0"] }" } # Remove the aux-item. talk_to client 0 send "1071 93 6 1 { $auxno } 0 { }\n" simple_expect "=1071" # Attempt to set some bad values, including the empty string, negative # numbers, hexadecimal numbers, whitespace-separated digits, et c. # They should all fail. talk_to client 1 send "1072 93 6 0 { } 1 { 33 00000000 1 [holl " 0"] }\n" simple_expect "%1072 48 0" send "1073 93 6 0 { } 1 { 33 00000000 1 [holl " 1"] }\n" simple_expect "%1073 48 0" send "1074 93 6 0 { } 1 { 33 00000000 1 [holl "-1 1"] }\n" simple_expect "%1074 48 0" send "1075 93 6 0 { } 1 { 33 00000000 1 [holl "-6 1"] }\n" simple_expect "%1075 48 0" send "1076 93 6 0 { } 1 { 33 00000000 1 [holl "a 2"] }\n" simple_expect "%1076 48 0" send "1077 93 6 0 { } 1 { 33 00000000 1 [holl "0a 2"] }\n" simple_expect "%1077 48 0" send "1078 93 6 0 { } 1 { 33 00000000 1 [holl "0x0a 1"] }\n" simple_expect "%1078 48 0" send "1079 93 6 0 { } 1 { 33 00000000 1 [holl "0 6 "] }\n" simple_expect "%1079 48 0" send "1080 93 6 0 { } 1 { 33 00000000 1 [holl "5 2"] }\n" simple_expect "%1080 48 0" send "1081 93 6 0 { } 1 { 33 00000000 1 [holl "5 5"] }\n" simple_expect "%1081 48 0" send "1082 93 6 0 { } 1 { 33 00000000 1 [holl "5 3"] }\n" simple_expect "%1082 48 0" send "1083 93 6 0 { } 1 { 33 00000000 1 [holl " 5 0"] }\n" simple_expect "%1083 48 0" send "1084 93 6 0 { } 1 { 33 00000000 1 [holl " 5 3"] }\n" simple_expect "%1084 48 0" send "1085 93 6 0 { } 1 { 33 00000000 1 [holl "0 0 "] }\n" simple_expect "%1085 48 0" send "1086 93 6 0 { } 1 { 33 00000000 1 [holl " 0 18"] }\n" simple_expect "%1086 48 0" send "1087 93 6 0 { } 1 { 33 00000000 1 [holl " 0 0"] }\n" simple_expect "%1087 48 0" # Set to "0". send "1088 94\n" simple_expect "=1088 $server_compat_version 1 2 3 4 0 0 \\*" send "1089 93 6 0 { } 1 { 33 00000000 1 [holl "0 15"] }\n" simple_expect "=1089" send "1090 94\n" simple_expect "=1090 $server_compat_version 1 2 3 4 0 0 \\*" # Check visibility for person 6. send "1091 91 6\n" extracting_expect "=1091 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 1 { (\[0-9\]*) 33 6 $any_time 00000000 1 [holl "0 15"] }" zeroauxno 1 if {$zeroauxno == $auxno + 1} { pass "Correct aux-no II" } else { fail "Correct aux-no II" } # Check visibility for person 7. talk_to client 2 send "1092 91 6\n" simple_expect "=1092 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 1 { $zeroauxno 33 6 $any_time 00000000 1 [holl "0 15"] }" # Remove "0" and set to "6". talk_to client 1 send "1093 93 6 1 { $zeroauxno } 1 { 33 00000000 1 [holl "6 1"] }\n" simple_expect "=1093" send "1094 94\n" simple_expect "=1094 $server_compat_version 1 2 3 4 0 0 \\*" # Check visibility for person 6. send "1095 91 6\n" extracting_expect "=1095 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 1 { (\[0-9\]*) 33 6 $any_time 00000000 1 [holl "6 1"] }" sixauxno 1 if {$sixauxno == $zeroauxno + 1} { pass "Correct aux-no III" } else { fail "Correct aux-no III" } # Check visibility for person 7. talk_to client 2 send "1096 91 6\n" simple_expect "=1096 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 1 { $sixauxno 33 6 $any_time 00000000 1 [holl "6 1"] }" # Remove "6". talk_to client 0 send "1097 93 6 1 { $sixauxno } 0 { }\n" simple_expect "=1097" # Set to "10". talk_to client 1 send "1098 93 6 0 { } 1 { 33 00000000 1 [holl "10 15"] }\n" simple_expect "=1098" # Check visibility for person 6. send "1099 91 6\n" extracting_expect "=1099 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 1 { (\[0-9\]*) 33 6 $any_time 00000000 1 [holl "10 15"] }" tenauxno 1 if {$tenauxno == $sixauxno + 1} { pass "Correct aux-no IV" } else { fail "Correct aux-no IV" } # Check visibility for person 7. Should not be visible. talk_to client 2 send "1100 91 6\n" setup_xfail "*-*-*" "Bug 314" if {0} { pass "Person 7 cannot see conference 10" simple_expect "=1100 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 0 { }" } else { fail "Person 7 cannot see conference 10" simple_expect "=1100 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 1 { $tenauxno 33 6 $any_time 00000000 1 [holl "10 15"] }" } # Remove "10". talk_to client 1 send "1101 93 6 1 { $tenauxno } 0 { }\n" simple_expect "=1101" # Change "10" to "9". Should fail, since "10" is already removed. # FIXME (bug 328): What error code should be returned? Currently, # 49=aux-item-permission is returned, but is that really proper? send "1102 93 6 1 { $tenauxno } 1 { 33 00000000 1 [holl "9 15"] }\n" simple_expect "%1102 49 0" # Set to "9". send "1103 93 6 0 { } 1 { 33 00000000 1 [holl "9 15"] }\n" simple_expect "=1103" # Check visibility for person 6. send "1104 91 6\n" extracting_expect "=1104 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 1 { (\[0-9\]*) 33 6 $any_time 00000000 1 [holl "9 15"] }" nineauxno 1 if {$nineauxno == $tenauxno + 1} { pass "Correct aux-no V" } else { fail "Correct aux-no V" } # Check visibility for person 7. talk_to client 2 send "1105 91 6\n" simple_expect "=1105 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 1 { $nineauxno 33 6 $any_time 00000000 1 [holl "9 15"] }" # Remove "9". talk_to client 1 send "1106 93 6 1 { $nineauxno } 0 { }\n" simple_expect "=1106" # Set to "8". send "1107 93 6 0 { } 1 { 33 00000000 2 [holl "8 0"] }\n" simple_expect "=1107" # Check visibility for person 6. send "1108 91 6\n" extracting_expect "=1108 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 1 { (\[0-9\]*) 33 6 $any_time 00000000 2 [holl "8 0"] }" eightauxno 1 if {$eightauxno == $nineauxno + 1} { pass "Correct aux-no VI" } else { fail "Correct aux-no VI" } # Check visibility for person 7. talk_to client 2 send "1109 91 6\n" simple_expect "=1109 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 1 { $eightauxno 33 6 $any_time 00000000 2 [holl "8 0"] }" # Remove "8". talk_to client 1 send "1110 93 6 1 { $eightauxno } 0 { }\n" simple_expect "=1110" # Attempt to set to "10" on person 7. Should fail, because this is a # unique aux-item, and person 7 isn't allowed to see conference 10. # See the 2001-12-12 00:30 entry on bug 25 for more info. # This will work, due to bug 314. talk_to client 0 send "1111 93 7 0 { } 1 { 33 00000000 1 [holl "10 0"] }\n" setup_xfail "*-*-*" "Bug 314" if {0} { pass "Cannot create global-unique link to object that the owner cannot see" simple_expect "%1111 49 0" } else { fail "Cannot create global-unique link to object that the owner cannot see" simple_expect "=1111" send "901 93 7 1 { 1 } 0 { }\n" simple_expect "=901" } # Finally, let the administrator fetch everything, to make sure # that no stray aux-items (or mirror aux-items) remain. send "1112 93 $conf_no 1 { 1 } 0 { }\n" simple_expect "=1112" send "1113 93 $conf_IV 1 { 1 } 0 { }\n" simple_expect "=1113" send "1114 93 $created_person 1 { 1 } 0 { }\n" simple_expect "=1114" send "1115 94\n" simple_expect "=1115 $server_compat_version 1 2 3 4 0 0 \\*" send "1116 91 1\n" simple_expect "=1116 [holl "Presentation .av nya. möten"] 00001000 $any_time $any_time 0 0 0 0 0 0 77 77 0 1 0 0 0 \\*" send "1117 91 2\n" simple_expect "=1117 [holl "Presentation .av nya. medlemmar"] 00001000 $any_time $any_time 0 0 0 0 0 0 77 77 0 1 0 0 0 \\*" send "1118 91 3\n" simple_expect "=1118 [holl "Lappar .på. dörren"] 00001000 $any_time $any_time 0 0 0 0 0 0 77 77 0 1 0 0 0 \\*" send "1119 91 4\n" simple_expect "=1119 [holl "Nyheter om LysKOM"] 00001000 $any_time $any_time 0 0 0 0 0 0 77 77 0 1 0 0 0 \\*" send "1120 91 5\n" simple_expect "=1120 [holl "Administratör .för. LysKOM"] 10011000 $any_time $any_time 5 0 5 0 0 0 77 77 1 1 0 0 0 \\*" send "1121 91 6\n" simple_expect "=1121 [holl "Person 6"] 10011000 $any_time $any_time 6 0 6 0 0 0 77 77 1 1 0 0 0 \\*" send "1122 91 7\n" simple_expect "=1122 [holl "Person 7"] 10011000 $any_time $any_time 7 0 7 0 0 0 77 77 1 1 0 0 0 \\*" send "1123 91 8\n" simple_expect "=1123 [holl "conf 8"] 00001000 $any_time $any_time 6 0 6 0 6 0 77 77 0 1 1 0 0 \\*" send "1124 91 9\n" simple_expect "=1124 [holl "conf 9"] 10001000 $any_time $any_time 6 0 6 0 6 0 77 77 0 1 1 0 0 \\*" send "1125 91 10\n" simple_expect "=1125 [holl "conf 10"] 10101000 $any_time $any_time 6 0 6 0 6 0 77 77 0 1 1 0 0 \\*" send "1126 91 $conf_no\n" simple_expect "=1126 [holl "person 11 III"] 10011000 $any_time $any_time $conf_no 0 $conf_no 0 0 0 77 77 1 1 0 0 0 \\*" send "1127 91 $conf_IV\n" simple_expect "=1127 [holl "person $conf_IV IV"] 10011000 $any_time $any_time $conf_IV 0 $conf_IV 0 0 0 77 77 1 1 0 0 0 \\*" send "1128 91 $created_person\n" simple_expect "=1128 [holl "person $created_person VII"] 10011000 $any_time $any_time $created_person 0 $created_person 0 0 0 77 77 1 1 0 0 0 \\*" send "1129 90 1\n" simple_expect "=1129 $any_time 6 0 6 0 2 { 0 8 6 1 } 0 \\*" send "1130 90 2\n" simple_expect "=1130 $any_time 6 0 6 0 2 { 0 9 6 1 } 0 \\*" send "1131 90 3\n" simple_expect "=1131 $any_time 6 0 6 0 2 { 0 10 6 1 } 0 \\*" # # Shut down # talk_to client 0 enable send "1132 44 0\n" simple_expect "=1132" client_death 0 client_death 1 client_death 2 client_death 3 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/29.exp0000664000015100472110000005216207721716133016750 # Test suite for lyskomd. # Copyright (C) 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check client disconnect. read_versions set tests { {"Disconnect while parsing a string." {"A3Hfoo\n" "LysKOM" "0 4 10Hxyzzy"}} {"Disconnect while parsing the end of an overly-long string." {"A3Hfoo\n" "LysKOM" "0 4 30HUUUUUUUUUUUUUUUUUUUUUUUU"}} {"Disconnect while parsing a c_string." {"A3Hfoo\n" "LysKOM" "0 12 10Hxyzzy"}} {"Disconnect while parsing the end of an overly-long c_string." {"A3Hfoo\n" "LysKOM" "0 12 30HUUUUUUUUUUUUUUUUUUUUUUUU"}} {"Disconnect after parsing the first greeting." {"A3Hfoo\n" "LysKOM"}} {"Disconnect after parsing the ref-no." {"A3Hfoo\n" "LysKOM" "982 "}} {"Disconnect while parsing the ref-no." {"A3Hfoo\n" "LysKOM" "982"}} {"Disconnect after parsing the request number." {"A3Hfoo\n" "LysKOM" "982 0 "}} {"Disconnect while parsing the request number." {"A3Hfoo\n" "LysKOM" "982 0"}} {"Disconnect after the initial A." {"A"}} {"Disconnect before sending anything." {}} {"Disconnect while parsing a number." {"A3Hfoo\n" "LysKOM" "0 0 5"}} {"Disconnect while parsing a priv_bits." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 7 5 0000"}} {"Disconnect while parsing a string length." {"A3Hfoo\n" "LysKOM" "0 4 10"}} {"Disconnect while parsing a c_string length." {"A3Hfoo\n" "LysKOM" "0 12 10"}} {"Disconnect while parsing a time_date (get_last_text)." {"A3Hfoo\n" "LysKOM" "0 58 59 59 23 31 12 101 3 365 0"}} {"Disconnect while parsing a time_date (get_last_text)." {"A3Hfoo\n" "LysKOM" "0 58 59 59 23 31 12 101 3 365 "}} {"Disconnect while parsing a time_date (get_last_text)." {"A3Hfoo\n" "LysKOM" "0 58 59 59 23 31 12 101 3 365"}} {"Disconnect while parsing a time_date (get_last_text)." {"A3Hfoo\n" "LysKOM" "0 58 59 59 23 31 12 101 3 "}} {"Disconnect while parsing a time_date (get_last_text)." {"A3Hfoo\n" "LysKOM" "0 58 59 59 23 31 12 101 3"}} {"Disconnect while parsing a time_date (get_last_text)." {"A3Hfoo\n" "LysKOM" "0 58 59 59 23 31 12 101 "}} {"Disconnect while parsing a time_date (get_last_text)." {"A3Hfoo\n" "LysKOM" "0 58 59 59 23 31 12 101"}} {"Disconnect while parsing a time_date (get_last_text)." {"A3Hfoo\n" "LysKOM" "0 58 59 59 23 31 12 "}} {"Disconnect while parsing a time_date (get_last_text)." {"A3Hfoo\n" "LysKOM" "0 58 59 59 23 31 12"}} {"Disconnect while parsing a time_date (get_last_text)." {"A3Hfoo\n" "LysKOM" "0 58 59 59 23 31 "}} {"Disconnect while parsing a time_date (get_last_text)." {"A3Hfoo\n" "LysKOM" "0 58 59 59 23 31"}} {"Disconnect while parsing a time_date (get_last_text)." {"A3Hfoo\n" "LysKOM" "0 58 59 59 23 "}} {"Disconnect while parsing a time_date (get_last_text)." {"A3Hfoo\n" "LysKOM" "0 58 59 59 23"}} {"Disconnect while parsing a time_date (get_last_text)." {"A3Hfoo\n" "LysKOM" "0 58 59 59 "}} {"Disconnect while parsing a time_date (get_last_text)." {"A3Hfoo\n" "LysKOM" "0 58 59 59"}} {"Disconnect while parsing a time_date (get_last_text)." {"A3Hfoo\n" "LysKOM" "0 58 59 "}} {"Disconnect while parsing a time_date (get_last_text)." {"A3Hfoo\n" "LysKOM" "0 58 59"}} {"Disconnect while parsing a time_date (get_last_text)." {"A3Hfoo\n" "LysKOM" "0 58 "}} {"Disconnect while parsing a time_date (get_last_text)." {"A3Hfoo\n" "LysKOM" "0 58"}} {"Disconnect while parsing pers_flags (0)." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 106 5 "}} {"Disconnect while parsing pers_flags (1)." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 106 5 0"}} {"Disconnect while parsing pers_flags (7)." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 106 5 0000000"}} {"Disconnect while parsing pers_flags (8)." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 106 5 00000000"}} {"Disconnect while parsing the conf_type of create_conf_old (8)." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 10 3Hfoo 00001000"}} {"Disconnect while parsing the conf_type of create_conf_old (0)." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 10 3Hfoo "}} {"Disconnect while parsing the conf_type of create_conf_old (1)." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 10 3Hfoo 0"}} {"Disconnect while parsing the conf_type of create_conf_old (4)." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 10 3Hfoo 0000"}} {"Disconnect while parsing the conf_type of create_conf_old (5)." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 10 3Hfoo 00001"}} {"Disconnect while parsing the conf_type of create_conf_old (8)." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 10 3Hfoo 00001000"}} {"Disconnect while parsing the fifth argument of add_member." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 100 1 5 200 1 00000"}} {"Disconnect while parsing the fourth argument of add_member_old." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 14 1 5 200 1"}} {"Disconnect while parsing the initial string length." {"A3"}} {"Disconnect while parsing the initial string." {"A3H"}} {"Disconnect while parsing the initial string." {"A3Hf"}} {"Disconnect while parsing the initial string." {"A3Hfo"}} {"Disconnect while parsing the initial string." {"A3Hfoo" "LysKOM"}} {"Disconnect while parsing the second string of set_passwd." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 8 5 6Hgazonk 6Hfoo"}} {"Disconnect while parsing a aux_item_list, before \{." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 1 "}} {"Disconnect while parsing a aux_item_list, after \{." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 1 \{"}} {"Disconnect while parsing a aux_item_list, after \{." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 1 \{ "}} {"Disconnect while parsing a aux_item_list, in middle." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 1 \{ 19 "}} {"Disconnect while parsing a aux_item_list, in middle." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 1 \{ 19 00000000 "}} {"Disconnect while parsing a aux_item_list, in middle." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 1 \{ 19 00000000 1 "}} {"Disconnect while parsing a aux_item_list, in middle." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 1 \{ 19 00000000 1 3"}} {"Disconnect while parsing a aux_item_list, in middle." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 1 \{ 19 00000000 1 3H"}} {"Disconnect while parsing a aux_item_list, in middle." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 1 \{ 19 00000000 1 3Hfo"}} {"Disconnect while parsing a aux_item_list, in middle." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 1 \{ 19 00000000 1 3Hfoo"}} {"Disconnect while parsing a aux_item_list, in middle." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 2 \{ 19 00000000 1 3Hbar "}} {"Disconnect while parsing a aux_item_list, in middle." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 2 \{ 19 00000000 1 3Hbar 19 "}} {"Disconnect while parsing a aux_item_list, in middle." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 2 \{ 19 00000000 1 3Hbar 19 00000000 "}} {"Disconnect while parsing a aux_item_list, in middle." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 2 \{ 19 00000000 1 3Hbar 19 00000000 1 "}} {"Disconnect while parsing a aux_item_list, in middle." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 2 \{ 19 00000000 1 3Hbar 19 00000000 1 3"}} {"Disconnect while parsing a aux_item_list, in middle." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 2 \{ 19 00000000 1 3Hbar 19 00000000 1 3H"}} {"Disconnect while parsing a aux_item_list, in middle." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 2 \{ 19 00000000 1 3Hbar 19 00000000 1 3Hfo"}} {"Disconnect while parsing a aux_item_list, in middle." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 2 \{ 19 00000000 1 3Hbar 19 00000000 1 3Hfoo"}} {"Disconnect while parsing a aux_item_list, before \}." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 2 \{ 19 00000000 1 3Hbar 19 00000000 1 3Hfoo "}} {"Disconnect while parsing a aux_item_list, overly long, before \{." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 150 "}} {"Disconnect while parsing a aux_item_list, overly long, after \{." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 150 \{ "}} {"Disconnect while parsing a aux_item_list, overly long, first half." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 150 \{ 19 00000000 1 3Hbar "}} {"Disconnect while parsing a aux_item_list, overly long, middle." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 150 \{ 19 00000000 1 3Hbar 19 00000000 1 3Hba2 19 00000000 1 3Hba3 19 00000000 1 3Hba4 19 00000000 1 3Hba"}} {"Disconnect while parsing a aux_item_list, overly long, second half." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 150 \{ 19 00000000 1 3Hbar 19 00000000 1 3Hba2 19 00000000 1 3Hba3 19 00000000 1 3Hba4 19 00000000 1 3Hba5 19 00000000 1 3Hba"}} {"Disconnect while parsing a aux_item_list, overly long, middle, with overly long string." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 150 \{ 19 00000000 1 3Hbar 19 00000000 1 3Hba2 19 00000000 1 3Hba3 19 00000000 1 3Hba4 19 00000000 1 15Hba"}} {"Disconnect while parsing a aux_item_list, overly long, second half, with overly long string." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 150 \{ 19 00000000 1 3Hbar 19 00000000 1 3Hba2 19 00000000 1 3Hba3 19 00000000 1 3Hba4 19 00000000 1 3Hba5 19 00000000 1 15Hba"}} {"Disconnect while parsing a aux_item_list, overly long, middle, with overly long string, second half." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 150 \{ 19 00000000 1 3Hbar 19 00000000 1 3Hba2 19 00000000 1 3Hba3 19 00000000 1 3Hba4 19 00000000 1 15Habcdeabcdeab"}} {"Disconnect while parsing a aux_item_list, overly long, second half, with overly long string, second half." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 150 \{ 19 00000000 1 3Hbar 19 00000000 1 3Hba2 19 00000000 1 3Hba3 19 00000000 1 3Hba4 19 00000000 1 3Hba5 19 00000000 1 15Habcdeabcdeab"}} {"Disconnect while parsing a aux_item_list, barely overly long, before \}." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 5 \{ 19 00000000 1 3Hbar 19 00000000 1 3Hba2 19 00000000 1 3Hba3 19 00000000 1 3Hba4 19 00000000 1 3Hba5 "}} {"Disconnect while parsing a aux_item_list, overly long, before \}." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 0 { } 6 \{ 19 00000000 1 3Hbar 19 00000000 1 3Hba2 19 00000000 1 3Hba3 19 00000000 1 3Hba4 19 00000000 1 3Hba5 19 00000000 1 3Hba6 "}} {"Disconnect while parsing a misc_info_list, before \{." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 86 3Hfoo 2 "}} {"Disconnect while parsing a misc_info_list, after \{." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 28 3Hfoo 2 \{"}} {"Disconnect while parsing a misc_info_list, after \{." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 28 3Hfoo 2 \{ "}} {"Disconnect while parsing a misc_info_list, in middle." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 28 3Hfoo 2 \{ 0 1 "}} {"Disconnect while parsing a misc_info_list, in middle." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 28 3Hfoo 2 \{ 0 1 0 "}} {"Disconnect while parsing a misc_info_list, before \}." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 28 3Hfoo 2 \{ 0 1 0 2 "}} {"Disconnect while parsing a misc_info_list, overly long, before \{." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 28 3Hfoo 5 "}} {"Disconnect while parsing a misc_info_list, overly long, after \{." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 28 3Hfoo 5 \{ "}} {"Disconnect while parsing a misc_info_list, overly long, first half." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 28 3Hfoo 5 \{ 0 1 0 2 "}} {"Disconnect while parsing a misc_info_list, overly long, middle." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 28 3Hfoo 520 \{ 0 1 0 2 0 3 0 4 0 "}} {"Disconnect while parsing a misc_info_list, overly long, second half." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 28 3Hfoo 520 \{ 0 1 0 2 0 3 0 4 0 5 "}} {"Disconnect while parsing a misc_info_list, overly long, second half." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 28 3Hfoo 520 \{ 0 1 0 2 0 3 0 4 0 5 0 "}} {"Disconnect while parsing a misc_info_list, overly long, second half." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 28 3Hfoo 520 \{ 0 1 0 2 0 3 0 4 0 5 0 6 "}} {"Disconnect while parsing a misc_info_list, barely overly long, before \}." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 28 3Hfoo 5 \{ 0 1 0 2 0 3 0 4 0 5 "}} {"Disconnect while parsing a misc_info_list, overly long, before \}." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 28 3Hfoo 6 \{ 0 1 0 2 0 3 0 4 0 5 0 6 "}} {"Disconnect while parsing a num_list, before \{." {"A3Hfoo\n" "LysKOM" "0 80 2 "}} {"Disconnect while parsing a num_list, after \{." {"A3Hfoo\n" "LysKOM" "0 80 2 \{"}} {"Disconnect while parsing a num_list, in middle." {"A3Hfoo\n" "LysKOM" "0 80 2 \{ 1 "}} {"Disconnect while parsing a num_list, before \}." {"A3Hfoo\n" "LysKOM" "0 80 2 \{ 1 2 "}} {"Disconnect while parsing a num_list, overly long, before \{." {"A3Hfoo\n" "LysKOM" "0 80 5 "}} {"Disconnect while parsing a num_list, overly long, after \{." {"A3Hfoo\n" "LysKOM" "0 80 5 \{ "}} {"Disconnect while parsing a num_list, overly long, first half." {"A3Hfoo\n" "LysKOM" "0 80 5 \{ 1 2 3 "}} {"Disconnect while parsing a num_list, overly long, second half." {"A3Hfoo\n" "LysKOM" "0 80 6 \{ 1 2 3 4 5 "}} {"Disconnect while parsing a num_list, overly long, before \}." {"A3Hfoo\n" "LysKOM" "0 80 6 \{ 1 2 3 4 5 6 "}} {"Disconnect while parsing a num_list, barely overly long, before \}." {"A3Hfoo\n" "LysKOM" "0 80 5 \{ 1 2 3 4 5 "}} {"Disconnect while parsing a c_local_text_no_p array, before \{." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 27 5 1 "}} {"Disconnect while parsing a c_local_text_no_p array, after \{." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 27 5 1 \{ "}} {"Disconnect while parsing a c_local_text_no_p array, in middle." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 27 5 2 \{ 1 "}} {"Disconnect while parsing a c_local_text_no_p array, before \}." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 27 5 1 \{ 1 "}} {"Disconnect parsing a c_local_text_no_p array, overly long, before \{." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 27 5 6 "}} {"Try to give an insanely large greeting (A47114711H...)" {"A47114711Hxyzzy"}} {"Disconnect parsing a read-range array, in length." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 110 1 2"}} {"Disconnect parsing a read-range array, after length." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 110 1 2 "}} {"Disconnect parsing a read-range array, after \{." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 110 1 2 \{"}} {"Disconnect parsing a read-range array, after \{." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 110 1 2 \{ "}} {"Disconnect parsing a read-range array, in first number of first pair." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 110 1 2 \{ 1"}} {"Disconnect parsing a read-range array, between numbers of first pair." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 110 1 2 \{ 1 "}} {"Disconnect parsing a read-range array, in second number of first pair." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 110 1 2 \{ 1 2"}} {"Disconnect parsing a read-range array, between first pairs." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 110 1 2 \{ 1 2 "}} {"Disconnect parsing a read-range array, before \}." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 110 1 2 \{ 1 2 4 4 "}} {"Disconnect parsing a read-range array, overly long, after \{." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 110 1 6 \{ "}} {"Disconnect parsing a read-range array, overly long, first half." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 110 1 6 \{ 1 1 3 3 5 "}} {"Disconnect parsing a read-range array, overly long, second half." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 110 1 6 \{ 1 1 3 3 5 5 7 7 9 9 11 "}} {"Disconnect parsing a read-range array, overly long, before \}." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 110 1 6 \{ 1 1 3 3 5 5 7 7 9 9 11 11 "}} {"Disconnect parsing a local_text_no_list, overly long, after \{." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 27 5 6 \{ "}} {"Disconnect parsing a local_text_no_list, overly long, first half." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 27 5 6 \{ 1 2 3 "}} {"Disconnect parsing a local_text_no_list, overly long, second half." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 27 5 6 \{ 1 2 3 4 5 "}} {"Disconnect parsing a local_text_no_list, overly long, before \}." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 27 5 6 \{ 1 2 3 4 5 6 "}} {"Disconnect parsing a local_text_no_list, barely overly long, before \}." {"A3Hfoo\n" "LysKOM" "1 62 5 6Hgazonk 1\n" "=1" "2 27 5 5 \{ 1 2 3 4 5 "}} } set next_client 2 set hanging_clients {} proc startup {} { lyskomd_start "" \ "Max accept_async len: 4 Max aux_items added per call: 4 Max aux_items deleted per call: 4 Max what am I doing length: 20 Max conference name length: 20 Max mark_as_read chunks: 4 Max aux_item length: 10 Max links per text: 4 Max read_ranges per call: 5 Connect timeout: 6 hours Login timeout: 6 hours Active timeout: 6 hours " } proc shutdown {} { global hanging_clients client_start 0 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" "connected" send "1000 62 5 [holl "gazonk"] 1\n" simple_expect "=1000" send "1001 42 255\n" simple_expect "=1001" send "1002 44 0\n" simple_expect "=1002" client_death 0 send_user "Total of [llength $hanging_clients] clients connected\n" foreach clnt $hanging_clients { client_death $clnt } set hanging_clients {} lyskomd_death } startup foreach test $tests { global next_client global hanging_clients verbose -log "Running test [lindex $test 0]" set chat [lindex $test 1] client_start 1 client_start $next_client set hanging_clients [lappend hanging_clients $next_client] for {set i 0} {$i < [llength $chat]} {set i [expr $i + 2]} { set snd "[lindex $chat $i]" if {[string index $snd [expr {[string length $snd] - 1}]] != "\n"} { set snd "#nocr $snd\n" } #send_user "SEND $snd\n" talk_to client 1 send "$snd" talk_to client $next_client send "$snd" if {$i + 1 < [llength $chat]} { set rcv "[lindex $chat [expr $i + 1]]" #send_user "RECV $rcv\n" talk_to client 1 simple_expect "$rcv" talk_to client $next_client simple_expect "$rcv" } } kill_client 1 set next_client [expr $next_client + 1] if {[llength $hanging_clients] > 15} { verbose -log "Restarting server." shutdown startup verbose -log "Server restarted." } } shutdown lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/30.exp0000664000015100472110000003476507721716133016751 # Test suite for lyskomd. # Copyright (C) 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test 109=mark-as-unread and 110=set-read-ranges. lyskomd_start "" "Max read_ranges per call: 10 Sync interval: 3000" client_start 0 talk_to client 0 send "A\n" send "0H\n" simple_expect "LysKOM" send "1000 62 5 6Hgazonk 0\n" simple_expect ":2 9 5 1" simple_expect "=1000" # Create texts 1-23. for {set tno 1} {$tno < 24} {incr tno} { send "100 86 [holl "text $tno"] 1 { 0 5 } 0 { }\n" simple_expect ":16 0 $tno $any_time 5 0 [string length "text $tno"] 0 2 { 0 5 6 $tno }" simple_expect "=100 $tno" } # Mark a single text as read, and then revert it. for {set tno 1} {$tno < 24} {incr tno} { # Mark text $tno as read. send "101 27 5 1 { $tno }\n" simple_expect "=101" send "102 107 5 5 1 0\n" simple_expect "=102 0 $any_time 5 255 1 { $tno $tno } 5 $any_time 00000000" # Revert it. send "103 109 5 $tno\n" simple_expect "=103" send "104 107 5 5 1 0\n" simple_expect "=104 0 $any_time 5 255 0 \\* 5 $any_time 00000000" } # Mark all texts as read. send "1001 110 5 1 { 1 23 }\n" simple_expect "=1001" send "1002 107 5 5 1 0\n" simple_expect "=1002 0 $any_time 5 255 1 { 1 23 } 5 $any_time 00000000" # Mark a single text as unread, and then revert it. for {set tno 1} {$tno < 24} {incr tno} { # Mark text $tno as unread. send "105 109 5 $tno\n" simple_expect "=105" send "106 107 5 5 1 0\n" if {$tno == 1} { simple_expect "=106 0 $any_time 5 255 1 { 2 23 } 5 $any_time 00000000" } elseif {$tno == 23} { simple_expect "=106 0 $any_time 5 255 1 { 1 22 } 5 $any_time 00000000" } else { simple_expect "=106 0 $any_time 5 255 2 { 1 [expr {$tno - 1}] [expr {$tno + 1}] 23 } 5 $any_time 00000000" } # Revert it. send "107 27 5 1 { $tno }\n" simple_expect "=107" send "108 107 5 5 1 0\n" simple_expect "=108 0 $any_time 5 255 1 { 1 23 } 5 $any_time 00000000" } # Mark all texts as unread, starting at text 1. for {set tno 1} {$tno < 24} {incr tno} { # Mark text $tno as unread. send "109 109 5 $tno\n" simple_expect "=109" send "110 107 5 5 1 0\n" if {$tno == 23} { simple_expect "=110 0 $any_time 5 255 0 \\* 5 $any_time 00000000" } else { simple_expect "=110 0 $any_time 5 255 1 { [expr {$tno + 1}] 23 } 5 $any_time 00000000" } } # Mark all texts as read. send "1003 110 5 1 { 1 23 }\n" simple_expect "=1003" send "1004 107 5 5 1 0\n" simple_expect "=1004 0 $any_time 5 255 1 { 1 23 } 5 $any_time 00000000" # Mark all texts as unread, starting at text 23. for {set tno 23} {$tno > 0} {incr tno -1} { # Mark text $tno as unread. send "111 109 5 $tno\n" simple_expect "=111" send "112 107 5 5 1 0\n" if {$tno == 1} { simple_expect "=112 0 $any_time 5 255 0 \\* 5 $any_time 00000000" } else { simple_expect "=112 0 $any_time 5 255 1 { 1 [expr {$tno - 1}] } 5 $any_time 00000000" } } # Mark all texts as read. send "1005 110 5 1 { 1 23 }\n" simple_expect "=1005" send "1006 107 5 5 1 0\n" simple_expect "=1006 0 $any_time 5 255 1 { 1 23 } 5 $any_time 00000000" # Mark texts unread in an order designed to test several special cases. # We also re-mark texts as unread, to ensure that that works. set unmarked {} proc unmark {tno res} { global unmarked global any_time send "113 109 5 $tno\n" simple_expect "=113" send "114 107 5 5 1 0\n" simple_expect "=114 0 $any_time 5 255 $res 5 $any_time 00000000" set unmarked [lappend unmarked $tno] foreach t $unmarked { send "115 109 5 $tno\n" simple_expect "=115" } send "116 107 5 5 1 0\n" simple_expect "=116 0 $any_time 5 255 $res 5 $any_time 00000000" } unmark 10 "2 { 1 9 11 23 }" unmark 9 "2 { 1 8 11 23 }" unmark 8 "2 { 1 7 11 23 }" unmark 11 "2 { 1 7 12 23 }" unmark 14 "3 { 1 7 12 13 15 23 }" unmark 15 "3 { 1 7 12 13 16 23 }" unmark 13 "3 { 1 7 12 12 16 23 }" unmark 12 "2 { 1 7 16 23 }" unmark 3 "3 { 1 2 4 7 16 23 }" unmark 2 "3 { 1 1 4 7 16 23 }" unmark 1 "2 { 4 7 16 23 }" unmark 16 "2 { 4 7 17 23 }" unmark 18 "3 { 4 7 17 17 19 23 }" unmark 20 "4 { 4 7 17 17 19 19 21 23 }" unmark 21 "4 { 4 7 17 17 19 19 22 23 }" unmark 22 "4 { 4 7 17 17 19 19 23 23 }" unmark 23 "3 { 4 7 17 17 19 19 }" unmark 19 "2 { 4 7 17 17 }" unmark 6 "3 { 4 5 7 7 17 17 }" unmark 7 "2 { 4 5 17 17 }" unmark 5 "2 { 4 4 17 17 }" unmark 4 "1 { 17 17 }" unmark 17 "0 \\*" # Mark all texts as read. send "1007 110 5 1 { 1 23 }\n" simple_expect "=1007" send "1008 107 5 5 1 0\n" simple_expect "=1008 0 $any_time 5 255 1 { 1 23 } 5 $any_time 00000000" set unread {} unmark 20 "2 { 1 19 21 23 }" unmark 23 "2 { 1 19 21 22 }" unmark 21 "2 { 1 19 22 22 }" unmark 22 "1 { 1 19 }" unmark 1 "1 { 2 19 }" unmark 5 "2 { 2 4 6 19 }" unmark 7 "3 { 2 4 6 6 8 19 }" unmark 9 "4 { 2 4 6 6 8 8 10 19 }" unmark 11 "5 { 2 4 6 6 8 8 10 10 12 19 }" unmark 13 "6 { 2 4 6 6 8 8 10 10 12 12 14 19 }" unmark 3 "7 { 2 2 4 4 6 6 8 8 10 10 12 12 14 19 }" unmark 4 "6 { 2 2 6 6 8 8 10 10 12 12 14 19 }" unmark 2 "5 { 6 6 8 8 10 10 12 12 14 19 }" unmark 19 "5 { 6 6 8 8 10 10 12 12 14 18 }" unmark 14 "5 { 6 6 8 8 10 10 12 12 15 18 }" unmark 18 "5 { 6 6 8 8 10 10 12 12 15 17 }" unmark 15 "5 { 6 6 8 8 10 10 12 12 16 17 }" unmark 17 "5 { 6 6 8 8 10 10 12 12 16 16 }" unmark 16 "4 { 6 6 8 8 10 10 12 12 }" unmark 10 "3 { 6 6 8 8 12 12 }" unmark 6 "2 { 8 8 12 12 }" unmark 12 "1 { 8 8 }" unmark 8 "0 \\*" # Test set-read-ranges a few times proc set_read {lst} { global any_time send "117 110 5 $lst\n" simple_expect "=117" send "118 107 5 5 1 0\n" simple_expect "=118 0 $any_time 5 255 $lst 5 $any_time 00000000" } send "1009 110 5 0 { }\n" simple_expect "=1009" send "1010 107 5 5 1 0\n" simple_expect "=1010 0 $any_time 5 255 0 \\* 5 $any_time 00000000" set_read "1 { 5 12 }" send "1011 110 5 0 { }\n" simple_expect "=1011" send "1012 107 5 5 1 0\n" simple_expect "=1012 0 $any_time 5 255 0 \\* 5 $any_time 00000000" set_read "1 { 1 23 }" set_read "1 { 1 22 }" set_read "1 { 1 20 }" set_read "1 { 2 23 }" set_read "1 { 2 22 }" set_read "1 { 2 20 }" set_read "1 { 4 23 }" set_read "1 { 4 22 }" set_read "1 { 4 20 }" send "1013 110 5 1 { 1 24 }\n" simple_expect "%1013 16 24" send "1014 110 5 1 { 24 24 }\n" simple_expect "%1014 16 24" send "1015 110 5 1 { 24 28 }\n" simple_expect "%1015 16 28" send "1016 110 5 1 { 25 28 }\n" simple_expect "%1016 16 28" send "1017 110 5 1 { 24 25 }\n" simple_expect "%1017 16 25" send "1018 110 5 1 { 21 28 }\n" simple_expect "%1018 16 28" send "1019 107 5 5 1 0\n" simple_expect "=1019 0 $any_time 5 255 1 { 4 20 } 5 $any_time 00000000" send "1020 109 5 24\n" simple_expect "%1020 16 24" send "1021 109 5 25\n" simple_expect "%1021 16 25" send "1022 109 5 26\n" simple_expect "%1022 16 26" send "1023 107 5 5 1 0\n" simple_expect "=1023 0 $any_time 5 255 1 { 4 20 } 5 $any_time 00000000" set_read "2 { 4 7 18 20 }" set_read "2 { 1 7 18 20 }" set_read "2 { 1 7 18 23 }" set_read "2 { 4 7 18 23 }" set_read "10 { 1 1 3 3 5 5 7 7 9 9 11 11 13 13 15 15 17 17 19 19 }" send "1024 110 5 2 { 4 7 8 12 }\n" simple_expect "=1024" send "1025 107 5 5 1 0\n" simple_expect "=1025 0 $any_time 5 255 1 { 4 12 } 5 $any_time 00000000" send "1026 110 5 2 { 1 7 8 23 }\n" simple_expect "=1026" send "1027 107 5 5 1 0\n" simple_expect "=1027 0 $any_time 5 255 1 { 1 23 } 5 $any_time 00000000" send "1028 110 5 2 { 1 8 7 23 }\n" simple_expect "%1028 56 1" send "1029 110 5 3 { 1 8 7 12 15 13 }\n" simple_expect "%1029 56 1" send "1030 110 5 3 { 1 7 8 12 15 13 }\n" simple_expect "%1030 55 2" send "1031 110 5 3 { 1 7 8 12 15 13 }\n" simple_expect "%1031 55 2" send "1032 110 5 11 { 1 1 3 3 5 5 7 7 9 9 11 11 13 13 15 15 17 17 19 19 21 21 }\n" simple_expect "%1032 46 10" send "1033 110 5 12 { 1 1 3 3 5 5 7 7 9 9 11 11 13 13 15 15 17 17 19 19 21 21 23 23 }\n" simple_expect "%1033 46 10" send "1034 110 4 1 { 1 1 }\n" simple_expect "%1034 13 4" send "1035 110 5 1 { 0 1 }\n" simple_expect "%1035 17 0" send "1036 110 6 1 { 1 1 }\n" simple_expect "%1036 9 6" send "1037 110 6 1 { 0 1 }\n" simple_expect "%1037 17 0" send "1038 110 0 1 { 1 1 }\n" simple_expect "%1038 8 0" send "1039 109 4 1\n" simple_expect "%1039 13 4" send "1040 109 5 0\n" simple_expect "%1040 17 0" send "1041 109 6 0\n" simple_expect "%1041 9 6" send "1042 109 6 1\n" simple_expect "%1042 9 6" send "1043 109 0 0\n" simple_expect "%1043 8 0" send "1044 109 0 1\n" simple_expect "%1044 8 0" send "1045 107 5 5 1 0\n" simple_expect "=1045 0 $any_time 5 255 1 { 1 23 } 5 $any_time 00000000" # Delete a few texts. Remaining: 4-6, 8-11, 15-16, 19-21. foreach tno {1 2 3 7 12 13 14 17 18 22 23} { send "119 29 $tno\n" simple_expect "=119" } send "1046 107 5 5 1 0\n" simple_expect "=1046 0 $any_time 5 255 1 { 1 23 } 5 $any_time 00000000" set unmarked {} unmark 9 "2 { 1 8 10 23 }" unmark 10 "2 { 1 8 11 23 }" unmark 1 "2 { 1 8 11 23 }" unmark 11 "2 { 1 8 12 23 }" unmark 12 "2 { 1 8 12 23 }" unmark 13 "2 { 1 8 12 23 }" unmark 14 "2 { 1 8 12 23 }" unmark 15 "3 { 1 8 12 14 16 23 }" unmark 16 "3 { 1 8 12 14 17 23 }" unmark 17 "3 { 1 8 12 14 17 23 }" unmark 18 "3 { 1 8 12 14 17 23 }" unmark 19 "4 { 1 8 12 14 17 18 20 23 }" unmark 4 "5 { 1 3 5 8 12 14 17 18 20 23 }" unmark 2 "5 { 1 3 5 8 12 14 17 18 20 23 }" unmark 3 "5 { 1 3 5 8 12 14 17 18 20 23 }" unmark 5 "5 { 1 3 6 8 12 14 17 18 20 23 }" unmark 6 "5 { 1 3 7 8 12 14 17 18 20 23 }" unmark 7 "5 { 1 3 7 8 12 14 17 18 20 23 }" unmark 8 "5 { 1 3 7 7 12 14 17 18 20 23 }" unmark 22 "5 { 1 3 7 7 12 14 17 18 20 23 }" unmark 21 "6 { 1 3 7 7 12 14 17 18 20 20 22 23 }" unmark 20 "5 { 1 3 7 7 12 14 17 18 22 23 }" unmark 23 "5 { 1 3 7 7 12 14 17 18 22 23 }" proc set_read_2 {lst exp} { global any_time send "120 110 5 $lst\n" simple_expect "=120" send "121 107 5 5 1 0\n" simple_expect "=121 0 $any_time 5 255 $exp 5 $any_time 00000000" } set_read_2 "0 { }" "0 \\*" set_read_2 "1 { 1 23 }" "1 { 1 23 }" set_read_2 "1 { 1 22 }" "1 { 1 23 }" set_read_2 "1 { 1 21 }" "1 { 1 23 }" set_read_2 "1 { 1 20 }" "1 { 1 20 }" set_read_2 "1 { 1 19 }" "1 { 1 19 }" set_read_2 "1 { 1 18 }" "1 { 1 18 }" set_read_2 "1 { 1 17 }" "1 { 1 18 }" set_read_2 "1 { 1 16 }" "1 { 1 18 }" set_read_2 "1 { 1 15 }" "1 { 1 15 }" set_read_2 "1 { 1 14 }" "1 { 1 14 }" set_read_2 "1 { 1 13 }" "1 { 1 14 }" set_read_2 "1 { 1 12 }" "1 { 1 14 }" set_read_2 "1 { 1 11 }" "1 { 1 14 }" set_read_2 "1 { 1 10 }" "1 { 1 10 }" set_read_2 "1 { 1 9 }" "1 { 1 9 }" set_read_2 "1 { 1 8 }" "1 { 1 8 }" set_read_2 "1 { 1 7 }" "1 { 1 7 }" set_read_2 "1 { 1 6 }" "1 { 1 7 }" set_read_2 "1 { 1 5 }" "1 { 1 5 }" set_read_2 "1 { 1 4 }" "1 { 1 4 }" set_read_2 "1 { 1 3 }" "1 { 1 3 }" set_read_2 "1 { 1 2 }" "1 { 1 3 }" set_read_2 "1 { 1 1 }" "1 { 1 3 }" set_read_2 "1 { 2 23 }" "1 { 1 23 }" set_read_2 "1 { 3 23 }" "1 { 1 23 }" set_read_2 "1 { 4 23 }" "1 { 1 23 }" set_read_2 "1 { 5 23 }" "1 { 5 23 }" set_read_2 "1 { 6 23 }" "1 { 6 23 }" set_read_2 "1 { 7 23 }" "1 { 7 23 }" set_read_2 "1 { 8 23 }" "1 { 7 23 }" set_read_2 "1 { 9 23 }" "1 { 9 23 }" set_read_2 "1 { 10 23 }" "1 { 10 23 }" set_read_2 "1 { 11 23 }" "1 { 11 23 }" set_read_2 "1 { 12 23 }" "1 { 12 23 }" set_read_2 "1 { 13 23 }" "1 { 12 23 }" set_read_2 "1 { 14 23 }" "1 { 12 23 }" set_read_2 "1 { 15 23 }" "1 { 12 23 }" set_read_2 "1 { 16 23 }" "1 { 16 23 }" set_read_2 "1 { 17 23 }" "1 { 17 23 }" set_read_2 "1 { 18 23 }" "1 { 17 23 }" set_read_2 "1 { 19 23 }" "1 { 17 23 }" set_read_2 "1 { 20 23 }" "1 { 20 23 }" set_read_2 "1 { 21 23 }" "1 { 21 23 }" set_read_2 "1 { 22 23 }" "1 { 22 23 }" set_read_2 "1 { 23 23 }" "1 { 22 23 }" set_read_2 "1 { 8 11 }" "1 { 7 14 }" set_read_2 "1 { 4 6 }" "1 { 1 7 }" set_read_2 "1 { 19 21 }" "1 { 17 23 }" set_read_2 "1 { 15 15 }" "1 { 12 15 }" set_read_2 "1 { 15 16 }" "1 { 12 18 }" set_read_2 "1 { 15 17 }" "1 { 12 18 }" set_read_2 "1 { 15 18 }" "1 { 12 18 }" set_read_2 "1 { 15 19 }" "1 { 12 19 }" set_read_2 "1 { 20 21 }" "1 { 20 23 }" set_read_2 "1 { 12 12 }" "1 { 12 14 }" # Mark all remaining texts as read. set_read_2 "4 { 4 6 8 11 15 16 19 21 }" "1 { 1 23 }" # Increase each range by one in each end. set_read_2 "4 { 3 6 8 11 15 16 19 21 }" "1 { 1 23 }" set_read_2 "4 { 4 7 8 11 15 16 19 21 }" "1 { 1 23 }" set_read_2 "4 { 4 6 7 11 15 16 19 21 }" "1 { 1 23 }" set_read_2 "4 { 4 6 8 12 15 16 19 21 }" "1 { 1 23 }" set_read_2 "4 { 4 6 8 11 14 16 19 21 }" "1 { 1 23 }" set_read_2 "4 { 4 6 8 11 15 17 19 21 }" "1 { 1 23 }" set_read_2 "4 { 4 6 8 11 15 16 18 21 }" "1 { 1 23 }" set_read_2 "4 { 4 6 8 11 15 16 19 22 }" "1 { 1 23 }" set_read_2 "4 { 4 6 8 11 15 16 19 23 }" "1 { 1 23 }" # Decrease each range by one in each end. set_read_2 "4 { 5 6 8 11 15 16 19 21 }" "1 { 5 23 }" set_read_2 "4 { 4 5 8 11 15 16 19 21 }" "2 { 1 5 7 23 }" set_read_2 "4 { 4 6 9 11 15 16 19 21 }" "2 { 1 7 9 23 }" set_read_2 "4 { 4 6 8 10 15 16 19 21 }" "2 { 1 10 12 23 }" set_read_2 "4 { 4 6 8 11 16 16 19 21 }" "2 { 1 14 16 23 }" set_read_2 "4 { 4 6 8 11 15 15 19 21 }" "2 { 1 15 17 23 }" set_read_2 "4 { 4 6 8 11 15 16 20 21 }" "2 { 1 18 20 23 }" set_read_2 "4 { 4 6 8 11 15 16 19 20 }" "1 { 1 20 }" # A few other test cases. set_read_2 "2 { 6 6 8 8 }" "1 { 6 8 }" set_read_2 "3 { 6 6 8 8 9 11 }" "1 { 6 14 }" set_read_2 "0 { }" "0 \\*" set_read_2 "1 { 1 1 }" "1 { 1 3 }" set_read_2 "1 { 1 2 }" "1 { 1 3 }" set_read_2 "1 { 1 3 }" "1 { 1 3 }" set_read_2 "1 { 2 2 }" "1 { 1 3 }" set_read_2 "1 { 2 3 }" "1 { 1 3 }" set_read_2 "1 { 3 3 }" "1 { 1 3 }" set_read_2 "1 { 1 4 }" "1 { 1 4 }" set_read_2 "1 { 2 4 }" "1 { 1 4 }" set_read_2 "1 { 3 4 }" "1 { 1 4 }" set_read_2 "1 { 4 4 }" "1 { 1 4 }" set_read_2 "1 { 3 5 }" "1 { 1 5 }" set_read_2 "1 { 3 5 }" "1 { 1 5 }" set_read_2 "2 { 3 5 20 21 }" "2 { 1 5 20 23 }" set_read_2 "3 { 8 11 15 16 19 21 }" "1 { 7 23 }" set_read_2 "3 { 8 11 15 15 19 21 }" "2 { 7 15 17 23 }" set_read_2 "2 { 10 11 15 15 }" "1 { 10 15 }" set_read_2 "2 { 10 12 15 15 }" "1 { 10 15 }" system "kill -TERM $lyskomd_pid" client_death 0 lyskomd_death "" signal lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/31.exp0000664000015100472110000001736007721716133016742 # Test suite for lyskomd. # Copyright (C) 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test large text- and conference numbers. Test what happens when we # hit the "Max texts" and "Max conferences" limits. # 1: Hit the limits with 86=create-text and 88=create-conf lyskomd_start "" "Max texts: 2 Max conferences: 6" client_start 0 talk_to client 0 send "A\n" send "0H\n" simple_expect "LysKOM" send "1000 62 5 6Hgazonk 0\n" simple_expect ":2 9 5 1" simple_expect "=1000" send "1001 86 [holl "text 1"] 1 { 0 1 } 0 { }\n" simple_expect "=1001 1" send "1002 86 [holl "text 2"] 1 { 0 1 } 0 { }\n" simple_expect "=1002 2" send "1003 86 [holl "text 3"] 1 { 0 1 } 0 { }\n" simple_expect "%1003 19 3" send "1004 86 [holl "text 4"] 1 { 0 1 } 0 { }\n" simple_expect "%1004 19 3" send "1005 86 [holl "text 5"] 1 { 0 1 } 0 { }\n" simple_expect "%1005 19 3" send "1006 28 [holl "text 6"] 1 { 0 1 }\n" simple_expect "%1006 19 3" send "1007 88 [holl "conf 6"] 0000 0 { }\n" simple_expect "=1007 6" send "1008 88 [holl "conf 7"] 0000 0 { }\n" lyskomd_expect "ERROR: Couldn't create conference\\. Too many conferences\\." simple_expect "%1008 19 7" send "1009 88 [holl "conf 8"] 0000 0 { }\n" lyskomd_expect "ERROR: Couldn't create conference\\. Too many conferences\\." simple_expect "%1009 19 7" send "1010 5 [holl "person 9"] [holl "secret"]\n" lyskomd_expect "ERROR: Couldn't create person\\. Too many conferences\\." simple_expect "%1010 19 7" send "1011 10 [holl "conf 10"] 0000\n" lyskomd_expect "ERROR: Couldn't create conference\\. Too many conferences\\." simple_expect "%1011 19 7" send "1012 89 [holl "person 11"] [holl "secret"] 00000000 0 { }\n" lyskomd_expect "ERROR: Couldn't create person\\. Too many conferences\\." simple_expect "%1012 19 7" system "kill -HUP $lyskomd_pid" client_death 0 lyskomd_death "" sighup # 2: Hit the limits with 28=create-text-old and 10=create-conf-old lyskomd_start "" "Max texts: 2 Max conferences: 6" client_start 0 talk_to client 0 send "A\n" send "0H\n" simple_expect "LysKOM" send "1013 62 5 6Hgazonk 0\n" simple_expect ":2 9 5 1" simple_expect "=1013" send "1014 28 [holl "text 1"] 1 { 0 1 }\n" simple_expect "=1014 1" send "1015 28 [holl "text 2"] 1 { 0 1 }\n" simple_expect "=1015 2" send "1016 28 [holl "text 3"] 1 { 0 1 }\n" simple_expect "%1016 19 3" send "1017 28 [holl "text 4"] 1 { 0 1 }\n" simple_expect "%1017 19 3" send "1018 86 [holl "text 5"] 1 { 0 1 } 0 { }\n" simple_expect "%1018 19 3" send "1019 10 [holl "conf 6"] 0000\n" simple_expect "=1019 6" send "1020 10 [holl "conf 7"] 0000\n" lyskomd_expect "ERROR: Couldn't create conference\\. Too many conferences\\." simple_expect "%1020 19 7" send "1021 88 [holl "conf 7"] 0000 0 { }\n" lyskomd_expect "ERROR: Couldn't create conference\\. Too many conferences\\." simple_expect "%1021 19 7" send "1022 88 [holl "conf 8"] 0000 0 { }\n" lyskomd_expect "ERROR: Couldn't create conference\\. Too many conferences\\." simple_expect "%1022 19 7" send "1023 5 [holl "person 9"] [holl "secret"]\n" lyskomd_expect "ERROR: Couldn't create person\\. Too many conferences\\." simple_expect "%1023 19 7" send "1024 10 [holl "conf 10"] 0000\n" lyskomd_expect "ERROR: Couldn't create conference\\. Too many conferences\\." simple_expect "%1024 19 7" send "1025 89 [holl "person 11"] [holl "secret"] 00000000 0 { }\n" lyskomd_expect "ERROR: Couldn't create person\\. Too many conferences\\." simple_expect "%1025 19 7" system "kill -TERM $lyskomd_pid" client_death 0 lyskomd_death "" signal # 3: Hit the limit with 5=create-person-old lyskomd_start "" "Max texts: 2 Max conferences: 6" client_start 0 talk_to client 0 send "A\n" send "0H\n" simple_expect "LysKOM" send "1026 62 5 6Hgazonk 0\n" simple_expect ":2 9 5 1" simple_expect "=1026" send "1027 5 [holl "person 6"] [holl "secret"]\n" simple_expect "=1027 6" send "1028 5 [holl "person 7"] [holl "secret"]\n" lyskomd_expect "ERROR: Couldn't create person\\. Too many conferences\\." simple_expect "%1028 19 7" send "1029 5 [holl "person 8"] [holl "secret"]\n" lyskomd_expect "ERROR: Couldn't create person\\. Too many conferences\\." simple_expect "%1029 19 7" send "1030 10 [holl "conf 7"] 0000\n" lyskomd_expect "ERROR: Couldn't create conference\\. Too many conferences\\." simple_expect "%1030 19 7" send "1031 88 [holl "conf 7"] 0000 0 { }\n" lyskomd_expect "ERROR: Couldn't create conference\\. Too many conferences\\." simple_expect "%1031 19 7" send "1032 88 [holl "conf 8"] 0000 0 { }\n" lyskomd_expect "ERROR: Couldn't create conference\\. Too many conferences\\." simple_expect "%1032 19 7" send "1033 5 [holl "person 9"] [holl "secret"]\n" lyskomd_expect "ERROR: Couldn't create person\\. Too many conferences\\." simple_expect "%1033 19 7" send "1034 10 [holl "conf 10"] 0000\n" lyskomd_expect "ERROR: Couldn't create conference\\. Too many conferences\\." simple_expect "%1034 19 7" send "1035 89 [holl "person 11"] [holl "secret"] 00000000 0 { }\n" lyskomd_expect "ERROR: Couldn't create person\\. Too many conferences\\." simple_expect "%1035 19 7" system "kill -INT $lyskomd_pid" client_death 0 lyskomd_death "" sigint # 4: Hit the limit with 89=create-person lyskomd_start "" "Max texts: 2 Max conferences: 6" client_start 0 talk_to client 0 send "A\n" send "0H\n" simple_expect "LysKOM" send "1036 62 5 6Hgazonk 0\n" simple_expect ":2 9 5 1" simple_expect "=1036" send "1037 89 [holl "person 6"] [holl "secret"] 00000000 0 { }\n" simple_expect "=1037 6" send "1038 89 [holl "person 7"] [holl "secret"] 00000000 0 { }\n" lyskomd_expect "ERROR: Couldn't create person\\. Too many conferences\\." simple_expect "%1038 19 7" send "1039 89 [holl "person 8"] [holl "secret"] 00000000 0 { }\n" lyskomd_expect "ERROR: Couldn't create person\\. Too many conferences\\." simple_expect "%1039 19 7" send "1040 5 [holl "person 7"] [holl "secret"]\n" lyskomd_expect "ERROR: Couldn't create person\\. Too many conferences\\." simple_expect "%1040 19 7" send "1041 5 [holl "person 8"] [holl "secret"]\n" lyskomd_expect "ERROR: Couldn't create person\\. Too many conferences\\." simple_expect "%1041 19 7" send "1042 10 [holl "conf 7"] 0000\n" lyskomd_expect "ERROR: Couldn't create conference\\. Too many conferences\\." simple_expect "%1042 19 7" send "1043 88 [holl "conf 7"] 0000 0 { }\n" lyskomd_expect "ERROR: Couldn't create conference\\. Too many conferences\\." simple_expect "%1043 19 7" send "1044 88 [holl "conf 8"] 0000 0 { }\n" lyskomd_expect "ERROR: Couldn't create conference\\. Too many conferences\\." simple_expect "%1044 19 7" send "1045 5 [holl "person 9"] [holl "secret"]\n" lyskomd_expect "ERROR: Couldn't create person\\. Too many conferences\\." simple_expect "%1045 19 7" send "1046 10 [holl "conf 10"] 0000\n" lyskomd_expect "ERROR: Couldn't create conference\\. Too many conferences\\." simple_expect "%1046 19 7" send "1047 89 [holl "person 11"] [holl "secret"] 00000000 0 { }\n" lyskomd_expect "ERROR: Couldn't create person\\. Too many conferences\\." simple_expect "%1047 19 7" system "kill -TERM $lyskomd_pid" client_death 0 lyskomd_death "" signal lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/32.exp0000664000015100472110000000535207721716133016741 # Test suite for lyskomd. # Copyright (C) 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test deletion of a person that is logged in on another session. lyskomd_start client_start 0 talk_to client 0 send "A\n" send "0H\n" simple_expect "LysKOM" send "1000 62 5 6Hgazonk 0\n" simple_expect ":2 9 5 1" simple_expect "=1000" # Create the user "First removed". Log in as it. client_start 1 talk_to client 1 send "A\n" send "0H\n" simple_expect "LysKOM" send "1001 89 [holl "First removed"] [holl "none"] 00000000 0 { }\n" simple_expect "=1001 6" send "1002 62 6 [holl "none"] 0\n" simple_expect ":2 9 6 2" simple_expect "=1002" talk_to client 0 simple_expect ":2 9 6 2" talk_to client 1 # Make sure we get "permission-denied", not "login-first". send "1003 7 5 00000000\n" simple_expect "%1003 12 0" # Remove "First removed". talk_to client 0 send "1004 42 255\n" simple_expect "=1004" send "1005 11 6\n" simple_expect ":2 13 6 2" simple_expect "=1005" talk_to client 1 simple_expect ":2 13 6 2" # Make sure we get "login-first". send "1006 7 5 00000000\n" simple_expect "%1006 6 0" # Create the user "2nd removed". Log in as it, and change-conference # to the letterbox. send "1007 89 [holl "2nd removed"] [holl "none"] 00000000 0 { }\n" simple_expect "=1007 7" send "1008 62 7 [holl "none"] 0\n" simple_expect ":2 9 7 2" simple_expect "=1008" talk_to client 0 simple_expect ":2 9 7 2" talk_to client 1 send "1009 2 7\n" simple_expect "=1009" # Make sure we get "permission-denied", not "login-first". send "1010 7 5 00000000\n" simple_expect "%1010 12 0" # Remove "2nd removed". talk_to client 0 send "1011 11 7\n" simple_expect ":2 13 7 2" simple_expect "=1011" talk_to client 1 simple_expect ":2 13 7 2" # Make sure we get "login-first". send "1012 7 5 00000000\n" simple_expect "%1012 6 0" # Shut everything down. talk_to client 0 send "1013 44 0\n" simple_expect "=1013" client_death 0 client_death 1 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/33.exp0000664000015100472110000000767407721716133016753 # Test suite for lyskomd. # Copyright (C) 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test async-new-user-area. lyskomd_start client_start 0 talk_to client 0 send "A0H\n" simple_expect "LysKOM" send "1000 80 1 { 19 }\n" simple_expect "=1000" send "1001 62 5 6Hgazonk 0\n" simple_expect "=1001" send "1002 42 255\n" simple_expect "=1002" # Create the user "Supervisor". Log in as it. client_start 1 talk_to client 1 send "A0H\n" simple_expect "LysKOM" send "1003 80 1 { 19 }\n" simple_expect "=1003" send "1004 89 [holl "Supervisor"] [holl "none"] 00000000 0 { }\n" simple_expect "=1004 6" send "1005 62 6 [holl "none"] 0\n" simple_expect "=1005" # As "Supervisor", create "Slave". send "1006 89 [holl "Slave"] [holl "none"] 00000000 0 { }\n" simple_expect "=1006 7" # Log in as "Slave" client_start 2 talk_to client 2 send "A0H\n" simple_expect "LysKOM" send "1007 80 1 { 19 }\n" simple_expect "=1007" send "1008 62 7 [holl "none"] 0\n" simple_expect "=1008" # Create the user "Bystander". Log in as it. client_start 3 talk_to client 3 send "A0H\n" simple_expect "LysKOM" send "1009 80 1 { 19 }\n" simple_expect "=1009" send "1010 89 [holl "Bystander"] [holl "none"] 00000000 0 { }\n" simple_expect "=1010 8" send "1011 62 8 [holl "none"] 0\n" simple_expect "=1011" # Set a user-area for "Supervisor". talk_to client 1 send "1012 86 [holl "user-area 1 for Supervisor"] 0 { } 0 { }\n" simple_expect "=1012 1" send "1013 57 6 1\n" simple_expect ":3 19 6 0 1" simple_expect "=1013" talk_to client 0 simple_expect ":3 19 6 0 1" # Change user-area for "Supervisor". talk_to client 1 send "1014 86 [holl "user-area 2 for Supervisor"] 0 { } 0 { }\n" simple_expect "=1014 2" send "1015 57 6 2\n" simple_expect ":3 19 6 1 2" simple_expect "=1015" talk_to client 0 simple_expect ":3 19 6 1 2" # Set a user-area for "Slave". talk_to client 2 send "1016 86 [holl "user-area 1 for Slave"] 0 { } 0 { }\n" simple_expect "=1016 3" send "1017 57 7 3\n" simple_expect ":3 19 7 0 3" simple_expect "=1017" talk_to client 0 simple_expect ":3 19 7 0 3" talk_to client 1 simple_expect ":3 19 7 0 3" # Change user-area for "Slave". talk_to client 2 send "1018 86 [holl "user-area 2 for Slave"] 0 { } 0 { }\n" simple_expect "=1018 4" send "1019 57 7 4\n" simple_expect ":3 19 7 3 4" simple_expect "=1019" talk_to client 0 simple_expect ":3 19 7 3 4" talk_to client 1 simple_expect ":3 19 7 3 4" # Set a user-area for "Bystander". talk_to client 3 send "1016 86 [holl "user-area 1 for Bystander"] 0 { } 0 { }\n" simple_expect "=1016 5" send "1017 57 8 5\n" simple_expect ":3 19 8 0 5" simple_expect "=1017" talk_to client 0 simple_expect ":3 19 8 0 5" # Change user-area for "Bystander". talk_to client 3 send "1016 86 [holl "user-area 2 for Bystander"] 0 { } 0 { }\n" simple_expect "=1016 6" send "1017 57 8 6\n" simple_expect ":3 19 8 5 6" simple_expect "=1017" talk_to client 0 simple_expect ":3 19 8 5 6" # Don't change user-area for "Bystander". talk_to client 3 send "1017 57 8 6\n" simple_expect "=1017" # Shut everything down. talk_to client 0 send "1020 44 0\n" simple_expect "=1020" client_death 0 client_death 1 client_death 2 client_death 3 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/34.exp0000664000015100472110000000467107721716133016746 # Test suite for lyskomd. # Copyright (C) 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test the passive-message-invert bit of Membership-Type. lyskomd_start client_start 0 talk_to client 0 send "A0H\n" simple_expect "LysKOM" send "1000 62 5 6Hgazonk 1\n" simple_expect "=1000" # Create the user "Listener". Log in as it. client_start 1 talk_to client 1 send "A0H\n" simple_expect "LysKOM" send "1001 89 [holl "Listener"] [holl "none"] 00000000 0 { }\n" simple_expect "=1001 6" send "1002 62 6 [holl "none"] 1\n" simple_expect "=1002" # Join conferences: # # Conf_no passive passive-message-invert # 1 0 0 # 2 0 1 # 3 1 0 # 4 1 1 send "1003 100 1 6 200 10 00000000\n" simple_expect "=1003" send "1004 100 2 6 200 10 00010000\n" simple_expect "=1004" send "1005 100 3 6 200 10 01000000\n" simple_expect "=1005" send "1006 100 4 6 200 10 01010000\n" simple_expect "=1006" # Send messages to the four conferences and ensure they arrive properly. talk_to client 0 send "1007 53 1 [holl "msg 1"]\n" simple_expect "=1007" talk_to client 1 simple_expect ":3 12 1 5 [holl "msg 1"]" talk_to client 0 send "1008 53 2 [holl "msg 2"]\n" simple_expect "%1008 53 0" send "1009 53 3 [holl "msg 3"]\n" simple_expect "%1009 53 0" talk_to client 0 send "1010 53 4 [holl "msg 4"]\n" simple_expect "=1010" talk_to client 1 simple_expect ":3 12 4 5 [holl "msg 4"]" # Shut everything down. talk_to client 0 send "1011 42 255\n" simple_expect "=1011" send "1012 44 0\n" simple_expect "=1012" client_death 0 client_death 1 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/35.exp0000664000015100472110000004104607721716133016744 # Test suite for lyskomd. # Copyright (C) 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test sending of async-deleted-text, async-new-text, # async-new-text-old, async-add-recipient and async-sub-recipient to # recipients of texts that are linked to the text. # We want to be able to set broken aux-items, so we start by # creating our own aux-item.conf which lack all validate lines. set auxfile "lyskomd.0/aux-items-35.conf" system "grep -v validate $aux_item_default_conf_file > $auxfile" lyskomd_start "$auxfile" client_start 0 talk_to client 0 send "A0H\n" simple_expect "LysKOM" send "1000 62 5 6Hgazonk 1\n" simple_expect "=1000" # Create the user "Listener". Log in as it. client_start 1 talk_to client 1 send "A0H\n" simple_expect "LysKOM" send "1001 89 [holl "Listener"] [holl "none"] 00000000 0 { }\n" simple_expect "=1001 6" send "1002 62 6 [holl "none"] 1\n" simple_expect "=1002" send "1003 80 5 { 14 15 16 17 0 }\n" simple_expect "=1003" # Join conferences: # # Conf_no passive? # 1 0 (no) # 2 1 (yes) send "1004 100 1 6 200 10 00000000\n" simple_expect "=1004" send "1005 100 2 6 200 10 01000000\n" simple_expect "=1005" # Create base texts: # # Text_no Recipient passive? # 1 1 0 (no) # 2 2 1 (yes) talk_to client 0 send "1006 86 [holl "text 1"] 1 { 0 1 } 0 { }\n" simple_expect "=1006 1" talk_to client 1 simple_expect ":16 0 1 $any_time 5 0 6 0 2 { 0 1 6 1 }" simple_expect ":18 15 1 $any_time 5 0 6 0 2 { 0 1 6 1 } 0 \\*" talk_to client 0 send "1007 86 [holl "text 2"] 1 { 0 2 } 0 { }\n" simple_expect "=1007 2" # Text 3: not linked at all. send "1008 86 [holl "text 3"] 1 { 0 3 } 0 { }\n" simple_expect "=1008 3" # Text 4: linked via a comm-to. send "1009 86 [holl "text 4"] 2 { 0 3 2 1 } 0 { }\n" simple_expect "=1009 4" talk_to client 1 simple_expect ":16 0 4 $any_time 5 0 6 0 3 { 0 3 6 2 2 1 }" simple_expect ":18 15 4 $any_time 5 0 6 0 3 { 0 3 6 2 2 1 } 0 \\*" # Add conference 4 as recipient of text 4. talk_to client 0 send "1010 30 4 4 0\n" simple_expect "=1010" talk_to client 1 simple_expect ":3 16 4 4 0" # Remove conference 4 as recipient of text 4. talk_to client 0 send "1011 31 4 4\n" simple_expect "=1011" talk_to client 1 simple_expect ":3 17 4 4 0" # Delete text 4. talk_to client 0 send "1012 29 4\n" simple_expect "=1012" talk_to client 1 simple_expect ":18 14 4 $any_time 5 0 6 0 3 { 0 3 6 2 2 1 } 0 \\*" # Text 5: linked via a comm-to, to passive recipient. # This produces no async messages. talk_to client 0 send "1013 86 [holl "text 5"] 2 { 0 3 2 2 } 0 { }\n" simple_expect "=1013 5" # Add conference 4 as recipient of text 5. send "1014 30 5 4 0\n" simple_expect "=1014" # Remove conference 4 as recipient of text 5. send "1015 31 5 4\n" simple_expect "=1015" # Delete text 5. send "1016 29 5\n" simple_expect "=1016" # Text 6: linked via a footn-to. send "1017 86 [holl "text 6"] 2 { 0 3 4 1 } 0 { }\n" simple_expect "=1017 6" talk_to client 1 simple_expect ":16 0 6 $any_time 5 0 6 0 3 { 0 3 6 4 4 1 }" simple_expect ":18 15 6 $any_time 5 0 6 0 3 { 0 3 6 4 4 1 } 0 \\*" # Add conference 4 as recipient of text 6. talk_to client 0 send "1018 30 6 4 0\n" simple_expect "=1018" talk_to client 1 simple_expect ":3 16 6 4 0" # Remove conference 4 as recipient of text 6. talk_to client 0 send "1019 31 6 4\n" simple_expect "=1019" talk_to client 1 simple_expect ":3 17 6 4 0" # Delete text 6. talk_to client 0 send "1020 29 6\n" simple_expect "=1020" talk_to client 1 simple_expect ":18 14 6 $any_time 5 0 6 0 3 { 0 3 6 4 4 1 } 0 \\*" # Text 7: linked via footn-in. For obvious reasons, this cannot # produce asycn-new-text or async-new-text-old. talk_to client 0 send "1021 86 [holl "text 7"] 1 { 0 3 } 0 { }\n" simple_expect "=1021 7" send "1022 37 1 7\n" simple_expect "=1022" talk_to client 1 # FIXME (bug 971): this should produce an async-new-footnote message, # but no such message exists. # Add conference 4 as recipient of text 7. talk_to client 0 send "1023 30 7 4 1\n" simple_expect "=1023" talk_to client 1 simple_expect ":3 16 7 4 1" # Remove conference 4 as recipient of text 7. talk_to client 0 send "1024 31 7 4\n" simple_expect "=1024" talk_to client 1 simple_expect ":3 17 7 4 1" # Delete text 7. talk_to client 0 send "1025 29 7\n" simple_expect "=1025" talk_to client 1 simple_expect ":18 14 7 $any_time 5 0 6 0 3 { 0 3 6 5 5 1 } 0 \\*" # Text 8: linked via comm-in. For obvious reasons, this cannot # produce asycn-new-text or async-new-text-old. talk_to client 0 send "1026 86 [holl "text 8"] 1 { 0 3 } 0 { }\n" simple_expect "=1026 8" send "1027 32 1 8\n" simple_expect "=1027" talk_to client 1 # FIXME (bug 971): this should produce an async-new-comment message, # but no such message exists. # Add conference 4 as recipient of text 8. talk_to client 0 send "1028 30 8 4 1\n" simple_expect "=1028" talk_to client 1 simple_expect ":3 16 8 4 1" # Remove conference 4 as recipient of text 8. talk_to client 0 send "1029 31 8 4\n" simple_expect "=1029" talk_to client 1 simple_expect ":3 17 8 4 1" # Delete text 8. talk_to client 0 send "1030 29 8\n" simple_expect "=1030" talk_to client 1 simple_expect ":18 14 8 $any_time 5 0 6 0 3 { 0 3 6 6 3 1 } 0 \\*" if {0} { set cross_mirror 1 } else { set cross_mirror 0 setup_xfail "*-*-*" "Bug 23" fail "There is no mirroring aux-item for cross-references" } # Text 9: linked via a cross-reference. talk_to client 0 send "1031 86 [holl "text 9"] 1 { 0 3 } 1 { 3 00000000 1 [holl "T1"] }\n" simple_expect "=1031 9" talk_to client 1 if {$cross_mirror} { simple_expect ":16 0 9 $any_time 5 0 6 0 2 { 0 3 6 7 }" simple_expect ":18 15 9 $any_time 5 0 6 0 2 { 0 3 6 7 } 1 { 1 3 5 $any_time 00000000 1 [holl "T1"] }" } # Add conference 4 as recipient of text 9. talk_to client 0 send "1032 30 9 4 0\n" simple_expect "=1032" talk_to client 1 if {$cross_mirror} { simple_expect ":3 16 9 4 0" } # Remove conference 4 as recipient of text 9. talk_to client 0 send "1033 31 9 4\n" simple_expect "=1033" talk_to client 1 if {$cross_mirror} { simple_expect ":3 17 9 4 0" } # Delete text 9. talk_to client 0 send "1034 29 9\n" simple_expect "=1034" talk_to client 1 if {$cross_mirror} { simple_expect ":18 14 9 $any_time 5 0 6 0 2 { 0 3 6 7 } 1 { 1 3 5 $any_time 00000000 1 [holl "T1"] }" } # Text 10: linked via a cross-reference with trailing info. talk_to client 0 send "1035 86 [holl "text 10"] 1 { 0 3 } 1 { 3 00000000 1 [holl "T1 ho ho"] }\n" simple_expect "=1035 10" talk_to client 1 if {$cross_mirror} { simple_expect ":16 0 10 $any_time 5 0 7 0 2 { 0 3 6 8 }" simple_expect ":18 15 10 $any_time 5 0 7 0 2 { 0 3 6 8 } 1 { 1 3 5 $any_time 00000000 1 [holl "T1 ho ho"] }" } # Add conference 4 as recipient of text 10. talk_to client 0 send "1036 30 10 4 0\n" simple_expect "=1036" talk_to client 1 if {$cross_mirror} { simple_expect ":3 16 10 4 0" } # Remove conference 4 as recipient of text 10. talk_to client 0 send "1037 31 10 4\n" simple_expect "=1037" talk_to client 1 if {$cross_mirror} { simple_expect ":3 17 10 4 0" } # Delete text 10. talk_to client 0 send "1038 29 10\n" simple_expect "=1038" talk_to client 1 if {$cross_mirror} { simple_expect ":18 14 10 $any_time 5 0 7 0 2 { 0 3 6 8 } 1 { 1 3 5 $any_time 00000000 1 [holl "T1 ho ho"] }" } # Text 11: linked via a cross-reference to a conf (no async). # FIXME (bug 23): Once a mirroring aux-item for cross-references # exists, we probably should expect async messages here. talk_to client 0 send "1039 86 [holl "text 11"] 1 { 0 3 } 1 { 3 00000000 1 [holl "C1 ho ho"] }\n" simple_expect "=1039 11" # Add conference 4 as recipient of text 11. talk_to client 0 send "1040 30 11 4 0\n" simple_expect "=1040" # Remove conference 4 as recipient of text 11. send "1041 31 11 4\n" simple_expect "=1041" # Delete text 11. send "1042 29 11\n" simple_expect "=1042" # Text 12: with a broken cross-reference. talk_to client 0 send "1043 86 [holl "text 12"] 1 { 0 3 } 1 { 3 00000000 1 [holl "C99"] }\n" simple_expect "=1043 12" # Add conference 4 as recipient of text 12. talk_to client 0 send "1044 30 12 4 0\n" simple_expect "=1044" # Remove conference 4 as recipient of text 12. send "1045 31 12 4\n" simple_expect "=1045" # Delete text 12. send "1046 29 12\n" simple_expect "=1046" # Text 13: with a broken cross-reference. talk_to client 0 send "1047 86 [holl "text 13"] 1 { 0 3 } 1 { 3 00000000 1 [holl "C"] }\n" simple_expect "=1047 13" # Add conference 4 as recipient of text 13. talk_to client 0 send "1048 30 13 4 0\n" simple_expect "=1048" # Remove conference 4 as recipient of text 13. send "1049 31 13 4\n" simple_expect "=1049" # Delete text 13. send "1050 29 13\n" simple_expect "=1050" # Text 14: linked via a mx-mime-belongs-to. talk_to client 0 send "1051 86 [holl "text 14"] 1 { 0 3 } 1 { 10100 00000000 1 [holl "1"] }\n" simple_expect "=1051 14" talk_to client 1 simple_expect ":16 0 14 $any_time 5 0 7 0 2 { 0 3 6 12 }" simple_expect ":18 15 14 $any_time 5 0 7 0 2 { 0 3 6 12 } 1 { 1 10100 5 $any_time 00000000 1 [holl "1"] }" # Add conference 4 as recipient of text 14. talk_to client 0 send "1052 30 14 4 0\n" simple_expect "=1052" talk_to client 1 simple_expect ":3 16 14 4 0" # Remove conference 4 as recipient of text 14. talk_to client 0 send "1053 31 14 4\n" simple_expect "=1053" talk_to client 1 simple_expect ":3 17 14 4 0" # Delete text 14. talk_to client 0 send "1054 29 14\n" simple_expect "=1054" talk_to client 1 simple_expect ":18 14 14 $any_time 5 0 7 0 2 { 0 3 6 12 } 1 { 1 10100 5 $any_time 00000000 1 [holl "1"] }" # Text 15: linked via a mx-mime-part-in. talk_to client 0 send "1055 86 [holl "text 15"] 1 { 0 3 } 1 { 10101 00000000 1 [holl "1"] }\n" simple_expect "=1055 15" talk_to client 1 simple_expect ":16 0 15 $any_time 5 0 7 0 2 { 0 3 6 13 }" simple_expect ":18 15 15 $any_time 5 0 7 0 2 { 0 3 6 13 } 1 { 1 10101 5 $any_time 00000000 1 [holl "1"] }" # Add conference 4 as recipient of text 15. talk_to client 0 send "1056 30 15 4 0\n" simple_expect "=1056" talk_to client 1 simple_expect ":3 16 15 4 0" # Remove conference 4 as recipient of text 15. talk_to client 0 send "1057 31 15 4\n" simple_expect "=1057" talk_to client 1 simple_expect ":3 17 15 4 0" # Delete text 15. talk_to client 0 send "1058 29 15\n" simple_expect "=1058" talk_to client 1 simple_expect ":18 14 15 $any_time 5 0 7 0 2 { 0 3 6 13 } 1 { 1 10101 5 $any_time 00000000 1 [holl "1"] }" # Text 16: linked via a mx-mime-belongs-to with empty data. talk_to client 0 send "1059 86 [holl "text 16"] 1 { 0 3 } 1 { 10100 00000000 1 [holl ""] }\n" lyskomd_expect "Bad aux-item 10100 found in text 16: \"\": bad number\\." simple_expect "=1059 16" # Add conference 4 as recipient of text 16. send "1060 30 16 4 0\n" simple_expect "=1060" # Remove conference 4 as recipient of text 16. send "1061 31 16 4\n" simple_expect "=1061" # Delete text 16. send "1062 29 16\n" simple_expect "=1062" # Text 17: linked via a mx-mime-part-in with empty data. talk_to client 0 send "1063 86 [holl "text 17"] 1 { 0 3 } 1 { 10101 00000000 1 [holl ""] }\n" lyskomd_expect "Bad aux-item 10101 found in text 17: \"\": bad number\\." simple_expect "=1063 17" # Add conference 4 as recipient of text 17. send "1064 30 17 4 0\n" simple_expect "=1064" # Remove conference 4 as recipient of text 17. send "1065 31 17 4\n" simple_expect "=1065" # Delete text 17. send "1066 29 17\n" simple_expect "=1066" # Text 18: linked via a mx-mime-belongs-to with extra data. set tno 18 talk_to client 0 send "1067 86 [holl "text $tno"] 1 { 0 3 } 1 { 10100 00000000 1 [holl "1x"] }\n" lyskomd_expect "Bad aux-item 10100 found in text $tno: \"1x\": trailing garbage\\." simple_expect "=1067 $tno" # Add conference 4 as recipient of text $tno. send "1068 30 $tno 4 0\n" simple_expect "=1068" # Remove conference 4 as recipient of text $tno. send "1069 31 $tno 4\n" simple_expect "=1069" # Delete text $tno. send "1070 29 $tno\n" simple_expect "=1070" # Text 19: linked via a mx-mime-part-in with extra data. set tno 19 talk_to client 0 send "1071 86 [holl "text $tno"] 1 { 0 3 } 1 { 10101 00000000 1 [holl "1 x"] }\n" lyskomd_expect "Bad aux-item 10101 found in text $tno: \"1 x\": trailing garbage\\." simple_expect "=1071 $tno" # Add conference 4 as recipient of text $tno. send "1072 30 $tno 4 0\n" simple_expect "=1072" # Remove conference 4 as recipient of text $tno. send "1073 31 $tno 4\n" simple_expect "=1073" # Delete text $tno. send "1074 29 $tno\n" simple_expect "=1074" # Text 20: linked via a mx-mime-belongs-to with broken data. set tno 20 talk_to client 0 send "1075 86 [holl "text $tno"] 1 { 0 3 } 1 { 10100 00000000 1 [holl "x1"] }\n" lyskomd_expect "Bad aux-item 10100 found in text $tno: \"x1\": trailing garbage\\." simple_expect "=1075 $tno" # Add conference 4 as recipient of text $tno. send "1076 30 $tno 4 0\n" simple_expect "=1076" # Remove conference 4 as recipient of text $tno. send "1077 31 $tno 4\n" simple_expect "=1077" # Delete text $tno. send "1078 29 $tno\n" simple_expect "=1078" # Text 21: linked via a mx-mime-part-in with broken data. set tno 21 talk_to client 0 send "1079 86 [holl "text $tno"] 1 { 0 3 } 1 { 10101 00000000 1 [holl "99999999999999999999999999999999999999999999999999999999999999999999999999999999"] }\n" simple_expect "=1079 $tno" # Add conference 4 as recipient of text $tno. send "1080 30 $tno 4 0\n" simple_expect "=1080" # Remove conference 4 as recipient of text $tno. send "1081 31 $tno 4\n" simple_expect "=1081" # Delete text $tno. send "1082 29 $tno\n" simple_expect "=1082" # Test for async-sub-recipient when we are not allowed to see the recipient. talk_to client 0 # Create conference 7, a secret conference. send "1083 88 [holl "secret conf"] 10100000 0 { }\n" simple_expect "=1083 7" # Text 22: linked via a comm-to. set tno 22 send "1084 86 [holl "text $tno"] 3 { 0 3 2 1 0 7 } 0 { }\n" simple_expect "=1084 $tno" talk_to client 1 simple_expect ":16 0 $tno $any_time 5 0 7 0 3 { 0 3 6 20 2 1 }" simple_expect ":18 15 $tno $any_time 5 0 7 0 3 { 0 3 6 20 2 1 } 0 \\*" # Add conference 4 as recipient of text $tno. talk_to client 0 send "1085 30 $tno 4 0\n" simple_expect "=1085" talk_to client 1 simple_expect ":3 16 $tno 4 0" # Remove conference 4 as recipient of text $tno. talk_to client 0 send "1086 31 $tno 4\n" simple_expect "=1086" talk_to client 1 simple_expect ":3 17 $tno 4 0" # Remove conference 7 as recipient of text $tno. talk_to client 0 send "1087 31 $tno 7\n" simple_expect "=1087" # Add conference 7 as recipient of text $tno. send "1088 30 $tno 7 0\n" simple_expect "=1088" # Delete text $tno. send "1089 29 $tno\n" simple_expect "=1089" talk_to client 1 simple_expect ":18 14 $tno $any_time 5 0 7 0 3 { 0 3 6 20 2 1 } 0 \\*" # Test for async-sub-recipient when we subtract the reason we want to # see it. # Text 23: linked via a comm-to, sent to a conference we are a member of. set tno 23 talk_to client 0 send "1090 86 [holl "text $tno"] 2 { 0 1 2 1 } 0 { }\n" simple_expect "=1090 $tno" talk_to client 1 simple_expect ":16 0 $tno $any_time 5 0 7 0 3 { 0 1 6 2 2 1 }" simple_expect ":18 15 $tno $any_time 5 0 7 0 3 { 0 1 6 2 2 1 } 0 \\*" # Remove conference 1 as recipient of text $tno. talk_to client 0 send "1091 31 $tno 1\n" simple_expect "=1091" talk_to client 1 simple_expect ":3 17 $tno 1 0" # Delete text $tno. talk_to client 0 send "1092 29 $tno\n" simple_expect "=1092" # Text 24: sent to a conference we are a member of. set tno 24 talk_to client 0 send "1093 86 [holl "text $tno"] 1 { 0 1 } 0 { }\n" simple_expect "=1093 $tno" talk_to client 1 simple_expect ":16 0 $tno $any_time 5 0 7 0 2 { 0 1 6 3 }" simple_expect ":18 15 $tno $any_time 5 0 7 0 2 { 0 1 6 3 } 0 \\*" # Remove conference 1 as recipient of text $tno. talk_to client 0 send "1094 31 $tno 1\n" simple_expect "=1094" talk_to client 1 simple_expect ":3 17 $tno 1 0" # Delete text $tno. talk_to client 0 send "1095 29 $tno\n" simple_expect "=1095" # Shut everything down. talk_to client 0 send "1096 42 255\n" simple_expect "=1096" send "1097 44 0\n" simple_expect "=1097" client_death 0 client_death 1 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/36.exp0000664000015100472110000000444707717413255016755 # Test suite for lyskomd. # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Try to trigger bug 1005: "lyskomd: prot-a-output.c:166: # prot_a_output_read_texts: Assertion `mship->no_of_read_ranges > 0' # failed." lyskomd_start client_start 0 talk_to client 0 send "A0H\n" simple_expect "LysKOM" send "1000 62 5 6Hgazonk 1\n" simple_expect "=1000" # Join conference 1. send "1001 100 1 5 200 10 00000000\n" simple_expect "=1001" # Log out, so that person 5 is no longer locked in memory. send "1002 1\n" simple_expect "=1002" # Start a save. This will move the person from ptr to a snapshot. if {$debug_calls} { send "990 1004\n" simple_expect ":0 7" simple_expect "=990" } else { unsupported "testing for bug 1005 requires --with-debug-calls" } # Log in again. This will trigger a copy of the snapshot to ptr. send "1003 62 5 6Hgazonk 1\n" simple_expect "=1003" # Do query-read-texts with want-read-ranges set to false. send "1004 107 5 1 0 0\n" simple_expect "=1004 1 $any_time 1 200 0 \\* 5 $any_time 00000000" # Do get-membership-old with want-read-texts set to false. send "1005 46 5 1 1 0\n" simple_expect "=1005 1 { $any_time 1 200 0 0 \\* }" if {$debug_calls} { # Save the snapshot of the database. send "993 1005\n" simple_expect ":0 7" simple_expect "=993" } # Shut everything down. talk_to client 0 send "1006 42 255\n" simple_expect "=1006" send "1007 44 0\n" simple_expect "=1007" client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/37.exp0000664000015100472110000001461207723706615016753 # Test suite for lyskomd. # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test the parsing of "timeval" entries in the configuration file. lyskomd_start "" "" "\ Max conferences: 200 Max texts: 200 DNS log threshold: 3600 Aux-item definition file: $aux_item_default_conf_file" client_start 0 talk_to client 0 send "A0H\n" simple_expect "LysKOM" if {$debug_calls == 0} { unsupported "enable value testing with configure --with-debug-calls" } else { send "1 1006\n" talk_to lyskomd simple_expect "Configuration timeval dump" simple_expect "Name: Garb busy postponement" simple_expect " Default suffix: milliseconds" simple_expect " Seconds: 0" simple_expect " Microseconds: 50000" simple_expect "Name: Garb timeout" simple_expect " Default suffix: milliseconds" simple_expect " Seconds: 0" simple_expect " Microseconds: 0" simple_expect "Name: Sync timeout" simple_expect " Default suffix: milliseconds" simple_expect " Seconds: 0" simple_expect " Microseconds: 0" simple_expect "Name: Garb interval" simple_expect " Default suffix: minutes" simple_expect " Seconds: 86400" simple_expect " Microseconds: 0" simple_expect "Name: Sync interval" simple_expect " Default suffix: minutes" simple_expect " Seconds: 300" simple_expect " Microseconds: 0" simple_expect "Name: Sync retry interval" simple_expect " Default suffix: minutes" simple_expect " Seconds: 60" simple_expect " Microseconds: 0" simple_expect "Name: Connect timeout" simple_expect " Default suffix: seconds" simple_expect " Seconds: 30" simple_expect " Microseconds: 0" simple_expect "Name: Login timeout" simple_expect " Default suffix: minutes" simple_expect " Seconds: 1800" simple_expect " Microseconds: 0" simple_expect "Name: Active timeout" simple_expect " Default suffix: days" simple_expect " Seconds: 993600" simple_expect " Microseconds: 0" simple_expect "Name: Stale timeout" simple_expect " Default suffix: minutes" simple_expect " Seconds: 3600" simple_expect " Microseconds: 0" simple_expect "End of timeval dump" talk_to client 0 simple_expect "=1" } system "kill -TERM $lyskomd_pid" client_death 0 lyskomd_death "" signal ################################################################## lyskomd_start "" "Garb busy postponement: 1 microfortnight Garb timeout: 1us Sync timeout: 10 us Garb interval: 4 Sync interval: 4 days Sync retry interval: 2.25 second" "\ Max conferences: 200 Max texts: 200 DNS log threshold: 3600 Aux-item definition file: $aux_item_default_conf_file" client_start 0 talk_to client 0 send "A0H\n" simple_expect "LysKOM" if {$debug_calls} { send "1 1006\n" talk_to lyskomd simple_expect "Configuration timeval dump" simple_expect "Name: Garb busy postponement" simple_expect " Default suffix: milliseconds" simple_expect " Seconds: 1" simple_expect " Microseconds: 209600" simple_expect "Name: Garb timeout" simple_expect " Default suffix: milliseconds" simple_expect " Seconds: 0" simple_expect " Microseconds: 1" simple_expect "Name: Sync timeout" simple_expect " Default suffix: milliseconds" simple_expect " Seconds: 0" simple_expect " Microseconds: 10" simple_expect "Name: Garb interval" simple_expect " Default suffix: minutes" simple_expect " Seconds: 240" simple_expect " Microseconds: 0" simple_expect "Name: Sync interval" simple_expect " Default suffix: minutes" simple_expect " Seconds: 345600" simple_expect " Microseconds: 0" simple_expect "Name: Sync retry interval" simple_expect " Default suffix: minutes" simple_expect " Seconds: 2" simple_expect " Microseconds: 250000" simple_expect "Name: Connect timeout" simple_expect " Default suffix: seconds" simple_expect " Seconds: 30" simple_expect " Microseconds: 0" simple_expect "Name: Login timeout" simple_expect " Default suffix: minutes" simple_expect " Seconds: 1800" simple_expect " Microseconds: 0" simple_expect "Name: Active timeout" simple_expect " Default suffix: days" simple_expect " Seconds: 993600" simple_expect " Microseconds: 0" simple_expect "Name: Stale timeout" simple_expect " Default suffix: minutes" simple_expect " Seconds: 3600" simple_expect " Microseconds: 0" simple_expect "End of timeval dump" talk_to client 0 simple_expect "=1" } system "kill -TERM $lyskomd_pid" client_death 0 lyskomd_death "" signal ################################################################## lyskomd_fail_start \ [list "Overflow for parameter Garb timeout \\($any_float seconds\\)" \ "assigner for Garb timeout failed" \ "Overflow for parameter Sync timeout \\($any_float seconds\\)" \ "assigner for Sync timeout failed" \ "Overflow for parameter Garb interval \\($any_float days\\)" \ "assigner for Garb interval failed" \ "Overflow for parameter Sync retry interval \\($any_float us\\)" \ "assigner for Sync retry interval failed" \ "Please fix the above errors in config/lyskomd-config and restart lyskomd" \ ] "" [exec ./timeval-overflow] lyskomd_fail_start { "Bad suffix for parameter Garb interval" "assigner for Garb interval failed" "Negative values not supported for parameter Sync timeout" "assigner for Sync timeout failed" "Please fix the above errors in config/lyskomd-config and restart lyskomd" } "" "Garb interval: 4 lifetimes Sync timeout: -2 us" lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/38.exp0000664000015100472110000001373507717413255016757 # Test suite for lyskomd. # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test what the server does under severe load. lyskomd_start "" "Stale timeout: 10 seconds Max client message size: 512 Sync interval: 1 days Max client transmit queue bytes: 2505" proc monitor_progress {} { global test global nl global any_num set aborted 0 set test "monitoring progress" expect { -re "Progress: $any_num pending reqs$nl" { exp_continue } -re "End of progress reports$nl" { pass "$test" } timeout { if {$aborted == 1} { fail "$test (timeout after shutdown)" } else { fail "$test (timeout - shutting down client)" send "shutdown\n" set aborted 1 } exp_continue } } unset test } proc req_rate {} { global test global spawn_id global any_num global any_float global req_rate_rate if {[info exists test]} { set oldtest $test unset test } set id $spawn_id talk_to client 0 send "998 112 [holl "reqs"]\n" extracting_expect "=998 6 { $any_num 0 0 $any_float $any_float $any_float $any_float $any_float ($any_float) $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float }" req_rate_rate 1 if {[info exists oldtest]} { set test $oldtest } set spawn_id $id return $req_rate_rate } proc send_queue_size {} { global test global spawn_id global any_num global any_float global send_queue_size_size if {[info exists test]} { set oldtest $test unset test } set id $spawn_id talk_to client 0 send "999 112 [holl "send-queue-bytes"]\n" extracting_expect "=999 6 { ($any_num) 0 0 $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float }" send_queue_size_size 1 if {[info exists oldtest]} { set test $oldtest } set spawn_id $id return $send_queue_size_size } client_start 0 talk_to client 0 send "A\n" send "[holl "DejaGnu test suite"]\n" simple_expect "LysKOM" "connected" set oldsize [send_queue_size] get_time_client_start 0 {"--time-limit"} monitor_progress extracting_expect "($any_num) reqs, $any_num bytes, $any_num reads" reqs 1 simple_expect "$reqs reqs, $any_num bytes, $any_num writes" simple_expect "0 pending reqs" simple_expect "" get_time_client_death 0 get_time_client_start 1 {"--time-abort"} monitor_progress simple_expect "$any_num reqs, $any_num bytes, $any_num reads" simple_expect "$any_num reqs, $any_num bytes, $any_num writes" simple_expect "\[1-9\]\[0-9\]* pending reqs" simple_expect "" get_time_client_death 1 get_time_client_start 2 {"--time-abort"} get_time_client_start 3 {"--time-limit"} talk_to get_time_client 2 monitor_progress simple_expect "$any_num reqs, $any_num bytes, $any_num reads" simple_expect "$any_num reqs, $any_num bytes, $any_num writes" simple_expect "\[1-9\]\[0-9\]* pending reqs" simple_expect "" get_time_client_death 2 talk_to get_time_client 3 monitor_progress extracting_expect "($any_num) reqs, $any_num bytes, $any_num reads" reqs 1 simple_expect "$reqs reqs, $any_num bytes, $any_num writes" simple_expect "0 pending reqs" simple_expect "" get_time_client_death 3 get_time_client_start 4 {"--write-only"} send "ping\n" simple_expect "pong" talk_to lyskomd # The server will wait 10 seconds before it kills the stalled client. # Give it 4 extra seconds. set test "server kills client 5" expect { -re "Client 6 from $any* has stalled\. Killing it\.$nl" { pass "$test" } timeout { set size [send_queue_size] set rate [req_rate] # Check to see if the client was killed after the timeout # fired but before execution arrives here. set old_timeout $timeout set timeout 0 set got_it 0 expect { -re "Client 6 from $any* has stalled\. Killing it\.$nl" { set got_it 1 } timeout { } } set timeout $old_timeout if {$got_it == 1} { pass "$test" } elseif {$size > $oldsize} { set oldsize $size send_user "Queue is growing... $size\n" exp_continue } elseif {$rate > 10} { send_user "Server is processing... $rate reqs/second (15 s avg) (size $size)\n" exp_continue } else { fail "$test (output queue not growing)" talk_to get_time_client 4 send "shutdown\n" } } } unset test talk_to get_time_client 4 send "ping\n" simple_expect "pong" send "start-reading\n" simple_expect "ok" monitor_progress simple_expect "$any_num reqs, $any_num bytes, $any_num reads" extracting_expect "($any_num) reqs, $any_num bytes, $any_num writes" reqs 1 extracting_expect "($any_num) pending reqs" pend 1 simple_expect "" set test "proper number of pending and sent requests" if {$pend > 0 && $reqs > $pend} { pass "$test" } else { fail "$test ($reqs sent, $pend pending)" } unset test get_time_client_death 4 talk_to client 0 send "1000 112 [holl "recv-queue-bytes"]\n" simple_expect "=1000 6 { $any_num 0 0 $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float $any_float }" system "kill -TERM $lyskomd_pid" client_death 0 lyskomd_death "" signal lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/39.exp0000664000015100472110000001110407717413255016744 # Test suite for lyskomd. # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test that clients are disconnected properly if they are idle too long. send_user "All timeouts short\n" lyskomd_start "" "Stale timeout: 1 seconds Connect timeout: 4 seconds Login timeout: 4 seconds Active timeout: 4 seconds Sync interval: 1 days" client_start 0 client_start 1 send "A\n" send "[holl "DejaGnu test suite"]\n" simple_expect "LysKOM" "connected" send "1000 80 0 { }\n" simple_expect "=1000" client_start 2 send "A\n" send "[holl "DejaGnu test suite"]\n" simple_expect "LysKOM" "connected" send "1001 80 0 { }\n" simple_expect "=1001" send "1002 0 5 [holl "gazonk"]\n" simple_expect "=1002" lyskomd_expect "Client 1 from $any* has been idle too long\. Killing it\." client_death 0 lyskomd_expect "Client 2 from $any* has been idle too long\. Killing it\." client_death 1 lyskomd_expect "Client 3 from $any* has been idle too long\. Killing it\." client_death 2 system "kill -TERM $lyskomd_pid" lyskomd_death "" signal # ========================================================================= send_user "Connect timeout short\n" lyskomd_start "" "Stale timeout: 1 seconds Connect timeout: 4 seconds Login timeout: 1 hour Active timeout: 1 hour Sync interval: 1 days" client_start 0 client_start 1 send "A\n" send "[holl "DejaGnu test suite"]\n" simple_expect "LysKOM" "connected" send "1003 80 0 { }\n" simple_expect "=1003" client_start 2 send "A\n" send "[holl "DejaGnu test suite"]\n" simple_expect "LysKOM" "connected" send "1004 80 0 { }\n" simple_expect "=1004" send "1005 0 5 [holl "gazonk"]\n" simple_expect "=1005" lyskomd_expect "Client 1 from $any* has been idle too long\. Killing it\." client_death 0 sleep 10 talk_to client 1 send "1006 35 \n" simple_expect "=1006 $any_time" talk_to client 2 send "1007 35 \n" simple_expect "=1007 $any_time" system "kill -TERM $lyskomd_pid" lyskomd_death "" signal client_death 1 client_death 2 # ========================================================================= send_user "Login timeout short\n" lyskomd_start "" "Stale timeout: 1 seconds Connect timeout: 1 hour Login timeout: 4 seconds Active timeout: 1 hour Sync interval: 1 days" client_start 0 client_start 1 send "A\n" send "[holl "DejaGnu test suite"]\n" simple_expect "LysKOM" "connected" send "1008 80 0 { }\n" simple_expect "=1008" client_start 2 send "A\n" send "[holl "DejaGnu test suite"]\n" simple_expect "LysKOM" "connected" send "1009 80 0 { }\n" simple_expect "=1009" send "1010 0 5 [holl "gazonk"]\n" simple_expect "=1010" lyskomd_expect "Client 2 from $any* has been idle too long\. Killing it\." client_death 1 sleep 10 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" talk_to client 2 send "1011 35 \n" simple_expect "=1011 $any_time" system "kill -TERM $lyskomd_pid" lyskomd_death "" signal client_death 0 client_death 2 # ========================================================================= send_user "Active timeout short\n" lyskomd_start "" "Stale timeout: 1 seconds Connect timeout: 1 hour Login timeout: 1 hour Active timeout: 4 seconds Sync interval: 1 days" client_start 0 client_start 1 send "A\n" send "[holl "DejaGnu test suite"]\n" simple_expect "LysKOM" "connected" send "1012 80 0 { }\n" simple_expect "=1012" client_start 2 send "A\n" send "[holl "DejaGnu test suite"]\n" simple_expect "LysKOM" "connected" send "1013 80 0 { }\n" simple_expect "=1013" send "1014 0 5 [holl "gazonk"]\n" simple_expect "=1014" lyskomd_expect "Client 3 from $any* has been idle too long\. Killing it\." client_death 2 sleep 10 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" talk_to client 1 send "1015 35 \n" simple_expect "=1015 $any_time" system "kill -TERM $lyskomd_pid" lyskomd_death "" signal client_death 0 client_death 1 lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/40.exp0000664000015100472110000001613307720646607016746 # Test suite for lyskomd. # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test async-new-presentation. # # Persons: # 5: admin # 6: super: creator of 9 and 10 # 7: member: a member of 9 and 10 # 8: bystander: not a member # # Conferences: # 9: public # 10: secret # # Texts: # 1: conf 1 as recipient # 2: conf 1 as recipient # 3: conf 10 as recipient # 4: conf 10 as recipient lyskomd_start # Log in as admin, and enable. client_start 5 send "A[holl "five"]\n" simple_expect "LysKOM" "connected" send "1000 80 1 { 20 }\n" good_bad_expect "=1000" "%50 20" send "1001 0 5 [holl "gazonk"]\n" simple_expect "=1001" send "1002 42 255\n" simple_expect "=1002" # Create person 6 and log in. client_start 6 send "A[holl "six"]\n" simple_expect "LysKOM" "connected" send "1003 80 1 { 20 }\n" good_bad_expect "=1003" "%50 20" send "1004 89 [holl "super"] [holl "super"] 00000000 0 { }\n" simple_expect "=1004 6" send "1005 0 6 [holl "super"]\n" simple_expect "=1005" # Create person 7 and log in. client_start 7 send "A[holl "seven"]\n" simple_expect "LysKOM" "connected" send "1006 80 1 { 20 }\n" good_bad_expect "=1006" "%50 20" send "1007 89 [holl "member"] [holl "member"] 00000000 0 { }\n" simple_expect "=1007 7" send "1008 0 7 [holl "member"]\n" simple_expect "=1008" # Create person 8 and log in. client_start 8 send "A[holl "eight"]\n" simple_expect "LysKOM" "connected" send "1009 80 1 { 20 }\n" good_bad_expect "=1009" "%50 20" send "1010 89 [holl "bystander"] [holl "bystander"] 00000000 0 { }\n" simple_expect "=1010 8" send "1011 0 8 [holl "bystander"]\n" simple_expect "=1011" # Create conferences 9 and 10, and let person 6 and 7 join them. talk_to client 6 send "1012 88 [holl "public"] 00000000 0 { }\n" simple_expect "=1012 9" send "1013 88 [holl "secret"] 10100000 0 { }\n" simple_expect "=1013 10" send "1014 100 9 6 200 1 00000000\n" simple_expect "=1014" send "1015 100 9 7 200 1 00000000\n" lyskomd_expect "Person 7 added to conference 9 by 6\." simple_expect "=1015" send "1016 100 10 6 200 1 00000000\n" simple_expect "=1016" send "1017 100 10 7 200 1 00000000\n" lyskomd_expect "Person 7 added to conference 10 by 6\." simple_expect "=1017" # Person 7 accepts the invitations. talk_to client 7 send "1018 100 9 7 200 1 00000000\n" simple_expect "=1018" send "1019 100 10 7 200 1 00000000\n" simple_expect "=1019" # Person 6 creates the four texts that will be used as presentations. talk_to client 6 send "1020 86 [holl "text 1"] 1 { 0 1 } 0 { }\n" simple_expect "=1020 1" send "1021 86 [holl "text 2"] 1 { 0 1 } 0 { }\n" simple_expect "=1021 2" send "1022 86 [holl "text 3"] 1 { 0 10 } 0 { }\n" simple_expect "=1022 3" send "1023 86 [holl "text 4"] 1 { 0 10 } 0 { }\n" simple_expect "=1023 4" # Set text 1 as presentation of conference 9. send "1024 16 9 1\n" simple_expect ":3 20 9 0 1" client_expect 5 ":3 20 9 0 1" client_expect 7 ":3 20 9 0 1" client_expect 8 ":3 20 9 0 1" simple_expect "=1024" # Set text 2 as presentation of conference 9. send "1025 16 9 2\n" simple_expect ":3 20 9 1 2" client_expect 5 ":3 20 9 1 2" client_expect 7 ":3 20 9 1 2" client_expect 8 ":3 20 9 1 2" simple_expect "=1025" # Set text 3 as presentation of conference 9. Since it isn't visible # to the bystander, the bystander will think the presentation has been # removed. send "1026 16 9 3\n" simple_expect ":3 20 9 2 3" client_extracting_expect 5 ":3 20 9 2 (0|3)" seen 1 set test "administrator sees proper text" if {$seen == 3} { pass "$test" } else { fail "$test (filtered)" } unset test client_expect 7 ":3 20 9 2 3" client_expect 8 ":3 20 9 2 0" simple_expect "=1026" # Set text 4 as presentation of conference 9. This text is also not # visible to the bystander. In the view of the bystander, the # presentation changes from 0 to 0. That is no change, so no async # message is sent to the bystander. send "1027 16 9 4\n" simple_expect ":3 20 9 3 4" client_expect 5 ":3 20 9 3 4" client_expect 7 ":3 20 9 3 4" simple_expect "=1027" # View the conf-stat of conference 9. send "1028 91 9\n" simple_expect "=1028 [holl "public"] 00000000 $any_time $any_time 6 4 6 0 6 0 77 77 2 1 0 0 0 \\*" talk_to client 5 send "1029 91 9\n" simple_expect "=1029 [holl "public"] 00000000 $any_time $any_time 6 4 6 0 6 0 77 77 2 1 0 0 0 \\*" talk_to client 7 send "1030 91 9\n" simple_expect "=1030 [holl "public"] 00000000 $any_time $any_time 6 4 6 0 6 0 77 77 2 1 0 0 0 \\*" talk_to client 8 send "1031 91 9\n" extracting_expect "=1031 [holl "public"] 00000000 $any_time $any_time 6 ($any_num) 6 0 6 0 77 77 2 1 0 0 0 \\*" pres 1 setup_xfail "*-*-*" "Bug 1074" set test "Unreadable presentation filtered" if {$pres == 0} { pass "$test" } else { fail "$test (presentation visible)" if {$pres != 4} { fail "$test (strange result $pres)" } } unset test # Set text 1 as presentation of conference 10. talk_to client 6 send "1032 16 10 1\n" simple_expect ":3 20 10 0 1" client_expect 5 ":3 20 10 0 1" client_expect 7 ":3 20 10 0 1" simple_expect "=1032" # Set text 2 as presentation of conference 10. send "1033 16 10 2\n" simple_expect ":3 20 10 1 2" client_expect 5 ":3 20 10 1 2" client_expect 7 ":3 20 10 1 2" simple_expect "=1033" # Set text 3 as presentation of conference 10. # removed. send "1034 16 10 3\n" simple_expect ":3 20 10 2 3" client_extracting_expect 5 ":3 20 10 2 (0|3)" seen 1 set test "administrator sees proper text" if {$seen == 3} { pass "$test" } else { fail "$test (filtered)" } unset test client_expect 7 ":3 20 10 2 3" simple_expect "=1034" # Set text 4 as presentation of conference 10. send "1035 16 10 4\n" simple_expect ":3 20 10 3 4" client_expect 5 ":3 20 10 3 4" client_expect 7 ":3 20 10 3 4" simple_expect "=1035" # View the conf-stat of conference 10. send "1036 91 10\n" simple_expect "=1036 [holl "secret"] 10100000 $any_time $any_time 6 4 6 0 6 0 77 77 2 1 2 0 0 \\*" talk_to client 5 send "1037 91 10\n" simple_expect "=1037 [holl "secret"] 10100000 $any_time $any_time 6 4 6 0 6 0 77 77 2 1 2 0 0 \\*" talk_to client 7 send "1038 91 10\n" simple_expect "=1038 [holl "secret"] 10100000 $any_time $any_time 6 4 6 0 6 0 77 77 2 1 2 0 0 \\*" talk_to client 8 send "1039 91 10\n" simple_expect "%1039 9 10" # Shut down. talk_to client 5 send "1040 44 0\n" simple_expect "=1040" client_death 5 client_death 6 client_death 7 client_death 8 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/41.exp0000664000015100472110000003030507720660670016740 # Test suite for lyskomd. # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test async-new-motd. # Also test first-unused-conf-no and first-unused-text-no. # Also test find-next-conf-no and find-previous-conf-no. # # Persons: # 5: admin # 6: super: creator of 9 and 10 # 7: member: a member of 9 and 10 # 8: bystander: not a member # # Conferences: # 9: public # 10: secret # # Texts: # 1: conf 1 as recipient # 2: conf 1 as recipient # 3: conf 10 as recipient # 4: conf 10 as recipient lyskomd_start # Log in as admin, and enable. client_start 5 send "A[holl "five"]\n" simple_expect "LysKOM" "connected" # 114:first-unused-conf-no send "1000 114\n" simple_expect "=1000 6" # 115:first-unused-text-no send "1001 115\n" simple_expect "=1001 1" send "1002 80 1 { 21 }\n" simple_expect "=1002" send "1003 0 5 [holl "gazonk"]\n" simple_expect "=1003" send "1004 42 255\n" simple_expect "=1004" # Create person 6 and log in. client_start 6 send "A[holl "six"]\n" simple_expect "LysKOM" "connected" send "1005 80 1 { 21 }\n" simple_expect "=1005" send "1006 89 [holl "super"] [holl "super"] 00000000 0 { }\n" simple_expect "=1006 6" send "1007 0 6 [holl "super"]\n" simple_expect "=1007" # Create person 7 and log in. client_start 7 send "A[holl "seven"]\n" simple_expect "LysKOM" "connected" send "1008 80 1 { 21 }\n" simple_expect "=1008" send "1009 89 [holl "member"] [holl "member"] 00000000 0 { }\n" simple_expect "=1009 7" send "1010 0 7 [holl "member"]\n" simple_expect "=1010" # Create person 8 and log in. client_start 8 send "A[holl "eight"]\n" simple_expect "LysKOM" "connected" send "1011 80 1 { 21 }\n" simple_expect "=1011" send "1012 89 [holl "bystander"] [holl "bystander"] 00000000 0 { }\n" simple_expect "=1012 8" send "1013 0 8 [holl "bystander"]\n" simple_expect "=1013" # Create conferences 9 and 10, and let person 6 and 7 join them. talk_to client 6 send "1014 88 [holl "public"] 00000000 0 { }\n" simple_expect "=1014 9" send "1015 88 [holl "secret"] 10100000 0 { }\n" simple_expect "=1015 10" send "1016 100 9 6 200 1 00000000\n" simple_expect "=1016" send "1017 100 9 7 200 1 00000000\n" lyskomd_expect "Person 7 added to conference 9 by 6\." simple_expect "=1017" send "1018 100 10 6 200 1 00000000\n" simple_expect "=1018" send "1019 100 10 7 200 1 00000000\n" lyskomd_expect "Person 7 added to conference 10 by 6\." simple_expect "=1019" # Person 7 accepts the invitations. talk_to client 7 send "1020 100 9 7 200 1 00000000\n" simple_expect "=1020" send "1021 100 10 7 200 1 00000000\n" simple_expect "=1021" # Person 6 creates the four texts that will be used as motds. talk_to client 6 send "1022 86 [holl "text 1"] 1 { 0 1 } 0 { }\n" simple_expect "=1022 1" send "1023 86 [holl "text 2"] 1 { 0 1 } 0 { }\n" simple_expect "=1023 2" send "1024 86 [holl "text 3"] 1 { 0 10 } 0 { }\n" simple_expect "=1024 3" send "1025 86 [holl "text 4"] 1 { 0 10 } 0 { }\n" simple_expect "=1025 4" # Set text 1 as motd of conference 9. send "1026 17 9 1\n" simple_expect ":3 21 9 0 1" client_expect 5 ":3 21 9 0 1" client_expect 7 ":3 21 9 0 1" client_expect 8 ":3 21 9 0 1" simple_expect "=1026" # Set text 2 as motd of conference 9. send "1027 17 9 2\n" simple_expect ":3 21 9 1 2" client_expect 5 ":3 21 9 1 2" client_expect 7 ":3 21 9 1 2" client_expect 8 ":3 21 9 1 2" simple_expect "=1027" # Set text 3 as motd of conference 9. Since it isn't visible # to the bystander, the bystander will think the motd has been # removed. send "1028 17 9 3\n" simple_expect ":3 21 9 2 3" client_extracting_expect 5 ":3 21 9 2 (0|3)" seen 1 set test "administrator sees proper text" if {$seen == 3} { pass "$test" } else { fail "$test (filtered)" } unset test client_expect 7 ":3 21 9 2 3" client_expect 8 ":3 21 9 2 0" simple_expect "=1028" # Set text 4 as presentation of conference 9. This text is also not # visible to the bystander. In the view of the bystander, the # presentation changes from 0 to 0. That is no change, so no async # message is sent to the bystander. send "1029 17 9 4\n" simple_expect ":3 21 9 3 4" client_expect 5 ":3 21 9 3 4" client_expect 7 ":3 21 9 3 4" simple_expect "=1029" # View the conf-stat of conference 9. send "1030 91 9\n" simple_expect "=1030 [holl "public"] 00000000 $any_time $any_time 6 0 6 0 6 4 77 77 2 1 0 0 0 \\*" talk_to client 5 send "1031 91 9\n" simple_expect "=1031 [holl "public"] 00000000 $any_time $any_time 6 0 6 0 6 4 77 77 2 1 0 0 0 \\*" talk_to client 7 send "1032 91 9\n" simple_expect "=1032 [holl "public"] 00000000 $any_time $any_time 6 0 6 0 6 4 77 77 2 1 0 0 0 \\*" talk_to client 8 send "1033 91 9\n" extracting_expect "=1033 [holl "public"] 00000000 $any_time $any_time 6 0 6 0 6 ($any_num) 77 77 2 1 0 0 0 \\*" motd 1 setup_xfail "*-*-*" "Bug 1074" set test "Unreadable motd filtered" if {$motd == 0} { pass "$test" } else { fail "$test (motd visible)" if {$motd != 4} { fail "$test (strange result $motd)" } } unset test # Set text 1 as motd of conference 10. talk_to client 6 send "1034 17 10 1\n" simple_expect ":3 21 10 0 1" client_expect 5 ":3 21 10 0 1" client_expect 7 ":3 21 10 0 1" simple_expect "=1034" # Set text 2 as motd of conference 10. send "1035 17 10 2\n" simple_expect ":3 21 10 1 2" client_expect 5 ":3 21 10 1 2" client_expect 7 ":3 21 10 1 2" simple_expect "=1035" # Set text 3 as motd of conference 10. # removed. send "1036 17 10 3\n" simple_expect ":3 21 10 2 3" client_extracting_expect 5 ":3 21 10 2 (0|3)" seen 1 set test "administrator sees proper text" if {$seen == 3} { pass "$test" } else { fail "$test (filtered)" } unset test client_expect 7 ":3 21 10 2 3" simple_expect "=1036" # Set text 4 as motd of conference 10. send "1037 17 10 4\n" simple_expect ":3 21 10 3 4" client_expect 5 ":3 21 10 3 4" client_expect 7 ":3 21 10 3 4" simple_expect "=1037" # View the conf-stat of conference 10. send "1038 91 10\n" simple_expect "=1038 [holl "secret"] 10100000 $any_time $any_time 6 0 6 0 6 4 77 77 2 1 2 0 0 \\*" talk_to client 5 send "1039 91 10\n" simple_expect "=1039 [holl "secret"] 10100000 $any_time $any_time 6 0 6 0 6 4 77 77 2 1 2 0 0 \\*" talk_to client 7 send "1040 91 10\n" simple_expect "=1040 [holl "secret"] 10100000 $any_time $any_time 6 0 6 0 6 4 77 77 2 1 2 0 0 \\*" talk_to client 8 send "1041 91 10\n" simple_expect "%1041 9 10" # Test find-next-conf-no and find-previous-conf-no. # Person 5 is allowed to see everything. talk_to client 5 send "1042 116 0\n" simple_expect "=1042 1" send "1043 116 1\n" simple_expect "=1043 2" send "1044 116 2\n" simple_expect "=1044 3" send "1045 116 3\n" simple_expect "=1045 4" send "1046 116 4\n" simple_expect "=1046 5" send "1047 116 5\n" simple_expect "=1047 6" send "1048 116 6\n" simple_expect "=1048 7" send "1049 116 7\n" simple_expect "=1049 8" send "1050 116 8\n" simple_expect "=1050 9" send "1051 116 9\n" simple_expect "=1051 10" send "1052 116 10\n" simple_expect "%1052 9 10" send "1053 116 11\n" simple_expect "%1053 9 11" send "1054 117 0\n" simple_expect "%1054 9 0" send "1055 117 1\n" simple_expect "%1055 9 1" send "1056 117 2\n" simple_expect "=1056 1" send "1057 117 3\n" simple_expect "=1057 2" send "1058 117 4\n" simple_expect "=1058 3" send "1059 117 5\n" simple_expect "=1059 4" send "1060 117 6\n" simple_expect "=1060 5" send "1061 117 7\n" simple_expect "=1061 6" send "1062 117 8\n" simple_expect "=1062 7" send "1063 117 9\n" simple_expect "=1063 8" send "1064 117 10\n" simple_expect "=1064 9" send "1065 117 11\n" simple_expect "=1065 10" send "1066 117 12\n" simple_expect "=1066 10" send "1067 117 120\n" simple_expect "=1067 10" # Person 6 is allowed to see everything. talk_to client 6 send "1068 116 0\n" simple_expect "=1068 1" send "1069 116 1\n" simple_expect "=1069 2" send "1070 116 2\n" simple_expect "=1070 3" send "1071 116 3\n" simple_expect "=1071 4" send "1072 116 4\n" simple_expect "=1072 5" send "1073 116 5\n" simple_expect "=1073 6" send "1074 116 6\n" simple_expect "=1074 7" send "1075 116 7\n" simple_expect "=1075 8" send "1076 116 8\n" simple_expect "=1076 9" send "1077 116 9\n" simple_expect "=1077 10" send "1078 116 10\n" simple_expect "%1078 9 10" send "1079 116 11\n" simple_expect "%1079 9 11" send "1080 117 0\n" simple_expect "%1080 9 0" send "1081 117 1\n" simple_expect "%1081 9 1" send "1082 117 2\n" simple_expect "=1082 1" send "1083 117 3\n" simple_expect "=1083 2" send "1084 117 4\n" simple_expect "=1084 3" send "1085 117 5\n" simple_expect "=1085 4" send "1086 117 6\n" simple_expect "=1086 5" send "1087 117 7\n" simple_expect "=1087 6" send "1088 117 8\n" simple_expect "=1088 7" send "1089 117 9\n" simple_expect "=1089 8" send "1090 117 10\n" simple_expect "=1090 9" send "1091 117 11\n" simple_expect "=1091 10" send "1092 117 12\n" simple_expect "=1092 10" send "1093 117 120\n" simple_expect "=1093 10" # Person 7 is allowed to see everything. talk_to client 7 send "1094 116 0\n" simple_expect "=1094 1" send "1095 116 1\n" simple_expect "=1095 2" send "1096 116 2\n" simple_expect "=1096 3" send "1097 116 3\n" simple_expect "=1097 4" send "1098 116 4\n" simple_expect "=1098 5" send "1099 116 5\n" simple_expect "=1099 6" send "1100 116 6\n" simple_expect "=1100 7" send "1101 116 7\n" simple_expect "=1101 8" send "1102 116 8\n" simple_expect "=1102 9" send "1103 116 9\n" simple_expect "=1103 10" send "1104 116 10\n" simple_expect "%1104 9 10" send "1105 116 11\n" simple_expect "%1105 9 11" send "1106 117 0\n" simple_expect "%1106 9 0" send "1107 117 1\n" simple_expect "%1107 9 1" send "1108 117 2\n" simple_expect "=1108 1" send "1109 117 3\n" simple_expect "=1109 2" send "1110 117 4\n" simple_expect "=1110 3" send "1111 117 5\n" simple_expect "=1111 4" send "1112 117 6\n" simple_expect "=1112 5" send "1113 117 7\n" simple_expect "=1113 6" send "1114 117 8\n" simple_expect "=1114 7" send "1115 117 9\n" simple_expect "=1115 8" send "1116 117 10\n" simple_expect "=1116 9" send "1117 117 11\n" simple_expect "=1117 10" send "1118 117 12\n" simple_expect "=1118 10" send "1119 117 120\n" simple_expect "=1119 10" # Person 8 is not allowed to see the secret conference 10 talk_to client 8 send "1120 116 0\n" simple_expect "=1120 1" send "1121 116 1\n" simple_expect "=1121 2" send "1122 116 2\n" simple_expect "=1122 3" send "1123 116 3\n" simple_expect "=1123 4" send "1124 116 4\n" simple_expect "=1124 5" send "1125 116 5\n" simple_expect "=1125 6" send "1126 116 6\n" simple_expect "=1126 7" send "1127 116 7\n" simple_expect "=1127 8" send "1128 116 8\n" simple_expect "=1128 9" send "1129 116 9\n" simple_expect "%1129 9 9" send "1130 116 10\n" simple_expect "%1130 9 10" send "1131 116 11\n" simple_expect "%1131 9 11" send "1132 117 0\n" simple_expect "%1132 9 0" send "1133 117 1\n" simple_expect "%1133 9 1" send "1134 117 2\n" simple_expect "=1134 1" send "1135 117 3\n" simple_expect "=1135 2" send "1136 117 4\n" simple_expect "=1136 3" send "1137 117 5\n" simple_expect "=1137 4" send "1138 117 6\n" simple_expect "=1138 5" send "1139 117 7\n" simple_expect "=1139 6" send "1140 117 8\n" simple_expect "=1140 7" send "1141 117 9\n" simple_expect "=1141 8" send "1142 117 10\n" simple_expect "=1142 9" send "1143 117 11\n" simple_expect "=1143 9" send "1144 117 12\n" simple_expect "=1144 9" send "1145 117 120\n" simple_expect "=1145 9" # Shut down. talk_to client 5 # 114:first-unused-conf-no send "1146 114\n" simple_expect "=1146 11" # 115:first-unused-text-no send "1147 115\n" simple_expect "=1147 5" send "1148 44 0\n" simple_expect "=1148" client_death 5 client_death 6 client_death 7 client_death 8 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/42.exp0000664000015100472110000002102107717413256016736 # Test suite for lyskomd. # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test keep-commented. # # Persons: # 5: admin # # Conferences: # 6: garb_nice=77, keep_commented=6 # 7: garb_nice=77, keep_commented=7 # 8: garb_nice=77, keep_commented=8 # 9: garb_nice=77, keep_commented=9 # 10: garb_nice=77, keep_commented=0 # # Texts: # 1: recip={6, 8} # 2: recip={6, 9}, comm_to=1 # 3: recip={9, 6}, comm_to=1, sent later # 4: recip={10} # 5: recip={10}, footn_to=4 # 6: recip={10}, comm_to=4, sent later # 7: recip={10} # 8: recip={7}, comm_to=7 # 9: recip={7} # 10: recip={10}, comm_to=9 # 11: recip={10} # 12: recip={7}, comm_to=11, sent later # 13: recip={7} # 14: recip={10}, footn_to=13, sent later # 15: recip={10} # 16: recip={10}, footn_to=15 # # "sent later" means that the comment link has a sent_at item. proc run_garb {removed} { global any global any_time # Run the garb and make sure that the texts mentioned in REMVOED # are removed. send "999 1003\n" lyskomd_expect "MSG: garb restarted." simple_expect "=999" lyskomd_expect "MSG: garb started." lyskomd_expect "MSG: garb ready. [llength $removed] texts deleted." foreach r $removed { simple_expect ":18 14 $r $any*" } simple_expect ":1 1000 [llength $removed]" # Check that no other async messages were produced. send "998 35\n" simple_expect "=998 $any_time" } lyskomd_start # Log in as admin. client_start 0 send "A[holl "foo"]\n" simple_expect "LysKOM" "connected" if {$debug_calls} { send "1000 80 2 { 14 1000 }\n" simple_expect "=1000" } else { send "1000 80 1 { 14 }\n" simple_expect "=1000" } send "1000 0 5 [holl "gazonk"]\n" simple_expect "=1000" # Create conferences. send "1001 88 [holl "6"] 00000000 0 { }\n" simple_expect "=1001 6" send "1002 88 [holl "7"] 10100000 0 { }\n" simple_expect "=1002 7" send "1003 88 [holl "8"] 00000000 0 { }\n" simple_expect "=1003 8" send "1004 88 [holl "9"] 10100000 0 { }\n" simple_expect "=1004 9" send "1005 88 [holl "10"] 10100000 0 { }\n" simple_expect "=1005 10" # Set keep_commented. send "1006 105 6 6\n" simple_expect "=1006" send "1007 105 7 7\n" simple_expect "=1007" send "1008 105 8 8\n" simple_expect "=1008" send "1009 105 9 9\n" simple_expect "=1009" send "1010 105 10 0\n" simple_expect "=1010" # Join the conferences. send "1011 100 6 5 200 1 00000000\n" simple_expect "=1011" send "1012 100 7 5 200 2 00000000\n" simple_expect "=1012" send "1013 100 8 5 200 3 00000000\n" simple_expect "=1013" send "1014 100 9 5 200 4 00000000\n" simple_expect "=1014" send "1015 100 10 5 200 5 00000000\n" simple_expect "=1015" # Create the texts. send "1016 86 [holl "text 1"] 2 { 0 6 0 8 } 0 { }\n" simple_expect "=1016 1" send "1017 86 [holl "text 2"] 3 { 0 6 0 9 2 1 } 0 { }\n" simple_expect "=1017 2" send "1018 86 [holl "text 3"] 2 { 0 9 0 6 } 0 { }\n" simple_expect "=1018 3" send "1019 86 [holl "text 4"] 1 { 0 10 } 0 { }\n" simple_expect "=1019 4" send "1020 86 [holl "text 5"] 2 { 0 10 4 4 } 0 { }\n" simple_expect "=1020 5" send "1021 86 [holl "text 6"] 1 { 0 10 } 0 { }\n" simple_expect "=1021 6" send "1022 86 [holl "text 7"] 1 { 0 10 } 0 { }\n" simple_expect "=1022 7" send "1023 86 [holl "text 8"] 2 { 0 7 2 7 } 0 { }\n" simple_expect "=1023 8" send "1024 86 [holl "text 9"] 1 { 0 7 } 0 { }\n" simple_expect "=1024 9" send "1025 86 [holl "text 10"] 2 { 0 10 2 9 } 0 { }\n" simple_expect "=1025 10" send "1026 86 [holl "text 11"] 1 { 0 10 } 0 { }\n" simple_expect "=1026 11" send "1027 86 [holl "text 12"] 1 { 0 7 } 0 { }\n" simple_expect "=1027 12" send "1028 86 [holl "text 13"] 1 { 0 7 } 0 { }\n" simple_expect "=1028 13" send "1029 86 [holl "text 14"] 1 { 0 10 } 0 { }\n" simple_expect "=1029 14" send "1030 86 [holl "text 15"] 1 { 0 10 } 0 { }\n" simple_expect "=1030 15" send "1031 86 [holl "text 16"] 2 { 0 10 4 15 } 0 { }\n" simple_expect "=1031 16" # Add links. send "1032 32 3 1\n" simple_expect "=1032" send "1033 32 6 4\n" simple_expect "=1033" send "1034 32 12 11\n" simple_expect "=1034" send "1035 37 14 13\n" simple_expect "=1035" if {$debug_calls} { set leafs {2 3 5 6 8 10 12 14 16} run_garb {} # Backdate the root texts (texts 1, 4, 7, 9, 11, 13, 15), so that # they would be removed by the garb, if not for keep-commented. send "1036 1002 1 [expr {78 * 24 * 3600}]\n" simple_expect "=1036" send "1037 1002 4 [expr {78 * 24 * 3600}]\n" simple_expect "=1037" send "1038 1002 7 [expr {78 * 24 * 3600}]\n" simple_expect "=1038" send "1039 1002 9 [expr {78 * 24 * 3600}]\n" simple_expect "=1039" send "1040 1002 11 [expr {78 * 24 * 3600}]\n" simple_expect "=1040" send "1041 1002 13 [expr {78 * 24 * 3600}]\n" simple_expect "=1041" send "1042 1002 15 [expr {78 * 24 * 3600}]\n" simple_expect "=1042" run_garb {} # Backdate the leaf texts (the other texts) 1 day + 1 second. # This isn't enough to make the garb remove them, but text 15 will # no longer be protected by its footnote. foreach t $leafs { send "1043 1002 $t [expr {1 * 24 * 3600 + 1}]\n" simple_expect "=1043" } run_garb {15} # Backdate the leaf texts (the other texts) four more days, for a # total of at least 5 days + 1 second. # This isn't enough to make the garb remove them. foreach t $leafs { send "1044 1002 $t [expr {4 * 24 * 3600}]\n" simple_expect "=1044" } run_garb {} # Backdate the leaf texts (the other texts) one more day, for a # total of at least 6 days + 1 second. # This isn't enough to make the garb remove any text. foreach t $leafs { send "1045 1002 $t [expr {1 * 24 * 3600}]\n" simple_expect "=1045" } run_garb {} # Backdate the leaf texts (the other texts) one more day, for a # total of at least 7 days + 1 second. # This will cause 7 and 9 to be deleted. foreach t $leafs { send "1046 1002 $t [expr {1 * 24 * 3600}]\n" simple_expect "=1046" } run_garb {7 9} # Backdate the leaf texts (the other texts) one more day, for a # total of at least 8 days + 1 second. # Nothing new will be deleted. foreach t $leafs { send "1047 1002 $t [expr {1 * 24 * 3600}]\n" simple_expect "=1047" } run_garb {} # Backdate the leaf texts (the other texts) one more day, for a # total of at least 9 days + 1 second. # Nothing new will be deleted. foreach t $leafs { send "1048 1002 $t [expr {1 * 24 * 3600}]\n" simple_expect "=1048" } run_garb {} # Backdate the sent_at links just enough that the texts are still # protected. send "1049 1007 1 3 [expr {8 * 24 * 3600 + 1}]\n" simple_expect "=1049" send "1050 1007 4 6 [expr {0 * 24 * 3600 + 1}]\n" simple_expect "=1050" send "1051 1007 11 12 [expr {6 * 24 * 3600 + 1}]\n" simple_expect "=1051" send "1052 1007 13 14 [expr {6 * 24 * 3600 + 1}]\n" simple_expect "=1052" run_garb {} # Backdate the sent_at links one more day. They no longer offer any # protection, so all remaining roots are removed. send "1053 1007 1 3 [expr {1 * 24 * 3600}]\n" simple_expect "=1053" send "1054 1007 4 6 [expr {1 * 24 * 3600}]\n" simple_expect "=1054" send "1055 1007 11 12 [expr {1 * 24 * 3600}]\n" simple_expect "=1055" send "1056 1007 13 14 [expr {1 * 24 * 3600}]\n" simple_expect "=1056" run_garb {1 4 11 13} # Nothing should happen if we run the garb again. run_garb {} } else { unsupported "testing the keep-commented -- use configure --with-debug-calls to enable" } # Shut down. send "1057 42 255\n" simple_expect "=1057" send "1058 44 0\n" simple_expect "=1058" client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/43.exp0000664000015100472110000001165007717447241016747 # Test suite for lyskomd. # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test async-text-aux-changed. # # Persons: # 5: admin # 6: author # 7: bystander lyskomd_start # Log in as admin. client_start 0 send "A[holl "foo"]\n" simple_expect "LysKOM" send "1000 80 1 { 22 }\n" simple_expect "=1000" send "1001 0 5 [holl "gazonk"]\n" simple_expect "=1001" # Log in as "author" client_start 1 send "A[holl "foo"]\n" simple_expect "LysKOM" send "1002 80 1 { 22 }\n" simple_expect "=1002" send "1003 89 [holl "author"] [holl "author"] 00000000 0 { }\n" simple_expect "=1003 6" send "1004 0 6 [holl "author"]\n" simple_expect "=1004" # Log in as "bystander" client_start 2 send "A[holl "foo"]\n" simple_expect "LysKOM" send "1005 80 1 { 22 }\n" simple_expect "=1005" send "1006 89 [holl "bystander"] [holl "bystander"] 00000000 0 { }\n" simple_expect "=1006 7" send "1007 0 7 [holl "bystander"]\n" simple_expect "=1007" # admin and author joins conference 1. talk_to client 0 send "1008 100 1 5 200 1 00000000\n" simple_expect "=1008" talk_to client 1 send "1009 100 1 6 200 1 00000000\n" simple_expect "=1009" # Create a text. send "1010 86 [holl "text 1"] 1 { 0 1 } 0 { }\n" simple_expect "=1010 1" # Add an aux-item to the text. We use fast-reply (type 2). send "1011 92 1 0 { } 1 { 2 00000000 1 [holl "I agree."] }\n" simple_expect ":5 22 1 0 \\* 1 { 1 2 6 $any_time 00000000 1 [holl "I agree."] }" simple_expect "=1011" client_expect 0 ":5 22 1 0 \\* 1 { 1 2 6 $any_time 00000000 1 [holl "I agree."] }" # Delete the aux-item. send "1012 92 1 1 { 1 } 0 { }\n" simple_expect ":5 22 1 1 { 1 2 6 $any_time 10000000 1 [holl "I agree."] } 0 \\*" simple_expect "=1012" client_expect 0 ":5 22 1 1 { 1 2 6 $any_time 10000000 1 [holl "I agree."] } 0 \\*" # Add two fast-replies. send "1013 92 1 0 { } 2 { 2 00000000 1 [holl "I don't disagree."] 2 00000000 1 [holl "I see your point."] }\n" simple_expect ":5 22 1 0 \\* 2 { 2 2 6 $any_time 00000000 1 [holl "I don't disagree."] 3 2 6 $any_time 00000000 1 [holl "I see your point."] }" simple_expect "=1013" client_expect 0 ":5 22 1 0 \\* 2 { 2 2 6 $any_time 00000000 1 [holl "I don't disagree."] 3 2 6 $any_time 00000000 1 [holl "I see your point."] }" # Delete one of the aux-items. send "1014 92 1 1 { 2 } 0 { }\n" simple_expect ":5 22 1 1 { 2 2 6 $any_time 10000000 1 [holl "I don't disagree."] } 0 \\*" simple_expect "=1014" client_expect 0 ":5 22 1 1 { 2 2 6 $any_time 10000000 1 [holl "I don't disagree."] } 0 \\*" # Add a fast-reply, a secret item, and an anonymous item, # and remove the old item. send "1015 92 1 1 { 3 } 3 { 2 00000000 1 [holl "You've gotta be kidding."] 10201 00100000 1 [holl "private."] 10202 00010000 1 [holl "anon."] }\n" simple_expect ":5 22 1 1 { 3 2 6 $any_time 10000000 1 [holl "I see your point."] } 3 { 4 2 6 $any_time 00000000 1 [holl "You've gotta be kidding."] 5 10201 6 $any_time 00100000 1 [holl "private."] 6 10202 6 $any_time 00010000 1 [holl "anon."] }" simple_expect "=1015" # As can be seen below, it isn't very clever to create a hide-creator # and a normal aux-item at the same time. They will be sent in the # same message. That they are added at the same time would anyhow be # a dead giveaway. client_expect 0 ":5 22 1 1 { 3 2 6 $any_time 10000000 1 [holl "I see your point."] } 2 { 4 2 6 $any_time 00000000 1 [holl "You've gotta be kidding."] 6 10202 0 $any_time 00010000 1 [holl "anon."] }" # Delete the private item. send "1016 92 1 1 { 5 } 0 { }\n" simple_expect ":5 22 1 1 { 5 10201 6 $any_time 10100000 1 [holl "private."] } 0 \\*" simple_expect "=1016" # Delete the anon item. send "1017 92 1 1 { 6 } 0 { }\n" simple_expect ":5 22 1 1 { 6 10202 6 $any_time 10010000 1 [holl "anon."] } 0 \\*" simple_expect "=1017" client_expect 0 ":5 22 1 1 { 6 10202 0 $any_time 10010000 1 [holl "anon."] } 0 \\*" # Through all of this, person 7 should not have received a single # async message. talk_to client 2 send "1018 35\n" simple_expect "=1018 $any_time" # Shut down. talk_to client 0 send "1019 42 255\n" simple_expect "=1019" send "1020 44 0\n" simple_expect "=1020" client_death 0 client_death 1 client_death 2 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/44.exp0000664000015100472110000002550007717661066016752 # Test suite for lyskomd. # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test conversion of recipients from one type to another. # # Persons: # 5: admin # 6: super: creator of 10 and 11 # 7: member: a member of 10 and 11 # 8: bystander: not a member # 9: provocateur: not a member # # Conferences: # 10: public # 11: secret # # Texts: # 1: # 2: # 3: # 4: lyskomd_start # Log in as admin, and enable. client_start 5 send "A[holl "five"]\n" simple_expect "LysKOM" "connected" # 114:first-unused-conf-no send "1000 114\n" simple_expect "=1000 6" # 115:first-unused-text-no send "1001 115\n" simple_expect "=1001 1" send "1002 80 1 { 21 }\n" simple_expect "=1002" send "1003 0 5 [holl "gazonk"]\n" simple_expect "=1003" send "1004 42 255\n" simple_expect "=1004" # Create person 6 and log in. client_start 6 send "A[holl "six"]\n" simple_expect "LysKOM" "connected" send "1005 80 1 { 21 }\n" simple_expect "=1005" send "1006 89 [holl "super"] [holl "super"] 00000000 0 { }\n" simple_expect "=1006 6" send "1007 0 6 [holl "super"]\n" simple_expect "=1007" # Create person 7 and log in. client_start 7 send "A[holl "seven"]\n" simple_expect "LysKOM" "connected" send "1008 80 1 { 21 }\n" simple_expect "=1008" send "1009 89 [holl "member"] [holl "member"] 00000000 0 { }\n" simple_expect "=1009 7" send "1010 0 7 [holl "member"]\n" simple_expect "=1010" # Create person 8 and log in. client_start 8 send "A[holl "eight"]\n" simple_expect "LysKOM" "connected" send "1011 80 1 { 21 }\n" simple_expect "=1011" send "1012 89 [holl "bystander"] [holl "bystander"] 00000000 0 { }\n" simple_expect "=1012 8" send "1013 0 8 [holl "bystander"]\n" simple_expect "=1013" # Create person 9 and log in. client_start 9 send "A[holl "nine"]\n" simple_expect "LysKOM" "connected" send "1014 80 1 { 21 }\n" simple_expect "=1014" send "1015 89 [holl "provocateur"] [holl "provocateur"] 00000000 0 { }\n" simple_expect "=1015 9" send "1016 0 9 [holl "provocateur"]\n" simple_expect "=1016" # Create conferences 10 and 11, and let person 6 and 7 join them. talk_to client 6 send "1017 88 [holl "public"] 00000000 0 { }\n" simple_expect "=1017 10" send "1018 88 [holl "secret"] 10100000 0 { }\n" simple_expect "=1018 11" send "1019 100 10 6 200 1 00000000\n" simple_expect "=1019" send "1020 100 10 7 200 1 00000000\n" lyskomd_expect "Person 7 added to conference 10 by 6\." simple_expect "=1020" send "1021 100 11 6 200 1 00000000\n" simple_expect "=1021" send "1022 100 11 7 200 1 00000000\n" lyskomd_expect "Person 7 added to conference 11 by 6\." simple_expect "=1022" # Person 7 accepts the invitations. talk_to client 7 send "1023 100 10 7 200 1 00000000\n" simple_expect "=1023" send "1024 100 11 7 200 1 00000000\n" simple_expect "=1024" # Person 6 creates texts 1 and 2. talk_to client 6 send "1025 86 [holl "text 1"] 1 { 0 1 } 0 { }\n" simple_expect "=1025 1" send "1026 86 [holl "text 2"] 1 { 0 1 } 0 { }\n" simple_expect "=1026 2" # Person 8 creates text 3 and 4. talk_to client 8 send "1027 86 [holl "text 3"] 1 { 0 1 } 0 { }\n" simple_expect "=1027 3" send "1028 86 [holl "text 4"] 1 { 0 1 } 0 { }\n" simple_expect "=1028 4" # Person 9 is not able to transform either of the recipients. talk_to client 9 foreach text {1 2 3 4} { send "1 30 $text 1 0\n" simple_expect "%1 27 1" send "2 90 $text\n" simple_expect "=2 $any_time $any_num 0 6 0 2 { 0 1 6 $text } 0 \\*" foreach rcpt {1 15} { send "3 30 $text 1 $rcpt\n" simple_expect "%3 12 1" send "4 90 $text\n" simple_expect "=4 $any_time $any_num 0 6 0 2 { 0 1 6 $text } 0 \\*" } } # Person 8 is not able to transform the texts created by person 6. talk_to client 9 foreach text {1 2} { send "5 30 $text 1 0\n" simple_expect "%5 27 1" send "6 90 $text\n" simple_expect "=6 $any_time $any_num 0 6 0 2 { 0 1 6 $text } 0 \\*" foreach rcpt {1 15} { send "7 30 $text 1 $rcpt\n" simple_expect "%7 12 1" send "8 90 $text\n" simple_expect "=8 $any_time $any_num 0 6 0 2 { 0 1 6 $text } 0 \\*" } } # Person 7 is not able to transform any text. talk_to client 9 foreach text {1 2 3 4} { send "9 30 $text 1 0\n" simple_expect "%9 27 1" send "10 90 $text\n" simple_expect "=10 $any_time $any_num 0 6 0 2 { 0 1 6 $text } 0 \\*" foreach rcpt {1 15} { send "11 30 $text 1 $rcpt\n" simple_expect "%11 12 1" send "12 90 $text\n" simple_expect "=12 $any_time $any_num 0 6 0 2 { 0 1 6 $text } 0 \\*" } } # Person 8 can transform the texts he wrote. talk_to client 8 foreach text {3 4} { send "13 30 $text 1 0\n" simple_expect "%13 27 1" send "14 90 $text\n" simple_expect "=14 $any_time $any_num 0 6 0 2 { 0 1 6 $text } 0 \\*" foreach rcpt {1 15 0} { send "15 30 $text 1 $rcpt\n" simple_expect "=15" send "16 90 $text\n" simple_expect "=16 $any_time 8 0 6 0 2 { $rcpt 1 6 $text } 0 \\*" } } # Person 5 can transform all texts. talk_to client 5 foreach text {1 2 3 4} { send "17 30 $text 1 0\n" simple_expect "%17 27 1" send "18 90 $text\n" simple_expect "=18 $any_time $any_num 0 6 0 2 { 0 1 6 $text } 0 \\*" foreach rcpt {1 15 0} { send "19 30 $text 1 $rcpt\n" simple_expect "=19" send "20 90 $text\n" simple_expect "=20 $any_time $any_num 0 6 0 2 { $rcpt 1 6 $text } 0 \\*" } } # Person 6 can transform the texts he wrote, but not the others. talk_to client 6 foreach text {1 2} { send "21 30 $text 1 0\n" simple_expect "%21 27 1" send "22 90 $text\n" simple_expect "=22 $any_time $any_num 0 6 0 2 { 0 1 6 $text } 0 \\*" foreach rcpt {1 15 0} { send "23 30 $text 1 $rcpt\n" simple_expect "=23" send "24 90 $text\n" simple_expect "=24 $any_time $any_num 0 6 0 2 { $rcpt 1 6 $text } 0 \\*" } } foreach text {3 4} { send "25 30 $text 1 0\n" simple_expect "%25 27 1" send "26 90 $text\n" simple_expect "=26 $any_time $any_num 0 6 0 2 { 0 1 6 $text } 0 \\*" foreach rcpt {1 15} { send "27 30 $text 1 $rcpt\n" simple_expect "%27 12 1" send "28 90 $text\n" simple_expect "=28 $any_time $any_num 0 6 0 2 { 0 1 6 $text } 0 \\*" } } # The fun is about to start. Just a quick recollection of the state first. # # Text 1: 0 1 6 1 author=6 # Text 2: 0 1 6 2 author=6 # Text 3: 0 1 6 3 author=8 # Text 4: 0 1 6 4 author=8 send "1029 90 1\n" simple_expect "=1029 $any_time 6 0 6 0 2 { 0 1 6 1 } 0 \\*" send "1030 90 2\n" simple_expect "=1030 $any_time 6 0 6 0 2 { 0 1 6 2 } 0 \\*" send "1031 90 3\n" simple_expect "=1031 $any_time 8 0 6 0 2 { 0 1 6 3 } 0 \\*" send "1032 90 4\n" simple_expect "=1032 $any_time 8 0 6 0 2 { 0 1 6 4 } 0 \\*" talk_to client 6 send "1033 30 1 10 0\n" simple_expect "=1033" send "1034 90 1\n" simple_expect "=1034 $any_time 6 0 6 0 5 { 0 1 6 1 0 10 6 1 9 $any_time } 0 \\*" send "1035 30 3 10 1\n" simple_expect "=1035" send "1036 90 3\n" simple_expect "=1036 $any_time 8 0 6 0 6 { 0 1 6 3 1 10 6 2 8 6 9 $any_time } 0 \\*" talk_to client 8 send "1037 30 4 11 15\n" simple_expect "%1037 9 11" send "1038 30 4 10 15\n" simple_expect "=1038" send "1039 31 4 1\n" simple_expect "=1039" send "1040 90 4\n" simple_expect "=1040 $any_time 8 0 6 0 3 { 15 10 6 3 9 $any_time } 0 \\*" talk_to client 7 send "1041 32 4 2\n" simple_expect "=1041" send "1042 90 4\n" simple_expect "=1042 $any_time 8 0 6 0 6 { 15 10 6 3 9 $any_time 2 2 8 7 9 $any_time } 0 \\*" send "1043 90 2\n" simple_expect "=1043 $any_time 6 0 6 0 3 { 0 1 6 2 3 4 } 0 \\*" # Current state: # Text 1: 0 1 6 1 0 10 6 1 9 * author=6 (can: 5 6) # Text 2: 0 1 6 2 3 4 author=6 # Text 3: 0 1 6 3 1 10 6 2 8 6 9 * author=8 (can: 5 6 8) # Text 4: 15 10 6 3 9 * 2 2 8 7 9 * author=8 (can: 5 6 8) # Check that person 7 cannot modify the recipient of text 4, even # though there is a "sent-by 7" later on in that text status. send "1044 30 4 10 1\n" simple_expect "%1044 12 10" # Text 1: recipient 10. Cannot change: foreach c {7 8 9} { talk_to client $c send "29 30 1 10 1\n" simple_expect "%29 12 10" } # Text 3: recipient 10. Cannot change: foreach c {7 9} { talk_to client $c send "30 30 3 10 0\n" simple_expect "%30 12 10" } # Text 4: recipient 10. Cannot change: foreach c {7 9} { talk_to client $c send "31 30 4 10 1\n" simple_expect "%31 12 10" } # Text 1: recipient 10. Can change: foreach c {5 6} { talk_to client $c foreach rcpt {1 15 0} { send "32 30 1 10 $rcpt\n" simple_expect "=32" } } # Text 3: recipient 10. Can change: foreach c {5 6 8} { talk_to client $c foreach rcpt {15 0 1} { send "33 30 3 10 $rcpt\n" simple_expect "=33" } } # Text 4: recipient 10. Can change: foreach c {5 6 8} { talk_to client $c foreach rcpt {1 0 15} { send "34 30 4 10 $rcpt\n" simple_expect "=34" } } # Make person 7 supervisor of person 6. This gives person 7 the # ability to modify text 1 (because 7 is now supervisor of author) # and text 3 (7 is supervisor of sender), but not 4 (even though 7 is # supervisor of the supervisor of the recipient). talk_to client 6 send "1045 18 6 7\n" simple_expect "=1045" talk_to client 7 foreach rcpt {1 15 0} { send "35 30 1 10 $rcpt\n" good_bad_expect "=35" "%(12|27) 10" } foreach rcpt {15 0 1} { send "36 30 3 10 $rcpt\n" good_bad_expect "=36" "%(12|27) 10" } send "1046 30 4 10 0\n" simple_expect "%1046 12 10" # If you can alter it, you should be able to remove it. send "1047 31 1 10\n" simple_expect "=1047" send "1048 31 3 10\n" good_bad_expect "=1048" "%12 3" send "1049 31 4 10\n" simple_expect "%1049 12 4" # Make text 2 a footnote of text 1. talk_to client 6 send "1050 37 2 1\n" simple_expect "=1050" # Attempt to make text 2 a comment of text 1. This should not be # possible, since it already is a footnote. send "1051 32 2 1\n" good_bad_expect "%1051 29 2" "=" # Make text 4 a comment of text 3. talk_to client 8 send "1052 32 4 3\n" simple_expect "=1052" # And now try to make it a footnote as well. send "1053 37 4 3\n" good_bad_expect "%1053 28 4" "=" # Shut down. talk_to client 5 send "1054 44 0\n" simple_expect "=1054" client_death 5 client_death 6 client_death 7 client_death 8 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/45.exp0000664000015100472110000002233307720646607016752 # Test suite for lyskomd. # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test inheritance of aux items. # Test who can add a canonical-name item on the server. # # Persons: # 5: admin # 6: Kalle # 7: Pelle # 8: Stina # 9: Anders # # Conferences: # 10: Fritt Forum (public) (admin: Kalle)(members: Kalle, Anders) # 11: Overstrike (private) (admin: Pelle)(members: Pelle, Stina, Anders) # 12: Hemliga Klubben (secret) (admin: Stina)(members: Kalle, Stina) lyskomd_start # Log in as admin, and enable. client_start 5 send "A[holl "five"]\n" simple_expect "LysKOM" "connected" send "1000 80 2 { 15 22 }\n" simple_expect "=1000" send "1001 0 5 [holl "gazonk"]\n" simple_expect "=1001" send "1002 42 255\n" simple_expect "=1002" # Create person 6 and log in. client_start 6 send "A[holl "Kalle"]\n" simple_expect "LysKOM" "connected" send "1003 80 2 { 15 22 }\n" simple_expect "=1003" send "1004 89 [holl "Kalle"] [holl "super"] 00000000 0 { }\n" simple_expect "=1004 6" send "1005 0 6 [holl "super"]\n" simple_expect "=1005" # Create person 7 and log in. client_start 7 send "A[holl "Pelle"]\n" simple_expect "LysKOM" "connected" send "1006 80 2 { 15 22 }\n" simple_expect "=1006" send "1007 89 [holl "Pelle"] [holl "member"] 00000000 0 { }\n" simple_expect "=1007 7" send "1008 0 7 [holl "member"]\n" simple_expect "=1008" # Create person 8 and log in. client_start 8 send "A[holl "Stina"]\n" simple_expect "LysKOM" "connected" send "1009 80 2 { 15 22 }\n" simple_expect "=1009" send "1010 89 [holl "Stina"] [holl "bystander"] 00000000 0 { }\n" simple_expect "=1010 8" send "1011 0 8 [holl "bystander"]\n" simple_expect "=1011" # Create person 9 and log in. client_start 9 send "A[holl "Anders"]\n" simple_expect "LysKOM" "connected" send "1012 80 2 { 15 22 }\n" simple_expect "=1012" send "1013 89 [holl "Anders"] [holl "provocateur"] 00000000 0 { }\n" simple_expect "=1013 9" send "1014 0 9 [holl "provocateur"]\n" simple_expect "=1014" # Create conferences 10, 11 and 12. talk_to client 6 send "1015 88 [holl "Fritt Forum"] 00000000 0 { }\n" simple_expect "=1015 10" talk_to client 7 send "1016 88 [holl "Overstrike"] 10000000 0 { }\n" simple_expect "=1016 11" talk_to client 8 send "1017 88 [holl "Hemliga klubben"] 10100000 0 { }\n" simple_expect "=1017 12" # Everybody joins conference 1 talk_to client 6 send "1018 100 1 6 200 1 00000000\n" simple_expect "=1018" talk_to client 7 send "1019 100 1 7 200 1 00000000\n" simple_expect "=1019" talk_to client 8 send "1020 100 1 8 200 1 00000000\n" simple_expect "=1020" talk_to client 9 send "1021 100 1 9 200 1 00000000\n" simple_expect "=1021" # Kalle (6) and Anders (9) joins Fritt Forum (10) talk_to client 6 send "1022 100 10 6 200 1 00000000\n" simple_expect "=1022" talk_to client 9 send "1023 100 10 9 200 1 00000000\n" simple_expect "=1023" # Pelle (7), Stina (8) and Anders (9) joins Overstrike (11) talk_to client 7 send "1024 100 11 7 200 1 00000000\n" simple_expect "=1024" send "1025 100 11 8 200 1 00000000\n" lyskomd_expect "Person 8 added to conference 11 by 7\\." simple_expect "=1025" send "1026 100 11 9 200 1 00000000\n" lyskomd_expect "Person 9 added to conference 11 by 7\\." simple_expect "=1026" talk_to client 8 send "1027 100 11 8 200 1 00000000\n" simple_expect "=1027" talk_to client 9 send "1028 100 11 9 200 1 00000000\n" simple_expect "=1028" # Kalle (6) and Stina (8) joins Hemliga klubben (12) talk_to client 8 send "1029 100 12 8 200 1 00000000\n" simple_expect "=1029" send "1030 100 12 6 200 1 00000000\n" lyskomd_expect "Person 6 added to conference 12 by 8\\." simple_expect "=1030" talk_to client 6 send "1031 100 12 6 200 1 00000000\n" simple_expect "=1031" # Pelle (7) creates text 1 in Fritt Forum (10). # It contains a public inherited aux-item with tag 10203 and infinite # inheritance. talk_to client 7 send "1032 86 [holl "text 1"] 1 { 0 10 } 1 { 10203 01000000 0 [holl "forever more"] }\n" client_extracting_expect 6 ":18 15 1 ($any_time) 7 0 6 0 2 { 0 10 6 1 } 1 { 1 10203 7 $any_time 01000000 0 [holl "forever more"] }" tt1 1 client_expect 9 ":18 15 1 $tt1 7 0 6 0 2 { 0 10 6 1 } 1 { 1 10203 7 $tt1 01000000 0 [holl "forever more"] }" simple_expect "=1032 1" # Wait for a new second. sleep 1 # Kalle (6) writes a comment (2) to text 1. Pelle is added as a cc-recpt. talk_to client 6 send "1033 86 [holl "text 2"] 3 { 0 10 2 1 1 7 } 0 { }\n" extracting_expect ":18 15 2 ($any_time) 6 0 6 0 5 { 0 10 6 2 2 1 1 7 6 1 } 1 { 1 10203 7 $any_time 01000000 0 [holl "forever more"] }" tt2 1 client_expect 9 ":18 15 2 $tt2 6 0 6 0 5 { 0 10 6 2 2 1 1 7 6 1 } 1 { 1 10203 7 $tt2 01000000 0 [holl "forever more"] }" client_expect 7 ":18 15 2 $tt2 6 0 6 0 5 { 0 10 6 2 2 1 1 7 6 1 } 1 { 1 10203 7 $tt2 01000000 0 [holl "forever more"] }" simple_expect "=1033 2" set test "aux-item created-at not inherited" if {$tt1 == $tt2} { fail "$test (tt1 == tt2 == $tt1)" } else { pass "$test" } unset test # Anders (9) adds a secret inheriting aux-item to text 2. talk_to client 9 send "1034 92 2 0 { } 1 { 10204 0110000 4 [holl "the invisible aux"] }\n" simple_expect ":5 22 2 0 \\* 1 { 2 10204 9 $any_time 01100000 4 [holl "the invisible aux"] }" simple_expect "=1034" # Kalle writes a comment to text 2 in "Hemliga klubben". talk_to client 6 send "1035 86 [holl "text 3"] 2 { 2 2 0 12 } 0 { }\n" simple_expect ":18 15 3 $any_time 6 0 6 0 3 { 2 2 0 12 6 1 } 1 { 1 10203 7 $any_time 01000000 0 [holl "forever more"] }" client_expect 8 ":18 15 3 $any_time 6 0 6 0 3 { 2 2 0 12 6 1 } 1 { 1 10203 7 $any_time 01000000 0 [holl "forever more"] }" simple_expect "=1035 3" # There is a secret aux-item on text 3, but Anders cannot read the text. talk_to client 9 send "1036 90 3\n" simple_expect "%1036 14 3" # The admin can read it, though. talk_to client 5 send "1037 90 3\n" simple_expect "=1037 $any_time 6 0 6 0 3 { 2 2 0 12 6 1 } 2 { 1 10203 7 $any_time 01000000 0 [holl "forever more"] 2 10204 9 $any_time 01100000 3 [holl "the invisible aux"] }" # Stina comments Kalles text. talk_to client 8 send "1038 86 [holl "text 4"] 2 { 0 12 2 3 } 0 { }\n" simple_expect ":18 15 4 $any_time 8 0 6 0 3 { 0 12 6 2 2 3 } 1 { 1 10203 7 $any_time 01000000 0 [holl "forever more"] }" client_expect 6 ":18 15 4 $any_time 8 0 6 0 3 { 0 12 6 2 2 3 } 1 { 1 10203 7 $any_time 01000000 0 [holl "forever more"] }" simple_expect "=1038 4" # Now Kalle makes a big mistake: he comments the text in a public conference. # The secret aux-item will once again be visible. talk_to client 6 send "1039 86 [holl "text 5"] 2 { 0 1 2 4 } 0 { }\n" simple_expect ":18 15 5 $any_time 6 0 6 0 3 { 0 1 6 1 2 4 } 1 { 1 10203 7 $any_time 01000000 0 [holl "forever more"] }" client_expect 7 ":18 15 5 $any_time 6 0 6 0 3 { 0 1 6 1 2 4 } 1 { 1 10203 7 $any_time 01000000 0 [holl "forever more"] }" client_expect 8 ":18 15 5 $any_time 6 0 6 0 3 { 0 1 6 1 2 4 } 1 { 1 10203 7 $any_time 01000000 0 [holl "forever more"] }" client_expect 9 ":18 15 5 $any_time 6 0 6 0 3 { 0 1 6 1 2 4 } 2 { 1 10203 7 $any_time 01000000 0 [holl "forever more"] 2 10204 9 $any_time 01100000 1 [holl "the invisible aux"] }" simple_expect "=1039 5" # Pelle writes a comment. The secret aux is no longer inherited. talk_to client 7 send "1040 86 [holl "text 6"] 2 { 0 1 2 5 } 0 { }\n" simple_expect ":18 15 6 $any_time 7 0 6 0 3 { 0 1 6 2 2 5 } 1 { 1 10203 7 $any_time 01000000 0 [holl "forever more"] }" client_expect 6 ":18 15 6 $any_time 7 0 6 0 3 { 0 1 6 2 2 5 } 1 { 1 10203 7 $any_time 01000000 0 [holl "forever more"] }" client_expect 8 ":18 15 6 $any_time 7 0 6 0 3 { 0 1 6 2 2 5 } 1 { 1 10203 7 $any_time 01000000 0 [holl "forever more"] }" client_expect 9 ":18 15 6 $any_time 7 0 6 0 3 { 0 1 6 2 2 5 } 1 { 1 10203 7 $any_time 01000000 0 [holl "forever more"] }" simple_expect "=1040 6" # Kalle attempts to add a canonical-name aux item on the server. talk_to client 6 send "1041 95 0 { } 1 { 31 00000000 1 [holl "kom.lysator.liu.se:4444"] }\n" simple_expect "%1041 12 0" # admin attempts to add a canonical-name aux item on the server, # without enabling. talk_to client 5 send "1042 42 0\n" simple_expect "=1042" send "1043 95 0 { } 1 { 31 00000000 1 [holl "kom.lysator.liu.se:4444"] }\n" simple_expect "%1043 12 0" # admin succeeds once he has enabled. send "1044 42 255\n" simple_expect "=1044" send "1045 95 0 { } 1 { 31 00000000 1 [holl "kom.lysator.liu.se:4444"] }\n" simple_expect "=1045" # Shut down. talk_to client 5 send "1046 44 0\n" simple_expect "=1046" client_death 5 client_death 6 client_death 7 client_death 8 client_death 9 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/46.exp0000664000015100472110000000632007721707035016743 # Test suite for lyskomd. # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test parsing a broken aux-item file as a result of SIGWINCH. set auxfile "lyskomd.0/aux-items-46.conf" system "rm -f $auxfile" system "cp $aux_item_default_conf_file $auxfile" lyskomd_start "$auxfile" # Log in as admin, and enable. client_start 5 send "A[holl "five"]\n" simple_expect "LysKOM" "connected" send "1000 80 0 { }\n" simple_expect "=1000" send "1001 0 5 [holl "gazonk"]\n" simple_expect "=1001" send "1002 42 255\n" simple_expect "=1002" send "1003 96\n" simple_expect "=1003 40 { 10104 10103 10102 10101 10100 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 }" # Create a broken aux-item file. A mistake can happen so easily... system "rm -f $auxfile" system "cp $srcdir/lyskomd.0/aux-items-bad.conf $auxfile" system "kill -WINCH $lyskomd_pid" talk_to lyskomd # FIXME (bug 1094): the error message from yyerror() isn't sent via # kom_log, so there is no leading timestamp on this line. So we # cannot use extracting_expect. set test "syntax error diagnosed" expect { -re "^/$any*/src/server/testsuite/lyskomd\\.0/aux-items-46\\.conf: ($any_num): parse error, unexpected ID$nl" { set lineno "$expect_out(1,string)" pass "$test" } timeout {fail "$test (timeout)"} eof {fail "$test (eof)"; wait} full_buffer {fail "$test (full_buffer)"} } unset test setup_xfail "*-*-*" "Bug 1093" set test "line numbers are reset" if {$lineno < 20} { pass "$test" } else { fail "$test (got insangely large line number $lineno)" } unset test simple_expect "Errors reading aux-item definition file" set dying 0 set test "Doing something predictable when reading bad aux-item file" expect { -re "^${line_leader}Signal WINCH received. aux definitions reloaded.$nl" { pass "$test (server surviving)" } -re "^${line_leader}Previous message is fatal\\. Will dump core now\\.$nl" { pass "$test (server aborting)" set dying 1 } } unset test set reason 5 setup_xfail "*-*-*" "Bug 1095" set test "server survives broken aux-item file" if {$dying} { set reason "restart_kom" fail "$test (server dies)" } else { pass "$test" } unset test if {$reason == 5} { send "1002 96\n" simple_expect "=1002 0 { }" # Shut down. send "1041 44 0\n" simple_expect "=1041" } lyskomd_death "" "$reason" client_death 5 lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/47.exp0000664000015100472110000000456707722446227016763 # Test suite for lyskomd. # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test client disconnect while logged in and receiving async-logout. lyskomd_start # Log in as admin on client 2. client_start 2 send "A[holl "two"]\n" simple_expect "LysKOM" "connected" send "1000 80 1 { 13 }\n" simple_expect "=1000" send "1001 0 5 [holl "gazonk"]\n" simple_expect "=1001" # Put something in the input buffer of the client, but don't read it. # Without this, the bug isn't triggered. With this, it is. At least # when running Linux 2.4.18pre1 with glibc-2.3.1. I suspect that the # exact behaviour is highly depent on your TCP/IP stack, but I don't # have a deep enough understanding of that to be really sure. send "#suspend socket\n" simple_expect "suspended" "" meta send "1002 35\n" # Disconnect client 2. kill_client 2 # Log in as admin on client 0. client_start 0 send "A[holl "zero"]\n" simple_expect "LysKOM" "connected" send "1003 80 1 { 13 }\n" simple_expect "=1003" send "1004 0 5 [holl "gazonk"]\n" simple_expect "=1004" # Log in as admin on client 1. client_start 1 send "A[holl "one"]\n" simple_expect "LysKOM" "connected" send "1005 80 1 { 13 }\n" simple_expect "=1005" send "1006 0 5 [holl "gazonk"]\n" simple_expect "=1006" talk_to client 0 send "#suspend socket\n" simple_expect "suspended" "" meta send "1007 35\n" # Disconnect client 0. kill_client 0 talk_to client 1 simple_expect ":2 13 5 2" # Shut down. send "1008 42 255\n" simple_expect "=1008" send "1009 44 0\n" simple_expect "=1009" lyskomd_death client_death 1 lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/48.exp0000664000015100472110000001422707721701653016752 # Test suite for lyskomd. # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test the bad-bool error code. lyskomd_start client_start 0 send "A[holl "foo%bar"]\n" simple_expect "LysKOM" "connected" send "1000 80 1 { 9 }\n" simple_expect "=1000" # Try stuff without logging in. # get-membership-old send "1001 46 5 0 1 2\n" simple_expect "%1001 61 0" # login send "1002 62 5 [holl "gazonk"] 2\n" simple_expect "%1002 61 0" # re-z-lookup send "1003 74 [holl "."] 1 2\n" simple_expect "%1003 61 0" send "1004 74 [holl "."] 2 1\n" simple_expect "%1004 61 0" send "1005 74 [holl "."] 2 2\n" simple_expect "%1005 61 0" # lookup-z-name send "1006 76 [holl "n"] 2 1\n" simple_expect "%1006 61 0" send "1007 76 [holl "n"] 1 2\n" simple_expect "%1007 61 0" send "1008 76 [holl "n"] 2 2\n" simple_expect "%1008 61 0" # who-is-on-dynamic send "1009 83 2 1 0\n" simple_expect "%1009 61 0" send "1010 83 1 2 0\n" simple_expect "%1010 61 0" send "1011 83 2 2 0\n" simple_expect "%1011 61 0" # get-membership-10 send "1012 99 5 0 1 2\n" simple_expect "%1012 61 0" # query-read-texts send "1013 107 5 5 2 0\n" simple_expect "%1013 61 0" # get-membership send "1014 108 5 0 1 2 0\n" simple_expect "%1014 61 0" # set-connection-time-format send "1015 120 2\n" simple_expect "%1015 61 0" send "1016 120 3\n" simple_expect "%1016 61 0" send "1017 120 4\n" simple_expect "%1017 61 0" send "1018 120 255\n" simple_expect "%1018 61 0" send "1019 120 256\n" simple_expect "%1019 61 0" send "1020 120 257\n" simple_expect "%1020 61 0" send "1021 120 65536\n" simple_expect "%1021 61 0" send "1022 120 65537\n" simple_expect "%1022 61 0" # Log in as admin. send "1023 0 5 [holl "gazonk"]\n" simple_expect ":2 9 5 1" simple_expect "=1023" # Try the stuff again. # get-membership-old send "1024 46 5 0 1 2\n" simple_expect "%1024 61 0" # login send "1025 62 5 [holl "gazonk"] 2\n" simple_expect "%1025 61 0" # re-z-lookup send "1026 74 [holl "."] 1 2\n" simple_expect "%1026 61 0" send "1027 74 [holl "."] 2 1\n" simple_expect "%1027 61 0" send "1028 74 [holl "."] 2 2\n" simple_expect "%1028 61 0" # lookup-z-name send "1029 76 [holl "n"] 2 1\n" simple_expect "%1029 61 0" send "1030 76 [holl "n"] 1 2\n" simple_expect "%1030 61 0" send "1031 76 [holl "n"] 2 2\n" simple_expect "%1031 61 0" # who-is-on-dynamic send "1032 83 2 1 0\n" simple_expect "%1032 61 0" send "1033 83 1 2 0\n" simple_expect "%1033 61 0" send "1034 83 2 2 0\n" simple_expect "%1034 61 0" # get-membership-10 send "1035 99 5 0 1 2\n" simple_expect "%1035 61 0" # query-read-texts send "1036 107 5 5 2 0\n" simple_expect "%1036 61 0" # get-membership send "1037 108 5 0 1 2 0\n" simple_expect "%1037 61 0" # set-connection-time-format send "1038 120 2\n" simple_expect "%1038 61 0" send "1039 120 3\n" simple_expect "%1039 61 0" send "1040 120 4\n" simple_expect "%1040 61 0" send "1041 120 255\n" simple_expect "%1041 61 0" send "1042 120 256\n" simple_expect "%1042 61 0" send "1043 120 257\n" simple_expect "%1043 61 0" send "1044 120 65536\n" simple_expect "%1044 61 0" send "1045 120 65537\n" simple_expect "%1045 61 0" # And now run the tests with valid bools, just to make sure the test # cases are OK. # get-membership-old send "1046 46 5 0 1 0\n" simple_expect "=1046 1 { $any_time 5 255 0 0 \\* }" # login (no need to give proper password, as we are admin). send "1047 62 5 [holl "dobedo"] 0\n" simple_expect ":2 9 5 1" simple_expect "=1047" # re-z-lookup send "1048 74 [holl "."] 1 1\n" simple_expect "=1048 5 { [holl "Presentation .av nya. möten"] 0000 1 [holl "Presentation .av nya. medlemmar"] 0000 2 [holl "Lappar .på. dörren"] 0000 3 [holl "Nyheter om LysKOM"] 0000 4 [holl "Administratör .för. LysKOM"] 1001 5 }" send "1049 74 [holl "."] 0 1\n" simple_expect "=1049 4 { [holl "Presentation .av nya. möten"] 0000 1 [holl "Presentation .av nya. medlemmar"] 0000 2 [holl "Lappar .på. dörren"] 0000 3 [holl "Nyheter om LysKOM"] 0000 4 }" send "1050 74 [holl "."] 1 0\n" simple_expect "=1050 1 { [holl "Administratör .för. LysKOM"] 1001 5 }" # lookup-z-name send "1051 76 [holl "n"] 0 1\n" simple_expect "=1051 1 { [holl "Nyheter om LysKOM"] 0000 4 }" send "1052 76 [holl "n"] 1 0\n" simple_expect "=1052 0 \\*" send "1053 76 [holl "n"] 1 1\n" simple_expect "=1053 1 { [holl "Nyheter om LysKOM"] 0000 4 }" # who-is-on-dynamic send "1054 83 0 1 0\n" simple_expect "=1054 0 \\*" send "1055 83 1 0 0\n" simple_expect "=1055 1 { 1 5 0 $any_num 00000000 [holl ""] }" send "1056 83 1 1 0\n" simple_expect "=1056 1 { 1 5 0 $any_num 00000000 [holl ""] }" # get-membership-10 send "1057 99 5 0 1 1\n" simple_expect "=1057 1 { 0 $any_time 5 255 0 0 \\* 5 $any_time 00000000 }" send "1058 99 5 0 1 0\n" simple_expect "=1058 1 { 0 $any_time 5 255 0 0 \\* 5 $any_time 00000000 }" # query-read-texts send "1059 107 5 5 1 0\n" simple_expect "=1059 0 $any_time 5 255 0 \\* 5 $any_time 00000000" send "1060 107 5 5 0 0\n" simple_expect "=1060 0 $any_time 5 255 0 \\* 5 $any_time 00000000" # get-membership send "1061 108 5 0 1 1 0\n" simple_expect "=1061 1 { 0 $any_time 5 255 0 \\* 5 $any_time 00000000 }" send "1062 108 5 0 1 0 0\n" simple_expect "=1062 1 { 0 $any_time 5 255 0 \\* 5 $any_time 00000000 }" # set-connection-time-format send "1063 120 1\n" simple_expect "=1063" send "1064 120 0\n" simple_expect "=1064" # Shut down. send "1065 42 255\n" simple_expect "=1065" send "1066 44 0\n" simple_expect "=1066" lyskomd_death client_death 0 lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/49.exp0000664000015100472110000000544307722441641016752 # Test suite for lyskomd. # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test client disconnect while logged in and receiving async-logout, # in a way that ensures the server detects the EOF condition during a write. set sleep 2 lyskomd_start if {$debug_calls} { # Log in as admin on client 2. client_start 2 send "A[holl "two"]\n" simple_expect "LysKOM" "connected" send "1000 80 1 { 13 }\n" simple_expect "=1000" send "1001 0 5 [holl "gazonk"]\n" simple_expect "=1001" # Put something in the input buffer of the client, but don't read it. # Without this, the bug isn't triggered. With this, it is. At least # when running Linux 2.4.18pre1 with glibc-2.3.1. I suspect that the # exact behaviour is highly depent on your TCP/IP stack, but I don't # have a deep enough understanding of that to be really sure. send "#suspend socket\n" simple_expect "suspended" "" meta send "1002 35\n" # Request 1008 will sleep a few seconds and then succeed. By that # time, the client is already killed, so the server should get a write # error when it tries to send the response. send "1003 1008 $sleep\n" # Disconnect client 2. kill_client 2 # Log in as admin on client 0. client_start 0 send "A[holl "zero"]\n" simple_expect "LysKOM" "connected" send "1004 80 1 { 13 }\n" simple_expect "=1004" send "1005 0 5 [holl "gazonk"]\n" simple_expect "=1005" # Log in as admin on client 1. client_start 1 send "A[holl "one"]\n" simple_expect "LysKOM" "connected" send "1006 80 1 { 13 }\n" simple_expect "=1006" send "1007 0 5 [holl "gazonk"]\n" simple_expect "=1007" talk_to client 0 send "#suspend socket\n" simple_expect "suspended" "" meta send "1008 35\n" send "1009 1008 $sleep\n" # Disconnect client 0. kill_client 0 talk_to client 1 simple_expect ":2 13 5 2" # Shut down. send "1010 42 255\n" simple_expect "=1010" send "1011 44 0\n" simple_expect "=1011" lyskomd_death client_death 1 } else { unsupported "Use configure --with-debug-calls to enable" kill_lyskomd } lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/admin-cov.exp0000664000015100472110000000725707721716133020400 # Test suite for lyskomd. # Copyright (C) 1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Supplementary test suites to get statement coverage of admin.c # # Note: 100% coverage depends on being able to put the database into # an inconsistent state. Call 1000 (set-marks) does this. # read_versions source "$srcdir/config/prot-a.exp" lyskomd_start "" \ "Max marks per text: 1 Max broadcast length: 10" client_start 0 talk_to client 0 send "A[holl "DejaGnu test suite"]\n" simple_expect "LysKOM" kom_accept_async "1 { 12 }" # Set up kom_login 5 "gazonk" 0 kom_create_conference "C6" "10100000" "0 { }" kom_create_person "P7" "PW7" "00000000" "0 { }" kom_create_person "P8" "PW8" "00000000" "0 { }" kom_create_conference "C9" "00000000" "0 { }" kom_add_member 9 8 100 0 "01000000" lyskomd_expect "Person 8 added to conference 9 by 5." # Attempt to do set-info of non-existent text kom_login 5 "gazonk" 0 kom_enable 255 send "1000 79 0 1 2 3 4 1\n" simple_expect "%1000 14 1" # Attempt to do set-info without privs kom_enable 0 send "1001 86 [holl "Text"] 1 { 0 1 } 0 { }\n" simple_expect "=1001 1" send "1002 79 0 1 2 3 4 1\n" simple_expect "%1002 12 0" # Attempt to do set-info with too many marks on the text kom_enable 255 send "1003 72 1 1\n" simple_expect "=1003" send "1005 79 0 1 2 3 4 1\n" lyskomd_expect "LIMIT: set_motd_of_lyskom.1.: New motd has 1 marks." simple_expect "%1005 36 1" kom_enable 0 # Attempt to do set-info with an old motd that isn't marked kom_enable 255 send "1100 86 [holl "Another text"] 1 { 0 1 } 0 { }\n" simple_expect "=1100 2" send "1101 86 [holl "Message of the day!"] 1 { 0 1 } 0 { }\n" simple_expect "=1101 3" send "1102 79 0 1 2 3 4 2\n" simple_expect "=1102" if {$debug_calls} { send "1103 1001 2 0\n" simple_expect "=1103" } else { unsupported "Use configure --with-debug-calls to enable" } send "1104 79 0 1 2 3 4 3\n" if {$debug_calls} { lyskomd_expect "ERROR: set_motd_of_lyskom\\(\\): Old motd not marked\\." } simple_expect "=1104" kom_enable 0 # Send a long message send "2000 53 0 [holl "1234567890X"]\n" simple_expect "%2000 5 10" # Send a message to a non-existent conference (9999) send "2001 53 9999 [holl "FUBAR"]\n" simple_expect "%2001 9 9999" # Attempt to sent a message to a secret conference kom_login 7 "PW7" 0 send "2002 53 6 [holl "FUBAR"]\n" simple_expect "%2002 9 6" # Send message to conference with passive members client_start 1 talk_to client 1 kom_connect "DejaGnu Test Suite" kom_accept_async "0 { }" kom_login 8 "PW8" 0 talk_to client 0 send "2003 53 9 [holl "SILENT"]\n" simple_expect "%2003 53 0" talk_to client 1 kom_ping_server # Attempt to shut down LysKOM without privs send "3000 44 0\n" simple_expect "%3000 12 0" # Finish kom_logout kom_login 5 "gazonk" 0 kom_enable 255 send "9999 44 0\n" simple_expect "=9999" client_death 1 client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/aux-items-bad.conf0000664000015100472110000000016407720356646021312 # This is not a legal aux-items file. 1 : just (kidding) { this make sense: false; } 2: die! die! please stay! lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/aux-items-cov.exp0000664000015100472110000005147207721716133021222 # Test suite for lyskomd. # Copyright (C) 1999-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Supplementary test suites to get statement coverage of aux-items.c # # We can't get 100% coverage # There's a check on the definition pointer in aux_item_add_perm # but the pointer passed to this function is never NULL in the # current code. # # It's difficult to test out-of-memory conditions # Out of memory condition when adding aux-item # Out of memory compiling validaion regexp # Out of memory condition in query_predefined_aux_items # # Some code is just really hard to reach # Internal error in regexp matcher # Invalid trigger name kills the server. It's been tested though. # # check_delete_aux_item_list with deleted items in list # I don't think this is possible any more # # In delete_aux_item_list, the check for call to check_delete_ax_item_list # This probably can't be triggered # Optimization artifacts # With -O2 we will never get 100% coverage # return at end of aux_item_find_trigger gets optimized to oblivion # The continue in aux_iherit_items is not hit # # Call to system_check_add_aux_item_list with NULL list # This can't be triggered # Missing tests # Test precompiled aux-items. We don't have any yet. # # We get in to aux_item_add_perm without a valid item tag # Call to aux_item_inherit_items with no parent or no target # Same thing in undelete # Try to add an item with no definition to system read_versions source "$srcdir/config/prot-a.exp" lyskomd_start "$srcdir/lyskomd.0/aux-items.cov" "\ Max aux_items deleted per call: 10 Max aux_items added per call: 10" client_start 0 talk_to client 0 send "A[holl "DejaGnu test suite"]\n" simple_expect "LysKOM" # Do something that gets the default aux-item definition kom_accept_async "0 { }" kom_login 5 "gazonk" 0 send "1000 86 [holl "Text"] 1 { 0 5 } 1 { 10000 00000000 0 [holl "FUBAR"] }\n" simple_expect "=1000 1" # Try an illegal aux-item tag send "1001 86 [holl "Text"] 1 { 0 5 } 1 { 0 00000000 0 [holl "FUBAR"] }\n" simple_expect "%1001 48 0" # Try an undefined aux-item in the predefined range send "1002 86 [holl "Text"] 1 { 0 5 } 1 { 9999 00000000 0 [holl "FUBAR"] }\n" simple_expect "%1002 48 0" # Try adding an aux-item that has an item with an invalid validation send "1003 86 [holl "Text"] 1 { 0 5 } 1 { 1000 00000000 0 [holl "FUBAR"] }\n" talk_to lyskomd simple_expect "Unmatched \\\[ or \\\[\\^ in validate regexp of aux-item definition 1000 \\(invalid-regexp\\)." simple_expect "Failed to cache regexp validator for \"invalid-regexp\". Rejecting all such items." talk_to client 0 simple_expect "%1003 48 0" # Create a valid text send "2000 86 [holl "Text"] 1 { 0 1 } 1 { 1001 01000000 0 [holl "FUBAR"] }\n" simple_expect "=2000 2" kom_logout kom_create_person "P1" "joshua5" "00000000" "0 { }" kom_login 6 "joshua5" 0 send "2001 86 [holl "Comment"] 2 { 0 1 2 2 } 0 { }\n" simple_expect "=2001 3" # Add an item with NULL definition to conference send "3000 93 1 0 { } 1 { 0 00000000 0 [holl "FUBAR"] }\n" simple_expect "%3000 48 0" kom_login 5 "gazonk" 0 kom_enable 255 send "3001 95 0 { } 1 { 0 00000000 0 [holl "FUBAR"] }\n" simple_expect "%3001 48 0" # Attempt to create aux-item with mark-text trigger with no valid text send "4000 93 1 0 { } 2 { 1003 00000000 0 [holl "999"] 1004 00000000 0 [holl "999"] }\n" simple_expect "=4000" # Attempt to use unmark-text trigger on item not on conf send "4001 95 0 { } 1 { 1004 00000000 0 [holl "999"] }\n" simple_expect "=4001" send "4002 94\n" simple_expect "=4002 $any_num $any_num $any_num $any_num $any_num $any_num 1 { 1 1004 5 $any_time 00000000 0 [holl "999"] }" # Attempt to create item with a broken validation regexp, twice send "5000 95 0 { } 1 { 1000 00000000 0 [holl "ABC"] }\n" simple_expect "%5000 48 0" send "5001 95 0 { } 1 { 1000 00000000 0 [holl "ABC"] }\n" simple_expect "%5001 48 0" # Attempt to create an item that is system-only send "5002 95 0 { } 1 { 1005 00000000 0 [holl "FUBAR"] }\n" simple_expect "%5002 49 0" # Delete aux-item zero is ignored # (this is undocumented behavior and may change) send "5003 93 1 1 { 0 } 0 { }\n" simple_expect "=5003" # FIXME (bug 220): Call to undelete_aux_item_list with item zero # FIXME (bug 220): Delete an item that has the delete flag set # FIXME (bug 220): Call to aux_item_trigger_mark_text on item added to text? # FIXME (bug 220): Call to aux_item_trigger_unmark_text on item added to text? # FIXME (bug 220): Call to modify-X-info with a too-long delete list # FIXME (bug 220): Call to modify-X-info with a too-long add list send "5100 92 1 11 { 1 2 3 4 5 6 7 8 9 10 11 } 0 { }\n" simple_expect "%5100 46 10" send "5101 92 1 0 { } 11 { 1 00000000 0 [holl "X"] 2 00000000 0 [holl "X"] 3 00000000 0 [holl "X"] 4 00000000 0 [holl "X"] 5 00000000 0 [holl "X"] 6 00000000 0 [holl "X"] 7 00000000 0 [holl "X"] 8 00000000 0 [holl "X"] 9 00000000 0 [holl "X"] 10 00000000 0 [holl "X"] 11 00000000 0 [holl "X"] }\n" simple_expect "%5101 46 10" send "5102 93 5 11 { 1 2 3 4 5 6 7 8 9 10 11 } 0 { }\n" simple_expect "%5102 46 10" send "5103 93 5 0 { } 11 { 1 00000000 0 [holl "X"] 2 00000000 0 [holl "X"] 3 00000000 0 [holl "X"] 4 00000000 0 [holl "X"] 5 00000000 0 [holl "X"] 6 00000000 0 [holl "X"] 7 00000000 0 [holl "X"] 8 00000000 0 [holl "X"] 9 00000000 0 [holl "X"] 10 00000000 0 [holl "X"] 11 00000000 0 [holl "X"] }\n" simple_expect "%5103 46 10" send "5104 95 11 { 1 2 3 4 5 6 7 8 9 10 11 } 0 { }\n" simple_expect "%5104 46 10" send "5105 95 0 { } 11 { 1 00000000 0 [holl "X"] 2 00000000 0 [holl "X"] 3 00000000 0 [holl "X"] 4 00000000 0 [holl "X"] 5 00000000 0 [holl "X"] 6 00000000 0 [holl "X"] 7 00000000 0 [holl "X"] 8 00000000 0 [holl "X"] 9 00000000 0 [holl "X"] 10 00000000 0 [holl "X"] 11 00000000 0 [holl "X"] }\n" simple_expect "%5105 46 10" # Test linking aux items # Create on text link to conf # Create on text link to info # Create on text link to text kom_login 5 "gazonk" 0 send "5998 86 [holl "Testing"] 1 { 0 5 } 0 { }\n" simple_expect "=5998 4" send "5999 86 [holl "Jesting"] 1 { 0 5 } 0 { }\n" simple_expect "=5999 5" send "6000 92 4 0 { } 3 { 1006 00000000 0 [holl "T 1007 5"] 1006 00000000 0 [holl "C 1007 5"] 1006 00000000 0 [holl "I 1007 0"] }\n" simple_expect "=6000" send "6001 90 5\n" simple_expect "=6001 $any_time 5 0 7 0 2 { 0 5 6 3 } 1 { 1 1007 5 $any_time 00000000 0 [holl "T 1006 4"] }" send "6002 91 5\n" simple_expect "=6002 [holl "Administratör .för. LysKOM"] 10011000 $any_time $any_time 5 0 5 0 0 0 77 77 1 1 3 0 1 { 1 1007 5 $any_time 00000000 0 [holl "T 1006 4"] }" send "6003 94\n" simple_expect "=6003 $any_num $any_num $any_num $any_num $any_num $any_num 2 { 1 1004 5 $any_time 00000000 0 [holl "999"] 2 1007 5 $any_time 00000000 0 [holl "T 1006 4"] }" send "6100 88 [holl "C7"] 00000000 0 { }\n" simple_expect "=6100 7" send "6101 88 [holl "C8"] 00000000 0 { }\n" simple_expect "=6101 8" # Create on conf link to conf # Create on conf link to info # Create on conf link to text send "6102 93 7 0 { } 3 { 1006 00000000 0 [holl "T 1007 5"] 1006 00000000 0 [holl "C 1007 8"] 1006 00000000 0 [holl "I 1007 0"] }\n" simple_expect "=6102" send "6103 90 5\n" simple_expect "=6103 $any_time 5 0 7 0 2 { 0 5 6 3 } 2 { 1 1007 5 $any_time 00000000 0 [holl "T 1006 4"] 2 1007 5 $any_time 00000000 0 [holl "C 1006 7"] }" send "6104 91 8\n" simple_expect "=6104 [holl "C8"] 00000000 $any_time $any_time 5 0 5 0 5 0 77 77 0 1 0 0 1 { 1 1007 5 $any_time 00000000 0 [holl "C 1006 7"] }" send "6105 94\n" simple_expect "=6105 $any_num $any_num $any_num $any_num $any_num $any_num 3 { 1 1004 5 $any_time 00000000 0 [holl "999"] 2 1007 5 $any_time 00000000 0 [holl "T 1006 4"] 3 1007 5 $any_time 00000000 0 [holl "C 1006 7"] }" # Create on info link to conf # Create on info link to info # Create on info link to text kom_enable 255 send "6106 95 0 { } 3 { 1006 00000000 0 [holl "T 1007 5"] 1006 00000000 0 [holl "C 1007 8"] 1006 00000000 0 [holl "I 1007 0"] }\n" simple_expect "=6106" send "6107 90 5\n" simple_expect "=6107 $any_time 5 0 7 0 2 { 0 5 6 3 } 3 { 1 1007 5 $any_time 00000000 0 [holl "T 1006 4"] 2 1007 5 $any_time 00000000 0 [holl "C 1006 7"] 3 1007 5 $any_time 00000000 0 [holl "I 1006 0"] }" send "6108 91 8\n" simple_expect "=6108 [holl "C8"] 00000000 $any_time $any_time 5 0 5 0 5 0 77 77 0 1 0 0 2 { 1 1007 5 $any_time 00000000 0 [holl "C 1006 7"] 2 1007 5 $any_time 00000000 0 [holl "I 1006 0"] }" send "6109 94\n" simple_expect "=6109 $any_num $any_num $any_num $any_num $any_num $any_num 7 { 1 1004 5 $any_time 00000000 0 [holl "999"] 2 1007 5 $any_time 00000000 0 [holl "T 1006 4"] 3 1007 5 $any_time 00000000 0 [holl "C 1006 7"] 4 1006 5 $any_time 00000000 0 [holl "T 1007 5"] 5 1006 5 $any_time 00000000 0 [holl "C 1007 8"] 6 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 7 1007 5 $any_time 00000000 0 [holl "I 1006 0"] }" # Delete manually created text items send "6200 92 4 3 { 1 2 3 } 0 { }\n" simple_expect "=6200" send "6201 90 5\n" simple_expect "=6201 $any_time 5 0 7 0 2 { 0 5 6 3 } 2 { 2 1007 5 $any_time 00000000 0 [holl "C 1006 7"] 3 1007 5 $any_time 00000000 0 [holl "I 1006 0"] }" send "6202 91 5\n" simple_expect "=6202 [holl "Administratör .för. LysKOM"] 10011000 $any_time $any_time 5 0 5 0 0 0 77 77 1 1 3 0 0 \\*" send "6203 94\n" simple_expect "=6203 $any_num $any_num $any_num $any_num $any_num $any_num 6 { 1 1004 5 $any_time 00000000 0 [holl "999"] 3 1007 5 $any_time 00000000 0 [holl "C 1006 7"] 4 1006 5 $any_time 00000000 0 [holl "T 1007 5"] 5 1006 5 $any_time 00000000 0 [holl "C 1007 8"] 6 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 7 1007 5 $any_time 00000000 0 [holl "I 1006 0"] }" # Delete manually created conf item send "6204 93 7 3 { 1 2 3 } 0 { }\n" simple_expect "=6204" send "6205 90 5\n" simple_expect "=6205 $any_time 5 0 7 0 2 { 0 5 6 3 } 1 { 3 1007 5 $any_time 00000000 0 [holl "I 1006 0"] }" send "6206 91 8\n" simple_expect "=6206 [holl "C8"] 00000000 $any_time $any_time 5 0 5 0 5 0 77 77 0 1 0 0 1 { 2 1007 5 $any_time 00000000 0 [holl "I 1006 0"] }" send "6207 94\n" simple_expect "=6207 $any_num $any_num $any_num $any_num $any_num $any_num 5 { 1 1004 5 $any_time 00000000 0 [holl "999"] 4 1006 5 $any_time 00000000 0 [holl "T 1007 5"] 5 1006 5 $any_time 00000000 0 [holl "C 1007 8"] 6 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 7 1007 5 $any_time 00000000 0 [holl "I 1006 0"] }" # Delete manually created info item kom_enable 255 send "6208 95 3 { 4 5 6 } 0 { }\n" simple_expect "=6208" send "6209 90 5\n" simple_expect "=6209 $any_time 5 0 7 0 2 { 0 5 6 3 } 0 \\*" send "6210 91 8\n" simple_expect "=6210 [holl "C8"] 00000000 $any_time $any_time 5 0 5 0 5 0 77 77 0 1 0 0 0 \\*" send "6211 94\n" simple_expect "=6211 $any_num $any_num $any_num $any_num $any_num $any_num 1 { 1 1004 5 $any_time 00000000 0 [holl "999"] }" # Delete auto created info item send "6212 92 4 0 { } 3 { 1006 00000000 0 [holl "T 1007 5"] 1006 00000000 0 [holl "C 1007 5"] 1006 00000000 0 [holl "I 1007 0"] }\n" simple_expect "=6212" send "6213 90 4\n" simple_expect "=6213 $any_time 5 0 7 0 2 { 0 5 6 2 } 3 { 4 1006 5 $any_time 00000000 0 [holl "T 1007 5"] 5 1006 5 $any_time 00000000 0 [holl "C 1007 5"] 6 1006 5 $any_time 00000000 0 [holl "I 1007 0"] }" send "6214 94\n" simple_expect "=6214 $any_num $any_num $any_num $any_num $any_num $any_num 2 { 1 1004 5 $any_time 00000000 0 [holl "999"] 8 1007 5 $any_time 00000000 0 [holl "T 1006 4"] }" send "6215 95 1 { 8 } 0 { }\n" simple_expect "=6215" send "6216 94\n" simple_expect "=6216 $any_num $any_num $any_num $any_num $any_num $any_num 1 { 1 1004 5 $any_time 00000000 0 [holl "999"] }" send "62160 90 4\n" simple_expect "=62160 $any_time 5 0 7 0 2 { 0 5 6 2 } 2 { 4 1006 5 $any_time 00000000 0 [holl "T 1007 5"] 5 1006 5 $any_time 00000000 0 [holl "C 1007 5"] }" # Delete auto created conf item send "6217 91 5\n" simple_expect "=6217 [holl "Administratör .för. LysKOM"] 10011000 $any_time $any_time 5 0 5 0 0 0 77 77 1 1 3 0 1 { 2 1007 5 $any_time 00000000 0 [holl "T 1006 4"] }" send "6218 93 5 1 { 2 } 0 { }\n" simple_expect "=6218" send "6219 91 5\n" simple_expect "=6219 [holl "Administratör .för. LysKOM"] 10011000 $any_time $any_time 5 0 5 0 0 0 77 77 1 1 3 0 0 \\*" send "6220 90 4\n" simple_expect "=6220 $any_time 5 0 7 0 2 { 0 5 6 2 } 1 { 4 1006 5 $any_time 00000000 0 [holl "T 1007 5"] }" # Delete auto created text item send "6221 90 5\n" simple_expect "=6221 $any_time 5 0 7 0 2 { 0 5 6 3 } 1 { 4 1007 5 $any_time 00000000 0 [holl "T 1006 4"] }" send "6222 92 5 1 { 4 } 0 { }\n" simple_expect "=6222" send "6223 90 5\n" simple_expect "=6223 $any_time 5 0 7 0 2 { 0 5 6 3 } 0 \\*" send "6224 90 4\n" simple_expect "=6224 $any_time 5 0 7 0 2 { 0 5 6 2 } 0 \\*" # Delete text with items linked to text, conf and info # Delete conf with items linked to text, conf and info # FIXME (bug 220): Test cases here # Text with permanent item, items linked to conf, text, info # Conf with permanent item, items linked to conf, text, info # Info with permanent item, items linked to conf, text, info # Attempt to delete all (this should cover undelete functions) # Create the items (bracketed by non-linked items for additional testing) send "6300 92 4 0 { } 5 { 2000 00000000 0 [holl "A"] 1006 00000000 0 [holl "T 1007 4"] 1006 00000000 0 [holl "C 1007 7"] 1006 00000000 0 [holl "I 1007 0"] 1008 00000000 0 [holl "X"] }\n" simple_expect "=6300" send "6301 93 7 0 { } 5 { 2000 00000000 0 [holl "A"] 1006 00000000 0 [holl "T 1007 4"] 1006 00000000 0 [holl "C 1007 7"] 1006 00000000 0 [holl "I 1007 0"] 1008 00000000 0 [holl "X"] }\n" simple_expect "=6301" send "6302 95 0 { } 5 { 2000 00000000 0 [holl "A"] 1006 00000000 0 [holl "T 1007 4"] 1006 00000000 0 [holl "C 1007 7"] 1006 00000000 0 [holl "I 1007 0"] 1008 00000000 0 [holl "X"] }\n" simple_expect "=6302" # Check the original data send "6303 90 4\n" simple_expect "=6303 $any_time 5 0 7 0 2 { 0 5 6 2 } 8 { 7 2000 5 $any_time 00000000 0 [holl "A"] 8 1006 5 $any_time 00000000 0 [holl "T 1007 4"] 9 1006 5 $any_time 00000000 0 [holl "C 1007 7"] 10 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 11 1008 5 $any_time 00000000 0 [holl "X"] 12 1007 5 $any_time 00000000 0 [holl "T 1006 4"] 13 1007 5 $any_time 00000000 0 [holl "C 1006 7"] 14 1007 5 $any_time 00000000 0 [holl "I 1006 0"] }" send "6304 91 7\n" simple_expect "=6304 [holl "C7"] 00000000 $any_time $any_time 5 0 5 0 5 0 77 77 0 1 0 0 8 { 4 1007 5 $any_time 00000000 0 [holl "T 1006 4"] 5 2000 5 $any_time 00000000 0 [holl "A"] 6 1006 5 $any_time 00000000 0 [holl "T 1007 4"] 7 1006 5 $any_time 00000000 0 [holl "C 1007 7"] 8 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 9 1008 5 $any_time 00000000 0 [holl "X"] 10 1007 5 $any_time 00000000 0 [holl "C 1006 7"] 11 1007 5 $any_time 00000000 0 [holl "I 1006 0"] }" send "6305 94\n" simple_expect "=6305 $any_num $any_num $any_num $any_num $any_num $any_num 9 { 1 1004 5 $any_time 00000000 0 [holl "999"] 9 1007 5 $any_time 00000000 0 [holl "T 1006 4"] 10 1007 5 $any_time 00000000 0 [holl "C 1006 7"] 11 2000 5 $any_time 00000000 0 [holl "A"] 12 1006 5 $any_time 00000000 0 [holl "T 1007 4"] 13 1006 5 $any_time 00000000 0 [holl "C 1007 7"] 14 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 15 1008 5 $any_time 00000000 0 [holl "X"] 16 1007 5 $any_time 00000000 0 [holl "I 1006 0"] }" # Attempt to delete all items on the text send "6307 92 4 5 { 7 8 9 10 11 } 1 { 1009 00000000 0 [holl "X"] }\n" simple_expect "%6307 48 0" send "6308 90 4\n" simple_expect "=6308 $any_time 5 0 7 0 2 { 0 5 6 2 } 8 { 7 2000 5 $any_time 00000000 0 [holl "A"] 8 1006 5 $any_time 00000000 0 [holl "T 1007 4"] 9 1006 5 $any_time 00000000 0 [holl "C 1007 7"] 10 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 11 1008 5 $any_time 00000000 0 [holl "X"] 12 1007 5 $any_time 00000000 0 [holl "T 1006 4"] 13 1007 5 $any_time 00000000 0 [holl "C 1006 7"] 14 1007 5 $any_time 00000000 0 [holl "I 1006 0"] }" send "6309 91 7\n" simple_expect "=6309 [holl "C7"] 00000000 $any_time $any_time 5 0 5 0 5 0 77 77 0 1 0 0 8 { 4 1007 5 $any_time 00000000 0 [holl "T 1006 4"] 5 2000 5 $any_time 00000000 0 [holl "A"] 6 1006 5 $any_time 00000000 0 [holl "T 1007 4"] 7 1006 5 $any_time 00000000 0 [holl "C 1007 7"] 8 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 9 1008 5 $any_time 00000000 0 [holl "X"] 10 1007 5 $any_time 00000000 0 [holl "C 1006 7"] 11 1007 5 $any_time 00000000 0 [holl "I 1006 0"] }" send "6310 94\n" simple_expect "=6310 $any_num $any_num $any_num $any_num $any_num $any_num 9 { 1 1004 5 $any_time 00000000 0 [holl "999"] 9 1007 5 $any_time 00000000 0 [holl "T 1006 4"] 10 1007 5 $any_time 00000000 0 [holl "C 1006 7"] 11 2000 5 $any_time 00000000 0 [holl "A"] 12 1006 5 $any_time 00000000 0 [holl "T 1007 4"] 13 1006 5 $any_time 00000000 0 [holl "C 1007 7"] 14 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 15 1008 5 $any_time 00000000 0 [holl "X"] 16 1007 5 $any_time 00000000 0 [holl "I 1006 0"] }" # FIXME (220): Check all linked objects too send "6311 93 7 5 { 5 6 7 8 9 } 1 { 1009 00000000 0 [holl "X"] }\n" simple_expect "%6311 48 0" send "6312 90 4\n" simple_expect "=6312 $any_time 5 0 7 0 2 { 0 5 6 2 } 8 { 7 2000 5 $any_time 00000000 0 [holl "A"] 8 1006 5 $any_time 00000000 0 [holl "T 1007 4"] 9 1006 5 $any_time 00000000 0 [holl "C 1007 7"] 10 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 11 1008 5 $any_time 00000000 0 [holl "X"] 12 1007 5 $any_time 00000000 0 [holl "T 1006 4"] 13 1007 5 $any_time 00000000 0 [holl "C 1006 7"] 14 1007 5 $any_time 00000000 0 [holl "I 1006 0"] }" send "6313 91 7\n" simple_expect "=6313 [holl "C7"] 00000000 $any_time $any_time 5 0 5 0 5 0 77 77 0 1 0 0 8 { 4 1007 5 $any_time 00000000 0 [holl "T 1006 4"] 5 2000 5 $any_time 00000000 0 [holl "A"] 6 1006 5 $any_time 00000000 0 [holl "T 1007 4"] 7 1006 5 $any_time 00000000 0 [holl "C 1007 7"] 8 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 9 1008 5 $any_time 00000000 0 [holl "X"] 10 1007 5 $any_time 00000000 0 [holl "C 1006 7"] 11 1007 5 $any_time 00000000 0 [holl "I 1006 0"] }" send "6314 94\n" simple_expect "=6314 $any_num $any_num $any_num $any_num $any_num $any_num 9 { 1 1004 5 $any_time 00000000 0 [holl "999"] 9 1007 5 $any_time 00000000 0 [holl "T 1006 4"] 10 1007 5 $any_time 00000000 0 [holl "C 1006 7"] 11 2000 5 $any_time 00000000 0 [holl "A"] 12 1006 5 $any_time 00000000 0 [holl "T 1007 4"] 13 1006 5 $any_time 00000000 0 [holl "C 1007 7"] 14 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 15 1008 5 $any_time 00000000 0 [holl "X"] 16 1007 5 $any_time 00000000 0 [holl "I 1006 0"] }" send "6315 95 6 { 1 11 12 13 14 15 } 1 { 1009 00000000 0 [holl "X"] }\n" simple_expect "%6315 48 0" send "6316 90 4\n" simple_expect "=6316 $any_time 5 0 7 0 2 { 0 5 6 2 } 8 { 7 2000 5 $any_time 00000000 0 [holl "A"] 8 1006 5 $any_time 00000000 0 [holl "T 1007 4"] 9 1006 5 $any_time 00000000 0 [holl "C 1007 7"] 10 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 11 1008 5 $any_time 00000000 0 [holl "X"] 12 1007 5 $any_time 00000000 0 [holl "T 1006 4"] 13 1007 5 $any_time 00000000 0 [holl "C 1006 7"] 14 1007 5 $any_time 00000000 0 [holl "I 1006 0"] }" send "6317 91 7\n" simple_expect "=6317 [holl "C7"] 00000000 $any_time $any_time 5 0 5 0 5 0 77 77 0 1 0 0 8 { 4 1007 5 $any_time 00000000 0 [holl "T 1006 4"] 5 2000 5 $any_time 00000000 0 [holl "A"] 6 1006 5 $any_time 00000000 0 [holl "T 1007 4"] 7 1006 5 $any_time 00000000 0 [holl "C 1007 7"] 8 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 9 1008 5 $any_time 00000000 0 [holl "X"] 10 1007 5 $any_time 00000000 0 [holl "C 1006 7"] 11 1007 5 $any_time 00000000 0 [holl "I 1006 0"] }" send "6318 94\n" simple_expect "=6318 $any_num $any_num $any_num $any_num $any_num $any_num 9 { 1 1004 5 $any_time 00000000 0 [holl "999"] 9 1007 5 $any_time 00000000 0 [holl "T 1006 4"] 10 1007 5 $any_time 00000000 0 [holl "C 1006 7"] 11 2000 5 $any_time 00000000 0 [holl "A"] 12 1006 5 $any_time 00000000 0 [holl "T 1007 4"] 13 1006 5 $any_time 00000000 0 [holl "C 1007 7"] 14 1006 5 $any_time 00000000 0 [holl "I 1007 0"] 15 1008 5 $any_time 00000000 0 [holl "X"] 16 1007 5 $any_time 00000000 0 [holl "I 1006 0"] }" # Finish kom_logout kom_login 5 "gazonk" 0 kom_enable 255 send "9999 44 0\n" simple_expect "=9999" client_death 0 lyskomd_death {"Bug 689" 1 0 0 25} # Try some broken config files # lyskomd_fail_start {} "lyskomd.0/broken-aux-items.conf" lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/aux-items.conf0000664000015100472110000000507107721716133020560 # Test suite for lyskomd. # Copyright (C) 1998-1999, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Test suite aux items # # Range 1000-9999 are not defined and can be used for anything 1000 : A (any) { } 1001 : A (any) { } 1002 : A (any) { } 1003 : A (any) { } 1004 : A (any) { } 1005 : A (any) { } 1006 : A (any) { } 1007 : A (any) { } 1008 : A (any) { } 1009 : A (any) { } 1010 : A (any) { } 1011 : A (any) { } 1012 : A (any) { } 1013 : A (any) { } 1014 : A (any) { } 1015 : A (any) { } 1016 : A (any) { } 1017 : A (any) { } 1018 : A (any) { } 1019 : A (any) { } 1020 : A (any) { } 1021 : A (any) { } 1022 : A (any) { } 2000 : force-all (any) { inherit = true; secret = true; hide-creator = true; dont-garb = true; reserved-2 = true; reserved-3 = true; reserved-4 = true; } 2001 : clear-all (any) { inherit = false; secret = false; hide-creator = false; dont-garb = false; reserved-2 = false; reserved-3 = false; reserved-4 = false; } 2002 : inherit-limit (any) { inherit-limit = 10; } 2003 : validation (any) { validate = "^GOOD$"; } 2004 : author-only (any) { author-only = true; } 2005 : supervisor-only (any) { supervisor-only = true; } 2006 : unique (any) { unique = true; } 2007 : permanent (any) { permanent = true; } 3000 : create-text (create text) { } 3001 : create-conf (create conference) { } 3002 : create-pers (create letterbox) { } 4000 : mark-text (any) { add-trigger = mark-text(); delete-trigger = unmark-text(); undelete-trigger = mark-text(); } 10000 : system-only (server) { } 10001 : conf-only (conference) { } 10002 : text-only (text) { } 10003 : pers-only (letterbox) { } lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/aux-items.cov0000664000015100472110000000267707721716134020434 # Test suite for lyskomd. # Copyright (C) 1999, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Test suite aux items # 1000 : invalid-regexp (any) { validate = "ABC[Foo>)"; } 1001 : author-only (any) { author-only = true; } 1003 : mark-text (any) { add-trigger = mark-text(); } 1004 : unmark-text (any) { add-trigger = unmark-text(); } 1005 : system-only (any) { system-only = true; } 1006 : linking (any) { add-trigger = link-item(); } 1007 : linking-target (any) { } 1008 : nothing-special (any) { } 1009 : cant-create (any) disabled { } 2000 : nothing-special (any) { } lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/aux-items.leaks0000664000015100472110000000006206642464354020733 # # Memory leaks test suite # 1000 : A (any) { } lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/broken-aux-items.conf0000664000015100472110000000206507721716134022037 # Test suite for lyskomd. # Copyright (C) 1999, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. 1002 : invalid-trigger (any) { add-trigger = fubar(); } 1003 : invalid-validator (any) { validate = fubar(); } lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/bug-1121.data0000664000015100472110000000240307723505447017771 CLEAN:00002 00000000001062109269 #C 6 #T 9 I 1 2 3 4 0 0 0 * C 1 27HPresentation (av nya) möten 0 * [1] 00001000 684774708 684774708 0 0 0 0 0 0 77 77 0 0 0 * C 2 31HPresentation (av nya) medlemmar 0 * [1] 00001000 684774708 684774708 0 0 0 0 0 0 77 77 0 0 0 * C 3 18HLappar (på) dörren 0 * [1] 00001000 684774708 684774708 0 0 0 0 0 0 77 77 0 0 0 * C 4 17HNyheter om LysKOM 0 * [1] 00001000 684774708 684774708 0 0 0 0 0 0 77 77 0 0 0 * C 5 26HAdministratör (för) LysKOM 1 { 5 5 684774889 00000000 } [9 1:1,2,3,4,5,6,7,8] 10011000 684774889 1062109269 5 0 5 0 0 0 77 77 0 0 0 * P 5 64H9gR7fFYRjkjts 22Hfoo(unknown)@localhost 1111111111111111 00000000 [9 1:1,2,3,4,5,6,7,8] 0 * 1 { 684774889 5 255 1 7 { 3 4 5 6 7 8 8 } 5 684774889 00000000 } 1062109269 0 482 5 0 32 0 0 0 0 T 1 1062109269 5 0 0 4 0 3 { 0 5 6 1 7 1062109269 } 0 0 * T 2 1062109269 5 4 0 4 0 2 { 0 5 6 2 } 0 0 * T 3 1062109269 5 8 0 4 0 3 { 0 5 6 3 7 1062109269 } 0 0 * T 4 1062109269 5 12 0 4 0 3 { 0 5 6 4 7 1062109269 } 0 0 * T 5 1062109269 5 16 0 4 0 3 { 0 5 6 5 7 1062109269 } 0 0 * T 6 1062109269 5 20 0 4 0 3 { 0 5 6 6 7 1062109269 } 0 0 * T 7 1062109269 5 24 0 4 0 3 { 0 5 6 7 7 1062109269 } 0 0 * T 8 1062109269 5 28 0 4 0 3 { 0 5 6 8 7 1062109269 } 0 0 * lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/bug-1121.exp0000664000015100472110000000676707723505660017672 # Test suite for lyskomd. # Copyright (C) 1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test for bug 1121: mark-as-read mishandles read texts in some # circumstances. Also test that lyskomd can repair the problems # introduced by this bug. lyskomd_start client_start 0 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" "connected" # Log in as administrator. send "1000 80 0 { }\n" simple_expect "=1000" send "1001 62 5 [holl "gazonk"] 1\n" simple_expect "=1001" # Create a few texts. send "1002 86 [holl "Text"] 1 { 0 5 } 0 { }\n" simple_expect "=1002 1" send "1003 86 [holl "Text"] 1 { 0 5 } 0 { }\n" simple_expect "=1003 2" send "1004 86 [holl "Text"] 1 { 0 5 } 0 { }\n" simple_expect "=1004 3" send "1005 86 [holl "Text"] 1 { 0 5 } 0 { }\n" simple_expect "=1005 4" send "1006 86 [holl "Text"] 1 { 0 5 } 0 { }\n" simple_expect "=1006 5" send "1007 86 [holl "Text"] 1 { 0 5 } 0 { }\n" simple_expect "=1007 6" send "1008 86 [holl "Text"] 1 { 0 5 } 0 { }\n" simple_expect "=1008 7" send "1009 86 [holl "Text"] 1 { 0 5 } 0 { }\n" simple_expect "=1009 8" # Check what is read. send "1010 107 5 5 1 0\n" simple_expect "=1010 0 $any_time 5 255 0 \\* 5 $any_time 00000000" # Mark texts. send "1011 27 5 4 { 1 3 4 8 }\n" simple_expect "=1011" send "1012 107 5 5 1 0\n" simple_expect "=1012 0 $any_time 5 255 3 { 1 1 3 4 8 8 } 5 $any_time 00000000" # Mark texts again. This triggers the bug. send "1013 27 5 4 { 5 6 7 8 }\n" simple_expect "=1013" send "1014 107 5 5 1 0\n" simple_expect "=1014 0 $any_time 5 255 2 { 1 1 3 8 } 5 $any_time 00000000" # Save the database. send "1015 42 255\n" simple_expect "=1015" # Shut down. send "1016 42 255\n" simple_expect "=1016" send "1017 44 0\n" simple_expect "=1017" client_death 0 lyskomd_death # Make sure we can read a broken database with no problem. unpack_db bug-1121 dbck_run { "fparse_read_range_0: discarded out-of-order local number 8 probably introduced by bug 1121" } lyskomd_start "" "" "" "" "" [list \ "WARN: [pwd]/db/number.txt: No such file" \ ] 0 0 6 9 0 { "fparse_read_range_0: discarded out-of-order local number 8 probably introduced by bug 1121" } # Log in as person 5. This reads the broken data into the core # memory, and marks it as read, so that it is saved back once lyskomd # terminates. The dbck that is run from lyskomd_death won't find any # problems. client_start 1 talk_to client 1 send "A3Hfoo\n" simple_expect "LysKOM" send "1018 80 0 { }\n" simple_expect "=1018" send "1019 0 5 [holl "gazonk"]\n" lyskomd_expect "fparse_read_range_0: discarded out-of-order local number 8 probably introduced by bug 1121" simple_expect "=1019" system "kill -TERM $lyskomd_pid" lyskomd_death "" signal lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/bug-1121.texts0000664000015100472110000000004007723505446020221 TextTextTextTextTextTextTextTextlyskom-server-2.1.2/src/server/testsuite/lyskomd.0/bug-145.exp0000664000015100472110000000315207721716134017576 # Test suite for lyskomd. # Copyright (C) 1999-2000, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. read_versions source "$srcdir/config/prot-a.exp" source "$srcdir/config/leaks.exp" startup_leaks kom_create_conference "Conference 6" "00000000" "0 { }" kom_create_conference "Conference 7" "00000000" "0 { }" kom_create_conference "Conference 8" "00000000" "0 { }" # Delete conferences kom_delete_conf 6 kom_delete_conf 7 kom_delete_conf 8 kom_lookup_z_name "Conference 6" 1 1 "=\$ref_no 0 \\\\*" kom_lookup_z_name "Conference 7" 1 1 "=\$ref_no 0 \\\\*" kom_lookup_z_name "Conference 8" 1 1 "=\$ref_no 0 \\\\*" kom_lookup_z_name "Conference" 1 1 "=\$ref_no 0 \\\\*" kom_lookup_z_name "C" 1 1 "=\$ref_no 0 \\\\*" shutdown_leaks check_usage "Checking bug 145" "bug-145" lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/bug-225.exp0000664000015100472110000000255007721716134017576 # Test suite for lyskomd. # Copyright (C) 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test bug 225: negative numbers in the protocol. # Start the server. lyskomd_start client_start 0 send "A3Hfoo\n" simple_expect "LysKOM" send "1000 0 5 [holl "gazonk"]\n" simple_expect ":2 9 5 1" simple_expect "=1000" send "1001 55 -2343\n" simple_expect "%% LysKOM protocol error." # Shut down. talk_to client 0 send "1002 42 255\n" simple_expect "=1002" send "1003 44 0\n" simple_expect "=1003" client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/bug-349.exp0000664000015100472110000000674707721716134017621 # Test suite for lyskomd. # Copyright (C) 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test bug 349: set_supervisor returns KOM_UNDEF_CONF instead of # KOM_PERM when a member of a secret conference tries to set a new # supervisor for the secret conference, and the member isn't a # supervisor of the conference. # Start the server. lyskomd_start # Log in as admin (person 5). client_start 0 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" send "1000 0 5 [holl "gazonk"]\n" simple_expect ":2 9 5 1" simple_expect "=1000" # Create a secret conference: "secret" (conf 6). send "1001 88 [holl "secret"] 10101000 0 { }\n" simple_expect "=1001 6" # Create and log in as "member" (person 7). client_start 1 talk_to client 1 send "A[holl "member"]\n" simple_expect "LysKOM" send "1002 81\n" simple_expect "=1002 8 { 0 5 7 8 9 11 12 13 }" send "1003 80 9 { 0 5 7 8 9 11 12 13 18 }\n" simple_expect "=1003" send "1004 89 [holl "member"] [holl "secrt"] 00000000 0 { }\n" simple_expect "=1004 7" send "1005 62 7 [holl "secrt"] 0\n" simple_expect ":2 9 7 2" simple_expect "=1005" talk_to client 0 simple_expect ":2 9 7 2" # Create and log in as "nonmember" (person 8). client_start 2 talk_to client 2 send "A[holl "nonmember"]\n" simple_expect "LysKOM" send "1006 89 [holl "nonmember"] [holl "Secrt"] 00000000 0 { }\n" simple_expect "=1006 8" send "1007 62 8 [holl "Secrt"] 0\n" simple_expect ":2 9 8 3" simple_expect "=1007" talk_to client 0 simple_expect ":2 9 8 3" talk_to client 1 simple_expect ":2 9 8 3" # As admin, add member to the secret conference. talk_to client 0 send "1008 100 6 7 200 1 00000000\n" lyskomd_expect "Person 7 added to conference 6 by 5." simple_expect "=1008" talk_to client 1 simple_expect ":2 18 7 6" # As "nonmember", try to change the supervisor of "secret" to # "nonmember". Should get KOM_UNDEF_CONF. talk_to client 2 send "1009 18 6 8\n" simple_expect "%1009 9 6" # As "member", try to change the supervisor of "secret" to "member". # Should get KOM_PERM. talk_to client 1 send "1010 18 6 7\n" extracting_expect "%1010 (12|9) 6" errorcode 1 setup_xfail "*-*-*" "Bug 349" set test "Got KOM_PERM" if {$errorcode == 12} { pass "$test" } else { fail "$test" } unset test # Shut down everything. talk_to client 2 send "1011 55 0\n" simple_expect "=1011" simple_expect ":2 13 8 3" client_death 2 talk_to client 1 simple_expect ":2 13 8 3" talk_to client 0 simple_expect ":2 13 8 3" talk_to client 1 send "1012 55 0\n" simple_expect "=1012" simple_expect ":2 13 7 2" client_death 1 talk_to client 0 simple_expect ":2 13 7 2" send "1013 42 255\n" simple_expect "=1013" send "1014 44 0\n" simple_expect "=1014" client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/bug-37-2.exp0000664000015100472110000005660307721716134017666 # Test suite for lyskomd. # Copyright (C) 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test bug 37: get_unread_confs does not check that the caller is # allowed to see the person, and returns the correct result even for # secret persons, including secret confs! # # Variant two: test with all memberships being secret. # # We also check get-membership, get-membership-10, get-membership-old, # query-read-texts, query-read-texts-10 and query-read-texts-old. # # While we are at it, we also test the unread-is-secret personal flag. # # Startup and create the players # # Start the server. lyskomd_start # Create and log in as foo (person 6). client_start 0 send "A3Hfoo\n" simple_expect "LysKOM" send "1000 80 0 { }\n" simple_expect "=1000" send "1001 89 [holl "foo"] [holl "p6"] 00000000 0 { }\n" simple_expect "=1001 6" send "1002 62 6 [holl "p6"] 0\n" simple_expect "=1002" # Create and log in as bar (person 7; secret). client_start 1 send "A3Hbar\n" simple_expect "LysKOM" send "1003 80 0 { }\n" simple_expect "=1003" send "1004 89 [holl "bar"] [holl "p7"] 00000000 0 { }\n" simple_expect "=1004 7" send "1005 62 7 [holl "p7"] 0\n" simple_expect "=1005" send "1006 21 7 10111000\n" simple_expect "=1006" # Create and log in as citrus (person 8; has unread-is-secret set). client_start 2 send "A6Hcitrus\n" simple_expect "LysKOM" send "1007 80 0 { }\n" simple_expect "=1007" send "1008 89 [holl "citrus"] [holl "p8"] 10000000 0 { }\n" simple_expect "=1008 8" send "1009 62 8 [holl "p8"] 0\n" simple_expect "=1009" # Create and log in as gazonk (person 9). This is the observer. client_start 3 send "A6Hgazonk\n" simple_expect "LysKOM" send "1010 80 0 { }\n" simple_expect "=1010" send "1011 89 [holl "gazonk"] [holl "p9"] 00000000 0 { }\n" simple_expect "=1011 9" send "1012 62 9 [holl "p9"] 0\n" simple_expect "=1012" # # Create conferences. # # As bar, create secret (conf 10; secret). talk_to client 1 send "1013 88 [holl "secret"] 10101000 0 { }\n" simple_expect "=1013 10" # As bar, create rd-prot (conf 11; rd-prot). send "1014 88 [holl "rd-prot"] 10001000 0 { }\n" simple_expect "=1014 11" # As bar, create public (conf 12). send "1015 88 [holl "public"] 00001000 0 { }\n" simple_expect "=1015 12" # # Join conferences # # bar joins secret, rd-prot and public. send "1016 100 10 7 200 1 00100000\n" simple_expect "=1016" send "1017 100 11 7 200 2 00100000\n" simple_expect "=1017" send "1018 100 12 7 200 3 00100000\n" simple_expect "=1018" # bar invites foo to secret, rd-prot and public. send "1019 100 10 6 200 1 00100000\n" lyskomd_expect "Person 6 added to conference 10 by 7." simple_expect "=1019" send "1020 100 11 6 200 2 00100000\n" lyskomd_expect "Person 6 added to conference 11 by 7." simple_expect "=1020" send "1021 100 12 6 200 3 00100000\n" lyskomd_expect "Person 6 added to conference 12 by 7." simple_expect "=1021" # bar invites citrus to secret, rd-prot and public. send "1022 100 10 8 200 1 00100000\n" lyskomd_expect "Person 8 added to conference 10 by 7." simple_expect "=1022" send "1023 100 11 8 200 2 00100000\n" lyskomd_expect "Person 8 added to conference 11 by 7." simple_expect "=1023" send "1024 100 12 8 200 3 00100000\n" lyskomd_expect "Person 8 added to conference 12 by 7." simple_expect "=1024" # # foo examines foo. # talk_to client 0 # foo does get-unread-confs of foo. Should return the empty list. send "1025 52 6\n" simple_expect "=1025 0 \\*" # foo does get-membership-10 of foo. Should return 4 { 6 10 11 12 }. send "1026 99 6 0 100 1\n" simple_expect "=1026 4 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 10 200 0 0 \\* 7 $any_time 10100000 2 $any_time 11 200 0 0 \\* 7 $any_time 10100000 3 $any_time 12 200 0 0 \\* 7 $any_time 10100000 }" # foo does get-membership-old of foo. Should return 4 { 6 10 11 12 }. send "1027 46 6 0 100 1\n" simple_expect "=1027 4 { $any_time 6 255 0 0 \\* $any_time 10 200 0 0 \\* $any_time 11 200 0 0 \\* $any_time 12 200 0 0 \\* }" # foo does get-membership of foo. Should return 4 { 6 10 11 12 }. send "1028 108 6 0 100 1 0\n" simple_expect "=1028 4 { 0 $any_time 6 255 0 \\* 6 $any_time 00000000 1 $any_time 10 200 0 \\* 7 $any_time 10100000 2 $any_time 11 200 0 \\* 7 $any_time 10100000 3 $any_time 12 200 0 \\* 7 $any_time 10100000 }" # foo does query-read-texts-10 on foo and 10, 11 and 12. Should get results. send "1029 98 6 10\n" simple_expect "=1029 1 $any_time 10 200 0 0 \\* 7 $any_time 10100000" send "1030 98 6 11\n" simple_expect "=1030 2 $any_time 11 200 0 0 \\* 7 $any_time 10100000" send "1031 98 6 12\n" simple_expect "=1031 3 $any_time 12 200 0 0 \\* 7 $any_time 10100000" # foo does query-read-texts-old on foo and 10, 11 and 12. Should get results. send "1032 9 6 10\n" simple_expect "=1032 $any_time 10 200 0 0 \\*" send "1033 9 6 11\n" simple_expect "=1033 $any_time 11 200 0 0 \\*" send "1034 9 6 12\n" simple_expect "=1034 $any_time 12 200 0 0 \\*" # foo does query-read-texts on foo and 10, 11 and 12. Should get results. send "1035 107 6 10 1 0\n" simple_expect "=1035 1 $any_time 10 200 0 \\* 7 $any_time 10100000" send "1036 107 6 11 1 0\n" simple_expect "=1036 2 $any_time 11 200 0 \\* 7 $any_time 10100000" send "1037 107 6 12 1 0\n" simple_expect "=1037 3 $any_time 12 200 0 \\* 7 $any_time 10100000" # # gazonk examines foo. # talk_to client 3 # gazonk does get-unread-confs of foo. Should return the empty list. send "1038 52 6\n" simple_expect "=1038 0 \\*" # gazonk does get-membership-10 of foo. Should return 1 { 6 }. send "1039 99 6 0 100 1\n" simple_expect "=1039 1 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 }" # (Just a quick check: does the renumber work properly even if we don't # start from the beginning of the list?) send "1040 99 6 2 100 1\n" simple_expect "%1040 19 2" send "1041 99 6 1 100 1\n" simple_expect "%1041 19 1" # gazonk does get-membership-old of foo. Should return 1 { 6 }. send "1042 46 6 0 100 1\n" simple_expect "=1042 1 { $any_time 6 255 0 0 \\* }" # gazonk does get-membership of foo. Should return 1 { 6 }. send "1043 108 6 0 100 1 0\n" simple_expect "=1043 1 { 0 $any_time 6 255 0 \\* 6 $any_time 00000000 }" # (Just a quick check: does the renumber work properly even if we don't # start from the beginning of the list?) send "1044 108 6 2 100 1 0\n" simple_expect "%1044 19 2" send "1045 108 6 1 100 1 0\n" simple_expect "%1045 19 1" # gazonk does query-read-texts-10 on foo and 10, 11 and 12. All should fail. send "1046 98 6 10\n" simple_expect "%1046 9 10" send "1047 98 6 11\n" simple_expect "%1047 13 11" send "1048 98 6 12\n" simple_expect "%1048 13 12" # gazonk does query-read-texts-old on foo and 10, 11 and 12. 10 should fail. send "1049 9 6 10\n" simple_expect "%1049 9 10" send "1050 9 6 11\n" simple_expect "%1050 13 11" send "1051 9 6 12\n" simple_expect "%1051 13 12" # gazonk does query-read-texts on foo and 10, 11 and 12. All should fail. send "1052 107 6 10 1 0\n" simple_expect "%1052 9 10" send "1053 107 6 11 1 0\n" simple_expect "%1053 13 11" send "1054 107 6 12 1 0\n" simple_expect "%1054 13 12" # # gazonk examines bar. # # gazonk does get-unread-confs of bar. Should return undefined-person. send "1055 52 7\n" good_bad_expect "%1055 10 7" "=0 \\*" "Bug 37" # gazonk does get-membership-10 of bar. Should return undefined-person. send "1056 99 7 0 100 1\n" simple_expect "%1056 10 7" # gazonk does get-membership-old of bar. Should return undefined-person. send "1057 46 7 0 100 1\n" simple_expect "%1057 10 7" # gazonk does get-membership of bar. Should return undefined-person. send "1058 108 7 0 100 1 0\n" simple_expect "%1058 10 7" # gazonk does query-read-texts-10 on bar and 10, 11 and 12. undefined-person. send "1059 98 7 10\n" simple_expect "%1059 10 7" send "1060 98 7 11\n" simple_expect "%1060 10 7" send "1061 98 7 12\n" simple_expect "%1061 10 7" # gazonk does query-read-texts-old on bar and 10, 11 and 12. undefined-person. send "1062 9 7 10\n" simple_expect "%1062 10 7" send "1063 9 7 11\n" simple_expect "%1063 10 7" send "1064 9 7 12\n" simple_expect "%1064 10 7" # gazonk does query-read-texts on bar and 10, 11 and 12. undefined-person. send "1065 107 7 10 1 0\n" simple_expect "%1065 10 7" send "1066 107 7 11 1 0\n" simple_expect "%1066 10 7" send "1067 107 7 12 1 0\n" simple_expect "%1067 10 7" # # gazonk examines citrus. # # gazonk does get-unread-confs of citrus. Should return the empty list. send "1068 52 8\n" simple_expect "=1068 0 \\*" # gazonk does get-membership-10 of citrus. Should return 1 { 6 }. send "1069 99 8 0 100 1\n" simple_expect "=1069 1 { 0 $any_time 8 255 0 0 \\* 8 $any_time 00000000 }" # gazonk does get-membership-old of citrus. Should return 1 { 6 }. send "1070 46 8 0 100 1\n" simple_expect "=1070 1 { $any_time 8 255 0 0 \\* }" # gazonk does get-membership of citrus. Should return 1 { 6 }. send "1071 108 8 0 100 1 0\n" simple_expect "=1071 1 { 0 $any_time 8 255 0 \\* 8 $any_time 00000000 }" # gazonk does query-read-texts-10 on citrus and 10, 11 and 12. All fails. send "1072 98 8 10\n" simple_expect "%1072 9 10" send "1073 98 8 11\n" simple_expect "%1073 13 11" send "1074 98 8 12\n" simple_expect "%1074 13 12" # gazonk does query-read-texts-old on citrus and 10, 11 and 12. All fails. send "1075 9 8 10\n" simple_expect "%1075 9 10" send "1076 9 8 11\n" simple_expect "%1076 13 11" send "1077 9 8 12\n" simple_expect "%1077 13 12" # gazonk does query-read-texts on citrus and 10, 11 and 12. All should fail. send "1078 107 8 10 1 0\n" simple_expect "%1078 9 10" send "1079 107 8 11 1 0\n" simple_expect "%1079 13 11" send "1080 107 8 12 1 0\n" simple_expect "%1080 13 12" # # foo writes a text with secret, rd-prot and public as recipients. # talk_to client 0 send "1081 86 [holl "foo"] 3 { 0 10 0 11 0 12 } 0 { }\n" simple_expect "=1081 1" # # foo examines foo # # foo does get-unread-confs of foo. Should return 3 { 10 11 12 }. send "1082 52 6\n" simple_expect "=1082 3 { 10 11 12 }" # foo does get-membership-10 of foo. Should return 4 { 6 10 11 12 }. send "1083 99 6 0 100 1\n" simple_expect "=1083 4 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 10 200 0 0 \\* 7 $any_time 10100000 2 $any_time 11 200 0 0 \\* 7 $any_time 10100000 3 $any_time 12 200 0 0 \\* 7 $any_time 10100000 }" # foo does get-membership-old of foo. Should return 4 { 6 10 11 12 }. send "1084 46 6 0 100 1\n" simple_expect "=1084 4 { $any_time 6 255 0 0 \\* $any_time 10 200 0 0 \\* $any_time 11 200 0 0 \\* $any_time 12 200 0 0 \\* }" # foo does get-membership of foo. Should return 4 { 6 10 11 12 }. send "1085 108 6 0 100 1 0\n" simple_expect "=1085 4 { 0 $any_time 6 255 0 \\* 6 $any_time 00000000 1 $any_time 10 200 0 \\* 7 $any_time 10100000 2 $any_time 11 200 0 \\* 7 $any_time 10100000 3 $any_time 12 200 0 \\* 7 $any_time 10100000 }" # foo does query-read-texts-10 on foo and 10, 11 and 12. Should get results. send "1086 98 6 10\n" simple_expect "=1086 1 $any_time 10 200 0 0 \\* 7 $any_time 10100000" send "1087 98 6 11\n" simple_expect "=1087 2 $any_time 11 200 0 0 \\* 7 $any_time 10100000" send "1088 98 6 12\n" simple_expect "=1088 3 $any_time 12 200 0 0 \\* 7 $any_time 10100000" # foo does query-read-texts-old on foo and 10, 11 and 12. Should get results. send "1089 9 6 10\n" simple_expect "=1089 $any_time 10 200 0 0 \\*" send "1090 9 6 11\n" simple_expect "=1090 $any_time 11 200 0 0 \\*" send "1091 9 6 12\n" simple_expect "=1091 $any_time 12 200 0 0 \\*" # foo does query-read-texts on foo and 10, 11 and 12. Should get results. send "1092 107 6 10 1 0\n" simple_expect "=1092 1 $any_time 10 200 0 \\* 7 $any_time 10100000" send "1093 107 6 11 1 0\n" simple_expect "=1093 2 $any_time 11 200 0 \\* 7 $any_time 10100000" send "1094 107 6 12 1 0\n" simple_expect "=1094 3 $any_time 12 200 0 \\* 7 $any_time 10100000" # # gazonk examines foo. # talk_to client 3 # gazonk does get-unread-confs of foo. Should return the empty list. send "1095 52 6\n" simple_expect "=1095 0 \\*" # gazonk does get-membership-10 of foo. Should return 1 { 6 }. send "1096 99 6 0 100 1\n" simple_expect "=1096 1 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 }" # gazonk does get-membership-old of foo. Should return 1 { 6 }. send "1097 46 6 0 100 1\n" simple_expect "=1097 1 { $any_time 6 255 0 0 \\* }" # gazonk does get-membership of foo. Should return 1 { 6 }. send "1098 108 6 0 100 1 0\n" simple_expect "=1098 1 { 0 $any_time 6 255 0 \\* 6 $any_time 00000000 }" # gazonk does query-read-texts-10 on foo and 10, 11 and 12. All should fail. send "1099 98 6 10\n" simple_expect "%1099 9 10" send "1100 98 6 11\n" simple_expect "%1100 13 11" send "1101 98 6 12\n" simple_expect "%1101 13 12" # gazonk does query-read-texts-old on foo and 10, 11 and 12. All should fail. send "1102 9 6 10\n" simple_expect "%1102 9 10" send "1103 9 6 11\n" simple_expect "%1103 13 11" send "1104 9 6 12\n" simple_expect "%1104 13 12" # gazonk does query-read-texts on foo and 10, 11 and 12. All should fail. send "1105 107 6 10 1 0\n" simple_expect "%1105 9 10" send "1106 107 6 11 1 0\n" simple_expect "%1106 13 11" send "1107 107 6 12 1 0\n" simple_expect "%1107 13 12" # # gazonk examines bar # # gazonk does get-unread-confs of bar. Should return undefined-person. send "1108 52 7\n" good_bad_expect "%1108 10 7" "=0 \\*" "Bug 37" # gazonk does get-membership-10 of bar. Should return undefined-person. send "1109 99 7 0 100 1\n" simple_expect "%1109 10 7" # gazonk does get-membership-old of bar. Should return undefined-person. send "1110 46 7 0 100 1\n" simple_expect "%1110 10 7" # gazonk does get-membership of bar. Should return undefined-person. send "1111 108 7 0 100 1 0\n" simple_expect "%1111 10 7" # gazonk does query-read-texts-10 on bar and 10, 11 and 12. undefined-person. send "1112 98 7 10\n" simple_expect "%1112 10 7" send "1113 98 7 11\n" simple_expect "%1113 10 7" send "1114 98 7 12\n" simple_expect "%1114 10 7" # gazonk does query-read-texts-old on bar and 10, 11 and 12. undefined-person. send "1115 9 7 10\n" simple_expect "%1115 10 7" send "1116 9 7 11\n" simple_expect "%1116 10 7" send "1117 9 7 12\n" simple_expect "%1117 10 7" # gazonk does query-read-texts on bar and 10, 11 and 12. undefined-person. send "1118 107 7 10 1 0\n" simple_expect "%1118 10 7" send "1119 107 7 11 1 0\n" simple_expect "%1119 10 7" send "1120 107 7 12 1 0\n" simple_expect "%1120 10 7" # # gazonk examines citrus. # # gazonk does get-unread-confs of citrus. Should return the empty list. send "1121 52 8\n" simple_expect "=1121 0 \\*" # gazonk does get-membership-10 of citrus. Should return 1 { 6 }. send "1122 99 8 0 100 1\n" simple_expect "=1122 1 { 0 $any_time 8 255 0 0 \\* 8 $any_time 00000000 }" # gazonk does get-membership-old of citrus. Should return 1 { 6 }. send "1123 46 8 0 100 1\n" simple_expect "=1123 1 { $any_time 8 255 0 0 \\* }" # gazonk does get-membership of citrus. Should return 1 { 6 }. send "1124 108 8 0 100 1 0\n" simple_expect "=1124 1 { 0 $any_time 8 255 0 \\* 8 $any_time 00000000 }" # gazonk does query-read-texts-10 on citrus and 10, 11 and 12. All fails. send "1125 98 8 10\n" simple_expect "%1125 9 10" send "1126 98 8 11\n" simple_expect "%1126 13 11" send "1127 98 8 12\n" simple_expect "%1127 13 12" # gazonk does query-read-texts-old on citrus and 10, 11 and 12. All fails. send "1128 9 8 10\n" simple_expect "%1128 9 10" send "1129 9 8 11\n" simple_expect "%1129 13 11" send "1130 9 8 12\n" simple_expect "%1130 13 12" # gazonk does query-read-texts on citrus and 10, 11 and 12. All should fail. send "1131 107 8 10 1 0\n" simple_expect "%1131 9 10" send "1132 107 8 11 1 0\n" simple_expect "%1132 13 11" send "1133 107 8 12 1 0\n" simple_expect "%1133 13 12" # # mark as read # # foo marks the text as read talk_to client 0 send "1134 27 10 1 { 1 }\n" simple_expect "=1134" send "1135 27 11 1 { 1 }\n" simple_expect "=1135" send "1136 27 12 1 { 1 }\n" simple_expect "=1136" # bar marks the text as read talk_to client 1 send "1137 27 10 1 { 1 }\n" simple_expect "=1137" send "1138 27 11 1 { 1 }\n" simple_expect "=1138" send "1139 27 12 1 { 1 }\n" simple_expect "=1139" # citrus marks the text as read talk_to client 2 send "1140 27 10 1 { 1 }\n" simple_expect "=1140" send "1141 27 11 1 { 1 }\n" simple_expect "=1141" send "1142 27 12 1 { 1 }\n" simple_expect "=1142" # # foo examines foo. # talk_to client 0 # foo does get-unread-confs of foo. Should return the empty list. send "1143 52 6\n" simple_expect "=1143 0 \\*" # foo does get-membership-10 of foo. Should return 4 { 6 10 11 12 }. send "1144 99 6 0 100 1\n" simple_expect "=1144 4 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 10 200 1 0 \\* 7 $any_time 10100000 2 $any_time 11 200 1 0 \\* 7 $any_time 10100000 3 $any_time 12 200 1 0 \\* 7 $any_time 10100000 }" # foo does get-membership-old of foo. Should return 4 { 6 10 11 12 }. send "1145 46 6 0 100 1\n" simple_expect "=1145 4 { $any_time 6 255 0 0 \\* $any_time 10 200 1 0 \\* $any_time 11 200 1 0 \\* $any_time 12 200 1 0 \\* }" # foo does get-membership of foo. Should return 4 { 6 10 11 12 }. send "1146 108 6 0 100 1 0\n" simple_expect "=1146 4 { 0 $any_time 6 255 0 \\* 6 $any_time 00000000 1 $any_time 10 200 1 { 1 1 } 7 $any_time 10100000 2 $any_time 11 200 1 { 1 1 } 7 $any_time 10100000 3 $any_time 12 200 1 { 1 1 } 7 $any_time 10100000 }" # foo does query-read-texts-10 on foo and 10, 11 and 12. Should get results. send "1147 98 6 10\n" simple_expect "=1147 1 $any_time 10 200 1 0 \\* 7 $any_time 10100000" send "1148 98 6 11\n" simple_expect "=1148 2 $any_time 11 200 1 0 \\* 7 $any_time 10100000" send "1149 98 6 12\n" simple_expect "=1149 3 $any_time 12 200 1 0 \\* 7 $any_time 10100000" # foo does query-read-texts-old on foo and 10, 11 and 12. Should get results. send "1150 9 6 10\n" simple_expect "=1150 $any_time 10 200 1 0 \\*" send "1151 9 6 11\n" simple_expect "=1151 $any_time 11 200 1 0 \\*" send "1152 9 6 12\n" simple_expect "=1152 $any_time 12 200 1 0 \\*" # foo does query-read-texts on foo and 10, 11 and 12. Should get results. send "1153 107 6 10 1 0\n" simple_expect "=1153 1 $any_time 10 200 1 { 1 1 } 7 $any_time 10100000" send "1154 107 6 11 1 0\n" simple_expect "=1154 2 $any_time 11 200 1 { 1 1 } 7 $any_time 10100000" send "1155 107 6 12 1 0\n" simple_expect "=1155 3 $any_time 12 200 1 { 1 1 } 7 $any_time 10100000" # # gazonk examines foo. # talk_to client 3 # gazonk does get-unread-confs of foo. Should return the empty list. send "1156 52 6\n" simple_expect "=1156 0 \\*" # gazonk does get-membership-10 of foo. Should return 1 { 6 }. send "1157 99 6 0 100 1\n" simple_expect "=1157 1 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 }" # gazonk does get-membership-old of foo. Should return 1 { 6 11 12 }. send "1158 46 6 0 100 1\n" simple_expect "=1158 1 { $any_time 6 255 0 0 \\* }" # gazonk does get-membership of foo. Should return 1 { 6 }. send "1159 108 6 0 100 1 0\n" simple_expect "=1159 1 { 0 $any_time 6 255 0 \\* 6 $any_time 00000000 }" # gazonk does query-read-texts-10 on foo and 10, 11 and 12. All should fail. send "1160 98 6 10\n" simple_expect "%1160 9 10" send "1161 98 6 11\n" simple_expect "%1161 13 11" send "1162 98 6 12\n" simple_expect "%1162 13 12" # gazonk does query-read-texts-old on foo and 10, 11 and 12. All should fail. send "1163 9 6 10\n" simple_expect "%1163 9 10" send "1164 9 6 11\n" simple_expect "%1164 13 11" send "1165 9 6 12\n" simple_expect "%1165 13 12" # gazonk does query-read-texts on foo and 10, 11 and 12. All should fail. send "1166 107 6 10 1 0\n" simple_expect "%1166 9 10" send "1167 107 6 11 1 0\n" simple_expect "%1167 13 11" send "1168 107 6 12 1 0\n" simple_expect "%1168 13 12" # # gazonk examines bar. # # gazonk does get-unread-confs of bar. Should return undefined-person. send "1169 52 7\n" good_bad_expect "%1169 10 7" "=0 \\*" "Bug 37" # gazonk does get-membership-10 of bar. Should return undefined-person. send "1170 99 7 0 100 1\n" simple_expect "%1170 10 7" # gazonk does get-membership-old of bar. Should return undefined-person. send "1171 46 7 0 100 1\n" simple_expect "%1171 10 7" # gazonk does get-membership of bar. Should return undefined-person. send "1172 108 7 0 100 1 0\n" simple_expect "%1172 10 7" # gazonk does query-read-texts-10 on bar and 10, 11 and 12. undefined-person. send "1173 98 7 10\n" simple_expect "%1173 10 7" send "1174 98 7 11\n" simple_expect "%1174 10 7" send "1175 98 7 12\n" simple_expect "%1175 10 7" # gazonk does query-read-texts-old on bar and 10, 11 and 12. undefined-person. send "1176 9 7 10\n" simple_expect "%1176 10 7" send "1177 9 7 11\n" simple_expect "%1177 10 7" send "1178 9 7 12\n" simple_expect "%1178 10 7" # gazonk does query-read-texts on bar and 10, 11 and 12. undefined-person. send "1179 107 7 10 1 0\n" simple_expect "%1179 10 7" send "1180 107 7 11 1 0\n" simple_expect "%1180 10 7" send "1181 107 7 12 1 0\n" simple_expect "%1181 10 7" # # gazonk examines citrus. # # gazonk does get-unread-confs of citrus. Should return the empty list. send "1182 52 8\n" simple_expect "=1182 0 \\*" # gazonk does get-membership-10 of citrus. Should return 1 { 6 }. send "1183 99 8 0 100 1\n" simple_expect "=1183 1 { 0 $any_time 8 255 0 0 \\* 8 $any_time 00000000 }" # gazonk does get-membership-old of citrus. Should return 1 { 6 }. send "1184 46 8 0 100 1\n" simple_expect "=1184 1 { $any_time 8 255 0 0 \\* }" # gazonk does get-membership of citrus. Should return 1 { 6 }. send "1185 108 8 0 100 1 0\n" simple_expect "=1185 1 { 0 $any_time 8 255 0 \\* 8 $any_time 00000000 }" # gazonk does query-read-texts-10 on citrus and 10, 11 and 12. All should fail. send "1186 98 8 10\n" simple_expect "%1186 9 10" send "1187 98 8 11\n" simple_expect "%1187 13 11" send "1188 98 8 12\n" simple_expect "%1188 13 12" # gazonk does query-read-texts-old on citrus and 10, 11 and 12. All fails. send "1189 9 8 10\n" simple_expect "%1189 9 10" send "1190 9 8 11\n" simple_expect "%1190 13 11" send "1191 9 8 12\n" simple_expect "%1191 13 12" # gazonk does query-read-texts on citrus and 10, 11 and 12. All should fail. send "1192 107 8 10 1 0\n" simple_expect "%1192 9 10" send "1193 107 8 11 1 0\n" simple_expect "%1193 13 11" send "1194 107 8 12 1 0\n" simple_expect "%1194 13 12" # # gazonk examines the conferences # # Test get-members-old send "1195 48 10 0 100\n" simple_expect "%1195 9 10" send "1196 48 11 0 100\n" simple_expect "=1196 3 { 0 0 0 }" send "1197 48 12 0 100\n" simple_expect "=1197 3 { 0 0 0 }" # Test get-members. send "1198 101 10 0 100\n" simple_expect "%1198 9 10" send "1199 101 11 0 100\n" simple_expect "=1199 3 { 0 0 $any_time 00100000 0 0 $any_time 00100000 0 0 $any_time 00100000 }" send "1200 101 12 0 100\n" simple_expect "=1200 3 { 0 0 $any_time 00100000 0 0 $any_time 00100000 0 0 $any_time 00100000 }" # Shut down. talk_to client 3 send "1201 0 5 [holl "gazonk"]\n" simple_expect "=1201" send "1202 42 255\n" simple_expect "=1202" send "1203 44 0\n" simple_expect "=1203" client_death 3 client_death 2 client_death 1 client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/bug-37-3.exp0000664000015100472110000007415207721716134017666 # Test suite for lyskomd. # Copyright (C) 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test bug 37: get_unread_confs does not check that the caller is # allowed to see the person, and returns the correct result even for # secret persons, including secret confs! # # Variant three: the observer is supervisor of all conferences. # # We also check get-membership, get-membership-10, get-membership-old, # query-read-texts, query-read-texts-10, and query-read-texts-old. # # While we are at it, we also test the unread-is-secret personal flag. # # Startup and create the players # # Start the server. lyskomd_start # Create and log in as foo (person 6). client_start 0 send "A3Hfoo\n" simple_expect "LysKOM" send "1000 80 0 { }\n" simple_expect "=1000" send "1001 89 [holl "foo"] [holl "p6"] 00000000 0 { }\n" simple_expect "=1001 6" send "1002 62 6 [holl "p6"] 0\n" simple_expect "=1002" # Create and log in as bar (person 7; secret). client_start 1 send "A3Hbar\n" simple_expect "LysKOM" send "1003 80 0 { }\n" simple_expect "=1003" send "1004 89 [holl "bar"] [holl "p7"] 00000000 0 { }\n" simple_expect "=1004 7" send "1005 62 7 [holl "p7"] 0\n" simple_expect "=1005" send "1006 21 7 10111000\n" simple_expect "=1006" # Create and log in as citrus (person 8; has unread-is-secret set). client_start 2 send "A6Hcitrus\n" simple_expect "LysKOM" send "1007 80 0 { }\n" simple_expect "=1007" send "1008 89 [holl "citrus"] [holl "p8"] 10000000 0 { }\n" simple_expect "=1008 8" send "1009 62 8 [holl "p8"] 0\n" simple_expect "=1009" # Create and log in as gazonk (person 9). This is the observer. client_start 3 send "A6Hgazonk\n" simple_expect "LysKOM" send "1010 80 0 { }\n" simple_expect "=1010" send "1011 89 [holl "gazonk"] [holl "p9"] 00000000 0 { }\n" simple_expect "=1011 9" send "1012 62 9 [holl "p9"] 0\n" simple_expect "=1012" # # Create conferences. # # As gazonk, create secret (conf 10; secret). talk_to client 3 send "1013 88 [holl "secret"] 10101000 0 { }\n" simple_expect "=1013 10" # As gazonk, create rd-prot (conf 11; rd-prot). send "1014 88 [holl "rd-prot"] 10001000 0 { }\n" simple_expect "=1014 11" # As gazonk, create public (conf 12). send "1015 88 [holl "public"] 00001000 0 { }\n" simple_expect "=1015 12" # # Join conferences # # gazonk invites bar to secret, rd-prot and public. send "1016 100 10 7 200 1 00000000\n" lyskomd_expect "Person 7 added to conference 10 by 9." simple_expect "=1016" send "1017 100 11 7 200 2 00000000\n" lyskomd_expect "Person 7 added to conference 11 by 9." simple_expect "=1017" send "1018 100 12 7 200 3 00000000\n" lyskomd_expect "Person 7 added to conference 12 by 9." simple_expect "=1018" # bar is secret, so gazonk should not be able to do the above. # When bug 604 is fixed, this test should be rewritten so that # bar is temporarily made public while being invited. setup_xfail "*-*-*" "Bug 604" fail "bar could add a secret person to a conference" # gazonk invites foo to secret, rd-prot and public. send "1019 100 10 6 200 1 00000000\n" lyskomd_expect "Person 6 added to conference 10 by 9." simple_expect "=1019" send "1020 100 11 6 200 2 00000000\n" lyskomd_expect "Person 6 added to conference 11 by 9." simple_expect "=1020" send "1021 100 12 6 200 3 00000000\n" lyskomd_expect "Person 6 added to conference 12 by 9." simple_expect "=1021" # gazonk invites citrus to secret, rd-prot and public. send "1022 100 10 8 200 1 00000000\n" lyskomd_expect "Person 8 added to conference 10 by 9." simple_expect "=1022" send "1023 100 11 8 200 2 00000000\n" lyskomd_expect "Person 8 added to conference 11 by 9." simple_expect "=1023" send "1024 100 12 8 200 3 00000000\n" lyskomd_expect "Person 8 added to conference 12 by 9." simple_expect "=1024" # # foo examines foo. # talk_to client 0 # foo does get-unread-confs of foo. Should return the empty list. send "1025 52 6\n" simple_expect "=1025 0 \\*" # foo does get-membership-10 of foo. Should return 4 { 6 10 11 12 }. send "1026 99 6 0 100 1\n" simple_expect "=1026 4 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 10 200 0 0 \\* 9 $any_time 10000000 2 $any_time 11 200 0 0 \\* 9 $any_time 10000000 3 $any_time 12 200 0 0 \\* 9 $any_time 10000000 }" # foo does get-membership-old of foo. Should return 4 { 6 10 11 12 }. send "1027 46 6 0 100 1\n" simple_expect "=1027 4 { $any_time 6 255 0 0 \\* $any_time 10 200 0 0 \\* $any_time 11 200 0 0 \\* $any_time 12 200 0 0 \\* }" # foo does get-membership of foo. Should return 4 { 6 10 11 12 }. send "1028 108 6 0 100 1 0\n" simple_expect "=1028 4 { 0 $any_time 6 255 0 \\* 6 $any_time 00000000 1 $any_time 10 200 0 \\* 9 $any_time 10000000 2 $any_time 11 200 0 \\* 9 $any_time 10000000 3 $any_time 12 200 0 \\* 9 $any_time 10000000 }" # foo does query-read-texts-10 on foo and 10, 11 and 12. Should get results. send "1029 98 6 10\n" simple_expect "=1029 1 $any_time 10 200 0 0 \\* 9 $any_time 10000000" send "1030 98 6 11\n" simple_expect "=1030 2 $any_time 11 200 0 0 \\* 9 $any_time 10000000" send "1031 98 6 12\n" simple_expect "=1031 3 $any_time 12 200 0 0 \\* 9 $any_time 10000000" # foo does query-read-texts-old on foo and 10, 11 and 12. Should get results. send "1032 9 6 10\n" simple_expect "=1032 $any_time 10 200 0 0 \\*" send "1033 9 6 11\n" simple_expect "=1033 $any_time 11 200 0 0 \\*" send "1034 9 6 12\n" simple_expect "=1034 $any_time 12 200 0 0 \\*" # foo does query-read-texts on foo and 10, 11 and 12. Should get results. send "1035 107 6 10 1 0\n" simple_expect "=1035 1 $any_time 10 200 0 \\* 9 $any_time 10000000" send "1036 107 6 11 1 0\n" simple_expect "=1036 2 $any_time 11 200 0 \\* 9 $any_time 10000000" send "1037 107 6 12 1 0\n" simple_expect "=1037 3 $any_time 12 200 0 \\* 9 $any_time 10000000" # # gazonk examines foo. # talk_to client 3 # gazonk does get-unread-confs of foo. Should return the empty list. send "1038 52 6\n" simple_expect "=1038 0 \\*" # gazonk does get-membership-10 of foo. Should return 4 { 6 10 11 12 }. send "1039 99 6 0 100 1\n" simple_expect "=1039 4 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 10 200 0 0 \\* 9 $any_time 10000000 2 $any_time 11 200 0 0 \\* 9 $any_time 10000000 3 $any_time 12 200 0 0 \\* 9 $any_time 10000000 }" # (Just a quick check: does the renumber work properly even if we don't # start from the beginning of the list?) (Hmm. No renumber in this # variant. Oh well.) send "1040 99 6 2 100 1\n" simple_expect "=1040 2 { 2 $any_time 11 200 0 0 \\* 9 $any_time 10000000 3 $any_time 12 200 0 0 \\* 9 $any_time 10000000 }" # gazonk does get-membership-old of foo. Should return 4 { 6 10 11 12 }. send "1041 46 6 0 100 1\n" simple_expect "=1041 4 { $any_time 6 255 0 0 \\* $any_time 10 200 0 0 \\* $any_time 11 200 0 0 \\* $any_time 12 200 0 0 \\* }" # gazonk does get-membership of foo. Should return 4 { 6 10 11 12 }. send "1042 108 6 0 100 1 0\n" simple_expect "=1042 4 { 0 $any_time 6 255 0 \\* 6 $any_time 00000000 1 $any_time 10 200 0 \\* 9 $any_time 10000000 2 $any_time 11 200 0 \\* 9 $any_time 10000000 3 $any_time 12 200 0 \\* 9 $any_time 10000000 }" # (Just a quick check: does the renumber work properly even if we don't # start from the beginning of the list?) (Hmm. No renumber in this # variant. Oh well.) send "1043 108 6 2 100 1 0\n" simple_expect "=1043 2 { 2 $any_time 11 200 0 \\* 9 $any_time 10000000 3 $any_time 12 200 0 \\* 9 $any_time 10000000 }" # gazonk does query-read-texts-10 on foo and 10, 11 and 12. send "1044 98 6 10\n" simple_expect "=1044 1 $any_time 10 200 0 0 \\* 9 $any_time 10000000" send "1045 98 6 11\n" simple_expect "=1045 2 $any_time 11 200 0 0 \\* 9 $any_time 10000000" send "1046 98 6 12\n" simple_expect "=1046 3 $any_time 12 200 0 0 \\* 9 $any_time 10000000" # gazonk does query-read-texts-old on foo and 10, 11 and 12. send "1047 9 6 10\n" simple_expect "=1047 $any_time 10 200 0 0 \\*" send "1048 9 6 11\n" simple_expect "=1048 $any_time 11 200 0 0 \\*" send "1049 9 6 12\n" simple_expect "=1049 $any_time 12 200 0 0 \\*" # gazonk does query-read-texts on foo and 10, 11 and 12. send "1050 107 6 10 1 0\n" simple_expect "=1050 1 $any_time 10 200 0 \\* 9 $any_time 10000000" send "1051 107 6 11 1 0\n" simple_expect "=1051 2 $any_time 11 200 0 \\* 9 $any_time 10000000" send "1052 107 6 12 1 0\n" simple_expect "=1052 3 $any_time 12 200 0 \\* 9 $any_time 10000000" # # gazonk examines bar. # # gazonk does get-unread-confs of bar. Should return undefined-person. send "1053 52 7\n" good_bad_expect "%1053 10 7" "=0 \\*" "Bug 37" # gazonk does get-membership-10 of bar. Should return undefined-person. send "1054 99 7 0 100 1\n" simple_expect "%1054 10 7" # gazonk does get-membership-old of bar. Should return undefined-person. send "1055 46 7 0 100 1\n" simple_expect "%1055 10 7" # gazonk does get-membership of bar. Should return undefined-person. send "1056 108 7 0 100 1 0\n" simple_expect "%1056 10 7" # gazonk does query-read-texts-10 on bar and 10, 11 and 12. undefined-person. # FIXME (bug 703): This should not be censored. But see Bug 70... setup_xfail "*-*-*" "Bug 703" fail "query-read-texts-10 returns info about secret persons to admin of conf" send "1057 98 7 10\n" simple_expect "%1057 10 7" send "1058 98 7 11\n" simple_expect "%1058 10 7" send "1059 98 7 12\n" simple_expect "%1059 10 7" # gazonk does query-read-texts-old on bar and 10, 11 and 12. undefined-person. # FIXME (bug 703): This should not be censored. But see Bug 70... setup_xfail "*-*-*" "Bug 703" fail "query-read-texts-old returns info about secret persons to admin of conf" send "1060 9 7 10\n" simple_expect "%1060 10 7" send "1061 9 7 11\n" simple_expect "%1061 10 7" send "1062 9 7 12\n" simple_expect "%1062 10 7" # gazonk does query-read-texts on bar and 10, 11 and 12. undefined-person. # FIXME (bug 703): This should not be censored. But see Bug 70... setup_xfail "*-*-*" "Bug 703" fail "query-read-texts returns info about secret persons to admin of conf" send "1063 107 7 10 1 0\n" simple_expect "%1063 10 7" send "1064 107 7 11 1 0\n" simple_expect "%1064 10 7" send "1065 107 7 12 1 0\n" simple_expect "%1065 10 7" # # gazonk examines citrus. # # gazonk does get-unread-confs of citrus. Should return the empty list. send "1066 52 8\n" simple_expect "=1066 0 \\*" # gazonk does get-membership-10 of citrus. Should return 4 { 6 10 11 12 }. send "1067 99 8 0 100 1\n" simple_expect "=1067 4 { 0 $any_time 8 255 0 0 \\* 8 $any_time 00000000 1 $any_time 10 200 0 0 \\* 9 $any_time 10000000 2 $any_time 11 200 0 0 \\* 9 $any_time 10000000 3 $any_time 12 200 0 0 \\* 9 $any_time 10000000 }" # gazonk does get-membership-old of citrus. Should return 4 { 6 10 11 12 }. send "1068 46 8 0 100 1\n" simple_expect "=1068 4 { $any_time 8 255 0 0 \\* $any_time 10 200 0 0 \\* $any_time 11 200 0 0 \\* $any_time 12 200 0 0 \\* }" # gazonk does get-membership of citrus. Should return 4 { 6 10 11 12 }. send "1069 108 8 0 100 1 0\n" simple_expect "=1069 4 { 0 $any_time 8 255 0 \\* 8 $any_time 00000000 1 $any_time 10 200 0 \\* 9 $any_time 10000000 2 $any_time 11 200 0 \\* 9 $any_time 10000000 3 $any_time 12 200 0 \\* 9 $any_time 10000000 }" # gazonk does query-read-texts-10 on citrus and 10, 11 and 12. send "1070 98 8 10\n" simple_expect "=1070 1 $any_time 10 200 0 0 \\* 9 $any_time 10000000" send "1071 98 8 11\n" simple_expect "=1071 2 $any_time 11 200 0 0 \\* 9 $any_time 10000000" send "1072 98 8 12\n" simple_expect "=1072 3 $any_time 12 200 0 0 \\* 9 $any_time 10000000" # gazonk does query-read-texts-old on citrus and 10, 11 and 12. send "1073 9 8 10\n" simple_expect "=1073 $any_time 10 200 0 0 \\*" send "1074 9 8 11\n" simple_expect "=1074 $any_time 11 200 0 0 \\*" send "1075 9 8 12\n" simple_expect "=1075 $any_time 12 200 0 0 \\*" # gazonk does query-read-texts on citrus and 10, 11 and 12. send "1076 107 8 10 1 0\n" simple_expect "=1076 1 $any_time 10 200 0 \\* 9 $any_time 10000000" send "1077 107 8 11 1 0\n" simple_expect "=1077 2 $any_time 11 200 0 \\* 9 $any_time 10000000" send "1078 107 8 12 1 0\n" simple_expect "=1078 3 $any_time 12 200 0 \\* 9 $any_time 10000000" # # foo writes a text with secret, rd-prot and public as recipients. # talk_to client 0 send "1079 86 [holl "foo"] 3 { 0 10 0 11 0 12 } 0 { }\n" simple_expect "=1079 1" # # foo examines foo # # foo does get-unread-confs of foo. Should return 3 { 10 11 12 }. send "1080 52 6\n" simple_expect "=1080 3 { 10 11 12 }" # foo does get-membership-10 of foo. Should return 4 { 6 10 11 12 }. send "1081 99 6 0 100 1\n" simple_expect "=1081 4 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 10 200 0 0 \\* 9 $any_time 10000000 2 $any_time 11 200 0 0 \\* 9 $any_time 10000000 3 $any_time 12 200 0 0 \\* 9 $any_time 10000000 }" # foo does get-membership-old of foo. Should return 4 { 6 10 11 12 }. send "1082 46 6 0 100 1\n" simple_expect "=1082 4 { $any_time 6 255 0 0 \\* $any_time 10 200 0 0 \\* $any_time 11 200 0 0 \\* $any_time 12 200 0 0 \\* }" # foo does get-membership of foo. Should return 4 { 6 10 11 12 }. send "1083 108 6 0 100 1 0\n" simple_expect "=1083 4 { 0 $any_time 6 255 0 \\* 6 $any_time 00000000 1 $any_time 10 200 0 \\* 9 $any_time 10000000 2 $any_time 11 200 0 \\* 9 $any_time 10000000 3 $any_time 12 200 0 \\* 9 $any_time 10000000 }" # foo does query-read-texts-10 on foo and 10, 11 and 12. Should get results. send "1084 98 6 10\n" simple_expect "=1084 1 $any_time 10 200 0 0 \\* 9 $any_time 10000000" send "1085 98 6 11\n" simple_expect "=1085 2 $any_time 11 200 0 0 \\* 9 $any_time 10000000" send "1086 98 6 12\n" simple_expect "=1086 3 $any_time 12 200 0 0 \\* 9 $any_time 10000000" # foo does query-read-texts-old on foo and 10, 11 and 12. Should get results. send "1087 9 6 10\n" simple_expect "=1087 $any_time 10 200 0 0 \\*" send "1088 9 6 11\n" simple_expect "=1088 $any_time 11 200 0 0 \\*" send "1089 9 6 12\n" simple_expect "=1089 $any_time 12 200 0 0 \\*" # foo does query-read-texts on foo and 10, 11 and 12. Should get results. send "1090 107 6 10 1 0\n" simple_expect "=1090 1 $any_time 10 200 0 \\* 9 $any_time 10000000" send "1091 107 6 11 1 0\n" simple_expect "=1091 2 $any_time 11 200 0 \\* 9 $any_time 10000000" send "1092 107 6 12 1 0\n" simple_expect "=1092 3 $any_time 12 200 0 \\* 9 $any_time 10000000" # # gazonk examines foo. # talk_to client 3 # gazonk does get-unread-confs of foo. Should return 3 { 10 11 12 }. send "1093 52 6\n" # "Bug 596" good_bad_expect "=1093 3 { 10 11 12 }" "=1 { 12 }" # gazonk does get-membership-10 of foo. Should return 4 { 6 10 11 12 }. send "1094 99 6 0 100 1\n" simple_expect "=1094 4 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 10 200 0 0 \\* 9 $any_time 10000000 2 $any_time 11 200 0 0 \\* 9 $any_time 10000000 3 $any_time 12 200 0 0 \\* 9 $any_time 10000000 }" # This is a totally pointless test of renumber--no renumbering here! send "1095 99 6 3 100 1\n" simple_expect "=1095 1 { 3 $any_time 12 200 0 0 \\* 9 $any_time 10000000 }" # gazonk does get-membership-old of foo. Should return 4 { 6 10 11 12 }. send "1096 46 6 0 100 1\n" simple_expect "=1096 4 { $any_time 6 255 0 0 \\* $any_time 10 200 0 0 \\* $any_time 11 200 0 0 \\* $any_time 12 200 0 0 \\* }" # gazonk does get-membership of foo. Should return 4 { 6 10 11 12 }. send "1097 108 6 0 100 1 0\n" simple_expect "=1097 4 { 0 $any_time 6 255 0 \\* 6 $any_time 00000000 1 $any_time 10 200 0 \\* 9 $any_time 10000000 2 $any_time 11 200 0 \\* 9 $any_time 10000000 3 $any_time 12 200 0 \\* 9 $any_time 10000000 }" # This is a totally pointless test of renumber--no renumbering here! send "1098 108 6 3 100 1 0\n" simple_expect "=1098 1 { 3 $any_time 12 200 0 \\* 9 $any_time 10000000 }" # gazonk does query-read-texts-10 on foo and 10, 11 and 12. send "1099 98 6 10\n" simple_expect "=1099 1 $any_time 10 200 0 0 \\* 9 $any_time 10000000" send "1100 98 6 11\n" simple_expect "=1100 2 $any_time 11 200 0 0 \\* 9 $any_time 10000000" send "1101 98 6 12\n" simple_expect "=1101 3 $any_time 12 200 0 0 \\* 9 $any_time 10000000" # gazonk does query-read-texts-old on foo and 10, 11 and 12. send "1102 9 6 10\n" simple_expect "=1102 $any_time 10 200 0 0 \\*" send "1103 9 6 11\n" simple_expect "=1103 $any_time 11 200 0 0 \\*" send "1104 9 6 12\n" simple_expect "=1104 $any_time 12 200 0 0 \\*" # gazonk does query-read-texts on foo and 10, 11 and 12. send "1105 107 6 10 1 0\n" simple_expect "=1105 1 $any_time 10 200 0 \\* 9 $any_time 10000000" send "1106 107 6 11 1 0\n" simple_expect "=1106 2 $any_time 11 200 0 \\* 9 $any_time 10000000" send "1107 107 6 12 1 0\n" simple_expect "=1107 3 $any_time 12 200 0 \\* 9 $any_time 10000000" # # gazonk examines bar # # gazonk does get-unread-confs of bar. Should return undefined-person. send "1108 52 7\n" good_bad_expect "%1108 10 7" "=3 { 10 11 12 }" "Bug 37" # gazonk does get-membership-10 of bar. Should return undefined-person. send "1109 99 7 0 100 1\n" simple_expect "%1109 10 7" # gazonk does get-membership-old of bar. Should return undefined-person. send "1110 46 7 0 100 1\n" simple_expect "%1110 10 7" # gazonk does get-membership of bar. Should return undefined-person. send "1111 108 7 0 100 1 0\n" simple_expect "%1111 10 7" # gazonk does query-read-texts-10 on bar and 10, 11 and 12. undefined-person. # FIXME (bug 703): This should not be censored. But see Bug 70... setup_xfail "*-*-*" "Bug 703" fail "query-read-texts returns info about secret persons to admin of conf" send "1112 98 7 10\n" simple_expect "%1112 10 7" send "1113 98 7 11\n" simple_expect "%1113 10 7" send "1114 98 7 12\n" simple_expect "%1114 10 7" # gazonk does query-read-texts-old on bar and 10, 11 and 12. undefined-person. # FIXME (bug 703): This should not be censored. But see Bug 70... setup_xfail "*-*-*" "Bug 703" fail "query-read-texts-old returns info about secret persons to admin of conf" send "1115 9 7 10\n" simple_expect "%1115 10 7" send "1116 9 7 11\n" simple_expect "%1116 10 7" send "1117 9 7 12\n" simple_expect "%1117 10 7" # gazonk does query-read-texts on bar and 10, 11 and 12. undefined-person. # FIXME (bug 703): This should not be censored. But see Bug 70... setup_xfail "*-*-*" "Bug 703" fail "query-read-texts returns info about secret persons to admin of conf" send "1118 107 7 10 1 0\n" simple_expect "%1118 10 7" send "1119 107 7 11 1 0\n" simple_expect "%1119 10 7" send "1120 107 7 12 1 0\n" simple_expect "%1120 10 7" # # gazonk examines citrus. # # gazonk does get-unread-confs of citrus. Should return the empty list. send "1121 52 8\n" good_bad_expect "=1121 0 \\*" "=3 { 10 11 12 }" "Bug 595" # gazonk does get-membership-10 of citrus. Should return 4 { 6 10 11 12 }. send "1122 99 8 0 100 1\n" simple_expect "=1122 4 { 0 $any_time 8 255 0 0 \\* 8 $any_time 00000000 1 $any_time 10 200 0 0 \\* 9 $any_time 10000000 2 $any_time 11 200 0 0 \\* 9 $any_time 10000000 3 $any_time 12 200 0 0 \\* 9 $any_time 10000000 }" # gazonk does get-membership-old of citrus. Should return 4 { 6 10 11 12 }. send "1123 46 8 0 100 1\n" simple_expect "=1123 4 { $any_time 8 255 0 0 \\* $any_time 10 200 0 0 \\* $any_time 11 200 0 0 \\* $any_time 12 200 0 0 \\* }" # gazonk does get-membership of citrus. Should return 4 { 6 10 11 12 }. send "1124 108 8 0 100 1 0\n" simple_expect "=1124 4 { 0 $any_time 8 255 0 \\* 8 $any_time 00000000 1 $any_time 10 200 0 \\* 9 $any_time 10000000 2 $any_time 11 200 0 \\* 9 $any_time 10000000 3 $any_time 12 200 0 \\* 9 $any_time 10000000 }" # gazonk does query-read-texts-10 on citrus and 10, 11 and 12. send "1125 98 8 10\n" simple_expect "=1125 1 $any_time 10 200 0 0 \\* 9 $any_time 10000000" send "1126 98 8 11\n" simple_expect "=1126 2 $any_time 11 200 0 0 \\* 9 $any_time 10000000" send "1127 98 8 12\n" simple_expect "=1127 3 $any_time 12 200 0 0 \\* 9 $any_time 10000000" # gazonk does query-read-texts-old on citrus and 10, 11 and 12. send "1128 9 8 10\n" simple_expect "=1128 $any_time 10 200 0 0 \\*" send "1129 9 8 11\n" simple_expect "=1129 $any_time 11 200 0 0 \\*" send "1130 9 8 12\n" simple_expect "=1130 $any_time 12 200 0 0 \\*" # gazonk does query-read-texts on citrus and 10, 11 and 12. send "1131 107 8 10 1 0\n" simple_expect "=1131 1 $any_time 10 200 0 \\* 9 $any_time 10000000" send "1132 107 8 11 1 0\n" simple_expect "=1132 2 $any_time 11 200 0 \\* 9 $any_time 10000000" send "1133 107 8 12 1 0\n" simple_expect "=1133 3 $any_time 12 200 0 \\* 9 $any_time 10000000" # # mark as read # # foo marks the text as read talk_to client 0 send "1134 27 10 1 { 1 }\n" simple_expect "=1134" send "1135 27 11 1 { 1 }\n" simple_expect "=1135" send "1136 27 12 1 { 1 }\n" simple_expect "=1136" # bar marks the text as read talk_to client 1 send "1137 27 10 1 { 1 }\n" simple_expect "=1137" send "1138 27 11 1 { 1 }\n" simple_expect "=1138" send "1139 27 12 1 { 1 }\n" simple_expect "=1139" # citrus marks the text as read talk_to client 2 send "1140 27 10 1 { 1 }\n" simple_expect "=1140" send "1141 27 11 1 { 1 }\n" simple_expect "=1141" send "1142 27 12 1 { 1 }\n" simple_expect "=1142" # # foo examines foo. # talk_to client 0 # foo does get-unread-confs of foo. Should return the empty list. send "1143 52 6\n" simple_expect "=1143 0 \\*" # foo does get-membership-10 of foo. Should return 4 { 6 10 11 12 }. send "1144 99 6 0 100 1\n" simple_expect "=1144 4 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 10 200 1 0 \\* 9 $any_time 10000000 2 $any_time 11 200 1 0 \\* 9 $any_time 10000000 3 $any_time 12 200 1 0 \\* 9 $any_time 10000000 }" # foo does get-membership-old of foo. Should return 4 { 6 10 11 12 }. send "1145 46 6 0 100 1\n" simple_expect "=1145 4 { $any_time 6 255 0 0 \\* $any_time 10 200 1 0 \\* $any_time 11 200 1 0 \\* $any_time 12 200 1 0 \\* }" # foo does get-membership of foo. Should return 4 { 6 10 11 12 }. send "1146 108 6 0 100 1 0\n" simple_expect "=1146 4 { 0 $any_time 6 255 0 \\* 6 $any_time 00000000 1 $any_time 10 200 1 { 1 1 } 9 $any_time 10000000 2 $any_time 11 200 1 { 1 1 } 9 $any_time 10000000 3 $any_time 12 200 1 { 1 1 } 9 $any_time 10000000 }" # foo does query-read-texts-10 on foo and 10, 11 and 12. Should get results. send "1147 98 6 10\n" simple_expect "=1147 1 $any_time 10 200 1 0 \\* 9 $any_time 10000000" send "1148 98 6 11\n" simple_expect "=1148 2 $any_time 11 200 1 0 \\* 9 $any_time 10000000" send "1149 98 6 12\n" simple_expect "=1149 3 $any_time 12 200 1 0 \\* 9 $any_time 10000000" # foo does query-read-texts-old on foo and 10, 11 and 12. Should get results. send "1150 9 6 10\n" simple_expect "=1150 $any_time 10 200 1 0 \\*" send "1151 9 6 11\n" simple_expect "=1151 $any_time 11 200 1 0 \\*" send "1152 9 6 12\n" simple_expect "=1152 $any_time 12 200 1 0 \\*" # foo does query-read-texts on foo and 10, 11 and 12. Should get results. send "1153 107 6 10 1 0\n" simple_expect "=1153 1 $any_time 10 200 1 { 1 1 } 9 $any_time 10000000" send "1154 107 6 11 1 0\n" simple_expect "=1154 2 $any_time 11 200 1 { 1 1 } 9 $any_time 10000000" send "1155 107 6 12 1 0\n" simple_expect "=1155 3 $any_time 12 200 1 { 1 1 } 9 $any_time 10000000" # # gazonk examines foo. # talk_to client 3 # gazonk does get-unread-confs of foo. Should return the empty list. send "1156 52 6\n" simple_expect "=1156 0 \\*" # gazonk does get-membership-10 of foo. Should return 4 { 6 10 11 12 }. send "1157 99 6 0 100 1\n" simple_expect "=1157 4 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 10 200 1 0 \\* 9 $any_time 10000000 2 $any_time 11 200 1 0 \\* 9 $any_time 10000000 3 $any_time 12 200 1 0 \\* 9 $any_time 10000000 }" # gazonk does get-membership-old of foo. Should return 4 { 6 10 11 12 }. send "1158 46 6 0 100 1\n" simple_expect "=1158 4 { $any_time 6 255 0 0 \\* $any_time 10 200 1 0 \\* $any_time 11 200 1 0 \\* $any_time 12 200 1 0 \\* }" # gazonk does get-membership of foo. Should return 4 { 6 10 11 12 }. send "1159 108 6 0 100 1 0\n" simple_expect "=1159 4 { 0 $any_time 6 255 0 \\* 6 $any_time 00000000 1 $any_time 10 200 1 { 1 1 } 9 $any_time 10000000 2 $any_time 11 200 1 { 1 1 } 9 $any_time 10000000 3 $any_time 12 200 1 { 1 1 } 9 $any_time 10000000 }" # gazonk does query-read-texts-10 on foo and 10, 11 and 12. send "1160 98 6 10\n" simple_expect "=1160 1 $any_time 10 200 1 0 \\* 9 $any_time 10000000" send "1161 98 6 11\n" simple_expect "=1161 2 $any_time 11 200 1 0 \\* 9 $any_time 10000000" send "1162 98 6 12\n" simple_expect "=1162 3 $any_time 12 200 1 0 \\* 9 $any_time 10000000" # gazonk does query-read-texts-old on foo and 10, 11 and 12. send "1163 9 6 10\n" simple_expect "=1163 $any_time 10 200 1 0 \\*" send "1164 9 6 11\n" simple_expect "=1164 $any_time 11 200 1 0 \\*" send "1165 9 6 12\n" simple_expect "=1165 $any_time 12 200 1 0 \\*" # gazonk does query-read-texts on foo and 10, 11 and 12. send "1166 107 6 10 1 0\n" simple_expect "=1166 1 $any_time 10 200 1 { 1 1 } 9 $any_time 10000000" send "1167 107 6 11 1 0\n" simple_expect "=1167 2 $any_time 11 200 1 { 1 1 } 9 $any_time 10000000" send "1168 107 6 12 1 0\n" simple_expect "=1168 3 $any_time 12 200 1 { 1 1 } 9 $any_time 10000000" # gazonk does on foo and 10, 11 and 12. Should work. # # gazonk examines bar. # # gazonk does get-unread-confs of bar. Should return undefined-person. send "1169 52 7\n" good_bad_expect "%1169 10 7" "=0 \\*" "Bug 37" # gazonk does get-membership-10 of bar. Should return undefined-person. send "1170 99 7 0 100 1\n" simple_expect "%1170 10 7" # gazonk does get-membership-old of bar. Should return undefined-person. send "1171 46 7 0 100 1\n" simple_expect "%1171 10 7" # gazonk does get-membership of bar. Should return undefined-person. send "1172 108 7 0 100 1 0\n" simple_expect "%1172 10 7" # gazonk does query-read-texts-10 on bar and 10, 11 and 12. undefined-person. # FIXME (bug 703): This should not be censored. But see Bug 70... setup_xfail "*-*-*" "Bug 703" fail "query-read-texts-10 returns info about secret persons to admin of conf" send "1173 98 7 10\n" simple_expect "%1173 10 7" send "1174 98 7 11\n" simple_expect "%1174 10 7" send "1175 98 7 12\n" simple_expect "%1175 10 7" # gazonk does query-read-texts-old on bar and 10, 11 and 12. undefined-person. # FIXME (bug 703): This should not be censored. But see Bug 70... setup_xfail "*-*-*" "Bug 703" fail "query-read-texts-old returns info about secret persons to admin of conf" send "1176 9 7 10\n" simple_expect "%1176 10 7" send "1177 9 7 11\n" simple_expect "%1177 10 7" send "1178 9 7 12\n" simple_expect "%1178 10 7" # gazonk does query-read-texts on bar and 10, 11 and 12. undefined-person. # FIXME (bug 703): This should not be censored. But see Bug 70... setup_xfail "*-*-*" "Bug 703" fail "query-read-texts returns info about secret persons to admin of conf" send "1179 107 7 10 1 0\n" simple_expect "%1179 10 7" send "1180 107 7 11 1 0\n" simple_expect "%1180 10 7" send "1181 107 7 12 1 0\n" simple_expect "%1181 10 7" # FIXME (bug 704): Now, set unread-is-secret for bar, and let gazonk # redo the query-read-texts-10, query-read-texts-old, and # query-read-texts requests. Check that unread-is-secret is # respected. Then change unread-is-secret back. # # gazonk examines citrus. # # gazonk does get-unread-confs of citrus. Should return the empty list. send "1182 52 8\n" simple_expect "=1182 0 \\*" # gazonk does get-membership-10 of citrus. Should return 4 { 6 10 11 12 }. send "1183 99 8 0 100 1\n" simple_expect "=1183 4 { 0 $any_time 8 255 0 0 \\* 8 $any_time 00000000 1 $any_time 10 200 0 0 \\* 9 $any_time 10000000 2 $any_time 11 200 0 0 \\* 9 $any_time 10000000 3 $any_time 12 200 0 0 \\* 9 $any_time 10000000 }" # gazonk does get-membership-old of citrus. Should return 4 { 6 10 11 12 }. send "1184 46 8 0 100 1\n" simple_expect "=1184 4 { $any_time 8 255 0 0 \\* $any_time 10 200 0 0 \\* $any_time 11 200 0 0 \\* $any_time 12 200 0 0 \\* }" # gazonk does get-membership of citrus. Should return 4 { 6 10 11 12 }. send "1185 108 8 0 100 1 0\n" simple_expect "=1185 4 { 0 $any_time 8 255 0 \\* 8 $any_time 00000000 1 $any_time 10 200 0 \\* 9 $any_time 10000000 2 $any_time 11 200 0 \\* 9 $any_time 10000000 3 $any_time 12 200 0 \\* 9 $any_time 10000000 }" # gazonk does query-read-texts-10 on citrus and 10, 11 and 12. send "1186 98 8 10\n" simple_expect "=1186 1 $any_time 10 200 0 0 \\* 9 $any_time 10000000" send "1187 98 8 11\n" simple_expect "=1187 2 $any_time 11 200 0 0 \\* 9 $any_time 10000000" send "1188 98 8 12\n" simple_expect "=1188 3 $any_time 12 200 0 0 \\* 9 $any_time 10000000" # gazonk does query-read-texts-old on citrus and 10, 11 and 12. send "1189 9 8 10\n" simple_expect "=1189 $any_time 10 200 0 0 \\*" send "1190 9 8 11\n" simple_expect "=1190 $any_time 11 200 0 0 \\*" send "1191 9 8 12\n" simple_expect "=1191 $any_time 12 200 0 0 \\*" # gazonk does query-read-texts on citrus and 10, 11 and 12. send "1192 107 8 10 1 0\n" simple_expect "=1192 1 $any_time 10 200 0 \\* 9 $any_time 10000000" send "1193 107 8 11 1 0\n" simple_expect "=1193 2 $any_time 11 200 0 \\* 9 $any_time 10000000" send "1194 107 8 12 1 0\n" simple_expect "=1194 3 $any_time 12 200 0 \\* 9 $any_time 10000000" # # gazonk examines the conferences # # Test get-members-old send "1195 48 10 0 100\n" simple_expect "=1195 3 { 7 6 8 }" send "1196 48 11 0 100\n" simple_expect "=1196 3 { 7 6 8 }" send "1197 48 12 0 100\n" simple_expect "=1197 3 { 7 6 8 }" # Test get-members. send "1198 101 10 0 100\n" simple_expect "=1198 3 { 7 9 $any_time 10000000 6 9 $any_time 10000000 8 9 $any_time 10000000 }" send "1199 101 11 0 100\n" simple_expect "=1199 3 { 7 9 $any_time 10000000 6 9 $any_time 10000000 8 9 $any_time 10000000 }" send "1200 101 12 0 100\n" simple_expect "=1200 3 { 7 9 $any_time 10000000 6 9 $any_time 10000000 8 9 $any_time 10000000 }" # Shut down. talk_to client 3 send "1201 0 5 [holl "gazonk"]\n" simple_expect "=1201" send "1202 42 255\n" simple_expect "=1202" send "1203 44 0\n" simple_expect "=1203" client_death 3 client_death 2 client_death 1 client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/bug-37-4.exp0000664000015100472110000007323607721716134017671 # Test suite for lyskomd. # Copyright (C) 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test bug 37: get_unread_confs does not check that the caller is # allowed to see the person, and returns the correct result even for # secret persons, including secret confs! # # Variant four: the observer is supervisor of all conferences, and all # memberships are secret. # # We also check get-membership, get-membership-10, get-membership-old, # query-read-texts, query-read-texts-10 and query-read-texts-old. # # While we are at it, we also test the unread-is-secret personal flag. proc check_pos {actual wanted} { global test set test "Correct position of membership returned" setup_xfail "*-*-*" "Bug 594" if {$actual == $wanted} { pass "$test" } else { fail "$test (got pos $actual instead of $wanted)" } unset test } # # Startup and create the players # # Start the server. lyskomd_start # Create and log in as foo (person 6). client_start 0 send "A3Hfoo\n" simple_expect "LysKOM" send "1000 80 0 { }\n" simple_expect "=1000" send "1001 89 [holl "foo"] [holl "p6"] 00000000 0 { }\n" simple_expect "=1001 6" send "1002 62 6 [holl "p6"] 0\n" simple_expect "=1002" # Create and log in as bar (person 7; secret). client_start 1 send "A3Hbar\n" simple_expect "LysKOM" send "1003 80 0 { }\n" simple_expect "=1003" send "1004 89 [holl "bar"] [holl "p7"] 00000000 0 { }\n" simple_expect "=1004 7" send "1005 62 7 [holl "p7"] 0\n" simple_expect "=1005" send "1006 21 7 10111000\n" simple_expect "=1006" # Create and log in as citrus (person 8; has unread-is-secret set). client_start 2 send "A6Hcitrus\n" simple_expect "LysKOM" send "1007 80 0 { }\n" simple_expect "=1007" send "1008 89 [holl "citrus"] [holl "p8"] 10000000 0 { }\n" simple_expect "=1008 8" send "1009 62 8 [holl "p8"] 0\n" simple_expect "=1009" # Create and log in as gazonk (person 9). This is the observer. client_start 3 send "A6Hgazonk\n" simple_expect "LysKOM" send "1010 80 0 { }\n" simple_expect "=1010" send "1011 89 [holl "gazonk"] [holl "p9"] 00000000 0 { }\n" simple_expect "=1011 9" send "1012 62 9 [holl "p9"] 0\n" simple_expect "=1012" # # Create conferences. # # As gazonk, create secret (conf 10; secret). talk_to client 3 send "1013 88 [holl "secret"] 10101000 0 { }\n" simple_expect "=1013 10" # As gazonk, create rd-prot (conf 11; rd-prot). send "1014 88 [holl "rd-prot"] 10001000 0 { }\n" simple_expect "=1014 11" # As gazonk, create public (conf 12). send "1015 88 [holl "public"] 00001000 0 { }\n" simple_expect "=1015 12" # # Join conferences # # gazonk invites bar to secret, rd-prot and public. send "1016 100 10 7 200 1 00100000\n" lyskomd_expect "Person 7 added to conference 10 by 9." simple_expect "=1016" send "1017 100 11 7 200 2 00100000\n" lyskomd_expect "Person 7 added to conference 11 by 9." simple_expect "=1017" send "1018 100 12 7 200 3 00100000\n" lyskomd_expect "Person 7 added to conference 12 by 9." simple_expect "=1018" # bar is secret, so gazonk should not be able to do the above. # When bug 604 is fixed, this test should be rewritten so that # bar is temporarily made public while being invited. setup_xfail "*-*-*" "Bug 604" fail "bar could add a secret person to a conference" # gazonk invites foo to secret, rd-prot and public. send "1019 100 10 6 200 1 00100000\n" lyskomd_expect "Person 6 added to conference 10 by 9." simple_expect "=1019" send "1020 100 11 6 200 2 00100000\n" lyskomd_expect "Person 6 added to conference 11 by 9." simple_expect "=1020" send "1021 100 12 6 200 3 00100000\n" lyskomd_expect "Person 6 added to conference 12 by 9." simple_expect "=1021" # gazonk invites citrus to secret, rd-prot and public. send "1022 100 10 8 200 1 00100000\n" lyskomd_expect "Person 8 added to conference 10 by 9." simple_expect "=1022" send "1023 100 11 8 200 2 00100000\n" lyskomd_expect "Person 8 added to conference 11 by 9." simple_expect "=1023" send "1024 100 12 8 200 3 00100000\n" lyskomd_expect "Person 8 added to conference 12 by 9." simple_expect "=1024" # # foo examines foo. # talk_to client 0 # foo does get-unread-confs of foo. Should return the empty list. send "1025 52 6\n" simple_expect "=1025 0 \\*" # foo does get-membership-10 of foo. Should return 4 { 6 10 11 12 }. send "1026 99 6 0 100 1\n" simple_expect "=1026 4 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 10 200 0 0 \\* 9 $any_time 10100000 2 $any_time 11 200 0 0 \\* 9 $any_time 10100000 3 $any_time 12 200 0 0 \\* 9 $any_time 10100000 }" # foo does get-membership-old of foo. Should return 4 { 6 10 11 12 }. send "1027 46 6 0 100 1\n" simple_expect "=1027 4 { $any_time 6 255 0 0 \\* $any_time 10 200 0 0 \\* $any_time 11 200 0 0 \\* $any_time 12 200 0 0 \\* }" # foo does get-membership of foo. Should return 4 { 6 10 11 12 }. send "1028 108 6 0 100 1 0\n" simple_expect "=1028 4 { 0 $any_time 6 255 0 \\* 6 $any_time 00000000 1 $any_time 10 200 0 \\* 9 $any_time 10100000 2 $any_time 11 200 0 \\* 9 $any_time 10100000 3 $any_time 12 200 0 \\* 9 $any_time 10100000 }" # foo does query-read-texts-10 on foo and 10, 11 and 12. Should get results. send "1029 98 6 10\n" simple_expect "=1029 1 $any_time 10 200 0 0 \\* 9 $any_time 10100000" send "1030 98 6 11\n" simple_expect "=1030 2 $any_time 11 200 0 0 \\* 9 $any_time 10100000" send "1031 98 6 12\n" simple_expect "=1031 3 $any_time 12 200 0 0 \\* 9 $any_time 10100000" # foo does query-read-texts-old on foo and 10, 11 and 12. Should get results. send "1032 9 6 10\n" simple_expect "=1032 $any_time 10 200 0 0 \\*" send "1033 9 6 11\n" simple_expect "=1033 $any_time 11 200 0 0 \\*" send "1034 9 6 12\n" simple_expect "=1034 $any_time 12 200 0 0 \\*" # foo does query-read-texts on foo and 10, 11 and 12. Should get results. send "1035 107 6 10 1 0\n" simple_expect "=1035 1 $any_time 10 200 0 \\* 9 $any_time 10100000" send "1036 107 6 11 1 0\n" simple_expect "=1036 2 $any_time 11 200 0 \\* 9 $any_time 10100000" send "1037 107 6 12 1 0\n" simple_expect "=1037 3 $any_time 12 200 0 \\* 9 $any_time 10100000" # # gazonk examines foo. # talk_to client 3 # gazonk does get-unread-confs of foo. Should return the empty list. send "1038 52 6\n" simple_expect "=1038 0 \\*" # gazonk does get-membership-10 of foo. Should return 4 { 6 10 11 12 }. send "1039 99 6 0 100 1\n" simple_expect "=1039 4 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 10 200 0 0 \\* 9 $any_time 10100000 2 $any_time 11 200 0 0 \\* 9 $any_time 10100000 3 $any_time 12 200 0 0 \\* 9 $any_time 10100000 }" # gazonk does get-membership-old of foo. Should return 4 { 6 10 11 12 }. send "1040 46 6 0 100 1\n" simple_expect "=1040 4 { $any_time 6 255 0 0 \\* $any_time 10 200 0 0 \\* $any_time 11 200 0 0 \\* $any_time 12 200 0 0 \\* }" # gazonk does get-membership of foo. Should return 4 { 6 10 11 12 }. send "1041 108 6 0 100 1 0\n" simple_expect "=1041 4 { 0 $any_time 6 255 0 \\* 6 $any_time 00000000 1 $any_time 10 200 0 \\* 9 $any_time 10100000 2 $any_time 11 200 0 \\* 9 $any_time 10100000 3 $any_time 12 200 0 \\* 9 $any_time 10100000 }" # gazonk does query-read-texts-10 on foo and 10, 11 and 12. send "1042 98 6 10\n" good_bad_expect "=1042 1 $any_time 10 200 0 0 \\* 9 $any_time 10100000" "%13 10" send "1043 98 6 11\n" good_bad_expect "=1043 2 $any_time 11 200 0 0 \\* 9 $any_time 10100000" "%13 11" send "1044 98 6 12\n" good_bad_expect "=1044 3 $any_time 12 200 0 0 \\* 9 $any_time 10100000" "%13 12" # gazonk does query-read-texts-old on foo and 10, 11 and 12. send "1045 9 6 10\n" good_bad_expect "=1045 $any_time 10 200 0 0 \\*" "%13 10" send "1046 9 6 11\n" good_bad_expect "=1046 $any_time 11 200 0 0 \\*" "%13 11" send "1047 9 6 12\n" good_bad_expect "=1047 $any_time 12 200 0 0 \\*" "%13 12" # gazonk does query-read-texts on foo and 10, 11 and 12. send "1048 107 6 10 1 0\n" good_bad_expect "=1048 1 $any_time 10 200 0 \\* 9 $any_time 10100000" "%13 10" send "1049 107 6 11 1 0\n" good_bad_expect "=1049 2 $any_time 11 200 0 \\* 9 $any_time 10100000" "%13 11" send "1050 107 6 12 1 0\n" good_bad_expect "=1050 3 $any_time 12 200 0 \\* 9 $any_time 10100000" "%13 12" # # gazonk examines bar. # # gazonk does get-unread-confs of bar. Should return undefined-person. send "1051 52 7\n" good_bad_expect "%1051 10 7" "=0 \\*" "Bug 37" # gazonk does get-membership-10 of bar. Should return undefined-person. send "1052 99 7 0 100 1\n" simple_expect "%1052 10 7" # gazonk does get-membership-old of bar. Should return undefined-person. send "1053 46 7 0 100 1\n" simple_expect "%1053 10 7" # gazonk does get-membership of bar. Should return undefined-person. send "1054 108 7 0 100 1 0\n" simple_expect "%1054 10 7" # gazonk does query-read-texts-10 on bar and 10, 11 and 12. undefined-person. # FIXME (bug 703): This should not be censored. But see Bug 70... setup_xfail "*-*-*" "Bug 703" fail "query-read-texts-10 returns info about secret persons to admin of conf" send "1055 98 7 10\n" simple_expect "%1055 10 7" send "1056 98 7 11\n" simple_expect "%1056 10 7" send "1057 98 7 12\n" simple_expect "%1057 10 7" # gazonk does query-read-texts-old on bar and 10, 11 and 12. undefined-person. # FIXME (bug 703): This should not be censored. But see Bug 70... setup_xfail "*-*-*" "Bug 703" fail "query-read-texts-old returns info about secret persons to admin of conf" send "1058 9 7 10\n" simple_expect "%1058 10 7" send "1059 9 7 11\n" simple_expect "%1059 10 7" send "1060 9 7 12\n" simple_expect "%1060 10 7" # gazonk does query-read-texts on bar and 10, 11 and 12. undefined-person. # FIXME (bug 703): This should not be censored. But see Bug 70... setup_xfail "*-*-*" "Bug 703" fail "query-read-texts returns info about secret persons to admin of conf" send "1061 107 7 10 1 0\n" simple_expect "%1061 10 7" send "1062 107 7 11 1 0\n" simple_expect "%1062 10 7" send "1063 107 7 12 1 0\n" simple_expect "%1063 10 7" # # gazonk examines citrus. # # gazonk does get-unread-confs of citrus. Should return the empty list. send "1064 52 8\n" simple_expect "=1064 0 \\*" # gazonk does get-membership-10 of citrus. Should return 4 { 6 10 11 12 }. send "1065 99 8 0 100 1\n" simple_expect "=1065 4 { 0 $any_time 8 255 0 0 \\* 8 $any_time 00000000 1 $any_time 10 200 0 0 \\* 9 $any_time 10100000 2 $any_time 11 200 0 0 \\* 9 $any_time 10100000 3 $any_time 12 200 0 0 \\* 9 $any_time 10100000 }" # gazonk does get-membership-old of citrus. Should return 4 { 6 10 11 12 }. send "1066 46 8 0 100 1\n" simple_expect "=1066 4 { $any_time 8 255 0 0 \\* $any_time 10 200 0 0 \\* $any_time 11 200 0 0 \\* $any_time 12 200 0 0 \\* }" # gazonk does get-membership of citrus. Should return 4 { 6 10 11 12 }. send "1067 108 8 0 100 1 0\n" simple_expect "=1067 4 { 0 $any_time 8 255 0 \\* 8 $any_time 00000000 1 $any_time 10 200 0 \\* 9 $any_time 10100000 2 $any_time 11 200 0 \\* 9 $any_time 10100000 3 $any_time 12 200 0 \\* 9 $any_time 10100000 }" # gazonk does query-read-texts-10 on citrus and 10, 11 and 12. send "1068 98 8 10\n" good_bad_expect "=1068 1 $any_time 10 200 0 0 \\* 9 $any_time 10100000" "%13 10" send "1069 98 8 11\n" good_bad_expect "=1069 2 $any_time 11 200 0 0 \\* 9 $any_time 10100000" "%13 11" send "1070 98 8 12\n" good_bad_expect "=1070 3 $any_time 12 200 0 0 \\* 9 $any_time 10100000" "%13 12" # gazonk does query-read-texts-old on citrus and 10, 11 and 12. send "1071 9 8 10\n" good_bad_expect "=1071 $any_time 10 200 0 0 \\*" "%13 10" send "1072 9 8 11\n" good_bad_expect "=1072 $any_time 11 200 0 0 \\*" "%13 11" send "1073 9 8 12\n" good_bad_expect "=1073 $any_time 12 200 0 0 \\*" "%13 12" # gazonk does query-read-texts on citrus and 10, 11 and 12. send "1074 107 8 10 1 0\n" good_bad_expect "=1074 1 $any_time 10 200 0 \\* 9 $any_time 10100000" "%13 10" send "1075 107 8 11 1 0\n" good_bad_expect "=1075 2 $any_time 11 200 0 \\* 9 $any_time 10100000" "%13 11" send "1076 107 8 12 1 0\n" good_bad_expect "=1076 3 $any_time 12 200 0 \\* 9 $any_time 10100000" "%13 12" # # foo writes a text with secret, rd-prot and public as recipients. # talk_to client 0 send "1077 86 [holl "foo"] 3 { 0 10 0 11 0 12 } 0 { }\n" simple_expect "=1077 1" # # foo examines foo # # foo does get-unread-confs of foo. Should return 3 { 10 11 12 }. send "1078 52 6\n" simple_expect "=1078 3 { 10 11 12 }" # foo does get-membership-10 of foo. Should return 4 { 6 10 11 12 }. send "1079 99 6 0 100 1\n" simple_expect "=1079 4 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 10 200 0 0 \\* 9 $any_time 10100000 2 $any_time 11 200 0 0 \\* 9 $any_time 10100000 3 $any_time 12 200 0 0 \\* 9 $any_time 10100000 }" # foo does get-membership-old of foo. Should return 4 { 6 10 11 12 }. send "1080 46 6 0 100 1\n" simple_expect "=1080 4 { $any_time 6 255 0 0 \\* $any_time 10 200 0 0 \\* $any_time 11 200 0 0 \\* $any_time 12 200 0 0 \\* }" # foo does get-membership of foo. Should return 4 { 6 10 11 12 }. send "1081 108 6 0 100 1 0\n" simple_expect "=1081 4 { 0 $any_time 6 255 0 \\* 6 $any_time 00000000 1 $any_time 10 200 0 \\* 9 $any_time 10100000 2 $any_time 11 200 0 \\* 9 $any_time 10100000 3 $any_time 12 200 0 \\* 9 $any_time 10100000 }" # foo does query-read-texts-10 on foo and 10, 11 and 12. Should get results. send "1082 98 6 10\n" simple_expect "=1082 1 $any_time 10 200 0 0 \\* 9 $any_time 10100000" send "1083 98 6 11\n" simple_expect "=1083 2 $any_time 11 200 0 0 \\* 9 $any_time 10100000" send "1084 98 6 12\n" simple_expect "=1084 3 $any_time 12 200 0 0 \\* 9 $any_time 10100000" # foo does query-read-texts-old on foo and 10, 11 and 12. Should get results. send "1085 9 6 10\n" simple_expect "=1085 $any_time 10 200 0 0 \\*" send "1086 9 6 11\n" simple_expect "=1086 $any_time 11 200 0 0 \\*" send "1087 9 6 12\n" simple_expect "=1087 $any_time 12 200 0 0 \\*" # foo does query-read-texts on foo and 10, 11 and 12. Should get results. send "1088 107 6 10 1 0\n" simple_expect "=1088 1 $any_time 10 200 0 \\* 9 $any_time 10100000" send "1089 107 6 11 1 0\n" simple_expect "=1089 2 $any_time 11 200 0 \\* 9 $any_time 10100000" send "1090 107 6 12 1 0\n" simple_expect "=1090 3 $any_time 12 200 0 \\* 9 $any_time 10100000" # # gazonk examines foo. # talk_to client 3 # gazonk does get-unread-confs of foo. Should return 3 { 10 11 12 }. send "1091 52 6\n" simple_expect "=1091 3 { 10 11 12 }" # gazonk does get-membership-10 of foo. Should return 4 { 6 10 11 12 }. send "1092 99 6 0 100 1\n" simple_expect "=1092 4 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 10 200 0 0 \\* 9 $any_time 10100000 2 $any_time 11 200 0 0 \\* 9 $any_time 10100000 3 $any_time 12 200 0 0 \\* 9 $any_time 10100000 }" # gazonk does get-membership-old of foo. Should return 4 { 6 10 11 12 }. send "1093 46 6 0 100 1\n" simple_expect "=1093 4 { $any_time 6 255 0 0 \\* $any_time 10 200 0 0 \\* $any_time 11 200 0 0 \\* $any_time 12 200 0 0 \\* }" # gazonk does get-membership of foo. Should return 4 { 6 10 11 12 }. send "1094 108 6 0 100 1 0\n" simple_expect "=1094 4 { 0 $any_time 6 255 0 \\* 6 $any_time 00000000 1 $any_time 10 200 0 \\* 9 $any_time 10100000 2 $any_time 11 200 0 \\* 9 $any_time 10100000 3 $any_time 12 200 0 \\* 9 $any_time 10100000 }" # gazonk does query-read-texts-10 on foo and 10, 11 and 12. send "1095 98 6 10\n" good_bad_expect "=1095 1 $any_time 10 200 0 0 \\* 9 $any_time 10100000" "%13 10" send "1096 98 6 11\n" good_bad_expect "=1096 2 $any_time 11 200 0 0 \\* 9 $any_time 10100000" "%13 11" send "1097 98 6 12\n" good_bad_expect "=1097 3 $any_time 12 200 0 0 \\* 9 $any_time 10100000" "%13 12" # gazonk does query-read-texts-old on foo and 10, 11 and 12. send "1098 9 6 10\n" good_bad_expect "=1098 $any_time 10 200 0 0 \\*" "%13 10" send "1099 9 6 11\n" good_bad_expect "=1099 $any_time 11 200 0 0 \\*" "%13 11" send "1100 9 6 12\n" good_bad_expect "=1100 $any_time 12 200 0 0 \\*" "%13 12" # gazonk does query-read-texts on foo and 10, 11 and 12. send "1101 107 6 10 1 0\n" good_bad_expect "=1101 1 $any_time 10 200 0 \\* 9 $any_time 10100000" "%13 10" send "1102 107 6 11 1 0\n" good_bad_expect "=1102 2 $any_time 11 200 0 \\* 9 $any_time 10100000" "%13 11" send "1103 107 6 12 1 0\n" good_bad_expect "=1103 3 $any_time 12 200 0 \\* 9 $any_time 10100000" "%13 12" # # gazonk examines bar # # gazonk does get-unread-confs of bar. Should return undefined-person. send "1104 52 7\n" good_bad_expect "%1104 10 7" "=3 { 10 11 12 }" "Bug 37" # gazonk does get-membership-10 of bar. Should return undefined-person. send "1105 99 7 0 100 1\n" simple_expect "%1105 10 7" # gazonk does get-membership-old of bar. Should return undefined-person. send "1106 46 7 0 100 1\n" simple_expect "%1106 10 7" # gazonk does get-membership of bar. Should return undefined-person. send "1107 108 7 0 100 1 0\n" simple_expect "%1107 10 7" # gazonk does query-read-texts-10 on bar and 10, 11 and 12. # FIXME (bug 703): This should not be censored. But see Bug 70... setup_xfail "*-*-*" "Bug 703" fail "query-read-texts-10 returns info about secret persons to admin of conf" send "1108 98 7 10\n" simple_expect "%1108 10 7" send "1109 98 7 11\n" simple_expect "%1109 10 7" send "1110 98 7 12\n" simple_expect "%1110 10 7" # gazonk does query-read-texts-old on bar and 10, 11 and 12. # FIXME (bug 703): This should not be censored. But see Bug 70... setup_xfail "*-*-*" "Bug 703" fail "query-read-texts-old returns info about secret persons to admin of conf" send "1111 9 7 10\n" simple_expect "%1111 10 7" send "1112 9 7 11\n" simple_expect "%1112 10 7" send "1113 9 7 12\n" simple_expect "%1113 10 7" # gazonk does query-read-texts on bar and 10, 11 and 12. # FIXME (bug 703): This should not be censored. But see Bug 70... setup_xfail "*-*-*" "Bug 703" fail "query-read-texts returns info about secret persons to admin of conf" send "1114 107 7 10 1 0\n" simple_expect "%1114 10 7" send "1115 107 7 11 1 0\n" simple_expect "%1115 10 7" send "1116 107 7 12 1 0\n" simple_expect "%1116 10 7" # # gazonk examines citrus. # # gazonk does get-unread-confs of citrus. Should return the empty list. send "1117 52 8\n" good_bad_expect "=1117 0 \\*" "=3 { 10 11 12 }" "Bug 595" # gazonk does get-membership-10 of citrus. Should return 4 { 6 10 11 12 }. send "1118 99 8 0 100 1\n" simple_expect "=1118 4 { 0 $any_time 8 255 0 0 \\* 8 $any_time 00000000 1 $any_time 10 200 0 0 \\* 9 $any_time 10100000 2 $any_time 11 200 0 0 \\* 9 $any_time 10100000 3 $any_time 12 200 0 0 \\* 9 $any_time 10100000 }" # gazonk does get-membership-old of citrus. Should return 4 { 6 10 11 12 }. send "1119 46 8 0 100 1\n" simple_expect "=1119 4 { $any_time 8 255 0 0 \\* $any_time 10 200 0 0 \\* $any_time 11 200 0 0 \\* $any_time 12 200 0 0 \\* }" # gazonk does get-membership of citrus. Should return 4 { 6 10 11 12 }. send "1120 108 8 0 100 1 0\n" simple_expect "=1120 4 { 0 $any_time 8 255 0 \\* 8 $any_time 00000000 1 $any_time 10 200 0 \\* 9 $any_time 10100000 2 $any_time 11 200 0 \\* 9 $any_time 10100000 3 $any_time 12 200 0 \\* 9 $any_time 10100000 }" # gazonk does query-read-texts-10 on citrus and 10, 11 and 12. send "1121 98 8 10\n" good_bad_expect "=1121 1 $any_time 10 200 0 0 \\* 9 $any_time 10100000" "%13 10" send "1122 98 8 11\n" good_bad_expect "=1122 2 $any_time 11 200 0 0 \\* 9 $any_time 10100000" "%13 11" send "1123 98 8 12\n" good_bad_expect "=1123 3 $any_time 12 200 0 0 \\* 9 $any_time 10100000" "%13 12" # gazonk does query-read-texts-old on citrus and 10, 11 and 12. send "1124 9 8 10\n" good_bad_expect "=1124 $any_time 10 200 0 0 \\*" "%13 10" send "1125 9 8 11\n" good_bad_expect "=1125 $any_time 11 200 0 0 \\*" "%13 11" send "1126 9 8 12\n" good_bad_expect "=1126 $any_time 12 200 0 0 \\*" "%13 12" # gazonk does query-read-texts on citrus and 10, 11 and 12. send "1127 107 8 10 1 0\n" good_bad_expect "=1127 1 $any_time 10 200 0 \\* 9 $any_time 10100000" "%13 10" send "1128 107 8 11 1 0\n" good_bad_expect "=1128 2 $any_time 11 200 0 \\* 9 $any_time 10100000" "%13 11" send "1129 107 8 12 1 0\n" good_bad_expect "=1129 3 $any_time 12 200 0 \\* 9 $any_time 10100000" "%13 12" # # mark as read # # foo marks the text as read talk_to client 0 send "1130 27 10 1 { 1 }\n" simple_expect "=1130" send "1131 27 11 1 { 1 }\n" simple_expect "=1131" send "1132 27 12 1 { 1 }\n" simple_expect "=1132" # bar marks the text as read talk_to client 1 send "1133 27 10 1 { 1 }\n" simple_expect "=1133" send "1134 27 11 1 { 1 }\n" simple_expect "=1134" send "1135 27 12 1 { 1 }\n" simple_expect "=1135" # citrus marks the text as read talk_to client 2 send "1136 27 10 1 { 1 }\n" simple_expect "=1136" send "1137 27 11 1 { 1 }\n" simple_expect "=1137" send "1138 27 12 1 { 1 }\n" simple_expect "=1138" # # foo examines foo. # talk_to client 0 # foo does get-unread-confs of foo. Should return the empty list. send "1139 52 6\n" simple_expect "=1139 0 \\*" # foo does get-membership-10 of foo. Should return 4 { 6 10 11 12 }. send "1140 99 6 0 100 1\n" simple_expect "=1140 4 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 10 200 1 0 \\* 9 $any_time 10100000 2 $any_time 11 200 1 0 \\* 9 $any_time 10100000 3 $any_time 12 200 1 0 \\* 9 $any_time 10100000 }" # foo does get-membership-old of foo. Should return 4 { 6 10 11 12 }. send "1141 46 6 0 100 1\n" simple_expect "=1141 4 { $any_time 6 255 0 0 \\* $any_time 10 200 1 0 \\* $any_time 11 200 1 0 \\* $any_time 12 200 1 0 \\* }" # foo does get-membership of foo. Should return 4 { 6 10 11 12 }. send "1142 108 6 0 100 1 0\n" simple_expect "=1142 4 { 0 $any_time 6 255 0 \\* 6 $any_time 00000000 1 $any_time 10 200 1 { 1 1 } 9 $any_time 10100000 2 $any_time 11 200 1 { 1 1 } 9 $any_time 10100000 3 $any_time 12 200 1 { 1 1 } 9 $any_time 10100000 }" # foo does query-read-texts-10 on foo and 10, 11 and 12. Should get results. send "1143 98 6 10\n" simple_expect "=1143 1 $any_time 10 200 1 0 \\* 9 $any_time 10100000" send "1144 98 6 11\n" simple_expect "=1144 2 $any_time 11 200 1 0 \\* 9 $any_time 10100000" send "1145 98 6 12\n" simple_expect "=1145 3 $any_time 12 200 1 0 \\* 9 $any_time 10100000" # foo does query-read-texts-old on foo and 10, 11 and 12. Should get results. send "1146 9 6 10\n" simple_expect "=1146 $any_time 10 200 1 0 \\*" send "1147 9 6 11\n" simple_expect "=1147 $any_time 11 200 1 0 \\*" send "1148 9 6 12\n" simple_expect "=1148 $any_time 12 200 1 0 \\*" # foo does query-read-texts on foo and 10, 11 and 12. Should get results. send "1149 107 6 10 1 0\n" simple_expect "=1149 1 $any_time 10 200 1 { 1 1 } 9 $any_time 10100000" send "1150 107 6 11 1 0\n" simple_expect "=1150 2 $any_time 11 200 1 { 1 1 } 9 $any_time 10100000" send "1151 107 6 12 1 0\n" simple_expect "=1151 3 $any_time 12 200 1 { 1 1 } 9 $any_time 10100000" # # gazonk examines foo. # talk_to client 3 # gazonk does get-unread-confs of foo. Should return the empty list. send "1152 52 6\n" simple_expect "=1152 0 \\*" # gazonk does get-membership-10 of foo. Should return 4 { 6 10 11 12 }. send "1153 99 6 0 100 1\n" simple_expect "=1153 4 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 10 200 1 0 \\* 9 $any_time 10100000 2 $any_time 11 200 1 0 \\* 9 $any_time 10100000 3 $any_time 12 200 1 0 \\* 9 $any_time 10100000 }" # gazonk does get-membership-old of foo. Should return 4 { 6 10 11 12 }. send "1154 46 6 0 100 1\n" simple_expect "=1154 4 { $any_time 6 255 0 0 \\* $any_time 10 200 1 0 \\* $any_time 11 200 1 0 \\* $any_time 12 200 1 0 \\* }" # gazonk does get-membership of foo. Should return 4 { 6 10 11 12 }. send "1155 108 6 0 100 1 0\n" simple_expect "=1155 4 { 0 $any_time 6 255 0 \\* 6 $any_time 00000000 1 $any_time 10 200 1 { 1 1 } 9 $any_time 10100000 2 $any_time 11 200 1 { 1 1 } 9 $any_time 10100000 3 $any_time 12 200 1 { 1 1 } 9 $any_time 10100000 }" # gazonk does query-read-texts-10 on foo and 10, 11 and 12. send "1156 98 6 10\n" good_bad_expect "=1156 1 $any_time 10 200 1 0 \\* 9 $any_time 10100000" "%13 10" send "1157 98 6 11\n" good_bad_expect "=1157 2 $any_time 11 200 1 0 \\* 9 $any_time 10100000" "%13 11" send "1158 98 6 12\n" good_bad_expect "=1158 3 $any_time 12 200 1 0 \\* 9 $any_time 10100000" "%13 12" # gazonk does query-read-texts-old on foo and 10, 11 and 12. send "1159 9 6 10\n" good_bad_expect "=1159 $any_time 10 200 1 0 \\*" "%13 10" send "1160 9 6 11\n" good_bad_expect "=1160 $any_time 11 200 1 0 \\*" "%13 11" send "1161 9 6 12\n" good_bad_expect "=1161 $any_time 12 200 1 0 \\*" "%13 12" # gazonk does query-read-texts on foo and 10, 11 and 12. send "1162 107 6 10 1 0\n" good_bad_expect "=1162 1 $any_time 10 200 1 { 1 1 } 9 $any_time 10100000" "%13 10" send "1163 107 6 11 1 0\n" good_bad_expect "=1163 2 $any_time 11 200 1 { 1 1 } 9 $any_time 10100000" "%13 11" send "1164 107 6 12 1 0\n" good_bad_expect "=1164 3 $any_time 12 200 1 { 1 1 } 9 $any_time 10100000" "%13 12" # # gazonk examines bar. # # gazonk does get-unread-confs of bar. Should return undefined-person. send "1165 52 7\n" good_bad_expect "%1165 10 7" "=0 \\*" "Bug 37" # gazonk does get-membership-10 of bar. Should return undefined-person. send "1166 99 7 0 100 1\n" simple_expect "%1166 10 7" # gazonk does get-membership-old of bar. Should return undefined-person. send "1167 46 7 0 100 1\n" simple_expect "%1167 10 7" # gazonk does get-membership of bar. Should return undefined-person. send "1168 108 7 0 100 1 0\n" simple_expect "%1168 10 7" # gazonk does query-read-texts-10 on bar and 10, 11 and 12. undefined-person. # FIXME (bug 703): This should not be censored. But see Bug 70... setup_xfail "*-*-*" "Bug 703" fail "query-read-texts-10 returns info about secret persons to admin of conf" send "1169 98 7 10\n" simple_expect "%1169 10 7" send "1170 98 7 11\n" simple_expect "%1170 10 7" send "1171 98 7 12\n" simple_expect "%1171 10 7" # gazonk does query-read-texts-old on bar and 10, 11 and 12. undefined-person. # FIXME (bug 703): This should not be censored. But see Bug 70... setup_xfail "*-*-*" "Bug 703" fail "query-read-texts returns info about secret persons to admin of conf" send "1172 9 7 10\n" simple_expect "%1172 10 7" send "1173 9 7 11\n" simple_expect "%1173 10 7" send "1174 9 7 12\n" simple_expect "%1174 10 7" # gazonk does query-read-texts on bar and 10, 11 and 12. undefined-person. # FIXME (bug 703): This should not be censored. But see Bug 70... setup_xfail "*-*-*" "Bug 703" fail "query-read-texts returns info about secret persons to admin of conf" send "1175 107 7 10 1 0\n" simple_expect "%1175 10 7" send "1176 107 7 11 1 0\n" simple_expect "%1176 10 7" send "1177 107 7 12 1 0\n" simple_expect "%1177 10 7" # # gazonk examines citrus. # # gazonk does get-unread-confs of citrus. Should return the empty list. send "1178 52 8\n" simple_expect "=1178 0 \\*" # gazonk does get-membership-10 of citrus. Should return 4 { 6 10 11 12 }. send "1179 99 8 0 100 1\n" simple_expect "=1179 4 { 0 $any_time 8 255 0 0 \\* 8 $any_time 00000000 1 $any_time 10 200 0 0 \\* 9 $any_time 10100000 2 $any_time 11 200 0 0 \\* 9 $any_time 10100000 3 $any_time 12 200 0 0 \\* 9 $any_time 10100000 }" # gazonk does get-membership-old of citrus. Should return 4 { 6 10 11 12 }. send "1180 46 8 0 100 1\n" simple_expect "=1180 4 { $any_time 8 255 0 0 \\* $any_time 10 200 0 0 \\* $any_time 11 200 0 0 \\* $any_time 12 200 0 0 \\* }" # gazonk does get-membership of citrus. Should return 4 { 6 10 11 12 }. send "1181 108 8 0 100 1 0\n" simple_expect "=1181 4 { 0 $any_time 8 255 0 \\* 8 $any_time 00000000 1 $any_time 10 200 0 \\* 9 $any_time 10100000 2 $any_time 11 200 0 \\* 9 $any_time 10100000 3 $any_time 12 200 0 \\* 9 $any_time 10100000 }" # gazonk does query-read-texts-10 on citrus and 10, 11 and 12. send "1182 98 8 10\n" good_bad_expect "=1182 1 $any_time 10 200 0 0 \\* 9 $any_time 10100000" "%13 10" send "1183 98 8 11\n" good_bad_expect "=1183 2 $any_time 11 200 0 0 \\* 9 $any_time 10100000" "%13 11" send "1184 98 8 12\n" good_bad_expect "=1184 3 $any_time 12 200 0 0 \\* 9 $any_time 10100000" "%13 12" # gazonk does query-read-texts-old on citrus and 10, 11 and 12. 10 fails. send "1185 9 8 10\n" good_bad_expect "=1185 $any_time 10 200 0 0 \\*" "%13 10" send "1186 9 8 11\n" good_bad_expect "=1186 $any_time 11 200 0 0 \\*" "%13 11" send "1187 9 8 12\n" good_bad_expect "=1187 $any_time 12 200 0 0 \\*" "%13 12" # gazonk does query-read-texts on citrus and 10, 11 and 12. send "1188 107 8 10 1 0\n" good_bad_expect "=1188 1 $any_time 10 200 0 \\* 9 $any_time 10100000" "%13 10" send "1189 107 8 11 1 0\n" good_bad_expect "=1189 2 $any_time 11 200 0 \\* 9 $any_time 10100000" "%13 11" send "1190 107 8 12 1 0\n" good_bad_expect "=1190 3 $any_time 12 200 0 \\* 9 $any_time 10100000" "%13 12" # # gazonk examines the conferences # # Test get-members-old send "1191 48 10 0 100\n" simple_expect "=1191 3 { 7 6 8 }" send "1192 48 11 0 100\n" simple_expect "=1192 3 { 7 6 8 }" send "1193 48 12 0 100\n" simple_expect "=1193 3 { 7 6 8 }" # Test get-members. send "1194 101 10 0 100\n" simple_expect "=1194 3 { 7 9 $any_time 10100000 6 9 $any_time 10100000 8 9 $any_time 10100000 }" send "1195 101 11 0 100\n" simple_expect "=1195 3 { 7 9 $any_time 10100000 6 9 $any_time 10100000 8 9 $any_time 10100000 }" send "1196 101 12 0 100\n" simple_expect "=1196 3 { 7 9 $any_time 10100000 6 9 $any_time 10100000 8 9 $any_time 10100000 }" # Shut down. talk_to client 3 send "1197 0 5 [holl "gazonk"]\n" simple_expect "=1197" send "1198 42 255\n" simple_expect "=1198" send "1199 44 0\n" simple_expect "=1199" client_death 3 client_death 2 client_death 1 client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/bug-37.exp0000664000015100472110000006672607721716134017536 # Test suite for lyskomd. # Copyright (C) 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test bug 37: get_unread_confs does not check that the caller is # allowed to see the person, and returns the correct result even for # secret persons, including secret confs! # # We also check get-membership, get-membership-10, get-membership-old, # query-read-texts, query-read-texts-10, and query-read-texts-old. # # While we are at it, we also test the unread-is-secret personal flag. proc check_pos {actual wanted} { global test set test "Correct position of membership returned" setup_xfail "*-*-*" "Bug 594" if {$actual == $wanted} { pass "$test" } else { fail "$test (got pos $actual instead of $wanted)" } unset test } # # Startup and create the players # # Start the server. lyskomd_start # Create and log in as foo (person 6). client_start 0 send "A3Hfoo\n" simple_expect "LysKOM" send "1000 80 0 { }\n" simple_expect "=1000" send "1001 89 [holl "foo"] [holl "p6"] 00000000 0 { }\n" simple_expect "=1001 6" send "1002 62 6 [holl "p6"] 0\n" simple_expect "=1002" # Create and log in as bar (person 7; secret). client_start 1 send "A3Hbar\n" simple_expect "LysKOM" send "1003 80 0 { }\n" simple_expect "=1003" send "1004 89 [holl "bar"] [holl "p7"] 00000000 0 { }\n" simple_expect "=1004 7" send "1005 62 7 [holl "p7"] 0\n" simple_expect "=1005" send "1006 21 7 10111000\n" simple_expect "=1006" # Create and log in as citrus (person 8; has unread-is-secret set). client_start 2 send "A6Hcitrus\n" simple_expect "LysKOM" send "1007 80 0 { }\n" simple_expect "=1007" send "1008 89 [holl "citrus"] [holl "p8"] 10000000 0 { }\n" simple_expect "=1008 8" send "1009 62 8 [holl "p8"] 0\n" simple_expect "=1009" # Create and log in as gazonk (person 9). This is the observer. client_start 3 send "A6Hgazonk\n" simple_expect "LysKOM" send "1010 80 0 { }\n" simple_expect "=1010" send "1011 89 [holl "gazonk"] [holl "p9"] 00000000 0 { }\n" simple_expect "=1011 9" send "1012 62 9 [holl "p9"] 0\n" simple_expect "=1012" # # Create conferences. # # As bar, create secret (conf 10; secret). talk_to client 1 send "1013 88 [holl "secret"] 10101000 0 { }\n" simple_expect "=1013 10" # As bar, create rd-prot (conf 11; rd-prot). send "1014 88 [holl "rd-prot"] 10001000 0 { }\n" simple_expect "=1014 11" # As bar, create public (conf 12). send "1015 88 [holl "public"] 00001000 0 { }\n" simple_expect "=1015 12" # # Join conferences # # bar joins secret, rd-prot and public. send "1016 100 10 7 200 1 00000000\n" simple_expect "=1016" send "1017 100 11 7 200 2 00000000\n" simple_expect "=1017" send "1018 100 12 7 200 3 00000000\n" simple_expect "=1018" # bar invites foo to secret, rd-prot and public. send "1019 100 10 6 200 1 00000000\n" lyskomd_expect "Person 6 added to conference 10 by 7." simple_expect "=1019" send "1020 100 11 6 200 2 00000000\n" lyskomd_expect "Person 6 added to conference 11 by 7." simple_expect "=1020" send "1021 100 12 6 200 3 00000000\n" lyskomd_expect "Person 6 added to conference 12 by 7." simple_expect "=1021" # bar invites citrus to secret, rd-prot and public. send "1022 100 10 8 200 1 00000000\n" lyskomd_expect "Person 8 added to conference 10 by 7." simple_expect "=1022" send "1023 100 11 8 200 2 00000000\n" lyskomd_expect "Person 8 added to conference 11 by 7." simple_expect "=1023" send "1024 100 12 8 200 3 00000000\n" lyskomd_expect "Person 8 added to conference 12 by 7." simple_expect "=1024" # # foo examines foo. # talk_to client 0 # foo does get-unread-confs of foo. Should return the empty list. send "1025 52 6\n" simple_expect "=1025 0 \\*" # foo does get-membership-10 of foo. Should return 4 { 6 10 11 12 }. send "1026 99 6 0 100 1\n" simple_expect "=1026 4 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 10 200 0 0 \\* 7 $any_time 10000000 2 $any_time 11 200 0 0 \\* 7 $any_time 10000000 3 $any_time 12 200 0 0 \\* 7 $any_time 10000000 }" # foo does get-membership-old of foo. Should return 4 { 6 10 11 12 }. send "1027 46 6 0 100 1\n" simple_expect "=1027 4 { $any_time 6 255 0 0 \\* $any_time 10 200 0 0 \\* $any_time 11 200 0 0 \\* $any_time 12 200 0 0 \\* }" # foo does get-membership of foo. Should return 4 { 6 10 11 12 }. send "1028 108 6 0 100 1 0\n" simple_expect "=1028 4 { 0 $any_time 6 255 0 \\* 6 $any_time 00000000 1 $any_time 10 200 0 \\* 7 $any_time 10000000 2 $any_time 11 200 0 \\* 7 $any_time 10000000 3 $any_time 12 200 0 \\* 7 $any_time 10000000 }" # foo does query-read-texts-10 on foo and 10, 11 and 12. Should get results. send "1029 98 6 10\n" simple_expect "=1029 1 $any_time 10 200 0 0 \\* 7 $any_time 10000000" send "1030 98 6 11\n" simple_expect "=1030 2 $any_time 11 200 0 0 \\* 7 $any_time 10000000" send "1031 98 6 12\n" simple_expect "=1031 3 $any_time 12 200 0 0 \\* 7 $any_time 10000000" # foo does query-read-texts-old on foo and 10, 11 and 12. Should get results. send "1032 9 6 10\n" simple_expect "=1032 $any_time 10 200 0 0 \\*" send "1033 9 6 11\n" simple_expect "=1033 $any_time 11 200 0 0 \\*" send "1034 9 6 12\n" simple_expect "=1034 $any_time 12 200 0 0 \\*" # foo does query-read-texts on foo and 10, 11 and 12. Should get results. send "1035 107 6 10 1 0\n" simple_expect "=1035 1 $any_time 10 200 0 \\* 7 $any_time 10000000" send "1036 107 6 11 1 0\n" simple_expect "=1036 2 $any_time 11 200 0 \\* 7 $any_time 10000000" send "1037 107 6 12 1 0\n" simple_expect "=1037 3 $any_time 12 200 0 \\* 7 $any_time 10000000" # # gazonk examines foo. # talk_to client 3 # gazonk does get-unread-confs of foo. Should return the empty list. send "1038 52 6\n" simple_expect "=1038 0 \\*" # gazonk does get-membership-10 of foo. Should return 3 { 6 11 12 }. send "1039 99 6 0 100 1\n" simple_expect "=1039 3 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 11 200 0 0 \\* 7 $any_time 10000000 2 $any_time 12 200 0 0 \\* 7 $any_time 10000000 }" # (Just a quick check: does the renumber work properly even if we don't # start from the beginning of the list?) send "1040 99 6 2 100 1\n" simple_expect "=1040 1 { 2 $any_time 12 200 0 0 \\* 7 $any_time 10000000 }" # gazonk does get-membership-old of foo. Should return 3 { 6 11 12 }. send "1041 46 6 0 100 1\n" simple_expect "=1041 3 { $any_time 6 255 0 0 \\* $any_time 11 200 0 0 \\* $any_time 12 200 0 0 \\* }" # gazonk does get-membership of foo. Should return 3 { 6 11 12 }. send "1042 108 6 0 100 1 0\n" simple_expect "=1042 3 { 0 $any_time 6 255 0 \\* 6 $any_time 00000000 1 $any_time 11 200 0 \\* 7 $any_time 10000000 2 $any_time 12 200 0 \\* 7 $any_time 10000000 }" # (Just a quick check: does the renumber work properly even if we don't # start from the beginning of the list?) send "1043 108 6 2 100 1 0\n" simple_expect "=1043 1 { 2 $any_time 12 200 0 \\* 7 $any_time 10000000 }" # gazonk does query-read-texts-10 on foo and 10, 11 and 12. 10 should fail. send "1044 98 6 10\n" simple_expect "%1044 9 10" send "1045 98 6 11\n" extracting_expect "=1045 (1|2) $any_time 11 200 0 0 \\* 7 $any_time 10000000" pos 1 check_pos $pos 1 send "1046 98 6 12\n" extracting_expect "=1046 (2|3) $any_time 12 200 0 0 \\* 7 $any_time 10000000" pos 1 check_pos $pos 2 # gazonk does query-read-texts-old on foo and 10, 11 and 12. 10 should fail. send "1047 9 6 10\n" simple_expect "%1047 9 10" send "1048 9 6 11\n" simple_expect "=1048 $any_time 11 200 0 0 \\*" send "1049 9 6 12\n" simple_expect "=1049 $any_time 12 200 0 0 \\*" # gazonk does query-read-texts on foo and 10, 11 and 12. 10 should fail. send "1050 107 6 10 1 0\n" simple_expect "%1050 9 10" send "1051 107 6 11 1 0\n" extracting_expect "=1051 (1|2) $any_time 11 200 0 \\* 7 $any_time 10000000" pos 1 check_pos $pos 1 send "1052 107 6 12 1 0\n" extracting_expect "=1052 (2|3) $any_time 12 200 0 \\* 7 $any_time 10000000" pos 1 check_pos $pos 2 # # gazonk examines bar. # # gazonk does get-unread-confs of bar. Should return undefined-person. send "1053 52 7\n" good_bad_expect "%1053 10 7" "=0 \\*" "Bug 37" # gazonk does get-membership-10 of bar. Should return undefined-person. send "1054 99 7 0 100 1\n" simple_expect "%1054 10 7" # gazonk does get-membership-old of bar. Should return undefined-person. send "1055 46 7 0 100 1\n" simple_expect "%1055 10 7" # gazonk does get-membership of bar. Should return undefined-person. send "1056 108 7 0 100 1 0\n" simple_expect "%1056 10 7" # gazonk does query-read-texts-10 on bar and 10, 11 and 12. undefined-person. send "1057 98 7 10\n" simple_expect "%1057 10 7" send "1058 98 7 11\n" simple_expect "%1058 10 7" send "1059 98 7 12\n" simple_expect "%1059 10 7" # gazonk does query-read-texts-old on bar and 10, 11 and 12. undefined-person. send "1060 9 7 10\n" simple_expect "%1060 10 7" send "1061 9 7 11\n" simple_expect "%1061 10 7" send "1062 9 7 12\n" simple_expect "%1062 10 7" # gazonk does query-read-texts on bar and 10, 11 and 12. undefined-person. send "1063 107 7 10 1 0\n" simple_expect "%1063 10 7" send "1064 107 7 11 1 0\n" simple_expect "%1064 10 7" send "1065 107 7 12 1 0\n" simple_expect "%1065 10 7" # # gazonk examines citrus. # # gazonk does get-unread-confs of citrus. Should return the empty list. send "1066 52 8\n" simple_expect "=1066 0 \\*" # gazonk does get-membership-10 of citrus. Should return 3 { 6 11 12 }. send "1067 99 8 0 100 1\n" simple_expect "=1067 3 { 0 $any_time 8 255 0 0 \\* 8 $any_time 00000000 1 $any_time 11 200 0 0 \\* 7 $any_time 10000000 2 $any_time 12 200 0 0 \\* 7 $any_time 10000000 }" # gazonk does get-membership-old of citrus. Should return 3 { 6 11 12 }. send "1068 46 8 0 100 1\n" simple_expect "=1068 3 { $any_time 8 255 0 0 \\* $any_time 11 200 0 0 \\* $any_time 12 200 0 0 \\* }" # gazonk does get-membership of citrus. Should return 3 { 6 11 12 }. send "1069 108 8 0 100 1 0\n" simple_expect "=1069 3 { 0 $any_time 8 255 0 \\* 8 $any_time 00000000 1 $any_time 11 200 0 \\* 7 $any_time 10000000 2 $any_time 12 200 0 \\* 7 $any_time 10000000 }" # gazonk does query-read-texts-10 on citrus and 10, 11 and 12. 10 should fail. send "1070 98 8 10\n" simple_expect "%1070 9 10" send "1071 98 8 11\n" simple_expect "=1071 2 $any_time 11 200 0 0 \\* 7 $any_time 10000000" send "1072 98 8 12\n" simple_expect "=1072 3 $any_time 12 200 0 0 \\* 7 $any_time 10000000" # gazonk does query-read-texts-old on citrus and 10, 11 and 12. 10 fails. send "1073 9 8 10\n" simple_expect "%1073 9 10" send "1074 9 8 11\n" simple_expect "=1074 $any_time 11 200 0 0 \\*" send "1075 9 8 12\n" simple_expect "=1075 $any_time 12 200 0 0 \\*" # gazonk does query-read-texts on citrus and 10, 11 and 12. 10 should fail. send "1076 107 8 10 1 0\n" simple_expect "%1076 9 10" send "1077 107 8 11 1 0\n" simple_expect "=1077 2 $any_time 11 200 0 \\* 7 $any_time 10000000" send "1078 107 8 12 1 0\n" simple_expect "=1078 3 $any_time 12 200 0 \\* 7 $any_time 10000000" # # foo writes a text with secret, rd-prot and public as recipients. # talk_to client 0 send "1079 86 [holl "foo"] 3 { 0 10 0 11 0 12 } 0 { }\n" simple_expect "=1079 1" # # foo examines foo # # foo does get-unread-confs of foo. Should return 3 { 10 11 12 }. send "1080 52 6\n" simple_expect "=1080 3 { 10 11 12 }" # foo does get-membership-10 of foo. Should return 4 { 6 10 11 12 }. send "1081 99 6 0 100 1\n" simple_expect "=1081 4 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 10 200 0 0 \\* 7 $any_time 10000000 2 $any_time 11 200 0 0 \\* 7 $any_time 10000000 3 $any_time 12 200 0 0 \\* 7 $any_time 10000000 }" # foo does get-membership-old of foo. Should return 4 { 6 10 11 12 }. send "1082 46 6 0 100 1\n" simple_expect "=1082 4 { $any_time 6 255 0 0 \\* $any_time 10 200 0 0 \\* $any_time 11 200 0 0 \\* $any_time 12 200 0 0 \\* }" # foo does get-membership of foo. Should return 4 { 6 10 11 12 }. send "1083 108 6 0 100 1 0\n" simple_expect "=1083 4 { 0 $any_time 6 255 0 \\* 6 $any_time 00000000 1 $any_time 10 200 0 \\* 7 $any_time 10000000 2 $any_time 11 200 0 \\* 7 $any_time 10000000 3 $any_time 12 200 0 \\* 7 $any_time 10000000 }" # foo does query-read-texts-10 on foo and 10, 11 and 12. Should get results. send "1084 98 6 10\n" simple_expect "=1084 1 $any_time 10 200 0 0 \\* 7 $any_time 10000000" send "1085 98 6 11\n" simple_expect "=1085 2 $any_time 11 200 0 0 \\* 7 $any_time 10000000" send "1086 98 6 12\n" simple_expect "=1086 3 $any_time 12 200 0 0 \\* 7 $any_time 10000000" # foo does query-read-texts-old on foo and 10, 11 and 12. Should get results. send "1087 9 6 10\n" simple_expect "=1087 $any_time 10 200 0 0 \\*" send "1088 9 6 11\n" simple_expect "=1088 $any_time 11 200 0 0 \\*" send "1089 9 6 12\n" simple_expect "=1089 $any_time 12 200 0 0 \\*" # foo does query-read-texts-10 on foo and 10, 11 and 12. Should get results. send "1090 107 6 10 1 0\n" simple_expect "=1090 1 $any_time 10 200 0 \\* 7 $any_time 10000000" send "1091 107 6 11 1 0\n" simple_expect "=1091 2 $any_time 11 200 0 \\* 7 $any_time 10000000" send "1092 107 6 12 1 0\n" simple_expect "=1092 3 $any_time 12 200 0 \\* 7 $any_time 10000000" # # gazonk examines foo. # talk_to client 3 # gazonk does get-unread-confs of foo. Should return 2 { 11 12 }. send "1093 52 6\n" # "Bug 596" good_bad_expect "=1093 2 { 11 12 }" "=1 { 12 }" # gazonk does get-membership-10 of foo. Should return 3 { 6 11 12 }. send "1094 99 6 0 100 1\n" simple_expect "=1094 3 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 11 200 0 0 \\* 7 $any_time 10000000 2 $any_time 12 200 0 0 \\* 7 $any_time 10000000 }" # (Just a quick check: does the renumber work properly even if we don't # start from the beginning of the list?) send "1095 99 6 2 100 1\n" simple_expect "=1095 1 { 2 $any_time 12 200 0 0 \\* 7 $any_time 10000000 }" # gazonk does get-membership-old of foo. Should return 3 { 6 11 12 }. send "1096 46 6 0 100 1\n" simple_expect "=1096 3 { $any_time 6 255 0 0 \\* $any_time 11 200 0 0 \\* $any_time 12 200 0 0 \\* }" # gazonk does get-membership of foo. Should return 3 { 6 11 12 }. send "1097 108 6 0 100 1 0\n" simple_expect "=1097 3 { 0 $any_time 6 255 0 \\* 6 $any_time 00000000 1 $any_time 11 200 0 \\* 7 $any_time 10000000 2 $any_time 12 200 0 \\* 7 $any_time 10000000 }" # (Just a quick check: does the renumber work properly even if we don't # start from the beginning of the list?) send "1098 108 6 2 100 1 0\n" simple_expect "=1098 1 { 2 $any_time 12 200 0 \\* 7 $any_time 10000000 }" # gazonk does query-read-texts-10 on foo and 10, 11 and 12. 10 should fail. send "1099 98 6 10\n" simple_expect "%1099 9 10" send "1100 98 6 11\n" extracting_expect "=1100 (1|2) $any_time 11 200 0 0 \\* 7 $any_time 10000000" pos 1 check_pos $pos 1 send "1101 98 6 12\n" extracting_expect "=1101 (2|3) $any_time 12 200 0 0 \\* 7 $any_time 10000000" pos 1 check_pos $pos 2 # gazonk does query-read-texts-old on foo and 10, 11 and 12. 10 should fail. send "1102 9 6 10\n" simple_expect "%1102 9 10" send "1103 9 6 11\n" simple_expect "=1103 $any_time 11 200 0 0 \\*" send "1104 9 6 12\n" simple_expect "=1104 $any_time 12 200 0 0 \\*" # gazonk does query-read-texts on foo and 10, 11 and 12. 10 should fail. send "1105 107 6 10 1 0\n" simple_expect "%1105 9 10" send "1106 107 6 11 1 0\n" extracting_expect "=1106 (1|2) $any_time 11 200 0 \\* 7 $any_time 10000000" pos 1 check_pos $pos 1 send "1107 107 6 12 1 0\n" extracting_expect "=1107 (2|3) $any_time 12 200 0 \\* 7 $any_time 10000000" pos 1 check_pos $pos 2 # # gazonk examines bar # # gazonk does get-unread-confs of bar. Should return undefined-person. send "1108 52 7\n" good_bad_expect "%1108 10 7" "=0 \\*" "Bug 37" # gazonk does get-membership-10 of bar. Should return undefined-person. send "1109 99 7 0 100 1\n" simple_expect "%1109 10 7" # gazonk does get-membership-old of bar. Should return undefined-person. send "1110 46 7 0 100 1\n" simple_expect "%1110 10 7" # gazonk does get-membership of bar. Should return undefined-person. send "1111 108 7 0 100 1 0\n" simple_expect "%1111 10 7" # gazonk does query-read-texts-10 on bar and 10, 11 and 12. undefined-person. send "1112 98 7 10\n" simple_expect "%1112 10 7" send "1113 98 7 11\n" simple_expect "%1113 10 7" send "1114 98 7 12\n" simple_expect "%1114 10 7" # gazonk does query-read-texts-old on bar and 10, 11 and 12. undefined-person. send "1115 9 7 10\n" simple_expect "%1115 10 7" send "1116 9 7 11\n" simple_expect "%1116 10 7" send "1117 9 7 12\n" simple_expect "%1117 10 7" # gazonk does query-read-texts on bar and 10, 11 and 12. undefined-person. send "1118 107 7 10 1 0\n" simple_expect "%1118 10 7" send "1119 107 7 11 1 0\n" simple_expect "%1119 10 7" send "1120 107 7 12 1 0\n" simple_expect "%1120 10 7" # # gazonk examines citrus. # # gazonk does get-unread-confs of citrus. Should return the empty list. send "1121 52 8\n" good_bad_expect "=1121 0 \\*" "=2 { 11 12 }" "Bug 595" # gazonk does get-membership-10 of citrus. Should return 3 { 6 11 12 }. send "1122 99 8 0 100 1\n" simple_expect "=1122 3 { 0 $any_time 8 255 0 0 \\* 8 $any_time 00000000 1 $any_time 11 200 0 0 \\* 7 $any_time 10000000 2 $any_time 12 200 0 0 \\* 7 $any_time 10000000 }" # gazonk does get-membership-old of citrus. Should return 3 { 6 11 12 }. send "1123 46 8 0 100 1\n" simple_expect "=1123 3 { $any_time 8 255 0 0 \\* $any_time 11 200 0 0 \\* $any_time 12 200 0 0 \\* }" # gazonk does get-membership of citrus. Should return 3 { 6 11 12 }. send "1124 108 8 0 100 1 0\n" simple_expect "=1124 3 { 0 $any_time 8 255 0 \\* 8 $any_time 00000000 1 $any_time 11 200 0 \\* 7 $any_time 10000000 2 $any_time 12 200 0 \\* 7 $any_time 10000000 }" # gazonk does query-read-texts-10 on citrus and 10, 11 and 12. 10 should fail. send "1125 98 8 10\n" simple_expect "%1125 9 10" send "1126 98 8 11\n" simple_expect "=1126 2 $any_time 11 200 0 0 \\* 7 $any_time 10000000" send "1127 98 8 12\n" simple_expect "=1127 3 $any_time 12 200 0 0 \\* 7 $any_time 10000000" # gazonk does query-read-texts-old on citrus and 10, 11 and 12. 10 fails. send "1128 9 8 10\n" simple_expect "%1128 9 10" send "1129 9 8 11\n" simple_expect "=1129 $any_time 11 200 0 0 \\*" send "1130 9 8 12\n" simple_expect "=1130 $any_time 12 200 0 0 \\*" # gazonk does query-read-texts on citrus and 10, 11 and 12. 10 should fail. send "1131 107 8 10 1 0\n" simple_expect "%1131 9 10" send "1132 107 8 11 1 0\n" simple_expect "=1132 2 $any_time 11 200 0 \\* 7 $any_time 10000000" send "1133 107 8 12 1 0\n" simple_expect "=1133 3 $any_time 12 200 0 \\* 7 $any_time 10000000" # # mark as read # # foo marks the text as read talk_to client 0 send "1134 27 10 1 { 1 }\n" simple_expect "=1134" send "1135 27 11 1 { 1 }\n" simple_expect "=1135" send "1136 27 12 1 { 1 }\n" simple_expect "=1136" # bar marks the text as read talk_to client 1 send "1137 27 10 1 { 1 }\n" simple_expect "=1137" send "1138 27 11 1 { 1 }\n" simple_expect "=1138" send "1139 27 12 1 { 1 }\n" simple_expect "=1139" # citrus marks the text as read talk_to client 2 send "1140 27 10 1 { 1 }\n" simple_expect "=1140" send "1141 27 11 1 { 1 }\n" simple_expect "=1141" send "1142 27 12 1 { 1 }\n" simple_expect "=1142" # # foo examines foo. # talk_to client 0 # foo does get-unread-confs of foo. Should return the empty list. send "1143 52 6\n" simple_expect "=1143 0 \\*" # foo does get-membership-10 of foo. Should return 4 { 6 10 11 12 }. send "1144 99 6 0 100 1\n" simple_expect "=1144 4 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 10 200 1 0 \\* 7 $any_time 10000000 2 $any_time 11 200 1 0 \\* 7 $any_time 10000000 3 $any_time 12 200 1 0 \\* 7 $any_time 10000000 }" # foo does get-membership-old of foo. Should return 4 { 6 10 11 12 }. send "1145 46 6 0 100 1\n" simple_expect "=1145 4 { $any_time 6 255 0 0 \\* $any_time 10 200 1 0 \\* $any_time 11 200 1 0 \\* $any_time 12 200 1 0 \\* }" # foo does get-membership of foo. Should return 4 { 6 10 11 12 }. send "1146 108 6 0 100 1 0\n" simple_expect "=1146 4 { 0 $any_time 6 255 0 \\* 6 $any_time 00000000 1 $any_time 10 200 1 { 1 1 } 7 $any_time 10000000 2 $any_time 11 200 1 { 1 1 } 7 $any_time 10000000 3 $any_time 12 200 1 { 1 1 } 7 $any_time 10000000 }" # foo does query-read-texts-10 on foo and 10, 11 and 12. Should get results. send "1147 98 6 10\n" simple_expect "=1147 1 $any_time 10 200 1 0 \\* 7 $any_time 10000000" send "1148 98 6 11\n" simple_expect "=1148 2 $any_time 11 200 1 0 \\* 7 $any_time 10000000" send "1149 98 6 12\n" simple_expect "=1149 3 $any_time 12 200 1 0 \\* 7 $any_time 10000000" # foo does query-read-texts-old on foo and 10, 11 and 12. Should get results. send "1150 9 6 10\n" simple_expect "=1150 $any_time 10 200 1 0 \\*" send "1151 9 6 11\n" simple_expect "=1151 $any_time 11 200 1 0 \\*" send "1152 9 6 12\n" simple_expect "=1152 $any_time 12 200 1 0 \\*" # foo does query-read-texts on foo and 10, 11 and 12. Should get results. send "1153 107 6 10 1 0\n" simple_expect "=1153 1 $any_time 10 200 1 { 1 1 } 7 $any_time 10000000" send "1154 107 6 11 1 0\n" simple_expect "=1154 2 $any_time 11 200 1 { 1 1 } 7 $any_time 10000000" send "1155 107 6 12 1 0\n" simple_expect "=1155 3 $any_time 12 200 1 { 1 1 } 7 $any_time 10000000" # # gazonk examines foo. # talk_to client 3 # gazonk does get-unread-confs of foo. Should return the empty list. send "1156 52 6\n" simple_expect "=1156 0 \\*" # gazonk does get-membership-10 of foo. Should return 3 { 6 11 12 }. send "1157 99 6 0 100 1\n" simple_expect "=1157 3 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 11 200 1 0 \\* 7 $any_time 10000000 2 $any_time 12 200 1 0 \\* 7 $any_time 10000000 }" # gazonk does get-membership-old of foo. Should return 3 { 6 11 12 }. send "1158 46 6 0 100 1\n" simple_expect "=1158 3 { $any_time 6 255 0 0 \\* $any_time 11 200 1 0 \\* $any_time 12 200 1 0 \\* }" # gazonk does get-membership of foo. Should return 3 { 6 11 12 }. send "1159 108 6 0 100 1 0\n" simple_expect "=1159 3 { 0 $any_time 6 255 0 \\* 6 $any_time 00000000 1 $any_time 11 200 1 { 1 1 } 7 $any_time 10000000 2 $any_time 12 200 1 { 1 1 } 7 $any_time 10000000 }" # gazonk does query-read-texts-10 on foo and 10, 11 and 12. 10 should fail. send "1160 98 6 10\n" simple_expect "%1160 9 10" send "1161 98 6 11\n" extracting_expect "=1161 (1|2) $any_time 11 200 1 0 \\* 7 $any_time 10000000" pos 1 check_pos $pos 1 send "1162 98 6 12\n" extracting_expect "=1162 (2|3) $any_time 12 200 1 0 \\* 7 $any_time 10000000" pos 1 check_pos $pos 2 # gazonk does query-read-texts-old on foo and 10, 11 and 12. 10 should fail. send "1163 9 6 10\n" simple_expect "%1163 9 10" send "1164 9 6 11\n" simple_expect "=1164 $any_time 11 200 1 0 \\*" send "1165 9 6 12\n" simple_expect "=1165 $any_time 12 200 1 0 \\*" # gazonk does query-read-texts on foo and 10, 11 and 12. 10 should fail. send "1166 107 6 10 1 0\n" simple_expect "%1166 9 10" send "1167 107 6 11 1 0\n" extracting_expect "=1167 (1|2) $any_time 11 200 1 { 1 1 } 7 $any_time 10000000" pos 1 check_pos $pos 1 send "1168 107 6 12 1 0\n" extracting_expect "=1168 (2|3) $any_time 12 200 1 { 1 1 } 7 $any_time 10000000" pos 1 check_pos $pos 2 # # gazonk examines bar. # # gazonk does get-unread-confs of bar. Should return undefined-person. send "1169 52 7\n" good_bad_expect "%1169 10 7" "=0 \\*" "Bug 37" # gazonk does get-membership-10 of bar. Should return undefined-person. send "1170 99 7 0 100 1\n" simple_expect "%1170 10 7" # gazonk does get-membership-old of bar. Should return undefined-person. send "1171 46 7 0 100 1\n" simple_expect "%1171 10 7" # gazonk does get-membership of bar. Should return undefined-person. send "1172 108 7 0 100 1 0\n" simple_expect "%1172 10 7" # gazonk does query-read-texts-10 on bar and 10, 11 and 12. undefined-person. send "1173 98 7 10\n" simple_expect "%1173 10 7" send "1174 98 7 11\n" simple_expect "%1174 10 7" send "1175 98 7 12\n" simple_expect "%1175 10 7" # gazonk does query-read-texts-old on bar and 10, 11 and 12. undefined-person. send "1176 9 7 10\n" simple_expect "%1176 10 7" send "1177 9 7 11\n" simple_expect "%1177 10 7" send "1178 9 7 12\n" simple_expect "%1178 10 7" # gazonk does query-read-texts on bar and 10, 11 and 12. undefined-person. send "1179 107 7 10 1 0\n" simple_expect "%1179 10 7" send "1180 107 7 11 1 0\n" simple_expect "%1180 10 7" send "1181 107 7 12 1 0\n" simple_expect "%1181 10 7" # # gazonk examines citrus. # # gazonk does get-unread-confs of citrus. Should return the empty list. send "1182 52 8\n" simple_expect "=1182 0 \\*" # gazonk does get-membership-10 of citrus. Should return 4 { 6 11 12 }. send "1183 99 8 0 100 1\n" simple_expect "=1183 3 { 0 $any_time 8 255 0 0 \\* 8 $any_time 00000000 1 $any_time 11 200 0 0 \\* 7 $any_time 10000000 2 $any_time 12 200 0 0 \\* 7 $any_time 10000000 }" # gazonk does get-membership-old of citrus. Should return 4 { 6 11 12 }. send "1184 46 8 0 100 1\n" simple_expect "=1184 3 { $any_time 8 255 0 0 \\* $any_time 11 200 0 0 \\* $any_time 12 200 0 0 \\* }" # gazonk does get-membership of citrus. Should return 4 { 6 11 12 }. send "1185 108 8 0 100 1 0\n" simple_expect "=1185 3 { 0 $any_time 8 255 0 \\* 8 $any_time 00000000 1 $any_time 11 200 0 \\* 7 $any_time 10000000 2 $any_time 12 200 0 \\* 7 $any_time 10000000 }" # gazonk does query-read-texts-10 on citrus and 10, 11 and 12. 10 should fail. send "1186 98 8 10\n" simple_expect "%1186 9 10" send "1187 98 8 11\n" simple_expect "=1187 2 $any_time 11 200 0 0 \\* 7 $any_time 10000000" send "1188 98 8 12\n" simple_expect "=1188 3 $any_time 12 200 0 0 \\* 7 $any_time 10000000" # gazonk does query-read-texts-old on citrus and 10, 11 and 12. 10 fails. send "1189 9 8 10\n" simple_expect "%1189 9 10" send "1190 9 8 11\n" simple_expect "=1190 $any_time 11 200 0 0 \\*" send "1191 9 8 12\n" simple_expect "=1191 $any_time 12 200 0 0 \\*" # gazonk does query-read-texts on citrus and 10, 11 and 12. 10 should fail. send "1192 107 8 10 1 0\n" simple_expect "%1192 9 10" send "1193 107 8 11 1 0\n" simple_expect "=1193 2 $any_time 11 200 0 \\* 7 $any_time 10000000" send "1194 107 8 12 1 0\n" simple_expect "=1194 3 $any_time 12 200 0 \\* 7 $any_time 10000000" # # gazonk examines the conferences # # Test get-members-old send "1195 48 10 0 100\n" simple_expect "%1195 9 10" send "1196 48 11 0 100\n" # As long as secret persons are allowed, the secret person number 7 should # be censored in the result of get-members-old. If this test is rewritten # to use a non-secret person, "set seven 7" should make the tests pass again. set seven 0 simple_expect "=1196 3 { $seven 6 8 }" send "1197 48 12 0 100\n" simple_expect "=1197 3 { $seven 6 8 }" # Test get-members. send "1198 101 10 0 100\n" simple_expect "%1198 9 10" send "1199 101 11 0 100\n" if {$seven == 0} { set seventype 00100000 } else { set seventype 00000000 } simple_expect "=1199 3 { $seven $seven $any_time $seventype 6 7 $any_time 10000000 8 7 $any_time 10000000 }" send "1200 101 12 0 100\n" simple_expect "=1200 3 { $seven $seven $any_time $seventype 6 7 $any_time 10000000 8 7 $any_time 10000000 }" # Shut down. talk_to client 3 send "1201 0 5 [holl "gazonk"]\n" simple_expect "=1201" send "1202 42 255\n" simple_expect "=1202" send "1203 44 0\n" simple_expect "=1203" client_death 3 client_death 2 client_death 1 client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/bug-38.exp0000664000015100472110000000315307721716134017520 # Test suite for lyskomd. # Copyright (C) 1999-2000, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. read_versions source "$srcdir/config/prot-a.exp" lyskomd_start client_start 0 talk_to client 0 send "A[holl "DejaGnu test suite"]\n" simple_expect "LysKOM" "bug38: Connected" kom_accept_async "0 { }" kom_create_person "P6" "pw1" "00000000" "0 { }" kom_login 5 "gazonk" 0 kom_create_conference "C7" "10000000" "0 { }" kom_create_conference "C8" "10100000" "0 { }" kom_create_text_simple "T1" 7 kom_create_text_simple "T2" 8 kom_set_user_area 5 1 kom_set_user_area 5 2 kom_login 6 "pw1" 0 kom_set_user_area 6 1 "%\$ref_no 14 1" kom_set_user_area 6 2 "%\$ref_no 14 2" kom_logout kom_login 5 "gazonk" 0 kom_enable 255 kom_shutdown_server client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/bug-48.exp0000664000015100472110000000522707721716134017525 # Test suite for lyskomd. # Copyright (C) 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check that mark-as-read, set-read-ranges, mark-as-unread and # query-read-texts doesn't leak info about secret conferences. lyskomd_start client_start 0 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" send "1000 62 5 [holl "gazonk"] 0\n" simple_expect ":2 9 5 1" simple_expect "=1000" # Create a secret conference. send "1001 88 [holl "secret"] 10101000 0 { }\n" simple_expect "=1001 6" # Join it. send "1002 100 6 5 100 0 00000000\n" simple_expect "=1002" # Log out. send "1003 1\n" simple_expect ":2 13 5 1" simple_expect "=1003" # Create an unprivileged observer, that isn't allowed to know anything # about the secret conference. send "1004 89 [holl "observer"] [holl "passwd"] 00000000 0 { }\n" simple_expect "=1004 7" send "1005 62 7 [holl "passwd"] 0\n" simple_expect ":2 9 7 1" simple_expect "=1005" # We want the error code "undefined-conference", not anything else # such as "not-member". # mark-as-read send "1006 27 6 1 { 1 }\n" simple_expect "%1006 9 6" # mark-as-unread send "1007 109 6 1\n" simple_expect "%1007 9 6" # set-read-ranges send "1008 110 6 1 { 1 1 }\n" simple_expect "%1008 9 6" # query-read-texts, self. send "1009 107 7 6 1 0\n" simple_expect "%1009 9 6" # query-read-texts, somebody who *is* a member. send "1010 107 5 6 1 0\n" simple_expect "%1010 9 6" # query-read-texts-10, self. send "1011 98 7 6\n" simple_expect "%1011 9 6" # query-read-texts-10, somebody who *is* a member. send "1012 98 5 6\n" simple_expect "%1012 9 6" # query-read-texts-old, self. send "1013 9 7 6\n" simple_expect "%1013 9 6" # query-read-texts-old, somebody who *is* a member. send "1014 9 5 6\n" simple_expect "%1014 9 6" # Shut everything down. system "kill -TERM $lyskomd_pid" lyskomd_death {} signal client_death 0 lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/bug-52.data0000664000015100472110000001430307563053425017631 CLEAN:00002 00000000001036797269 #C 6 #T 21 I 1 2 3 4 0 0 0 * C 1 31HPresentations (for) conferences 1 { 5 5 1036796628 00000000 } [21 1:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] 00001000 684774708 1036796606 0 0 0 0 0 0 77 77 0 0 0 * C 2 27HPresentations (for) members 1 { 5 5 1036796631 00000000 } [21 1:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] 00001000 684774708 1036796606 0 0 0 0 0 0 77 77 0 0 0 * C 3 7HNotices 1 { 5 5 1036796635 00000000 } [21 1:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] 00001000 684774708 1036796606 0 0 0 0 0 0 77 77 0 0 0 * C 4 17HNews about LysKOM 1 { 5 5 1036796638 00000000 } [21 1:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] 00001000 684774708 1036796606 0 0 0 0 0 0 77 77 0 0 0 * C 5 25HAdministrator (of) LysKOM 1 { 5 5 1036796654 00000000 } [21 1:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] 10011000 684774889 1036796606 5 0 5 0 0 0 77 77 0 0 0 * P 5 64H9gR7fFYRjkjts 26Hceder%moria(unknown)@moria 1111111111111111 00000000 [21 1:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] 0 * 5 { 1036796654 5 255 0 0 * 5 1036796654 00000000 1036796628 1 100 0 0 * 5 1036796628 00000000 1036796631 2 100 0 0 * 5 1036796631 00000000 1036796635 3 100 0 0 * 5 1036796635 00000000 1036796638 4 100 0 0 * 5 1036796638 00000000 } 1036796668 0 701 5 20 251 20 40 0 0 T 1 1036796499 5 0 1 12 0 12 { 0 1 6 1 0 2 6 1 0 3 6 1 0 4 6 1 0 5 6 1 7 1036796502 3 2 } 2 2 { 1 15 5 1036796499 00000000 0 34Hlyskom.el 0.47.1 (2002-11-01; CVS) 0 0 2 1 5 1036796499 00000000 1 33Htext/x-kom-basic;charset=us-ascii 0 0 } T 2 1036796509 5 12 1 12 0 13 { 2 1 0 1 6 2 0 2 6 2 0 3 6 2 0 4 6 2 0 5 6 2 7 1036796511 3 3 } 2 2 { 1 15 5 1036796509 00000000 0 34Hlyskom.el 0.47.1 (2002-11-01; CVS) 0 0 2 1 5 1036796509 00000000 1 33Htext/x-kom-basic;charset=us-ascii 0 0 } T 3 1036796517 5 24 1 12 0 13 { 2 2 0 1 6 3 0 2 6 3 0 3 6 3 0 4 6 3 0 5 6 3 7 1036796517 3 4 } 2 2 { 1 15 5 1036796517 00000000 0 34Hlyskom.el 0.47.1 (2002-11-01; CVS) 0 0 2 1 5 1036796517 00000000 1 33Htext/x-kom-basic;charset=us-ascii 0 0 } T 4 1036796525 5 36 1 12 0 13 { 2 3 0 1 6 4 0 2 6 4 0 3 6 4 0 4 6 4 0 5 6 4 7 1036796526 3 5 } 2 2 { 1 15 5 1036796525 00000000 0 34Hlyskom.el 0.47.1 (2002-11-01; CVS) 0 0 2 1 5 1036796525 00000000 1 33Htext/x-kom-basic;charset=us-ascii 0 0 } T 5 1036796531 5 48 1 12 0 13 { 2 4 0 1 6 5 0 2 6 5 0 3 6 5 0 4 6 5 0 5 6 5 7 1036796532 3 6 } 2 2 { 1 15 5 1036796531 00000000 0 34Hlyskom.el 0.47.1 (2002-11-01; CVS) 0 0 2 1 5 1036796531 00000000 1 33Htext/x-kom-basic;charset=us-ascii 0 0 } T 6 1036796541 5 60 1 12 0 13 { 2 5 0 1 6 6 0 2 6 6 0 3 6 6 0 4 6 6 0 5 6 6 7 1036796543 3 7 } 2 2 { 1 15 5 1036796541 00000000 0 34Hlyskom.el 0.47.1 (2002-11-01; CVS) 0 0 2 1 5 1036796541 00000000 1 33Htext/x-kom-basic;charset=us-ascii 0 0 } T 7 1036796547 5 72 1 12 0 13 { 2 6 0 1 6 7 0 2 6 7 0 3 6 7 0 4 6 7 0 5 6 7 7 1036796548 3 8 } 2 2 { 1 15 5 1036796547 00000000 0 34Hlyskom.el 0.47.1 (2002-11-01; CVS) 0 0 2 1 5 1036796547 00000000 1 33Htext/x-kom-basic;charset=us-ascii 0 0 } T 8 1036796551 5 84 1 12 0 13 { 2 7 0 1 6 8 0 2 6 8 0 3 6 8 0 4 6 8 0 5 6 8 7 1036796552 3 9 } 2 2 { 1 15 5 1036796551 00000000 0 34Hlyskom.el 0.47.1 (2002-11-01; CVS) 0 0 2 1 5 1036796551 00000000 1 33Htext/x-kom-basic;charset=us-ascii 0 0 } T 9 1036796556 5 96 1 12 0 13 { 2 8 0 1 6 9 0 2 6 9 0 3 6 9 0 4 6 9 0 5 6 9 7 1036796557 3 10 } 2 2 { 1 15 5 1036796556 00000000 0 34Hlyskom.el 0.47.1 (2002-11-01; CVS) 0 0 2 1 5 1036796556 00000000 1 33Htext/x-kom-basic;charset=us-ascii 0 0 } T 10 1036796560 5 108 1 13 0 13 { 2 9 0 1 6 10 0 2 6 10 0 3 6 10 0 4 6 10 0 5 6 10 7 1036796561 3 11 } 2 2 { 1 15 5 1036796560 00000000 0 34Hlyskom.el 0.47.1 (2002-11-01; CVS) 0 0 2 1 5 1036796560 00000000 1 33Htext/x-kom-basic;charset=us-ascii 0 0 } T 11 1036796565 5 121 1 13 0 13 { 2 10 0 1 6 11 0 2 6 11 0 3 6 11 0 4 6 11 0 5 6 11 7 1036796567 3 12 } 2 2 { 1 15 5 1036796565 00000000 0 34Hlyskom.el 0.47.1 (2002-11-01; CVS) 0 0 2 1 5 1036796565 00000000 1 33Htext/x-kom-basic;charset=us-ascii 0 0 } T 12 1036796570 5 134 1 13 0 13 { 2 11 0 1 6 12 0 2 6 12 0 3 6 12 0 4 6 12 0 5 6 12 7 1036796570 3 13 } 2 2 { 1 15 5 1036796570 00000000 0 34Hlyskom.el 0.47.1 (2002-11-01; CVS) 0 0 2 1 5 1036796570 00000000 1 33Htext/x-kom-basic;charset=us-ascii 0 0 } T 13 1036796574 5 147 1 13 0 13 { 2 12 0 1 6 13 0 2 6 13 0 3 6 13 0 4 6 13 0 5 6 13 7 1036796574 3 14 } 2 2 { 1 15 5 1036796574 00000000 0 34Hlyskom.el 0.47.1 (2002-11-01; CVS) 0 0 2 1 5 1036796574 00000000 1 33Htext/x-kom-basic;charset=us-ascii 0 0 } T 14 1036796578 5 160 1 13 0 13 { 2 13 0 1 6 14 0 2 6 14 0 3 6 14 0 4 6 14 0 5 6 14 7 1036796578 3 15 } 2 2 { 1 15 5 1036796578 00000000 0 34Hlyskom.el 0.47.1 (2002-11-01; CVS) 0 0 2 1 5 1036796578 00000000 1 33Htext/x-kom-basic;charset=us-ascii 0 0 } T 15 1036796583 5 173 1 13 0 13 { 2 14 0 1 6 15 0 2 6 15 0 3 6 15 0 4 6 15 0 5 6 15 7 1036796584 3 16 } 2 2 { 1 15 5 1036796583 00000000 0 34Hlyskom.el 0.47.1 (2002-11-01; CVS) 0 0 2 1 5 1036796583 00000000 1 33Htext/x-kom-basic;charset=us-ascii 0 0 } T 16 1036796590 5 186 1 13 0 13 { 2 15 0 1 6 16 0 2 6 16 0 3 6 16 0 4 6 16 0 5 6 16 7 1036796591 3 17 } 2 2 { 1 15 5 1036796590 00000000 0 34Hlyskom.el 0.47.1 (2002-11-01; CVS) 0 0 2 1 5 1036796590 00000000 1 33Htext/x-kom-basic;charset=us-ascii 0 0 } T 17 1036796595 5 199 1 13 0 13 { 2 16 0 1 6 17 0 2 6 17 0 3 6 17 0 4 6 17 0 5 6 17 7 1036796596 3 18 } 2 2 { 1 15 5 1036796595 00000000 0 34Hlyskom.el 0.47.1 (2002-11-01; CVS) 0 0 2 1 5 1036796595 00000000 1 33Htext/x-kom-basic;charset=us-ascii 0 0 } T 18 1036796599 5 212 1 13 0 13 { 2 17 0 1 6 18 0 2 6 18 0 3 6 18 0 4 6 18 0 5 6 18 7 1036796600 3 19 } 2 2 { 1 15 5 1036796599 00000000 0 34Hlyskom.el 0.47.1 (2002-11-01; CVS) 0 0 2 1 5 1036796599 00000000 1 33Htext/x-kom-basic;charset=us-ascii 0 0 } T 19 1036796603 5 225 1 13 0 13 { 2 18 0 1 6 19 0 2 6 19 0 3 6 19 0 4 6 19 0 5 6 19 7 1036796603 3 20 } 2 2 { 1 15 5 1036796603 00000000 0 34Hlyskom.el 0.47.1 (2002-11-01; CVS) 0 0 2 1 5 1036796603 00000000 1 33Htext/x-kom-basic;charset=us-ascii 0 0 } T 20 1036796606 5 238 1 13 0 12 { 2 19 0 1 6 20 0 2 6 20 0 3 6 20 0 4 6 20 0 5 6 20 7 1036796607 } 2 2 { 1 15 5 1036796606 00000000 0 34Hlyskom.el 0.47.1 (2002-11-01; CVS) 0 0 2 1 5 1036796606 00000000 1 33Htext/x-kom-basic;charset=us-ascii 0 0 } lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/bug-52.exp0000664000015100472110000007037007722446227017525 # Test suite for lyskomd. # Copyright (C) 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check that the read-text part of a membership can be saved and # restored. # Set to 1 if testing version 2.0.7 or earlier, where the check for # deleted texts only is performed at the end of the first interval. set lazy_expand 0 # Set to 0 if testing version 2.0.7 or earlier, where mark-as-read # processed each local number in turn, without checking for errors # first. set mark_as_read_atomic 1 # Set to 1 to repeatedly stop and start lyskomd, thus testing that we # can save and restore the information about read texts. Set to 0 to # speed up the test, at the cost of not testing everything that needs # to be tested. set do_restart 1 if {$do_restart == 0} { unsupported "saving read-ranges to disk (Bug 52)" } obtain_lock unpack_db bug-52 proc start {} { lyskomd_start "" "Garb: no" "" "" "" [list \ "WARN: [pwd]/db/number.txt: No such file" \ ] 0 0 6 21 1 client_start 0 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" send "999 62 5 [holl "gazonk"] 0\n" simple_expect ":2 9 5 1" simple_expect "=999" } proc stop {} { global lyskomd_pid system "kill -TERM $lyskomd_pid" lyskomd_death {} signal client_death 0 } proc restart {} { global do_restart if {$do_restart} { stop start } } proc checkit {pos conf prio last arrsize array ranges} { global any_time send "1 99 5 $pos 1 0\n" simple_expect "=1 1 { $pos $any_time $conf $prio $last $arrsize \\* 5 $any_time 00000000 }" "$last $arrsize $array" send "2 99 5 $pos 1 1\n" simple_expect "=2 1 { $pos $any_time $conf $prio $last $arrsize $array 5 $any_time 00000000 }" "$last $arrsize $array" send "3 98 5 $conf\n" simple_expect "=3 $pos $any_time $conf $prio $last $arrsize $array 5 $any_time 00000000" "$last $arrsize $array" send "4 46 5 $pos 1 0\n" simple_expect "=4 1 { $any_time $conf $prio $last $arrsize \\* }" "$last $arrsize $array" send "5 46 5 $pos 1 1\n" simple_expect "=5 1 { $any_time $conf $prio $last $arrsize $array }" "$last $arrsize $array" send "6 9 5 $conf\n" simple_expect "=6 $any_time $conf $prio $last $arrsize $array" "$last $arrsize $array" send "7 107 5 $conf 1 0\n" simple_expect "=7 $pos $any_time $conf $prio $ranges 5 $any_time 00000000" "$ranges" send "8 107 5 $conf 1 99\n" simple_expect "=8 $pos $any_time $conf $prio $ranges 5 $any_time 00000000" "$ranges" send "9 107 5 $conf 0 99\n" simple_expect "=9 $pos $any_time $conf $prio [lindex $ranges 0] \\* 5 $any_time 00000000" "[lindex $ranges 0] *" send "10 108 5 $pos 1 0 0\n" simple_expect "=10 1 { $pos $any_time $conf $prio [lindex $ranges 0] \\* 5 $any_time 00000000 }" "[lindex $ranges 0] *" send "11 108 5 $pos 1 1 0\n" simple_expect "=11 1 { $pos $any_time $conf $prio $ranges 5 $any_time 00000000 }" "$ranges" send "12 108 5 $pos 1 1 99\n" simple_expect "=12 1 { $pos $any_time $conf $prio $ranges 5 $any_time 00000000 }" "$ranges" } proc check_unread_confs {confs} { send "50 52 5\n" if {[llength $confs] > 0} { simple_expect "=50 [llength $confs] { $confs }" } else { simple_expect "=50 [llength $confs] \\*" } } start checkit 0 5 255 0 0 "\\*" "0 \\*" checkit 1 1 100 0 0 "\\*" "0 \\*" checkit 2 2 100 0 0 "\\*" "0 \\*" checkit 3 3 100 0 0 "\\*" "0 \\*" checkit 4 4 100 0 0 "\\*" "0 \\*" check_unread_confs {5 1 2 3 4} restart checkit 0 5 255 0 0 "\\*" "0 \\*" checkit 1 1 100 0 0 "\\*" "0 \\*" checkit 2 2 100 0 0 "\\*" "0 \\*" checkit 3 3 100 0 0 "\\*" "0 \\*" checkit 4 4 100 0 0 "\\*" "0 \\*" check_unread_confs {5 1 2 3 4} send "1000 27 5 1 { 2 }\n" simple_expect "=1000" send "1001 27 1 0 { }\n" simple_expect "=1001" send "1002 27 2 1 { 1 }\n" simple_expect "=1002" send "1003 27 3 2 { 1 2 }\n" simple_expect "=1003" send "1004 27 4 2 { 1 3 }\n" simple_expect "=1004" checkit 0 5 255 0 1 "{ 2 }" "1 { 2 2 }" checkit 1 1 100 0 0 "\\*" "0 \\*" checkit 2 2 100 1 0 "\\*" "1 { 1 1 }" checkit 3 3 100 2 0 "\\*" "1 { 1 2 }" checkit 4 4 100 1 1 "{ 3 }" "2 { 1 1 3 3 }" check_unread_confs {5 1 2 3 4} restart checkit 0 5 255 0 1 "{ 2 }" "1 { 2 2 }" checkit 1 1 100 0 0 "\\*" "0 \\*" checkit 2 2 100 1 0 "\\*" "1 { 1 1 }" checkit 3 3 100 2 0 "\\*" "1 { 1 2 }" checkit 4 4 100 1 1 "{ 3 }" "2 { 1 1 3 3 }" check_unread_confs {5 1 2 3 4} send "1005 27 5 1 { 4 }\n" simple_expect "=1005" send "1006 27 1 2 { 2 4 }\n" simple_expect "=1006" send "1007 27 2 1 { 2 }\n" simple_expect "=1007" send "1008 27 3 2 { 4 3 }\n" simple_expect "=1008" send "1009 27 4 2 { 5 6 }\n" simple_expect "=1009" checkit 0 5 255 0 2 "{ 2 4 }" "2 { 2 2 4 4 }" checkit 1 1 100 0 2 "{ 2 4 }" "2 { 2 2 4 4 }" checkit 2 2 100 2 0 "\\*" "1 { 1 2 }" checkit 3 3 100 4 0 "\\*" "1 { 1 4 }" checkit 4 4 100 1 3 "{ 3 5 6 }" "3 { 1 1 3 3 5 6 }" check_unread_confs {5 1 2 3 4} restart checkit 0 5 255 0 2 "{ 2 4 }" "2 { 2 2 4 4 }" checkit 1 1 100 0 2 "{ 2 4 }" "2 { 2 2 4 4 }" checkit 2 2 100 2 0 "\\*" "1 { 1 2 }" checkit 3 3 100 4 0 "\\*" "1 { 1 4 }" checkit 4 4 100 1 3 "{ 3 5 6 }" "3 { 1 1 3 3 5 6 }" check_unread_confs {5 1 2 3 4} send "1010 27 5 1 { 3 }\n" simple_expect "=1010" send "1011 27 1 2 { 8 6 }\n" simple_expect "=1011" send "1012 27 2 1 { 3 }\n" simple_expect "=1012" send "1013 27 3 7 { 7 8 9 11 12 14 18 }\n" simple_expect "=1013" send "1014 27 4 1 { 2 }\n" simple_expect "=1014" checkit 0 5 255 0 3 "{ 2 3 4 }" "1 { 2 4 }" checkit 1 1 100 0 4 "{ 2 4 6 8 }" "4 { 2 2 4 4 6 6 8 8 }" checkit 2 2 100 3 0 "\\*" "1 { 1 3 }" checkit 3 3 100 4 7 "{ 7 8 9 11 12 14 18 }" "5 { 1 4 7 9 11 12 14 14 18 18 }" checkit 4 4 100 3 2 "{ 5 6 }" "2 { 1 3 5 6 }" check_unread_confs {5 1 2 3 4} restart checkit 0 5 255 0 3 "{ 2 3 4 }" "1 { 2 4 }" checkit 1 1 100 0 4 "{ 2 4 6 8 }" "4 { 2 2 4 4 6 6 8 8 }" checkit 2 2 100 3 0 "\\*" "1 { 1 3 }" checkit 3 3 100 4 7 "{ 7 8 9 11 12 14 18 }" "5 { 1 4 7 9 11 12 14 14 18 18 }" checkit 4 4 100 3 2 "{ 5 6 }" "2 { 1 3 5 6 }" check_unread_confs {5 1 2 3 4} send "1015 27 5 1 { 1 }\n" simple_expect "=1015" send "1016 27 1 1 { 1 }\n" simple_expect "=1016" send "1017 27 2 1 { 2 }\n" simple_expect "=1017" send "1018 27 3 1 { 13 }\n" simple_expect "=1018" send "1019 27 4 1 { 4 }\n" simple_expect "=1019" checkit 0 5 255 4 0 "\\*" "1 { 1 4 }" checkit 1 1 100 2 3 "{ 4 6 8 }" "4 { 1 2 4 4 6 6 8 8 }" checkit 2 2 100 3 0 "\\*" "1 { 1 3 }" checkit 3 3 100 4 8 "{ 7 8 9 11 12 13 14 18 }" "4 { 1 4 7 9 11 14 18 18 }" checkit 4 4 100 6 0 "\\*" "1 { 1 6 }" check_unread_confs {5 1 2 3 4} restart checkit 0 5 255 4 0 "\\*" "1 { 1 4 }" checkit 1 1 100 2 3 "{ 4 6 8 }" "4 { 1 2 4 4 6 6 8 8 }" checkit 2 2 100 3 0 "\\*" "1 { 1 3 }" checkit 3 3 100 4 8 "{ 7 8 9 11 12 13 14 18 }" "4 { 1 4 7 9 11 14 18 18 }" checkit 4 4 100 6 0 "\\*" "1 { 1 6 }" check_unread_confs {5 1 2 3 4} send "1020 27 5 1 { 7 }\n" simple_expect "=1020" send "1021 27 1 3 { 3 5 7 }\n" simple_expect "=1021" send "1022 27 2 1 { 8 }\n" simple_expect "=1022" send "1023 27 3 1 { 16 }\n" simple_expect "=1023" send "1024 40 4 20\n" simple_expect "=1024" checkit 0 5 255 4 1 "{ 7 }" "2 { 1 4 7 7 }" checkit 1 1 100 8 0 "\\*" "1 { 1 8 }" checkit 2 2 100 3 1 "{ 8 }" "2 { 1 3 8 8 }" checkit 3 3 100 4 9 "{ 7 8 9 11 12 13 14 16 18 }" \ "5 { 1 4 7 9 11 14 16 16 18 18 }" checkit 4 4 100 0 0 "\\*" "0 \\*" check_unread_confs {5 1 2 3 4} restart checkit 0 5 255 4 1 "{ 7 }" "2 { 1 4 7 7 }" checkit 1 1 100 8 0 "\\*" "1 { 1 8 }" checkit 2 2 100 3 1 "{ 8 }" "2 { 1 3 8 8 }" checkit 3 3 100 4 9 "{ 7 8 9 11 12 13 14 16 18 }" \ "5 { 1 4 7 9 11 14 16 16 18 18 }" checkit 4 4 100 0 0 "\\*" "0 \\*" check_unread_confs {5 1 2 3 4} send "1025 27 5 1 { 6 }\n" simple_expect "=1025" send "1026 77 1 0\n" simple_expect "=1026" send "1027 77 2 1\n" simple_expect "=1027" send "1028 27 3 1 { 6 }\n" simple_expect "=1028" send "1029 27 4 1 { 3 }\n" simple_expect "=1029" checkit 0 5 255 4 2 "{ 6 7 }" "2 { 1 4 6 7 }" checkit 1 1 100 0 0 "\\*" "0 \\*" checkit 2 2 100 1 0 "\\*" "1 { 1 1 }" checkit 3 3 100 4 10 "{ 6 7 8 9 11 12 13 14 16 18 }" \ "5 { 1 4 6 9 11 14 16 16 18 18 }" checkit 4 4 100 0 1 "{ 3 }" "1 { 3 3 }" check_unread_confs {5 1 2 3 4} restart checkit 0 5 255 4 2 "{ 6 7 }" "2 { 1 4 6 7 }" checkit 1 1 100 0 0 "\\*" "0 \\*" checkit 2 2 100 1 0 "\\*" "1 { 1 1 }" checkit 3 3 100 4 10 "{ 6 7 8 9 11 12 13 14 16 18 }" \ "5 { 1 4 6 9 11 14 16 16 18 18 }" checkit 4 4 100 0 1 "{ 3 }" "1 { 3 3 }" check_unread_confs {5 1 2 3 4} send "1030 27 5 1 { 5 }\n" simple_expect "=1030" send "1031 77 1 2\n" simple_expect "=1031" send "1032 40 2 19\n" simple_expect "=1032" send "1033 27 3 1 { 5 }\n" simple_expect "=1033" send "1034 27 4 1 { 2 }\n" simple_expect "=1034" checkit 0 5 255 7 0 "\\*" "1 { 1 7 }" checkit 1 1 100 2 0 "\\*" "1 { 1 2 }" checkit 2 2 100 1 0 "\\*" "1 { 1 1 }" checkit 3 3 100 9 6 "{ 11 12 13 14 16 18 }" "4 { 1 9 11 14 16 16 18 18 }" checkit 4 4 100 0 2 "{ 2 3 }" "1 { 2 3 }" check_unread_confs {5 1 2 3 4} restart checkit 0 5 255 7 0 "\\*" "1 { 1 7 }" checkit 1 1 100 2 0 "\\*" "1 { 1 2 }" checkit 2 2 100 1 0 "\\*" "1 { 1 1 }" checkit 3 3 100 9 6 "{ 11 12 13 14 16 18 }" "4 { 1 9 11 14 16 16 18 18 }" checkit 4 4 100 0 2 "{ 2 3 }" "1 { 2 3 }" check_unread_confs {5 1 2 3 4} send "1035 27 5 1 { 20 }\n" simple_expect "=1035" send "1036 27 5 1 { 21 }\n" simple_expect "%1036 16 0" send "1037 40 2 18\n" simple_expect "=1037" send "1038 27 3 1 { 15 }\n" simple_expect "=1038" send "1039 27 4 1 { 1 }\n" simple_expect "=1039" checkit 0 5 255 7 1 "{ 20 }" "2 { 1 7 20 20 }" checkit 1 1 100 2 0 "\\*" "1 { 1 2 }" checkit 2 2 100 2 0 "\\*" "1 { 1 2 }" checkit 3 3 100 9 7 "{ 11 12 13 14 15 16 18 }" "3 { 1 9 11 16 18 18 }" checkit 4 4 100 3 0 "\\*" "1 { 1 3 }" check_unread_confs {5 1 2 3 4} restart checkit 0 5 255 7 1 "{ 20 }" "2 { 1 7 20 20 }" checkit 1 1 100 2 0 "\\*" "1 { 1 2 }" checkit 2 2 100 2 0 "\\*" "1 { 1 2 }" checkit 3 3 100 9 7 "{ 11 12 13 14 15 16 18 }" "3 { 1 9 11 16 18 18 }" checkit 4 4 100 3 0 "\\*" "1 { 1 3 }" # Subtract text 3 from conference 2. send "1040 31 3 2\n" simple_expect "=1040" send "1041 27 5 2 { 19 21 }\n" simple_expect "%1041 16 1" send "1042 27 1 2 { 21 19 }\n" simple_expect "%1042 16 0" send "1043 27 2 0 { }\n" simple_expect "=1043" send "1044 27 3 1 { 10 }\n" simple_expect "=1044" send "1045 27 4 1 { 18 }\n" simple_expect "=1045" if {$mark_as_read_atomic} { checkit 0 5 255 7 1 "{ 20 }" "2 { 1 7 20 20 }" } else { setup_xfail "*-*-*" "mark-as-read processes some stuff and returns error" fail "mark-as-read" checkit 0 5 255 7 2 "{ 19 20 }" "2 { 1 7 19 20 }" } checkit 1 1 100 2 0 "\\*" "1 { 1 2 }" checkit 2 2 100 3 0 "\\*" "1 { 1 3 }" checkit 3 3 100 16 1 "{ 18 }" "2 { 1 16 18 18 }" checkit 4 4 100 3 1 "{ 18 }" "2 { 1 3 18 18 }" check_unread_confs {5 1 2 3 4} restart if {$mark_as_read_atomic} { checkit 0 5 255 7 1 "{ 20 }" "2 { 1 7 20 20 }" } else { checkit 0 5 255 7 2 "{ 19 20 }" "2 { 1 7 19 20 }" } checkit 1 1 100 2 0 "\\*" "1 { 1 2 }" checkit 2 2 100 3 0 "\\*" "1 { 1 3 }" checkit 3 3 100 16 1 "{ 18 }" "2 { 1 16 18 18 }" checkit 4 4 100 3 1 "{ 18 }" "2 { 1 3 18 18 }" check_unread_confs {5 1 2 3 4} # Subtract texts 10-12, 14-15 from conference 1. send "1046 31 10 1\n" simple_expect "=1046" send "1047 31 11 1\n" simple_expect "=1047" send "1048 31 12 1\n" simple_expect "=1048" send "1049 31 14 1\n" simple_expect "=1049" send "1050 31 15 1\n" simple_expect "=1050" # Subtract text 4 from conference 2. send "1051 31 4 2\n" simple_expect "=1051" send "1052 27 5 1 { 19 }\n" simple_expect "=1052" send "1053 27 1 1 { 8 }\n" simple_expect "=1053" send "1054 27 2 0 { }\n" simple_expect "=1054" send "1055 27 3 1 { 17 }\n" simple_expect "=1055" send "1056 27 4 1 { 17 }\n" simple_expect "=1056" checkit 0 5 255 7 2 "{ 19 20 }" "2 { 1 7 19 20 }" checkit 1 1 100 2 1 "{ 8 }" "2 { 1 2 8 8 }" checkit 2 2 100 4 0 "\\*" "1 { 1 4 }" checkit 3 3 100 18 0 "\\*" "1 { 1 18 }" checkit 4 4 100 3 2 "{ 17 18 }" "2 { 1 3 17 18 }" check_unread_confs {5 1 2 3 4} restart checkit 0 5 255 7 2 "{ 19 20 }" "2 { 1 7 19 20 }" checkit 1 1 100 2 1 "{ 8 }" "2 { 1 2 8 8 }" checkit 2 2 100 4 0 "\\*" "1 { 1 4 }" checkit 3 3 100 18 0 "\\*" "1 { 1 18 }" checkit 4 4 100 3 2 "{ 17 18 }" "2 { 1 3 17 18 }" check_unread_confs {5 1 2 3 4} send "1057 27 5 1 { 18 }\n" simple_expect "=1057" send "1058 27 1 1 { 9 }\n" simple_expect "=1058" send "1059 27 2 1 { 4 }\n" simple_expect "=1059" send "1060 27 3 1 { 20 }\n" simple_expect "=1060" send "1061 27 4 1 { 19 }\n" simple_expect "=1061" checkit 0 5 255 7 3 "{ 18 19 20 }" "2 { 1 7 18 20 }" if {$lazy_expand} { checkit 1 1 100 2 2 "{ 8 9 }" "2 { 1 2 8 9 }" } else { checkit 1 1 100 2 5 "{ 8 9 10 11 12 }" "2 { 1 2 8 12 }" } checkit 2 2 100 4 0 "\\*" "1 { 1 4 }" checkit 3 3 100 18 1 "{ 20 }" "2 { 1 18 20 20 }" checkit 4 4 100 3 3 "{ 17 18 19 }" "2 { 1 3 17 19 }" check_unread_confs {5 1 2 3 4} restart checkit 0 5 255 7 3 "{ 18 19 20 }" "2 { 1 7 18 20 }" if {$lazy_expand} { checkit 1 1 100 2 2 "{ 8 9 }" "2 { 1 2 8 9 }" } else { checkit 1 1 100 2 5 "{ 8 9 10 11 12 }" "2 { 1 2 8 12 }" } checkit 2 2 100 4 0 "\\*" "1 { 1 4 }" checkit 3 3 100 18 1 "{ 20 }" "2 { 1 18 20 20 }" checkit 4 4 100 3 3 "{ 17 18 19 }" "2 { 1 3 17 19 }" check_unread_confs {5 1 2 3 4} send "1062 27 5 4 { 9 16 12 13 }\n" simple_expect "=1062" send "1063 27 1 1 { 4 }\n" simple_expect "=1063" send "1064 27 2 1 { 5 }\n" simple_expect "=1064" send "1065 27 3 1 { 19 }\n" simple_expect "=1065" send "1066 27 4 1 { 20 }\n" simple_expect "=1066" checkit 0 5 255 7 7 "{ 9 12 13 16 18 19 20 }" "5 { 1 7 9 9 12 13 16 16 18 20 }" if {$lazy_expand} { checkit 1 1 100 2 3 "{ 4 8 9 }" "3 { 1 2 4 4 8 9 }" } else { checkit 1 1 100 2 6 "{ 4 8 9 10 11 12 }" "3 { 1 2 4 4 8 12 }" } checkit 2 2 100 5 0 "\\*" "1 { 1 5 }" checkit 3 3 100 20 0 "\\*" "1 { 1 20 }" checkit 4 4 100 3 4 "{ 17 18 19 20 }" "2 { 1 3 17 20 }" check_unread_confs {5 1 2 4} restart checkit 0 5 255 7 7 "{ 9 12 13 16 18 19 20 }" "5 { 1 7 9 9 12 13 16 16 18 20 }" if {$lazy_expand} { checkit 1 1 100 2 3 "{ 4 8 9 }" "3 { 1 2 4 4 8 9 }" } else { checkit 1 1 100 2 6 "{ 4 8 9 10 11 12 }" "3 { 1 2 4 4 8 12 }" } checkit 2 2 100 5 0 "\\*" "1 { 1 5 }" checkit 3 3 100 20 0 "\\*" "1 { 1 20 }" checkit 4 4 100 3 4 "{ 17 18 19 20 }" "2 { 1 3 17 20 }" check_unread_confs {5 1 2 4} send "1067 27 5 6 { 8 10 11 14 17 15 }\n" simple_expect "=1067" send "1068 27 1 1 { 16 }\n" simple_expect "=1068" send "1069 27 2 1 { 6 }\n" simple_expect "=1069" send "1070 27 4 1 { 4 }\n" simple_expect "=1070" checkit 0 5 255 20 0 "\\*" "1 { 1 20 }" if {$lazy_expand} { checkit 1 1 100 2 4 "{ 4 8 9 16 }" "4 { 1 2 4 4 8 9 16 16 }" } else { checkit 1 1 100 2 9 "{ 4 8 9 10 11 12 14 15 16 }" \ "4 { 1 2 4 4 8 12 14 16 }" } checkit 2 2 100 6 0 "\\*" "1 { 1 6 }" checkit 4 4 100 4 4 "{ 17 18 19 20 }" "2 { 1 4 17 20 }" check_unread_confs {1 2 4} restart checkit 0 5 255 20 0 "\\*" "1 { 1 20 }" if {$lazy_expand} { checkit 1 1 100 2 4 "{ 4 8 9 16 }" "4 { 1 2 4 4 8 9 16 16 }" } else { checkit 1 1 100 2 9 "{ 4 8 9 10 11 12 14 15 16 }" \ "4 { 1 2 4 4 8 12 14 16 }" } checkit 2 2 100 6 0 "\\*" "1 { 1 6 }" checkit 4 4 100 4 4 "{ 17 18 19 20 }" "2 { 1 4 17 20 }" check_unread_confs {1 2 4} send "1071 27 1 1 { 3 }\n" simple_expect "=1071" send "1072 27 2 1 { 8 }\n" simple_expect "=1072" send "1073 27 4 1 { 16 }\n" simple_expect "=1073" if {$lazy_expand} { checkit 1 1 100 4 3 "{ 8 9 16 }" "3 { 1 4 8 9 16 16 }" } else { checkit 1 1 100 4 8 "{ 8 9 10 11 12 14 15 16 }" "3 { 1 4 8 12 14 16 }" } checkit 2 2 100 6 1 "{ 8 }" "2 { 1 6 8 8 }" checkit 4 4 100 4 5 "{ 16 17 18 19 20 }" "2 { 1 4 16 20 }" check_unread_confs {1 2 4} restart if {$lazy_expand} { checkit 1 1 100 4 3 "{ 8 9 16 }" "3 { 1 4 8 9 16 16 }" } else { checkit 1 1 100 4 8 "{ 8 9 10 11 12 14 15 16 }" "3 { 1 4 8 12 14 16 }" } checkit 2 2 100 6 1 "{ 8 }" "2 { 1 6 8 8 }" checkit 4 4 100 4 5 "{ 16 17 18 19 20 }" "2 { 1 4 16 20 }" check_unread_confs {1 2 4} send "1074 27 1 1 { 5 }\n" simple_expect "=1074" send "1075 27 2 1 { 7 }\n" simple_expect "=1075" send "1076 27 4 1 { 5 }\n" simple_expect "=1076" if {$lazy_expand} { checkit 1 1 100 5 3 "{ 8 9 16 }" "3 { 1 5 8 9 16 16 }" } else { checkit 1 1 100 5 8 "{ 8 9 10 11 12 14 15 16 }" "3 { 1 5 8 12 14 16 }" } checkit 2 2 100 8 0 "\\*" "1 { 1 8 }" checkit 4 4 100 5 5 "{ 16 17 18 19 20 }" "2 { 1 5 16 20 }" check_unread_confs {1 2 4} restart if {$lazy_expand} { checkit 1 1 100 5 3 "{ 8 9 16 }" "3 { 1 5 8 9 16 16 }" } else { checkit 1 1 100 5 8 "{ 8 9 10 11 12 14 15 16 }" "3 { 1 5 8 12 14 16 }" } checkit 2 2 100 8 0 "\\*" "1 { 1 8 }" checkit 4 4 100 5 5 "{ 16 17 18 19 20 }" "2 { 1 5 16 20 }" check_unread_confs {1 2 4} send "1077 27 1 1 { 6 }\n" simple_expect "=1077" send "1078 27 2 1 { 9 }\n" simple_expect "=1078" send "1079 27 4 1 { 6 }\n" simple_expect "=1079" if {$lazy_expand} { checkit 1 1 100 6 3 "{ 8 9 16 }" "3 { 1 6 8 9 16 16 }" } else { checkit 1 1 100 6 8 "{ 8 9 10 11 12 14 15 16 }" "3 { 1 6 8 12 14 16 }" } checkit 2 2 100 9 0 "\\*" "1 { 1 9 }" checkit 4 4 100 6 5 "{ 16 17 18 19 20 }" "2 { 1 6 16 20 }" check_unread_confs {1 2 4} restart if {$lazy_expand} { checkit 1 1 100 6 3 "{ 8 9 16 }" "3 { 1 6 8 9 16 16 }" } else { checkit 1 1 100 6 8 "{ 8 9 10 11 12 14 15 16 }" "3 { 1 6 8 12 14 16 }" } checkit 2 2 100 9 0 "\\*" "1 { 1 9 }" checkit 4 4 100 6 5 "{ 16 17 18 19 20 }" "2 { 1 6 16 20 }" check_unread_confs {1 2 4} send "1080 27 1 1 { 7 }\n" simple_expect "=1080" send "1081 27 2 1 { 10 }\n" simple_expect "=1081" send "1082 27 4 1 { 7 }\n" simple_expect "=1082" if {$lazy_expand} { checkit 1 1 100 12 1 "{ 16 }" "2 { 1 12 16 16 }" } else { checkit 1 1 100 12 3 "{ 14 15 16 }" "2 { 1 12 14 16 }" } checkit 2 2 100 10 0 "\\*" "1 { 1 10 }" checkit 4 4 100 7 5 "{ 16 17 18 19 20 }" "2 { 1 7 16 20 }" check_unread_confs {1 2 4} restart if {$lazy_expand} { checkit 1 1 100 12 1 "{ 16 }" "2 { 1 12 16 16 }" } else { checkit 1 1 100 12 3 "{ 14 15 16 }" "2 { 1 12 14 16 }" } checkit 2 2 100 10 0 "\\*" "1 { 1 10 }" checkit 4 4 100 7 5 "{ 16 17 18 19 20 }" "2 { 1 7 16 20 }" check_unread_confs {1 2 4} send "1083 27 1 1 { 13 }\n" simple_expect "=1083" send "1084 27 2 1 { 11 }\n" simple_expect "=1084" send "1085 27 4 1 { 8 }\n" simple_expect "=1085" checkit 1 1 100 16 0 "\\*" "1 { 1 16 }" checkit 2 2 100 11 0 "\\*" "1 { 1 11 }" checkit 4 4 100 8 5 "{ 16 17 18 19 20 }" "2 { 1 8 16 20 }" check_unread_confs {1 2 4} restart checkit 1 1 100 16 0 "\\*" "1 { 1 16 }" checkit 2 2 100 11 0 "\\*" "1 { 1 11 }" checkit 4 4 100 8 5 "{ 16 17 18 19 20 }" "2 { 1 8 16 20 }" check_unread_confs {1 2 4} send "1086 27 1 1 { 17 }\n" simple_expect "=1086" send "1087 27 1 1 { 18 }\n" simple_expect "=1087" send "1088 27 1 1 { 19 }\n" simple_expect "=1088" send "1089 27 1 1 { 20 }\n" simple_expect "=1089" send "1090 27 2 1 { 12 }\n" simple_expect "=1090" send "1091 27 2 1 { 13 }\n" simple_expect "=1091" send "1092 27 2 1 { 14 }\n" simple_expect "=1092" send "1093 27 2 1 { 15 }\n" simple_expect "=1093" send "1094 27 2 1 { 16 }\n" simple_expect "=1094" send "1095 27 2 1 { 17 }\n" simple_expect "=1095" send "1096 27 2 1 { 18 }\n" simple_expect "=1096" send "1097 27 2 1 { 19 }\n" simple_expect "=1097" send "1098 27 2 1 { 20 }\n" simple_expect "=1098" send "1099 27 4 1 { 9 }\n" simple_expect "=1099" send "1100 27 4 1 { 10 }\n" simple_expect "=1100" send "1101 27 4 1 { 11 }\n" simple_expect "=1101" send "1102 27 4 1 { 12 }\n" simple_expect "=1102" send "1103 27 4 1 { 13 }\n" simple_expect "=1103" send "1104 27 4 1 { 14 }\n" simple_expect "=1104" send "1105 27 4 1 { 15 }\n" simple_expect "=1105" checkit 0 5 255 20 0 "\\*" "1 { 1 20 }" checkit 1 1 100 20 0 "\\*" "1 { 1 20 }" checkit 2 2 100 20 0 "\\*" "1 { 1 20 }" checkit 3 3 100 20 0 "\\*" "1 { 1 20 }" checkit 4 4 100 20 0 "\\*" "1 { 1 20 }" check_unread_confs {} restart checkit 0 5 255 20 0 "\\*" "1 { 1 20 }" checkit 1 1 100 20 0 "\\*" "1 { 1 20 }" checkit 2 2 100 20 0 "\\*" "1 { 1 20 }" checkit 3 3 100 20 0 "\\*" "1 { 1 20 }" checkit 4 4 100 20 0 "\\*" "1 { 1 20 }" check_unread_confs {} # Make everything unread once again. send "1106 77 5 0\n" simple_expect "=1106" send "1107 77 1 0\n" simple_expect "=1107" send "1108 77 2 0\n" simple_expect "=1108" send "1109 77 3 0\n" simple_expect "=1109" send "1110 77 4 0\n" simple_expect "=1110" checkit 0 5 255 0 0 "\\*" "0 \\*" checkit 1 1 100 0 0 "\\*" "0 \\*" checkit 2 2 100 0 0 "\\*" "0 \\*" checkit 3 3 100 0 0 "\\*" "0 \\*" checkit 4 4 100 0 0 "\\*" "0 \\*" check_unread_confs {5 1 2 3 4} # Subtract text 1, 3, 5-18, 20 from conference 5. foreach lno {1 3 5 6 7 8 9 10 11 12 13 14 15 16 17 18 20} { send "101 31 $lno 5\n" simple_expect "=101" } # Subtract text 1-2 (10-12, 14-15) from conference 1. send "1111 31 1 1\n" simple_expect "=1111" send "1112 31 2 1\n" simple_expect "=1112" # Subtract text (3-4), 5-8, 10-18 from conference 2. foreach lno {5 6 7 8 10 11 12 13 14 15 16 17 18} { send "101 31 $lno 2\n" simple_expect "=101" } # Subtract text 1-20 from conference 3. foreach lno {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20} { send "101 31 $lno 3\n" simple_expect "=101" } # Subtract text 10-20 from conference 4. foreach lno {10 11 12 13 14 15 16 17 18 19 20} { send "101 31 $lno 4\n" simple_expect "=101" } checkit 0 5 255 0 0 "\\*" "0 \\*" checkit 1 1 100 0 0 "\\*" "0 \\*" checkit 2 2 100 0 0 "\\*" "0 \\*" checkit 3 3 100 0 0 "\\*" "0 \\*" checkit 4 4 100 0 0 "\\*" "0 \\*" check_unread_confs {5 1 2 3 4} restart checkit 0 5 255 0 0 "\\*" "0 \\*" checkit 1 1 100 0 0 "\\*" "0 \\*" checkit 2 2 100 0 0 "\\*" "0 \\*" checkit 3 3 100 0 0 "\\*" "0 \\*" checkit 4 4 100 0 0 "\\*" "0 \\*" check_unread_confs {5 1 2 3 4} send "1113 27 5 1 { 2 }\n" simple_expect "=1113" send "1114 27 1 1 { 3 }\n" simple_expect "=1114" send "1115 27 2 1 { 1 }\n" simple_expect "=1115" send "1116 27 3 1 { 10 }\n" simple_expect "=1116" send "1117 27 4 1 { 1 }\n" simple_expect "=1117" checkit 0 5 255 3 0 "\\*" "1 { 1 3 }" checkit 1 1 100 3 0 "\\*" "1 { 1 3 }" checkit 2 2 100 1 0 "\\*" "1 { 1 1 }" checkit 3 3 100 20 0 "\\*" "1 { 1 20 }" checkit 4 4 100 1 0 "\\*" "1 { 1 1 }" check_unread_confs {5 1 2 4} restart checkit 0 5 255 3 0 "\\*" "1 { 1 3 }" checkit 1 1 100 3 0 "\\*" "1 { 1 3 }" checkit 2 2 100 1 0 "\\*" "1 { 1 1 }" checkit 3 3 100 20 0 "\\*" "1 { 1 20 }" checkit 4 4 100 1 0 "\\*" "1 { 1 1 }" check_unread_confs {5 1 2 4} send "1118 27 5 1 { 19 }\n" simple_expect "=1118" send "1119 27 1 1 { 4 }\n" simple_expect "=1119" send "1120 27 2 1 { 2 }\n" simple_expect "=1120" send "1121 27 4 1 { 2 }\n" simple_expect "=1121" if {$lazy_expand} { checkit 0 5 255 3 1 "{ 19 }" "2 { 1 3 19 19 }" } else { checkit 0 5 255 3 16 "{ 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 }" "2 { 1 3 5 20 }" } checkit 1 1 100 4 0 "\\*" "1 { 1 4 }" checkit 2 2 100 8 0 "\\*" "1 { 1 8 }" checkit 4 4 100 2 0 "\\*" "1 { 1 2 }" check_unread_confs {5 1 2 4} restart if {$lazy_expand} { checkit 0 5 255 3 1 "{ 19 }" "2 { 1 3 19 19 }" } else { checkit 0 5 255 3 16 "{ 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 }" "2 { 1 3 5 20 }" } checkit 1 1 100 4 0 "\\*" "1 { 1 4 }" checkit 2 2 100 8 0 "\\*" "1 { 1 8 }" checkit 4 4 100 2 0 "\\*" "1 { 1 2 }" check_unread_confs {5 1 2 4} send "1122 27 5 1 { 4 }\n" simple_expect "=1122" send "1123 27 1 1 { 5 }\n" simple_expect "=1123" send "1124 27 2 1 { 9 }\n" simple_expect "=1124" send "1125 27 4 1 { 3 }\n" simple_expect "=1125" checkit 0 5 255 20 0 "\\*" "1 { 1 20 }" checkit 1 1 100 5 0 "\\*" "1 { 1 5 }" checkit 2 2 100 18 0 "\\*" "1 { 1 18 }" checkit 4 4 100 3 0 "\\*" "1 { 1 3 }" check_unread_confs {1 2 4} restart checkit 0 5 255 20 0 "\\*" "1 { 1 20 }" checkit 1 1 100 5 0 "\\*" "1 { 1 5 }" checkit 2 2 100 18 0 "\\*" "1 { 1 18 }" checkit 4 4 100 3 0 "\\*" "1 { 1 3 }" check_unread_confs {1 2 4} send "1126 27 1 3 { 6 7 8 }\n" simple_expect "=1126" send "1127 27 2 1 { 19 }\n" simple_expect "=1127" send "1128 27 4 5 { 4 6 8 7 5 }\n" simple_expect "=1128" checkit 1 1 100 8 0 "\\*" "1 { 1 8 }" checkit 2 2 100 19 0 "\\*" "1 { 1 19 }" checkit 4 4 100 8 0 "\\*" "1 { 1 8 }" check_unread_confs {1 2 4} restart checkit 1 1 100 8 0 "\\*" "1 { 1 8 }" checkit 2 2 100 19 0 "\\*" "1 { 1 19 }" checkit 4 4 100 8 0 "\\*" "1 { 1 8 }" check_unread_confs {1 2 4} send "1129 27 1 1 { 9 }\n" simple_expect "=1129" send "1130 27 2 1 { 20 }\n" simple_expect "=1130" send "1131 27 4 1 { 9 }\n" simple_expect "=1131" checkit 1 1 100 12 0 "\\*" "1 { 1 12 }" checkit 2 2 100 20 0 "\\*" "1 { 1 20 }" checkit 4 4 100 20 0 "\\*" "1 { 1 20 }" check_unread_confs {1} restart checkit 1 1 100 12 0 "\\*" "1 { 1 12 }" checkit 2 2 100 20 0 "\\*" "1 { 1 20 }" checkit 4 4 100 20 0 "\\*" "1 { 1 20 }" check_unread_confs {1} send "1132 27 1 1 { 13 }\n" simple_expect "=1132" checkit 1 1 100 15 0 "\\*" "1 { 1 15 }" check_unread_confs {1} restart checkit 1 1 100 15 0 "\\*" "1 { 1 15 }" check_unread_confs {1} send "1133 27 1 5 { 20 19 18 17 16 }\n" simple_expect "=1133" checkit 0 5 255 20 0 "\\*" "1 { 1 20 }" checkit 1 1 100 20 0 "\\*" "1 { 1 20 }" checkit 2 2 100 20 0 "\\*" "1 { 1 20 }" checkit 3 3 100 20 0 "\\*" "1 { 1 20 }" checkit 4 4 100 20 0 "\\*" "1 { 1 20 }" check_unread_confs {} restart checkit 0 5 255 20 0 "\\*" "1 { 1 20 }" checkit 1 1 100 20 0 "\\*" "1 { 1 20 }" checkit 2 2 100 20 0 "\\*" "1 { 1 20 }" checkit 3 3 100 20 0 "\\*" "1 { 1 20 }" checkit 4 4 100 20 0 "\\*" "1 { 1 20 }" check_unread_confs {} proc checktrunc {limit res} { global any_time send "200 108 5 4 1 1 $limit\n" simple_expect "=200 1 { 4 $any_time 4 100 $res 5 $any_time 00000000 }" send "201 107 5 4 1 $limit\n" simple_expect "=201 4 $any_time 4 100 $res 5 $any_time 00000000" } checktrunc 0 "1 { 1 20 }" checktrunc 1 "1 { 1 20 }" checktrunc 2 "1 { 1 20 }" checktrunc 3 "1 { 1 20 }" send "1134 77 4 0\n" simple_expect "=1134" checktrunc 0 "0 \\*" checktrunc 1 "0 \\*" checktrunc 2 "0 \\*" checktrunc 3 "0 \\*" send "1135 27 4 1 { 18 }\n" simple_expect "=1135" checktrunc 0 "1 { 10 20 }" checktrunc 1 "1 { 10 20 }" checktrunc 2 "1 { 10 20 }" checktrunc 3 "1 { 10 20 }" send "1136 27 4 1 { 2 }\n" simple_expect "=1136" checktrunc 0 "2 { 2 2 10 20 }" checktrunc 1 "1 { 2 2 }" checktrunc 2 "2 { 2 2 10 20 }" checktrunc 3 "2 { 2 2 10 20 }" send "1137 27 4 1 { 5 }\n" simple_expect "=1137" checktrunc 0 "3 { 2 2 5 5 10 20 }" checktrunc 1 "1 { 2 2 }" checktrunc 2 "2 { 2 2 5 5 }" checktrunc 3 "3 { 2 2 5 5 10 20 }" checktrunc 4 "3 { 2 2 5 5 10 20 }" send "1138 27 4 1 { 1 }\n" simple_expect "=1138" checktrunc 0 "3 { 1 2 5 5 10 20 }" checktrunc 1 "1 { 1 2 }" checktrunc 2 "2 { 1 2 5 5 }" checktrunc 3 "3 { 1 2 5 5 10 20 }" checktrunc 4 "3 { 1 2 5 5 10 20 }" send "1139 27 4 2 { 4 3 }\n" simple_expect "=1139" checktrunc 0 "2 { 1 5 10 20 }" checktrunc 1 "1 { 1 5 }" checktrunc 2 "2 { 1 5 10 20 }" checktrunc 3 "2 { 1 5 10 20 }" checktrunc 4 "2 { 1 5 10 20 }" stop release_lock lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/bug-52.texts0000664000015100472110000000037307563053424020070 hello text 1hello text 2hello text 3hello text 4hello text 5hello text 6hello text 7hello text 8hello text 9hello text 10hello text 11hello text 12hello text 13hello text 14hello text 15hello text 16hello text 17hello text 18hello text 19hello text 20lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/bug-572.exp0000664000015100472110000000475707717413256017622 # Test suite for lyskomd. # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test that the same text cannot be FAQ for the same conference more # than once. # # Persons: # 5: admin # # Conferences: # 6: # 7: # # Texts: # 1: # 2: lyskomd_start # Log in as admin. client_start 0 send "A[holl "foo"]\n" simple_expect "LysKOM" "connected" send "1000 80 0 { }\n" simple_expect "=1000" send "1001 0 5 [holl "gazonk"]\n" simple_expect "=1001" # Create conferences. send "1002 88 [holl "6"] 00000000 0 { }\n" simple_expect "=1002 6" send "1003 88 [holl "7"] 10100000 0 { }\n" simple_expect "=1003 7" # Join the conferences. send "1004 100 6 5 200 1 00000000\n" simple_expect "=1004" send "1005 100 7 5 200 2 00000000\n" simple_expect "=1005" # Create the texts. send "1006 86 [holl "text 1"] 1 { 0 6 } 0 { }\n" simple_expect "=1006 1" send "1007 86 [holl "text 2"] 1 { 0 6 } 0 { }\n" simple_expect "=1007 2" # Set text 1 as FAQ of conference 6. send "1008 93 6 0 { } 1 { 14 00000000 1 [holl "1"] }\n" simple_expect "=1008" # Set text 2 as FAQ of conference 6. send "1009 93 6 0 { } 1 { 14 00000000 1 [holl "2"] }\n" simple_expect "=1009" # Set text 1 as FAQ of conference 7. send "1010 93 7 0 { } 1 { 14 00000000 1 [holl "1"] }\n" simple_expect "=1010" # Set text 2 as FAQ of conference 7. send "1011 93 7 0 { } 1 { 14 00000000 1 [holl "2"] }\n" simple_expect "=1011" # Set text 1 as FAQ of conference 6, again. This should fail. send "1012 93 6 0 { } 1 { 14 00000000 1 [holl "1"] }\n" simple_expect "%1012 48 0" # Shut down. send "1013 42 255\n" simple_expect "=1013" send "1014 44 0\n" simple_expect "=1014" client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/bug-598-2.exp0000664000015100472110000001426607721716134017761 # Test suite for lyskomd. # Copyright (C) 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test bug 598: get-membership and get-membership-old sometimes drops # the array size. # # In this version: the victim has unread-is-secret set. # # Startup and create the players # # Start the server. lyskomd_start # Create and log in as foo (person 6). client_start 0 send "A3Hfoo\n" simple_expect "LysKOM" send "1000 80 0 { }\n" simple_expect "=1000" send "1001 89 [holl "foo"] [holl "p6"] 10000000 0 { }\n" simple_expect "=1001 6" send "1002 62 6 [holl "p6"] 0\n" simple_expect "=1002" # Create and log in as bar (person 7). client_start 1 send "A3Hbar\n" simple_expect "LysKOM" send "1003 80 0 { }\n" simple_expect "=1003" send "1004 89 [holl "bar"] [holl "p7"] 00000000 0 { }\n" simple_expect "=1004 7" send "1005 62 7 [holl "p7"] 0\n" simple_expect "=1005" # Create and log in as super (person 8). client_start 2 send "A3Hsup\n" simple_expect "LysKOM" send "1006 80 0 { }\n" simple_expect "=1006" send "1007 89 [holl "super"] [holl "p8"] 00000000 0 { }\n" simple_expect "=1007 8" send "1008 62 8 [holl "p8"] 0\n" simple_expect "=1008" # # Join conferences # # foo joins 1. talk_to client 0 send "1009 100 1 6 200 1 00000000\n" simple_expect "=1009" # bar joins 1. talk_to client 1 send "1010 100 1 7 200 1 00000000\n" simple_expect "=1010" # # foo writes three texts with 1 as recipient. # talk_to client 0 send "1011 86 [holl "text 1"] 1 { 0 1 } 0 { }\n" simple_expect "=1011 1" send "1012 86 [holl "text 2"] 1 { 0 1 } 0 { }\n" simple_expect "=1012 2" send "1013 86 [holl "text 3"] 1 { 0 1 } 0 { }\n" simple_expect "=1013 3" # foo marks texts 2 and 3 as read send "1014 27 1 2 { 2 3 }\n" simple_expect "=1014" # Get membership with unread info. talk_to client 0 send "1015 99 6 0 100 1\n" simple_expect "=1015 2 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 1 200 0 2 { 2 3 } 6 $any_time 00000000 }" send "1016 46 6 0 100 1\n" simple_expect "=1016 2 { $any_time 6 255 0 0 \\* $any_time 1 200 0 2 { 2 3 } }" talk_to client 1 send "1017 99 6 0 100 1\n" simple_expect "=1017 2 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 1 200 0 0 \\* 6 $any_time 00000000 }" send "1018 46 6 0 100 1\n" simple_expect "=1018 2 { $any_time 6 255 0 0 \\* $any_time 1 200 0 0 \\* }" talk_to client 2 send "1019 99 6 0 100 1\n" simple_expect "=1019 2 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 1 200 0 0 \\* 6 $any_time 00000000 }" send "1020 46 6 0 100 1\n" simple_expect "=1020 2 { $any_time 6 255 0 0 \\* $any_time 1 200 0 0 \\* }" # Get membership without unread info. talk_to client 0 send "1021 99 6 0 100 0\n" simple_expect "=1021 2 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 1 200 0 2 \\* 6 $any_time 00000000 }" send "1022 46 6 0 100 0\n" simple_expect "=1022 2 { $any_time 6 255 0 0 \\* $any_time 1 200 0 2 \\* }" talk_to client 1 send "1023 99 6 0 100 0\n" simple_expect "=1023 2 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 1 200 0 0 \\* 6 $any_time 00000000 }" send "1024 46 6 0 100 0\n" simple_expect "=1024 2 { $any_time 6 255 0 0 \\* $any_time 1 200 0 0 \\* }" talk_to client 2 send "1025 99 6 0 100 0\n" simple_expect "=1025 2 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 1 200 0 0 \\* 6 $any_time 00000000 }" send "1026 46 6 0 100 0\n" simple_expect "=1026 2 { $any_time 6 255 0 0 \\* $any_time 1 200 0 0 \\* }" # Make super admin for foo. talk_to client 0 send "1027 18 6 8\n" simple_expect "=1027" # Get membership with unread info. talk_to client 0 send "1028 99 6 0 100 1\n" simple_expect "=1028 2 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 1 200 0 2 { 2 3 } 6 $any_time 00000000 }" send "1029 46 6 0 100 1\n" simple_expect "=1029 2 { $any_time 6 255 0 0 \\* $any_time 1 200 0 2 { 2 3 } }" talk_to client 1 send "1030 99 6 0 100 1\n" simple_expect "=1030 2 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 1 200 0 0 \\* 6 $any_time 00000000 }" send "1031 46 6 0 100 1\n" simple_expect "=1031 2 { $any_time 6 255 0 0 \\* $any_time 1 200 0 0 \\* }" talk_to client 2 send "1032 99 6 0 100 1\n" simple_expect "=1032 2 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 1 200 0 2 { 2 3 } 6 $any_time 00000000 }" send "1033 46 6 0 100 1\n" simple_expect "=1033 2 { $any_time 6 255 0 0 \\* $any_time 1 200 0 2 { 2 3 } }" # Get membership without unread info. talk_to client 0 send "1034 99 6 0 100 0\n" simple_expect "=1034 2 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 1 200 0 2 \\* 6 $any_time 00000000 }" send "1035 46 6 0 100 0\n" simple_expect "=1035 2 { $any_time 6 255 0 0 \\* $any_time 1 200 0 2 \\* }" talk_to client 1 send "1036 99 6 0 100 0\n" simple_expect "=1036 2 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 1 200 0 0 \\* 6 $any_time 00000000 }" send "1037 46 6 0 100 0\n" simple_expect "=1037 2 { $any_time 6 255 0 0 \\* $any_time 1 200 0 0 \\* }" talk_to client 2 send "1038 99 6 0 100 0\n" simple_expect "=1038 2 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 1 200 0 2 \\* 6 $any_time 00000000 }" send "1039 46 6 0 100 0\n" simple_expect "=1039 2 { $any_time 6 255 0 0 \\* $any_time 1 200 0 2 \\* }" # Shut down. talk_to client 0 send "1040 0 5 [holl "gazonk"]\n" simple_expect "=1040" send "1041 42 255\n" simple_expect "=1041" send "1042 44 0\n" simple_expect "=1042" client_death 1 client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/bug-598.exp0000664000015100472110000001531207721716134017613 # Test suite for lyskomd. # Copyright (C) 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test bug 598: get-membership and get-membership-old sometimes drops # the array size. proc want_array_size {wanted actual} { global test set test "Correct array size returned" # Bug 598 is now fixed. # setup_xfail "*-*-*" "Bug 598" if {$actual == $wanted} { pass "$test" } else { fail "$test (got size $wanted instead of $actual)" } unset test } # # Startup and create the players # # Start the server. lyskomd_start # Create and log in as foo (person 6). client_start 0 send "A3Hfoo\n" simple_expect "LysKOM" send "1000 80 0 { }\n" simple_expect "=1000" send "1001 89 [holl "foo"] [holl "p6"] 00000000 0 { }\n" simple_expect "=1001 6" send "1002 62 6 [holl "p6"] 0\n" simple_expect "=1002" # Create and log in as bar (person 7). client_start 1 send "A3Hbar\n" simple_expect "LysKOM" send "1003 80 0 { }\n" simple_expect "=1003" send "1004 89 [holl "bar"] [holl "p7"] 00000000 0 { }\n" simple_expect "=1004 7" send "1005 62 7 [holl "p7"] 0\n" simple_expect "=1005" # Create and log in as super (person 8). client_start 2 send "A3Hsup\n" simple_expect "LysKOM" send "1006 80 0 { }\n" simple_expect "=1006" send "1007 89 [holl "super"] [holl "p8"] 00000000 0 { }\n" simple_expect "=1007 8" send "1008 62 8 [holl "p8"] 0\n" simple_expect "=1008" # # Join conferences # # foo joins 1. talk_to client 0 send "1009 100 1 6 200 1 00000000\n" simple_expect "=1009" # bar joins 1. talk_to client 1 send "1010 100 1 7 200 1 00000000\n" simple_expect "=1010" # # foo writes three texts with 1 as recipient. # talk_to client 0 send "1011 86 [holl "text 1"] 1 { 0 1 } 0 { }\n" simple_expect "=1011 1" send "1012 86 [holl "text 2"] 1 { 0 1 } 0 { }\n" simple_expect "=1012 2" send "1013 86 [holl "text 3"] 1 { 0 1 } 0 { }\n" simple_expect "=1013 3" # foo marks texts 2 and 3 as read send "1014 27 1 2 { 2 3 }\n" simple_expect "=1014" # Get membership with unread info. talk_to client 0 send "1015 99 6 0 100 1\n" simple_expect "=1015 2 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 1 200 0 2 { 2 3 } 6 $any_time 00000000 }" send "1016 46 6 0 100 1\n" simple_expect "=1016 2 { $any_time 6 255 0 0 \\* $any_time 1 200 0 2 { 2 3 } }" talk_to client 1 send "1017 99 6 0 100 1\n" simple_expect "=1017 2 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 1 200 0 2 { 2 3 } 6 $any_time 00000000 }" send "1018 46 6 0 100 1\n" simple_expect "=1018 2 { $any_time 6 255 0 0 \\* $any_time 1 200 0 2 { 2 3 } }" talk_to client 2 send "1019 99 6 0 100 1\n" simple_expect "=1019 2 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 1 200 0 2 { 2 3 } 6 $any_time 00000000 }" send "1020 46 6 0 100 1\n" simple_expect "=1020 2 { $any_time 6 255 0 0 \\* $any_time 1 200 0 2 { 2 3 } }" # Get membership without unread info. talk_to client 0 send "1021 99 6 0 100 0\n" simple_expect "=1021 2 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 1 200 0 2 \\* 6 $any_time 00000000 }" send "1022 46 6 0 100 0\n" simple_expect "=1022 2 { $any_time 6 255 0 0 \\* $any_time 1 200 0 2 \\* }" talk_to client 1 send "1023 99 6 0 100 0\n" extracting_expect "=1023 2 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 1 200 0 (0|2) \\* 6 $any_time 00000000 }" arrsize 1 want_array_size 2 $arrsize send "1024 46 6 0 100 0\n" extracting_expect "=1024 2 { $any_time 6 255 0 0 \\* $any_time 1 200 0 (0|2) \\* }" arrsize 1 want_array_size 2 $arrsize talk_to client 2 send "1025 99 6 0 100 0\n" extracting_expect "=1025 2 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 1 200 0 (0|2) \\* 6 $any_time 00000000 }" arrsize 1 want_array_size 2 $arrsize send "1026 46 6 0 100 0\n" extracting_expect "=1026 2 { $any_time 6 255 0 0 \\* $any_time 1 200 0 (0|2) \\* }" arrsize 1 want_array_size 2 $arrsize # Make super admin for foo. talk_to client 0 send "1027 18 6 8\n" simple_expect "=1027" # Get membership with unread info. talk_to client 0 send "1028 99 6 0 100 1\n" simple_expect "=1028 2 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 1 200 0 2 { 2 3 } 6 $any_time 00000000 }" send "1029 46 6 0 100 1\n" simple_expect "=1029 2 { $any_time 6 255 0 0 \\* $any_time 1 200 0 2 { 2 3 } }" talk_to client 1 send "1030 99 6 0 100 1\n" simple_expect "=1030 2 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 1 200 0 2 { 2 3 } 6 $any_time 00000000 }" send "1031 46 6 0 100 1\n" simple_expect "=1031 2 { $any_time 6 255 0 0 \\* $any_time 1 200 0 2 { 2 3 } }" talk_to client 2 send "1032 99 6 0 100 1\n" simple_expect "=1032 2 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 1 200 0 2 { 2 3 } 6 $any_time 00000000 }" send "1033 46 6 0 100 1\n" simple_expect "=1033 2 { $any_time 6 255 0 0 \\* $any_time 1 200 0 2 { 2 3 } }" # Get membership without unread info. talk_to client 0 send "1034 99 6 0 100 0\n" simple_expect "=1034 2 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 1 200 0 2 \\* 6 $any_time 00000000 }" send "1035 46 6 0 100 0\n" simple_expect "=1035 2 { $any_time 6 255 0 0 \\* $any_time 1 200 0 2 \\* }" talk_to client 1 send "1036 99 6 0 100 0\n" extracting_expect "=1036 2 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 1 200 0 (0|2) \\* 6 $any_time 00000000 }" arrsize 1 want_array_size 2 $arrsize send "1037 46 6 0 100 0\n" extracting_expect "=1037 2 { $any_time 6 255 0 0 \\* $any_time 1 200 0 (0|2) \\* }" arrsize 1 want_array_size 2 $arrsize talk_to client 2 send "1038 99 6 0 100 0\n" simple_expect "=1038 2 { 0 $any_time 6 255 0 0 \\* 6 $any_time 00000000 1 $any_time 1 200 0 2 \\* 6 $any_time 00000000 }" send "1039 46 6 0 100 0\n" simple_expect "=1039 2 { $any_time 6 255 0 0 \\* $any_time 1 200 0 2 \\* }" # Shut down. talk_to client 0 send "1040 0 5 [holl "gazonk"]\n" simple_expect "=1040" send "1041 42 255\n" simple_expect "=1041" send "1042 44 0\n" simple_expect "=1042" client_death 1 client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/bug-612.exp0000664000015100472110000001552107721716134017600 # Test suite for lyskomd. # Copyright (C) 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test bug 612: the error codes from sub-member are sometimes wrong. # # Startup and create the players # # Start the server. lyskomd_start # Create and log in as foo (person 6). client_start 0 send "A3Hfoo\n" simple_expect "LysKOM" send "1000 80 0 { }\n" simple_expect "=1000" send "1001 89 [holl "foo"] [holl "p6"] 00000000 0 { }\n" simple_expect "=1001 6" send "1002 62 6 [holl "p6"] 0\n" simple_expect "=1002" # Create and log in as bar (person 7) (creator of confs) client_start 1 send "A3Hbar\n" simple_expect "LysKOM" send "1003 80 0 { }\n" simple_expect "=1003" send "1004 89 [holl "bar"] [holl "p7"] 00000000 0 { }\n" simple_expect "=1004 7" send "1005 62 7 [holl "p7"] 0\n" simple_expect "=1005" # Avoid massive renumber... send "1006 35\n" simple_expect "=1006 $any_time" # Create and log in as citrus (person 8) (gazonk is supervisor; unread-is-secret). client_start 2 send "A6Hcitrus\n" simple_expect "LysKOM" send "1007 80 0 { }\n" simple_expect "=1007" send "1008 89 [holl "citrus"] [holl "p8"] 10000000 0 { }\n" simple_expect "=1008 8" send "1009 62 8 [holl "p8"] 0\n" simple_expect "=1009" # Create and log in as gazonk (person 9). This is the observer. client_start 3 send "A6Hgazonk\n" simple_expect "LysKOM" send "1010 80 0 { }\n" simple_expect "=1010" send "1011 89 [holl "gazonk"] [holl "p9"] 00000000 0 { }\n" simple_expect "=1011 9" send "1012 62 9 [holl "p9"] 0\n" simple_expect "=1012" # Set gazonk as supervisor of citrus. talk_to client 2 send "1013 18 8 9\n" simple_expect "=1013" # # Create conferences. # # As bar, create secret (conf 10; secret). talk_to client 1 send "1014 88 [holl "secret"] 10101000 0 { }\n" simple_expect "=1014 10" # As bar, create rd-prot (conf 11; rd-prot). send "1015 88 [holl "rd-prot"] 10001000 0 { }\n" simple_expect "=1015 11" # As bar, create public (conf 12). send "1016 88 [holl "public"] 00001000 0 { }\n" simple_expect "=1016 12" # # Join conferences # # bar joins secret, rd-prot and public. send "1017 100 10 7 200 1 00000000\n" simple_expect "=1017" send "1018 100 11 7 200 2 00000000\n" simple_expect "=1018" send "1019 100 12 7 200 3 00000000\n" simple_expect "=1019" # bar invites foo to secret, rd-prot and public. send "1020 100 10 6 200 1 00000000\n" lyskomd_expect "Person 6 added to conference 10 by 7." simple_expect "=1020" send "1021 100 11 6 200 2 00000000\n" lyskomd_expect "Person 6 added to conference 11 by 7." simple_expect "=1021" send "1022 100 12 6 200 3 00000000\n" lyskomd_expect "Person 6 added to conference 12 by 7." simple_expect "=1022" # bar invites citrus to secret, rd-prot and public. send "1023 100 10 8 200 1 00000000\n" lyskomd_expect "Person 8 added to conference 10 by 7." simple_expect "=1023" send "1024 100 11 8 200 2 00000000\n" lyskomd_expect "Person 8 added to conference 11 by 7." simple_expect "=1024" send "1025 100 12 8 200 3 00000000\n" lyskomd_expect "Person 8 added to conference 12 by 7." simple_expect "=1025" # # gazonk attempts to unsubscribe foo. # talk_to client 3 send "1026 15 10 6\n" simple_expect "%1026 9 10" send "1027 15 11 6\n" simple_expect "%1027 12 11" send "1028 15 12 6\n" simple_expect "%1028 12 12" # # gazonk attempts to unsubscribe bar. # talk_to client 3 send "1029 15 10 7\n" simple_expect "%1029 9 10" send "1030 15 11 7\n" simple_expect "%1030 12 11" send "1031 15 12 7\n" simple_expect "%1031 12 12" # # gazonk attempts to unsubscribe citrus. This works, since # gazonk is supervisor of citrus. # talk_to client 3 send "1032 15 10 8\n" simple_expect "=1032" send "1033 15 11 8\n" simple_expect "=1033" send "1034 15 12 8\n" simple_expect "=1034" # bar re-invites citrus to secret, rd-prot and public. talk_to client 1 send "1035 100 10 8 200 1 00000000\n" lyskomd_expect "Person 8 added to conference 10 by 7." simple_expect "=1035" send "1036 100 11 8 200 2 00000000\n" lyskomd_expect "Person 8 added to conference 11 by 7." simple_expect "=1036" send "1037 100 12 8 200 3 00000000\n" lyskomd_expect "Person 8 added to conference 12 by 7." simple_expect "=1037" # bar invites gazonk to secret, rd-prot and public. send "1038 100 10 9 200 1 00000000\n" lyskomd_expect "Person 9 added to conference 10 by 7." simple_expect "=1038" send "1039 100 11 9 200 2 00000000\n" lyskomd_expect "Person 9 added to conference 11 by 7." simple_expect "=1039" send "1040 100 12 9 200 3 00000000\n" lyskomd_expect "Person 9 added to conference 12 by 7." simple_expect "=1040" # # gazonk attempts to unsubscribe foo. # talk_to client 3 send "1041 15 10 6\n" simple_expect "%1041 12 10" send "1042 15 11 6\n" simple_expect "%1042 12 11" send "1043 15 12 6\n" simple_expect "%1043 12 12" # # gazonk attempts to unsubscribe bar. # talk_to client 3 send "1044 15 10 7\n" simple_expect "%1044 12 10" send "1045 15 11 7\n" simple_expect "%1045 12 11" send "1046 15 12 7\n" simple_expect "%1046 12 12" # # gazonk attempts to unsubscribe citrus. This works, since # gazonk is supervisor of citrus. # talk_to client 3 send "1047 15 10 8\n" simple_expect "=1047" send "1048 15 11 8\n" simple_expect "=1048" send "1049 15 12 8\n" simple_expect "=1049" # make gazonk supervisor of bar talk_to client 1 send "1050 18 7 9\n" simple_expect "=1050" # # gazonk attempts to unsubscribe foo. # talk_to client 3 send "1051 15 10 6\n" simple_expect "%1051 12 10" send "1052 15 11 6\n" simple_expect "%1052 12 11" send "1053 15 12 6\n" simple_expect "%1053 12 12" # # gazonk attempts to unsubscribe bar. # talk_to client 3 send "1054 15 10 7\n" simple_expect "=1054" send "1055 15 11 7\n" simple_expect "=1055" send "1056 15 12 7\n" simple_expect "=1056" # ...and again, when bar already is unsubscribed. send "1057 15 10 7\n" simple_expect "%1057 13 10" send "1058 15 11 7\n" simple_expect "%1058 13 11" send "1059 15 12 7\n" simple_expect "%1059 13 12" # Shut down. talk_to client 3 send "1060 0 5 [holl "gazonk"]\n" simple_expect "=1060" send "1061 42 255\n" simple_expect "=1061" send "1062 44 0\n" simple_expect "=1062" client_death 3 client_death 2 client_death 1 client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/bug-810.exp0000664000015100472110000000510407721716134017574 # Test suite for lyskomd. # Copyright (C) 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Check that text, person and conference numbers are never ever # reused, not even when the server crashes. obtain_lock lyskomd_start # Create person, a conference and two texts. client_start 0 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" send "1000 89 [holl "person before"] [holl "pb"] 00000000 0 { }\n" simple_expect "=1000 6" send "1001 62 6 [holl "pb"] 0\n" simple_expect ":2 9 6 1" simple_expect "=1001" send "1002 88 [holl "conf b e f o r e"] 00001000 0 { }\n" simple_expect "=1002 7" send "1003 86 [holl "text 1 before"] 1 { 0 7 } 0 { }\n" simple_expect "=1003 1" send "1004 86 [holl "text 2 before"] 1 { 0 7 } 0 { }\n" simple_expect "=1004 2" kill_lyskomd client_death 0 dbck_run lyskomd_start "" "" "" "" "" { "WARN: Texts 1 - 2 were lost\\." "WARN: Confs 6 - 7 were lost\\." } 0 1 # Create person, a conference and two texts. client_start 0 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" send "1005 89 [holl "person after"] [holl "pa"] 00000000 0 { }\n" extracting_expect "=1005 (6|8)" pa 1 if {$pa == 8} { pass "Person number retained" } else { fail "Person number retained" } send "1006 62 $pa [holl "pa"] 0\n" simple_expect ":2 9 $pa 1" simple_expect "=1006" send "1007 88 [holl "conf after"] 00001000 0 { }\n" extracting_expect "=1007 (7|9)" ca 1 if {$ca == 9} { pass "Conference number retained" } else { fail "Conference number retained" } send "1008 86 [holl "text 1 after"] 1 { 0 $ca } 0 { }\n" good_bad_expect "=1008 3" "=1" send "1009 86 [holl "text 2 after"] 1 { 0 $ca } 0 { }\n" good_bad_expect "=1009 4" "=2" system "kill -TERM $lyskomd_pid" lyskomd_death {} signal client_death 0 release_lock lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/bug-877.exp0000664000015100472110000000726207721716134017620 # Test suite for lyskomd. # Copyright (C) 1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Test for bug 877: »The mark_as_read() function calls # mark_conference_as_changed, as if it thinks that the Membership is # stored in the Conference structure. It is stored in the Person # structure. This may lead to the text not being properly marked as # read. One factor that reduces the seriousness is that when marking a # text in the current conference as read, a call to # mark_person_as_changed will also be made, so as long as the client # does a change_conference() to one of the recipients before marking # the text as read, it will sooner or later be marked as read for # real.» lyskomd_start client_start 0 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" "connected" # Log in as administrator. send "1000 62 5 [holl "gazonk"] 1\n" simple_expect "=1000" # Create a text. send "1001 86 [holl "Text 1"] 1 { 0 1 } 0 { }\n" simple_expect "=1001 1" # Join conference 1. send "1002 100 1 5 200 1 00000000\n" simple_expect "=1002" # Check what is read. send "1003 107 5 1 1 0\n" simple_expect "=1003 1 $any_time 1 200 0 \\* 5 $any_time 00000000" # Save the database. We want the person to be clean. send "1004 42 255\n" simple_expect "=1004" send "1005 43\n" simple_expect ":0 7" simple_expect ":0 7" simple_expect "=1005" if {$debug_calls} { # Start saving the database. A dirty copy of the person now exists, # so all future references to the person requires that we get a copy # of him from the cache. send "1003 1004\n" simple_expect ":0 7" simple_expect "=1003" } else { unsupported "testing for bug 877 requires --with-debug-calls" } # Mark the text as read. This modifies the person, and should # mark the person as dirty. send "1006 27 1 1 { 1 }\n" simple_expect "=1006" if {$debug_calls} { # Actually save the previous snapshot of the database. # However, this will also save the supposedly clean but modified # person! send "1007 1005\n" simple_expect ":0 7" simple_expect "=1007" } # Check what is read, to ensure we have the expected proper stuff in core. send "1007 107 5 1 1 0\n" simple_expect "=1007 1 $any_time 1 200 1 { 1 1 } 5 $any_time 00000000" # Crash lyskomd. kill_lyskomd client_death 0 dbck_run # Start lyskomd, from the previously saved database. lyskomd_start "" "" "" "" "" "" 0 1 6 2 client_start 0 talk_to client 0 send "A3Hfoo\n" simple_expect "LysKOM" "connected" # Log in as administrator. send "1008 62 5 [holl "gazonk"] 1\n" simple_expect "=1008" # Check what is read. The mark-as-read should be lost -- we are # reading from an older snapshot. send "1009 107 5 1 1 0\n" simple_expect "=1009 1 $any_time 1 200 0 \\* 5 $any_time 00000000" # Shut down. send "1010 42 255\n" simple_expect "=1010" send "1011 44 0\n" simple_expect "=1011" client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/bug-84.exp0000664000015100472110000000473507721716134017530 # Test suite for lyskomd. # Copyright (C) 1999-2000, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. read_versions source "$srcdir/config/prot-a.exp" lyskomd_start client_start 0 talk_to client 0 send "A[holl "DejaGnu test suite"]\n" simple_expect "LysKOM" "bug94: Connected" kom_accept_async "0 { }" kom_login 5 "gazonk" 0 kom_enable 255 kom_create_text_simple "T1" 5 kom_create_text_simple "T2" 5 send "1000 95 0 { } 1 { 14 00000000 1 [holl "1"] }\n" simple_expect "=1000" send "1001 95 0 { } 1 { 14 00000000 1 [holl "2"] }\n" simple_expect "=1001" send "1002 94\n" simple_expect "=1002 $server_compat_version 1 2 3 4 0 2 { 1 14 5 $any_time 00000000 1 [holl "1"] 2 14 5 $any_time 00000000 1 [holl "2"] }" # Text 1 should have a mirror aux item send "1003 90 1\n" simple_expect "=1003 $any_time 5 0 2 0 2 { 0 5 6 1 } 1 { 1 28 5 $any_time 00001000 0 1H0 }" # Text 1 should have a mirror aux item send "1004 90 2\n" simple_expect "=1004 $any_time 5 0 2 0 2 { 0 5 6 2 } 1 { 1 28 5 $any_time 00001000 0 1H0 }" # Now delete a FAQ aux item from the server send "1005 95 1 { 2 } 0 { }\n" simple_expect "=1005" # Get server info and make sure it's gone send "1007 94\n" simple_expect "=1007 $server_compat_version 1 2 3 4 0 1 { 1 14 5 $any_time 00000000 1 [holl "1"] }" # Get text stat for text 2 and make sure the mirror item is gone send "1008 90 2\n" simple_expect "=1008 $any_time 5 0 2 0 2 { 0 5 6 2 } 0 \\*" # Delete a FAQ, then check that the FAQ aux-item is gone kom_delete_text 1 send "1009 94\n" setup_xfail "*-*-*" "Bug 690" simple_expect "=1009 $server_compat_version 1 2 3 4 0 0 \\*" kom_shutdown_server client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/cache-node-cov.exp0000664000015100472110000000241007721716134021261 # Test suite for lyskomd. # Copyright (C) 1999, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Supplemental tests for cache-node.c # get_cache_node # Try to get a text beyond the text table size # Try to get a conf beyond the conf table size # destruct_cache_node # Try to go beyond the table size -- can't be done in LysKOM # # Remaining stuff is defensive programming # Can't do any of this from outside the server lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/conf-file-cov.exp0000664000015100472110000002405307721716134021144 # Test suite for lyskomd. # Copyright (C) 1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Supplemental test cases to work through conf-file.c # Make the default assigner for a parameter fail # If this happens, it is a bug in the server. The server # will never be released with a problem like this # Start server so it can't find config file set conf_file "\ \# This is a comment Lots of spaces before key Key too long XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Colon right at max XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX: Foo Key and colon ok: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Line no colon val \# Don't assign Max conferences: 100 Max: 102 Garb timeout: 100000 Garb timeout: 100001 Send async: Juggle! Max texts: ¤ Presentation of conferences: ¤ Message of the day: ¤ Garb interval: ¤ " # Read a file with a comment # Read a file that has one line that whose key is longer than max line # Read a file that has one line that whose key + value is too long # Read a file that has one line with colon just before max line # Read a file with a line without a colon # Assign a parameter too few times. # Assign a variable too many times # Read a file that has a line that matches more than one param # Try to assign a bool with value "Juggle!" # Try to assign an int with a non-ascii and non-digit character # Ditto for conf_no # Ditto for text_no # Ditto for ulong read_versions lyskomd_fail_start { "line too long \\(max 1000 chars allowed\\): " "missing colon: Lots of spaces before key" "missing colon: Key too long XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" "missing colon: XXXXXXXXXXXXXX" "line too long \\(max 1000 chars allowed\\): Colon right at max XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" "missing colon: Foo" "line too long \\(max 1000 chars allowed\\): Key and colon ok" "missing colon: XXXXXXXXXXXXXX" "missing colon: Line no colon val" "line matches 0 times: Max" "variable already assigned 1 times: Garb timeout" "assigner for Send async failed" "assigner for Max texts failed" "assigner for Presentation of conferences failed" "assigner for Message of the day failed" "assigner for Garb interval failed" "Parameter Max conferences only assigned 0 times \\(1 times needed\\)" "Please fix the above errors in config/lyskomd-config and restart lyskomd" } "" "" $conf_file lyskomd_fail_start { "cannot open config file nosuchfile" } "" "" "" "nosuchfile" lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/conference-cov.exp0000664000015100472110000002531107721716134021407 # Test suite for lyskomd. # Copyright (C) 1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Supplemental test cases to give conference.c a workout # No-can-dos # General stuff # Can't really reach any restart_kom lines # do_delete_conf # Can't get to the kom_logs after do_set_presentation and do_set_etc_motd # since none of them can return FAILURE if called with 0 as argument. # unique_name # Can't simulate -1 exit from parse() # delete_conf # Can't get to the kom_log since do_delete_pers always succeeds # lookup_name, lookup_z_name # Can't get to first return FAILURE since cached_lookup_name only fails # if parse failse, which it won't # lookup_z_name # Can't get to internal error # do_lookup # Can't get to the first return FAILURE # Can't get to far too many matches without creating 2^32 confs # get_conf_stat_old # Can't get to first return FAILURE # Privilege bits # 0001000000000000 create pers # 0000100000000000 create conf # 0000010000000000 change name read_versions source "$srcdir/config/prot-a.exp" lyskomd_start "" "\ Max marks per text: 1 Max conference name length: 60 Anyone can create new conferences: false Default change name capability: false Max conferences: 19 " client_start 0 talk_to client 0 kom_connect "DejaGnu Test Suite" kom_accept_async "0 { }" kom_create_person "P6" "PW6" "00000000" "0 { }" kom_create_person "P7" "PW7" "00000000" "0 { }" kom_create_person "P8" "PW8" "00000000" "0 { }" kom_create_person "P9" "PW9" "00000000" "0 { }" kom_login 5 "gazonk" 0 kom_enable 255 kom_set_priv_bits 6 "0001110000000000" kom_set_priv_bits 7 "0001110000000000" kom_login 6 "PW6" 0 kom_create_conference "C10" "00000000" "0 { }" kom_create_conference "C11" "00000000" "0 { }" kom_create_conference "Conference With a Name 12" "00000000" "0 { }" kom_create_conference "Conference With a Name 13" "00000000" "0 { }" kom_create_conference "C14" "10100000" "0 { }" # Delete a conference with three members kom_login 7 "PW7" 0 kom_create_conference "C15" "00000000" "0 { }" kom_add_member 15 5 100 0 "00000000" lyskomd_expect "Person 5 added to conference 15 by 7." kom_add_member 15 6 100 0 "00000000" lyskomd_expect "Person 6 added to conference 15 by 7." kom_add_member 15 7 100 0 "00000000" send "1000 11 15\n" simple_expect "=1000" # Attempt to delete a secret conf we don't know about send "1001 11 14\n" simple_expect "%1001 9 14" # Attempt to delete someone else's conference send "1002 11 10\n" simple_expect "%1002 12 10" # Delete the letterbox of a person who is logged in client_start 1 talk_to client 1 kom_connect "DejaGnu Test Suite" kom_accept_async "0 { }" kom_login 9 "PW9" 0 talk_to client 0 kom_login 5 "gazonk" 0 kom_enable 255 send "1003 11 9\n" simple_expect "=1003" talk_to client 1 send "1004 2 10\n" simple_expect "%1004 6 0" send "1005 55 0\n" simple_expect "=1005" client_death 1 talk_to client 0 # Attempt to create a conf without privs to do so kom_login 8 "PW8" 0 send "1100 88 [holl "No Can Do"] 00000000 0 { }\n" simple_expect "%1100 12 0" # Attempt to create a conf with long name kom_login 6 "PW6" 0 send "1101 88 [holl "\ Some folks say there ain't no bears in Arkansas \ Some folks never seen a bear at all \ Some folks say bears go around eating rabbits raw \ Some folks got a bear across the hall \ "] 00000000 0 { }\n" simple_expect "%1101 5 60" # Attempt to create a conf with nonprintable character send "1102 88 [holl "Nonprintable \001"] 00000000 0 { }\n" simple_expect "%1102 18 0" # Attempt to create a conf with empty name send "1103 88 [holl ""] 00000000 0 { }\n" simple_expect "%1103 18 0" # Attempt to create a conf with duplicate name send "1104 88 [holl "C10"] 00000000 0 { }\n" simple_expect "%1104 20 0" # Create a conf with name matching two others but fewer words send "1105 88 [holl "Conference With a Name"] 00000000 0 { }\n" simple_expect "=1105 16" send "1106 11 16\n" simple_expect "=1106" # Create a conf with name matching two others but not exact match send "1107 88 [holl "Conf W a Name 1"] 00000000 0 { }\n" simple_expect "=1107 17" send "1108 11 17\n" simple_expect "=1108" # Attempt to create a conf with invalid aux-item list send "1109 88 [holl "CXX"] 00000000 1 { 0 00000000 0 [holl "A1"] }\n" simple_expect "%1109 48 0" # Attempt to create a conf with letterbox bit set send "1110 88 [holl "CXX"] 00010000 0 { }\n" simple_expect "%1110 12 0" # Attempt to create a conf with secret but not rd_prot set send "1111 88 [holl "CXX"] 00100000 0 { }\n" simple_expect "%1111 22 0" # Attempt to change name of secret conf we don't know about kom_login 7 "PW7" 0 send "1200 3 14 [holl "Lungs"]\n" simple_expect "%1200 9 14" # Attempt to change name of conf without enough privs send "1201 3 10 [holl "Step Inside This House"]\n" simple_expect "%1201 12 10" # Attempt to change name to empty send "1202 3 7 [holl ""]\n" simple_expect "%1202 18 0" # Attempt to change name to one with nonprinting character send "1203 3 7 [holl "Memphis Midnight \001"]\n" simple_expect "%1203 18 0" # Call lookup-name with args that show a secret conf kom_login 7 "PW7" 0 send "1300 12 [holl "C"]\n" simple_expect "=1300 4 { 10 11 12 13 } { 0000 0000 0000 0000 }" # Call lookup-z-name with args that show a secret conf send "1301 76 [holl "C"] 0 1\n" simple_expect "=1301 4 { [holl "C10"] 0000 10 [holl "C11"] 0000 11 [holl "Conference With a Name 12"] 0000 12 [holl "Conference With a Name 13"] 0000 13 }" # Do a get-conf-stat that fails somehow kom_login 7 "PW7" 0 send "1400 91 9999\n" simple_expect "%1400 9 9999" # Do a get-conf-stat for a secret conf send "1401 91 14\n" simple_expect "%1401 9 14" # Do a get-uconf-stat for a secret conf send "1402 78 14\n" simple_expect "%1402 9 14" # Do a get-conf-stat-older on a secret conf send "1403 13 14 1\n" simple_expect "%1403 9 14" # Do set-presentation on a secret conf we don't know about # Do set-presentation on conf without enough privs kom_login 7 "PW7" 0 send "1500 86 [holl "T1"] 1 { 0 10 } 0 { }\n" simple_expect "=1500 1" send "1501 16 10 1\n" simple_expect "%1501 12 10" send "1502 16 14 1\n" simple_expect "%1502 9 14" # Do set-etc-motd on secret and conf wo privs send "1503 17 10 1\n" simple_expect "%1503 12 10" send "1504 17 14 1\n" simple_expect "%1504 9 14" # Do set-supervisor on secret and conf wo privs send "1505 18 10 7\n" simple_expect "%1505 12 10" send "1506 18 14 7\n" simple_expect "%1506 9 14" # Do set-permitted-submitters on secret and conf wo privs send "1507 19 10 7\n" simple_expect "%1507 12 10" send "1508 19 14 7\n" simple_expect "%1508 9 14" # Do set-super-conf on secret and conf wo privs send "1509 20 10 7\n" simple_expect "%1509 12 10" send "1510 20 14 7\n" simple_expect "%1510 9 14" # Do set-garb-nice on secret and conf wo privs send "1511 22 10 1\n" simple_expect "%1511 12 10" send "1512 22 14 1\n" simple_expect "%1512 9 14" # Do set-expire on secret and conf wo privs send "1513 97 10 1\n" simple_expect "%1513 12 10" send "1514 97 14 1\n" simple_expect "%1514 9 14" # Do set-keep-commented on secret and conf wo privs send "1515 105 10 1\n" simple_expect "%1515 12 10" send "1516 105 14 1\n" simple_expect "%1516 9 14" # Do set-conf-type on secret conf and conf wo privs send "1517 21 10 00000000\n" simple_expect "%1517 12 10" send "1518 21 14 00000000\n" simple_expect "%1518 9 14" # Do set-conf-type with secret but not rd_prot kom_login 6 "PW6" 0 send "1600 21 10 00100000\n" simple_expect "%1600 22 0" # Attempt to set letterbox bit send "1601 21 10 00010000\n" simple_expect "%1601 23 10" # Attemp to clear the letterbox bit send "1602 21 6 00000000\n" simple_expect "%1602 23 6" # Attempt to set presentation to a text with max marks kom_login 6 "PW6" 0 send "1700 86 [holl "T2"] 1 { 0 10 } 0 { }\n" simple_expect "=1700 2" send "1701 86 [holl "T3"] 1 { 0 10 } 0 { }\n" simple_expect "=1701 3" send "1702 72 2 0\n" simple_expect "=1702" # Do it send "1703 16 10 2\n" lyskomd_expect "LIMIT: do_set_presentation\\(10, ptr, 2\\): New presentation has 1 marks." simple_expect "%1703 36 2" # Succeed send "1704 73 2\n" simple_expect "=1704" send "1705 16 10 2\n" simple_expect "=1705" # Change to a new text send "1706 16 10 3\n" simple_expect "=1706" if {$debug_calls} { # Change to a new presentation when current presentation has zero marks send "1707 1001 3 0\n" simple_expect "=1707" } else { unsupported "Use configure --with-debug-calls to enable" } send "1708 16 10 0\n" if {$debug_calls} { lyskomd_expect "ERROR: do_set_presentation\\(10, ptr, 0\\): Old presentation 3 not marked\\." } simple_expect "=1708" # Do set-etc-motd with text that has max marks # Do set-etc-motd with when there already is a motd # Do set-etc-motd when current motd has zero marks kom_login 6 "PW6" 0 send "1800 86 [holl "T4"] 1 { 0 10 } 0 { }\n" simple_expect "=1800 4" send "1801 86 [holl "T5"] 1 { 0 10 } 0 { }\n" simple_expect "=1801 5" send "1802 72 4 0\n" simple_expect "=1802" # Do it send "1803 17 10 4\n" lyskomd_expect "LIMIT: do_set_etc_motd\\(10, ptr, 4\\): New motd has 1 marks\\." simple_expect "%1803 36 4" # Succeed send "1804 73 4\n" simple_expect "=1804" send "1805 17 10 4\n" simple_expect "=1805" # Change to a new text send "1806 17 10 5\n" simple_expect "=1806" # Do set-etc-motd when there already is a motd if {$debug_calls} { send "1807 1001 5 0\n" simple_expect "=1807" } else { unsupported "Use configure --with-debug-calls to enable" } send "1808 17 10 0\n" if {$debug_calls} { lyskomd_expect "ERROR: do_set_etc_motd\\(10, ptr, 0\\): Old motd 5 not marked\\." } simple_expect "=1808" # Try to create too many conferences kom_create_conference "C19" "00000000" "0 { }" send "9000 88 [holl "C20"] 00000000 0 { }\n" lyskomd_expect "ERROR: Couldn't create conference. Too many conferences." simple_expect "%9000 19 20" # Finish talk_to client 0 kom_login 5 "gazonk" 0 kom_enable 255 send "9999 44 0\n" simple_expect "=9999" client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/connections-cov.exp0000664000015100472110000001134707721716134021626 # Test suite for lyskomd. # Copyright (C) 1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Supplemental test cases for connections.c # # Note: With the MUX support compiled-in, the coverage of this file # is really low, around 65-66% or so. There is also quite a lot # of panic code which is never reached. # Hard to do # Connect from a client with not reverse name mapping # Connect from a client where we can't get the IP number either # Add more than one client at a time to the kill list # Stuff to ignore # Mux-related garbage read_versions source "$srcdir/config/prot-a.exp" lyskomd_start "" "\ Open files: [expr $PROTECTED_FDS + 5] Log statistics: /tmp/swedish/chef/bork/bork/bork/nosuchfile Nologin file: nologin " # Attempt to connect with invalid protocol client_start 0 talk_to client 0 send "B[holl "DejaGnu Test Suite]\n"]" simple_expect "%%LysKOM unsupported protocol." client_death 0 # Attempt to disconnect a client that has not declared a protocol yet. # It should be invisible. client_start 1 talk_to client 1 client_start 0 talk_to client 0 kom_connect "DejaGnu Test Suite" kom_accept_async "0 { }" kom_create_person "P6" "PW6" "00000000" "0 { }" kom_login 5 "gazonk" 0 kom_enable 255 send "1000 55 2\n" simple_expect "%1000 42 2" kom_login 6 "PW6" 0 kill_client 1 # Kill off three clients with EPIPE client_start 1 talk_to client 1 kom_connect "DejaGnu Test Suite" kom_accept_async "1 { 12 }" client_start 2 talk_to client 2 kom_connect "DejaGnu Test Suite" kom_accept_async "1 { 12 }" client_start 3 talk_to client 3 kom_connect "DejaGnu Test Suite" kom_accept_async "1 { 12 }" talk_to client 1 suspend_client talk_to client 2 suspend_client talk_to client 3 suspend_client talk_to client 0 send "1001 53 0 [holl "\ And cattle is their game And Archer is the name They give to the acres that they own If the Brazons don't run dry And the newborn calves don't die Another year from Mary will have flown Another year from Mary will have flown"]\n" simple_expect "=1001" kill_client 1 kill_client 2 kill_client 3 talk_to client 0 send "1002 53 0 [holl "\ Mary Martin was a schoolgirl Just seventeen or so When she married Billy Archer About fourteen years ago Not even out of high school Folks said it wouldn't last But when you grow up in the country You grow up mighty fast"]\n" simple_expect "=1002" # Generate a protocol error talk_to client 0 send "We crossed the wild Pecos\n" simple_expect "%% LysKOM protocol error." # Cause dump_statistics to fail because of bad file name dump_statistics lyskomd_expect "dump_statistics\\(\\): can't open file /tmp/swedish/chef/bork/bork/bork/nosuchfile" # Attempt to create too many connections client_start 1 talk_to client 1 kom_connect "DejaGnu Test Suite" kom_accept_async "0 { }" client_start 2 talk_to client 2 kom_connect "DejaGnu Test Suite" kom_accept_async "0 { }" client_start 3 talk_to client 3 kom_connect "DejaGnu Test Suite" kom_accept_async "0 { }" client_start 4 talk_to client 4 send "A[holl "DejaGnu Test Suite"]\n" simple_expect "%% No connections left." client_death 4 talk_to client 1 send "1003 55 0\n" simple_expect "=1003" client_death 1 talk_to client 2 send "1004 55 0\n" simple_expect "=1004" client_death 2 talk_to client 3 send "1005 55 0\n" simple_expect "=1005" client_death 3 # Check that nologin file actually works set fp [open "nologin" "w+"] close $fp client_start_fail 1 "%% No logins allowed." system "rm -f nologin" # Finish with lots of clients connected client_start 1 talk_to client 1 kom_connect "DejaGnu Test Suite" kom_accept_async "0 { }" client_start 2 talk_to client 2 kom_connect "DejaGnu Test Suite" kom_accept_async "0 { }" client_start 3 talk_to client 3 kom_connect "DejaGnu Test Suite" kom_accept_async "0 { }" talk_to client 0 kom_login 5 "gazonk" 0 kom_enable 255 send "1006 44 0\n" simple_expect "=1006" client_death 0 client_death 1 client_death 2 client_death 3 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/disk-end-of-atomic-cov.exp0000664000015100472110000000223007721716134022645 # Test suite for lyskomd. # Copyright (C) 1999, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Supplemental test cases for end-of-atomic # Hard to do cause of timing issues # Start a sync and then issue an atomic call while the server # is writing data to one of the data files (so sync_part returns FALSE) lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/gen-15.py0000664000015100472110000004521607721716134017351 # Test suite for lyskomd. # Copyright (C) 2000-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Generate a test script that tests permissions of recpt, cc-recpt and # bcc-recpt, and that proper asynchronous messages are sent. This # only tests active membership. import string # Set EXTENDED to 1 to emit tests for lots of misc-into combinations, # which takes a very long time to test (approx. 5 minutes on a 600 MHz Athlon). EXTENDED = 0 # Set DEBUG to 1 to emit extra "get-time" calls, which slows the test down # approximately 5%, but makes it easier to track down errors. DEBUG = 0 # The database that this test sets up, before any texts are created, # looks like this: # # Persons: # 6 "Person 6" Member of 6. # 7 "Person 7" Creator of 10, 11, 12. Member of 10, 11, 12, 13, 14, 15. # 8 "Person 8" Member of 8, 10, 11, 12, 13, 14, 15. # 9 "Person 9" Creator of 13, 14, 15. Member of 9. # # Conferences: # 10 "conf 10" # 11 "conf 11" rd-prot # 12 "conf 12" rd-prot, secret # 13 "conf 13" # 14 "conf 14" rd-prot # 15 "conf 15" rd-prot, secret class factory: def __init__(self, bcc_trigg, bcc_visible, bcc_author_visible, other_trigg, other_visible, rd): self.__bcc_trigg = bcc_trigg self.__bcc_visible = bcc_trigg + bcc_visible self.__bcc_author_visible = (bcc_trigg + bcc_visible + bcc_author_visible) self.__other_trigg = bcc_trigg + other_trigg self.__other_visible = bcc_trigg + other_trigg + other_visible for n in bcc_visible: if n not in self.__other_visible: self.__other_visible.append(n) self.__readable = bcc_trigg + other_trigg + rd def create(self, author, misc, conf, loc, rec_time = None, sent_by = None, sent_at = None): if misc == 15: trigg = self.__bcc_trigg visib = self.__bcc_visible author_visib = self.__bcc_author_visible else: trigg = self.__other_trigg visib = self.__other_visible author_visib = self.__other_visible return misc_group(misc, conf, loc, trigg, visib, author_visib, self.__readable, rec_time, sent_by, sent_at, author) def a_list_pattern(lst): if len(lst) == 0: return "0 \\\\\\*" else: return "%d { %s }" % (len(lst), string.join(lst, " ")) def a_list_rq(lst): return "%d { %s }" % (len(lst), string.join(lst, " ")) class sequence_allocator: def __init__(self, start): self.curr = start def next(self): self.curr = self.curr + 1 return self.curr class misc_group: def __init__(self, misc, conf, loc, trigg, visib, visib_by_author, readable, rec_time, sent_by, sent_at, author): self.__misc = misc self.__conf = conf self.__loc = loc self.__trigg = trigg self.__visib = visib self.__visib_by_author = visib_by_author self.__readable = readable self.__rec_time = rec_time self.__sent_by = sent_by self.__sent_at = sent_at self.__author = author def visible(self, viewer): return (viewer in self.__visib or (viewer == self.__author and viewer in self.__visib_by_author)) def miscs(self, viewer): if not self.visible(viewer): return [] res = ["%d %d" % (self.__misc, self.__conf), "6 %d" % self.__loc] if self.__rec_time != None: res.append("7 $any_time") if self.__sent_by != None: res.append("8 %d" % self.__sent_by) if self.__sent_at != None: res.append("9 $any_time") return res def async(self, viewer, text_no): if not self.visible(viewer): return None return "%d %d %d" % (text_no, self.__conf, self.__misc) def trigger(self, viewer): return viewer in self.__trigg def readable(self, viewer): return viewer in self.__readable def recipient(self): return self.__conf def recipient_type(self): return self.__misc class text_stat: tno = sequence_allocator(0) def __init__(self, author): self.__author = author self.__misc_groups = [] self.__text_no = self.tno.next() def add_misc_group(self, misc_grp): assert isinstance(misc_grp, misc_group) self.__misc_groups.append(misc_grp) def author(self): return self.__author def misc_groups(self): return self.__misc_groups[:] def text_no(self): return self.__text_no def remove_misc_group(self, removed): self.__misc_groups.remove(removed) # (creat, rcpt): bcc-trigg, bcc-vis, bcc-author-vis, other-trigg, other-vis, rd obj = { (6, 6): factory([6], [], [7, 8, 9], [], [7, 8, 9], []), (6, 7): factory([], [6, 7], [8, 9], [], [8, 9], [7]), (6, 8): factory([8], [6], [7, 9], [], [7, 9], []), (6, 9): factory([9], [6], [7, 8], [], [7, 8], []), (6, 10): factory([7, 8], [6, 9], [], [], [], [6, 9]), (6, 11): factory([7, 8], [6], [9], [], [9], []), (6, 12): factory([7, 8], [6], [], [], [9], []), (6, 13): factory([7, 8], [6, 9], [], [], [], [6, 9]), (6, 14): factory([7, 8], [6, 9], [], [], [], [9]), (6, 15): factory([7, 8], [6, 9], [], [], [], [9]), (7, 6): factory([6], [7], [8, 9], [], [8, 9], []), (7, 7): factory([], [7], [6, 8, 9], [], [6, 8, 9], [7]), (7, 8): factory([8], [7], [6, 9], [], [6, 7, 9], []), (7, 9): factory([9], [7], [6, 8], [], [6, 7, 8], []), (7, 10): factory([7, 8], [6, 9], [], [], [], [6, 9]), (7, 11): factory([7, 8], [], [6, 9], [], [6, 9], []), (7, 12): factory([7, 8], [], [], [], [], []), (7, 13): factory([7, 8], [6, 9], [], [], [], [6, 9]), (7, 14): factory([7, 8], [9], [6], [], [6], [9]), (7, 15): factory([7, 8], [9], [], [], [], [9]), (8, 6): factory([6], [8], [7, 9], [], [7, 9], []), (8, 7): factory([], [7, 8], [6, 9], [], [6, 9], [7]), (8, 8): factory([8], [], [6, 7, 9], [], [6, 7, 9], []), (8, 9): factory([9], [8], [6, 7], [], [6, 7], []), (8, 10): factory([7, 8], [6, 9], [], [], [], [6, 9]), (8, 11): factory([7, 8], [], [6, 9], [], [6, 9], []), (8, 12): factory([7, 8], [], [], [], [], []), (8, 13): factory([7, 8], [6, 9], [], [], [], [6, 9]), (8, 14): factory([7, 8], [9], [6], [], [6], [9]), (8, 15): factory([7, 8], [9], [], [], [], [9]), (9, 6): factory([6], [9], [7, 8], [], [7, 8], []), (9, 7): factory([], [7, 9], [6, 8], [], [6, 8], [7]), (9, 8): factory([8], [9], [6, 7], [], [6, 7], []), (9, 9): factory([9], [], [6, 7, 8], [], [6, 7, 8], []), (9, 10): factory([7, 8], [6, 9], [], [], [], [6, 9]), (9, 11): factory([7, 8], [9], [6], [], [6], []), (9, 12): factory([7, 8], [9], [], [], [], []), (9, 13): factory([7, 8], [6, 9], [], [], [], [6, 9]), (9, 14): factory([7, 8], [9], [6], [], [6], [9]), (9, 15): factory([7, 8], [9], [], [], [], [9]), } class loc_no_allocator: def __init__(self): self.__prev = {} def alloc(self, conf): res = self.__prev.get(conf, 0) + 1 self.__prev[conf] = res return res locno = loc_no_allocator() def talk_to(person): global active_person if active_person != person: print "talk_to client %d" % (person - 6) active_person = person active_person = None ref = sequence_allocator(999) def create(author, recipients): print txt = text_stat(author) crea = [] for (m, r) in recipients: txt.add_misc_group(obj[(author, r)].create(author, m, r, locno.alloc(r))) crea.append("%d %d" % (m, r)) talk_to(author) cs = ref.next() print "# Creating text %d by %d" % (txt.text_no(), txt.author()) print "send \"%d 86 [holl \"text %d\"] %s 0 { }\\n\"" % ( cs, txt.text_no(), a_list_rq(crea)) new_text(txt) talk_to(author) print "simple_expect \"=%d %d\"" % (cs, txt.text_no()) verify_text_stat(txt) return txt def add_misc(adder, txt, misc_type, rcpt): sent_by = None if adder != txt.author(): sent_by = adder misc = obj[(adder, rcpt)].create(txt.author(), misc_type, rcpt, locno.alloc(rcpt), sent_at = 1, sent_by = sent_by) talk_to(adder) cs = ref.next() print "# Adding recipient to text %d; adder %d" % (txt.text_no(), adder) print "send \"%d 30 %d %d %d\\n\"" % (cs, txt.text_no(), rcpt, misc_type) new_recipient(adder, txt, misc) talk_to(adder) print "simple_expect \"=%d\"" % cs txt.add_misc_group(misc) def verify_text_stat(txt): for p in PERSONS: talk_to(p) print "send \"%d 90 %d\\n\"" % (ref.next(), txt.text_no()) visib = p == txt.author() pattern = [] for m in txt.misc_groups(): pattern = pattern + m.miscs(p) if m.readable(p): visib = 1 if visib: print "simple_expect \"=%d $any_time " \ "%d 0 %d 0 %s 0 \\\\\\*\"" % ( ref.curr, txt.author(), len("text %d" % txt.text_no()), a_list_pattern(pattern)) else: print "simple_expect \"%%%d 14 %d\"" % (ref.curr, txt.text_no()) PERSONS = range(6, 10) def new_text(txt): for viewer in PERSONS: sent = 0 pattern = [] for m in txt.misc_groups(): if m.trigger(viewer): sent = 1 pattern = pattern + m.miscs(viewer) if sent: talk_to(viewer) print "simple_expect \":18 15 %d $any_time " \ "%d 0 %d 0 %s 0 \\\\\\*\"" % ( txt.text_no(), txt.author(), len("text %d" % txt.text_no()), a_list_pattern(pattern)) elif txt.author() != viewer and DEBUG: talk_to(viewer) print "send \"%d 35\\n\"" % ref.next() print "simple_expect \"=%d $any_time\"" % ref.curr def new_recipient(author, txt, misc): for viewer in PERSONS: sent = 0 for m in txt.misc_groups() + [misc]: if m.trigger(viewer): sent = 1 async = misc.async(viewer, txt.text_no()) if sent and async != None: talk_to(viewer) print "simple_expect \":3 16 %s\"" % async elif author != viewer and DEBUG: talk_to(viewer) print "send \"%d 35\\n\"" % ref.next() print "simple_expect \"=%d $any_time\"" % ref.curr def delete(deleter, txt): nr = ref.next() talk_to(deleter) print "# Deleting text %d; deleter %d" % (txt.text_no(), deleter) print "send \"%d 29 %d\\n\"" % (nr, txt.text_no()) deleted_text(deleter, txt) talk_to(deleter) print "simple_expect \"=%d\"" % nr def deleted_text(deleter, txt): for viewer in PERSONS: sent = 0 pattern = [] for m in txt.misc_groups(): if m.trigger(viewer): sent = 1 pattern = pattern + m.miscs(viewer) if sent: talk_to(viewer) print "simple_expect \":18 14 %d $any_time " \ "%d 0 %d 0 %s 0 \\\\\\*\"" % ( txt.text_no(), txt.author(), len("text %d" % txt.text_no()), a_list_pattern(pattern)) elif deleter != viewer and DEBUG: talk_to(viewer) print "send \"%d 35\\n\"" % ref.next() print "simple_expect \"=%d $any_time\"" % ref.curr def remove_misc(remover, txt, recip): for removed in txt.misc_groups(): if removed.recipient() == recip: break else: raise 'no-such-recipient' nr = ref.next() talk_to(remover) print "# Removing recipient from text %d; remover %d" % ( txt.text_no(), remover) print "send \"%d 31 %d %d\\n\"" % (nr, txt.text_no(), recip) sub_recipient(remover, txt, recip, removed.recipient_type()) talk_to(remover) print "simple_expect \"=%d\"" % nr txt.remove_misc_group(removed) def sub_recipient(remover, txt, recip, misc_type): for viewer in PERSONS: sent = 0 for m in txt.misc_groups(): if m.trigger(viewer): sent = 1 if sent: talk_to(viewer) print "simple_expect \":3 17 %d %d %s\"" % ( txt.text_no(), recip, misc_type) elif remover != viewer and DEBUG: talk_to(viewer) print "send \"%d 35\\n\"" % ref.next() print "simple_expect \"=%d $any_time\"" % ref.curr def setup(): print "lyskomd_start" for p in PERSONS: print "client_start %d" % (p - 6) talk_to(p) print "send \"A3Hfoo\\n\"" print "simple_expect \"LysKOM\" \"connected %d\"" % p print "send \"%d 80 4 { 14 15 16 17 }\\n\"" % ref.next() print "simple_expect \"=%d\"" % ref.curr print "send \"%d 89 [holl \"Person %d\"] [holl \"foo\"] " \ "00000000 0 { }\\n\"" % (ref.next(), p) print "simple_expect \"=%d %d\"" % (ref.curr, p) print "send \"%d 62 %d [holl \"foo\"] 0\\n\"" % (ref.next(), p) print "simple_expect \"=%d\"" % ref.curr for (creator, conf, conf_type) in [ (7, 10, "0000"), (7, 11, "1000"), (7, 12, "1010"), (9, 13, "0000"), (9, 14, "1000"), (9, 15, "1010"), ]: talk_to(creator) print "send \"%d 88 [holl \"conf %d\"] %s 0 { }\\n\"" % ( ref.next(), conf, conf_type) print "simple_expect \"=%d %d\"" % (ref.curr, conf) talk_to(7) for conf in [10, 11, 12]: for reader in [7, 8]: print "send \"%d 100 %d %d 100 3 00000000\\n\"" % ( ref.next(), conf, reader) print "simple_expect \"=%d\"" % ref.curr talk_to(9) for conf in [13, 14, 15]: for reader in [7, 8]: print "send \"%d 100 %d %d 100 6 00000000\\n\"" % ( ref.next(), conf, reader) print "simple_expect \"=%d\"" % ref.curr print "talk_to lyskomd" for conf in [10, 11, 12]: print "simple_expect \"Person 8 added to conference %d by 7.\"" % conf for conf in [13, 14, 15]: for reader in [7, 8]: print ("simple_expect " + "\"Person %d added to conference %d by 9.\"") % ( reader, conf) talk_to(7) print "send \"%d 15 7 7\\n\"" % ref.next() print "simple_expect \"=%d\"" % ref.curr def disco(): for p in PERSONS[:-1]: talk_to(p) print "send \"%d 55 0\\n\"" % ref.next() print "simple_expect \"=%d\"" % ref.curr print "client_death %d" % (p - 6) talk_to(PERSONS[-1]) print "send \"%d 62 5 [holl \"gazonk\"] 1\\n\"" % ref.next() print "simple_expect \"=%d\"" % ref.curr print "send \"%d 42 255\\n\"" % ref.next() print "simple_expect \"=%d\"" % ref.curr print "send \"%d 44 0\\n\"" % ref.next() print "simple_expect \"=%d\"" % ref.curr print "client_death %d" % (PERSONS[-1] - 6) print "lyskomd_death" def simple_create_delete(): print "send_user \"testing simple create+delete\\n\"" for author in [6, 7, 8, 9]: if EXTENDED: print "send_user \"...author %d (be patient)\\n\"" % author for misc_type in [0, 1, 15]: for rcpt in [6, 7, 8, 9, 10, 11, 12, 13, 14, 15]: if author in [6, 9] and rcpt in [12, 15]: continue txt = create(author, [(misc_type, rcpt)]) delete(author, txt) if not EXTENDED: continue for second_misc_type in [0, 1, 15]: for second_rcpt in [6, 7, 8, 9, 10, 11, 12, 13, 14, 15]: if rcpt == second_rcpt: continue if author in [6, 9] and second_rcpt in [12, 15]: continue txt = create(author, [ (misc_type, rcpt), (second_misc_type, second_rcpt)]) delete(author, txt) def simple_create_add_delete(): print "send_user \"testing simple create+add+delete\\n\"" for author in [6, 7, 8, 9]: if EXTENDED: print "send_user \"...author %d (be patient)\\n\"" % author for misc_type in [0, 1, 15]: for rcpt in [6, 7, 8, 9, 10, 11, 12, 13, 14, 15]: if author in [6, 9] and rcpt in [12, 15]: continue txt = create(author, []) add_misc(author, txt, misc_type, rcpt) verify_text_stat(txt) delete(author, txt) if not EXTENDED: continue for second_misc_type in [0, 1, 15]: for second_rcpt in [6, 7, 8, 9, 10, 11, 12, 13, 14, 15]: if rcpt == second_rcpt: continue if author in [6, 9] and second_rcpt in [12, 15]: continue txt = create(author, []) add_misc(author, txt, misc_type, rcpt) verify_text_stat(txt) add_misc(author, txt, second_misc_type, second_rcpt) verify_text_stat(txt) delete(author, txt) def special_cases(): print "send_user \"testing some special cases\\n\"" txt = create(7, [(0, 10)]) add_misc(6, txt, 15, 8) verify_text_stat(txt) remove_misc(7, txt, 10) verify_text_stat(txt) delete(7, txt) def generate_test(): setup() simple_create_delete() simple_create_add_delete() special_cases() disco() print "# Automatically generated by gen-15.py. Do not edit." generate_test() print "# Automatically generated by gen-15.py. Do not edit." lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/gen-19.py0000664000015100472110000004605107721716134017353 # Test suite for lyskomd. # Copyright (C) 2000-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Generate a test script that tests permissions of recpt, cc-recpt and # bcc-recpt, and that proper asynchronous messages are sent. This # tests combinations of active and passive memberships. import string # Set EXTENDED to 1 to emit tests for lots of misc-into combinations, # which takes a very long time to test (approx. 5 minutes on a 600 MHz Athlon). EXTENDED = 0 # Set DEBUG to 1 to emit extra "get-time" calls, which slows the test down # approximately 5%, but makes it easier to track down errors. DEBUG = 0 # The database that this test sets up, before any texts are created, # looks like this: # # Persons: # 6 "Person 6" Member of 6. # 7 "Person 7" Creator of 10, 11, 12. Member of 10, 11, 12. # Passive member of 13, 14, 15. # 8 "Person 8" Member of 8, 13, 14, 15. # Passive member of 10, 11, 12. # 9 "Person 9" Creator of 13, 14, 15. Member of 9. # # Conferences: # 10 "conf 10" # 11 "conf 11" rd-prot # 12 "conf 12" rd-prot, secret # 13 "conf 13" # 14 "conf 14" rd-prot # 15 "conf 15" rd-prot, secret class factory: def __init__(self, bcc_trigg, bcc_visible, bcc_author_visible, other_trigg, other_visible, rd): self.__bcc_trigg = bcc_trigg self.__bcc_visible = bcc_trigg + bcc_visible self.__bcc_author_visible = (bcc_trigg + bcc_visible + bcc_author_visible) self.__other_trigg = bcc_trigg + other_trigg self.__other_visible = bcc_trigg + other_trigg + other_visible for n in bcc_visible: if n not in self.__other_visible: self.__other_visible.append(n) self.__readable = bcc_trigg + other_trigg + rd def create(self, author, misc, conf, loc, rec_time = None, sent_by = None, sent_at = None): if misc == 15: trigg = self.__bcc_trigg visib = self.__bcc_visible author_visib = self.__bcc_author_visible else: trigg = self.__other_trigg visib = self.__other_visible author_visib = self.__other_visible return misc_group(misc, conf, loc, trigg, visib, author_visib, self.__readable, rec_time, sent_by, sent_at, author) def a_list_pattern(lst): if len(lst) == 0: return "0 \\\\\\*" else: return "%d { %s }" % (len(lst), string.join(lst, " ")) def a_list_rq(lst): return "%d { %s }" % (len(lst), string.join(lst, " ")) class sequence_allocator: def __init__(self, start): self.curr = start def next(self): self.curr = self.curr + 1 return self.curr class misc_group: def __init__(self, misc, conf, loc, trigg, visib, visib_by_author, readable, rec_time, sent_by, sent_at, author): self.__misc = misc self.__conf = conf self.__loc = loc self.__trigg = trigg self.__visib = visib self.__visib_by_author = visib_by_author self.__readable = readable self.__rec_time = rec_time self.__sent_by = sent_by self.__sent_at = sent_at self.__author = author def visible(self, viewer): return (viewer in self.__visib or (viewer == self.__author and viewer in self.__visib_by_author)) def miscs(self, viewer): if not self.visible(viewer): return [] res = ["%d %d" % (self.__misc, self.__conf), "6 %d" % self.__loc] if self.__rec_time != None: res.append("7 $any_time") if self.__sent_by != None: res.append("8 %d" % self.__sent_by) if self.__sent_at != None: res.append("9 $any_time") return res def async(self, viewer, text_no): if not self.visible(viewer): return None return "%d %d %d" % (text_no, self.__conf, self.__misc) def trigger(self, viewer): return viewer in self.__trigg def readable(self, viewer): return viewer in self.__readable def recipient(self): return self.__conf def recipient_type(self): return self.__misc class text_stat: tno = sequence_allocator(0) def __init__(self, author): self.__author = author self.__misc_groups = [] self.__text_no = self.tno.next() def add_misc_group(self, misc_grp): assert isinstance(misc_grp, misc_group) self.__misc_groups.append(misc_grp) def author(self): return self.__author def misc_groups(self): return self.__misc_groups[:] def text_no(self): return self.__text_no def remove_misc_group(self, removed): self.__misc_groups.remove(removed) # (creat, rcpt): bcc-trigg, bcc-vis, bcc-author-vis, other-trigg, other-vis, rd obj = { (6, 6): factory([6], [], [7, 8, 9], [], [7, 8, 9], []), (6, 7): factory([], [6, 7], [8, 9], [], [8, 9], [7]), (6, 8): factory([8], [6], [7, 9], [], [7, 9], []), (6, 9): factory([9], [6], [7, 8], [], [7, 8], []), (6, 10): factory([7], [6, 8, 9], [], [], [8], [6, 8, 9]), (6, 11): factory([7], [6, 8], [9], [], [8, 9], [8]), (6, 12): factory([7], [6, 8], [], [], [8, 9], [8]), (6, 13): factory([8], [6, 7, 9], [], [], [7], [6, 7, 9]), (6, 14): factory([8], [6, 7, 9], [], [], [7], [7, 9]), (6, 15): factory([8], [6, 7, 9], [], [], [7], [7, 9]), (7, 6): factory([6], [7], [8, 9], [], [8, 9], []), (7, 7): factory([], [7], [6, 8, 9], [], [6, 8, 9], [7]), (7, 8): factory([8], [7], [6, 9], [], [6, 7, 9], []), (7, 9): factory([9], [7], [6, 8], [], [6, 7, 8], []), (7, 10): factory([7], [6, 8, 9], [], [], [8], [6, 8, 9]), (7, 11): factory([7], [8], [6, 9], [], [6, 8, 9], [8]), (7, 12): factory([7], [8], [], [], [8], [8]), (7, 13): factory([8], [6, 7, 9], [], [], [7], [6, 7, 9]), (7, 14): factory([8], [7, 9], [6], [], [6, 7], [7, 9]), (7, 15): factory([8], [7, 9], [], [], [7], [7, 9]), (8, 6): factory([6], [8], [7, 9], [], [7, 9], []), (8, 7): factory([], [7, 8], [6, 9], [], [6, 9], [7]), (8, 8): factory([8], [], [6, 7, 9], [], [6, 7, 9], []), (8, 9): factory([9], [8], [6, 7], [], [6, 7], []), (8, 10): factory([7], [6, 8, 9], [], [], [8], [6, 8, 9]), (8, 11): factory([7], [8], [6, 9], [], [6, 8, 9], [8]), (8, 12): factory([7], [8], [], [], [8], [7]), (8, 13): factory([8], [6, 7, 9], [], [], [7], [6, 7, 9]), (8, 14): factory([8], [7, 9], [6], [], [6, 7], [7, 9]), (8, 15): factory([8], [7, 9], [], [], [7], [7, 9]), (9, 6): factory([6], [9], [7, 8], [], [7, 8], []), (9, 7): factory([], [7, 9], [6, 8], [], [6, 8], [7]), (9, 8): factory([8], [9], [6, 7], [], [6, 7], []), (9, 9): factory([9], [], [6, 7, 8], [], [6, 7, 8], []), (9, 10): factory([7], [6, 8, 9], [], [], [8], [6, 8, 9]), (9, 11): factory([7], [8, 9], [6], [], [6, 8], [8]), (9, 12): factory([7], [8, 9], [], [], [8], [8]), (9, 13): factory([8], [6, 7, 9], [], [], [7], [6, 7, 9]), (9, 14): factory([8], [7, 9], [6], [], [6, 7], [7, 9]), (9, 15): factory([8], [7, 9], [], [], [7], [7, 9]), } class loc_no_allocator: def __init__(self): self.__prev = {} def alloc(self, conf): res = self.__prev.get(conf, 0) + 1 self.__prev[conf] = res return res locno = loc_no_allocator() def talk_to(person): global active_person if active_person != person: print "# talk to Person %d" % person print "talk_to client %d" % (person - 6) active_person = person active_person = None ref = sequence_allocator(999) def create(author, recipients): print txt = text_stat(author) crea = [] for (m, r) in recipients: txt.add_misc_group(obj[(author, r)].create(author, m, r, locno.alloc(r))) crea.append("%d %d" % (m, r)) talk_to(author) cs = ref.next() print "# Creating text %d by %d" % (txt.text_no(), txt.author()) print "send \"%d 86 [holl \"text %d\"] %s 0 { }\\n\"" % ( cs, txt.text_no(), a_list_rq(crea)) new_text(txt) talk_to(author) print "simple_expect \"=%d %d\"" % (cs, txt.text_no()) verify_text_stat(txt) return txt def add_misc(adder, txt, misc_type, rcpt): sent_by = None if adder != txt.author(): sent_by = adder misc = obj[(adder, rcpt)].create(txt.author(), misc_type, rcpt, locno.alloc(rcpt), sent_at = 1, sent_by = sent_by) talk_to(adder) cs = ref.next() print "# Adding recipient to text %d; adder %d" % (txt.text_no(), adder) print "send \"%d 30 %d %d %d\\n\"" % (cs, txt.text_no(), rcpt, misc_type) new_recipient(adder, txt, misc) talk_to(adder) print "simple_expect \"=%d\"" % cs txt.add_misc_group(misc) def verify_text_stat(txt): for p in PERSONS: talk_to(p) print "send \"%d 90 %d\\n\"" % (ref.next(), txt.text_no()) visib = p == txt.author() pattern = [] for m in txt.misc_groups(): pattern = pattern + m.miscs(p) if m.readable(p): visib = 1 if visib: print "simple_expect \"=%d $any_time " \ "%d 0 %d 0 %s 0 \\\\\\*\"" % ( ref.curr, txt.author(), len("text %d" % txt.text_no()), a_list_pattern(pattern)) else: print "simple_expect \"%%%d 14 %d\"" % (ref.curr, txt.text_no()) PERSONS = range(6, 10) def new_text(txt): for viewer in PERSONS: sent = 0 pattern = [] for m in txt.misc_groups(): if m.trigger(viewer): sent = 1 pattern = pattern + m.miscs(viewer) if sent: talk_to(viewer) print "simple_expect \":18 15 %d $any_time " \ "%d 0 %d 0 %s 0 \\\\\\*\"" % ( txt.text_no(), txt.author(), len("text %d" % txt.text_no()), a_list_pattern(pattern)) elif txt.author() != viewer and DEBUG: talk_to(viewer) print "send \"%d 35\\n\"" % ref.next() print "simple_expect \"=%d $any_time\"" % ref.curr def new_recipient(author, txt, misc): for viewer in PERSONS: sent = 0 for m in txt.misc_groups() + [misc]: if m.trigger(viewer): sent = 1 async = misc.async(viewer, txt.text_no()) if sent and async != None: talk_to(viewer) print "simple_expect \":3 16 %s\"" % async elif author != viewer and DEBUG: talk_to(viewer) print "send \"%d 35\\n\"" % ref.next() print "simple_expect \"=%d $any_time\"" % ref.curr def delete(deleter, txt): nr = ref.next() talk_to(deleter) print "# Deleting text %d; deleter %d" % (txt.text_no(), deleter) print "send \"%d 29 %d\\n\"" % (nr, txt.text_no()) deleted_text(deleter, txt) talk_to(deleter) print "simple_expect \"=%d\"" % nr def deleted_text(deleter, txt): for viewer in PERSONS: sent = 0 pattern = [] for m in txt.misc_groups(): if m.trigger(viewer): sent = 1 pattern = pattern + m.miscs(viewer) if sent: talk_to(viewer) print "simple_expect \":18 14 %d $any_time " \ "%d 0 %d 0 %s 0 \\\\\\*\"" % ( txt.text_no(), txt.author(), len("text %d" % txt.text_no()), a_list_pattern(pattern)) elif deleter != viewer and DEBUG: talk_to(viewer) print "send \"%d 35\\n\"" % ref.next() print "simple_expect \"=%d $any_time\"" % ref.curr def remove_misc(remover, txt, recip): for removed in txt.misc_groups(): if removed.recipient() == recip: break else: raise 'no-such-recipient' nr = ref.next() talk_to(remover) print "# Removing recipient from text %d; remover %d" % ( txt.text_no(), remover) print "send \"%d 31 %d %d\\n\"" % (nr, txt.text_no(), recip) sub_recipient(remover, txt, recip, removed.recipient_type()) talk_to(remover) print "simple_expect \"=%d\"" % nr txt.remove_misc_group(removed) def sub_recipient(remover, txt, recip, misc_type): for viewer in PERSONS: sent = 0 for m in txt.misc_groups(): if m.trigger(viewer): sent = 1 if sent: talk_to(viewer) print "simple_expect \":3 17 %d %d %s\"" % ( txt.text_no(), recip, misc_type) elif remover != viewer and DEBUG: talk_to(viewer) print "send \"%d 35\\n\"" % ref.next() print "simple_expect \"=%d $any_time\"" % ref.curr def setup(): print "lyskomd_start" for p in PERSONS: print "client_start %d" % (p - 6) talk_to(p) print "send \"A3Hfoo\\n\"" print "simple_expect \"LysKOM\" \"connected %d\"" % p print "send \"%d 80 4 { 14 15 16 17 }\\n\"" % ref.next() print "simple_expect \"=%d\"" % ref.curr print "send \"%d 89 [holl \"Person %d\"] [holl \"foo\"] " \ "00000000 0 { }\\n\"" % (ref.next(), p) print "simple_expect \"=%d %d\"" % (ref.curr, p) print "send \"%d 62 %d [holl \"foo\"] 0\\n\"" % (ref.next(), p) print "simple_expect \"=%d\"" % ref.curr for (creator, conf, conf_type) in [ (7, 10, "0000"), (7, 11, "1000"), (7, 12, "1010"), (9, 13, "0000"), (9, 14, "1000"), (9, 15, "1010"), ]: talk_to(creator) print "send \"%d 88 [holl \"conf %d\"] %s 0 { }\\n\"" % ( ref.next(), conf, conf_type) print "simple_expect \"=%d %d\"" % (ref.curr, conf) talk_to(7) for conf in [10, 11, 12]: for (reader, mtype) in [(7, "00000000"), (8, "01000000")]: print "send \"%d 100 %d %d 100 3 %s\\n\"" % ( ref.next(), conf, reader, mtype) print "simple_expect \"=%d\"" % ref.curr talk_to(9) for conf in [13, 14, 15]: for (reader, mtype) in [(7, "01000000"), (8, "00000000")]: print "send \"%d 100 %d %d 100 6 %s\\n\"" % ( ref.next(), conf, reader, mtype) print "simple_expect \"=%d\"" % ref.curr print "talk_to lyskomd" for conf in [10, 11, 12]: print "simple_expect \"Person 8 added to conference %d by 7.\"" % conf for conf in [13, 14, 15]: for reader in [7, 8]: print ("simple_expect " + "\"Person %d added to conference %d by 9.\"") % ( reader, conf) talk_to(7) print "send \"%d 15 7 7\\n\"" % ref.next() print "simple_expect \"=%d\"" % ref.curr def disco(): for p in PERSONS[:-1]: talk_to(p) print "send \"%d 55 0\\n\"" % ref.next() print "simple_expect \"=%d\"" % ref.curr print "client_death %d" % (p - 6) talk_to(PERSONS[-1]) print "send \"%d 62 5 [holl \"gazonk\"] 1\\n\"" % ref.next() print "simple_expect \"=%d\"" % ref.curr print "send \"%d 42 255\\n\"" % ref.next() print "simple_expect \"=%d\"" % ref.curr print "send \"%d 44 0\\n\"" % ref.next() print "simple_expect \"=%d\"" % ref.curr print "client_death %d" % (PERSONS[-1] - 6) print "lyskomd_death" def simple_create_delete(): print "send_user \"testing simple create+delete\\n\"" for author in [6, 7, 8, 9]: if EXTENDED: print "send_user \"...author %d (be patient)\\n\"" % author for misc_type in [0, 1, 15]: for rcpt in [6, 7, 8, 9, 10, 11, 12, 13, 14, 15]: if author in [6, 9] and rcpt in [12, 15]: continue txt = create(author, [(misc_type, rcpt)]) delete(author, txt) if not EXTENDED: continue for second_misc_type in [0, 1, 15]: for second_rcpt in [6, 7, 8, 9, 10, 11, 12, 13, 14, 15]: if rcpt == second_rcpt: continue if author in [6, 9] and second_rcpt in [12, 15]: continue txt = create(author, [ (misc_type, rcpt), (second_misc_type, second_rcpt)]) delete(author, txt) def simple_create_add_delete(): print "send_user \"testing simple create+add+delete\\n\"" for author in [6, 7, 8, 9]: if EXTENDED: print "send_user \"...author %d (be patient)\\n\"" % author for misc_type in [0, 1, 15]: for rcpt in [6, 7, 8, 9, 10, 11, 12, 13, 14, 15]: if author in [6, 9] and rcpt in [12, 15]: continue txt = create(author, []) add_misc(author, txt, misc_type, rcpt) verify_text_stat(txt) delete(author, txt) if not EXTENDED: continue for second_misc_type in [0, 1, 15]: for second_rcpt in [6, 7, 8, 9, 10, 11, 12, 13, 14, 15]: if rcpt == second_rcpt: continue if author in [6, 9] and second_rcpt in [12, 15]: continue txt = create(author, []) add_misc(author, txt, misc_type, rcpt) verify_text_stat(txt) add_misc(author, txt, second_misc_type, second_rcpt) verify_text_stat(txt) delete(author, txt) def special_cases(): print "send_user \"testing some special cases\\n\"" txt = create(7, [(0, 10)]) add_misc(6, txt, 15, 8) verify_text_stat(txt) remove_misc(7, txt, 10) verify_text_stat(txt) delete(7, txt) def generate_test(): setup() simple_create_delete() simple_create_add_delete() special_cases() disco() print "# Automatically generated by gen-19.py. Do not edit." generate_test() print "# Automatically generated by gen-19.py. Do not edit." lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/internal-connections-cov.exp0000664000015100472110000000023206716300557023430 # Supplemental test cases for internal-connections.c # No test cases here yet. As of 1999-91-24 the other test cases # cover all of internal-connections lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/isc-parse-cov.exp0000664000015100472110000000012506716300560021155 # Supplemental test cases for isc-parse # The regular test suide gets 100% coverage lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/log-cov.exp0000664000015100472110000000012106716300561020045 # Supplemental test cases for log # Regular test suite does the job well enough lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/membership-cov.exp0000664000015100472110000002133707721716134021437 # Test suite for lyskomd. # Copyright (C) 1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Supplemental tests for membership.c # Second iteration (possibly) # Call to do_sub_member with conf_c, pers_p set to NULL # Generate a call to access_perm, fast_access_perm with viewer_p set to NULL # --- I don't think there are any such calls in the server # Generate a call to locate_member that fails to locate a member # --- Can't be done unless the membership and member lists are out of sync # Stuff to ignore # Everything in check_membership # Error statements in DEBUG_MARK_AS_READ # Membership and member record mismatches source "$srcdir/config/prot-a.exp" read_versions lyskomd_start "" "\ Add members by invitation: false" client_start 0 talk_to client 0 kom_connect "DejaGnu Test Suite" kom_accept_async "0 { }" kom_create_person "P6" "PW6" "00000000" "0 { }" kom_create_person "P7" "PW7" "00000000" "0 { }" kom_create_person "P8" "PW8" "00000000" "0 { }" kom_create_person "P9" "PW9" "00000000" "0 { }" kom_login 7 "PW7" 0 kom_set_conf_type 7 "10110000" kom_login 6 "PW6" 0 kom_create_conference "C10" "00000000" "0 { }" kom_create_conference "C11" "00000000" "0 { }" kom_create_conference "C12" "00000000" "0 { }" kom_create_conference "C13" "00000000" "0 { }" kom_create_conference "C14" "10000000" "0 { }" kom_create_conference "C15" "10100000" "0 { }" kom_create_conference "C16" "00000000" "0 { }" kom_add_member 16 6 200 9999 "00000000" kom_logout kom_create_person "P17" "PW17" "00000000" "0 { }" kom_create_person "P18" "PW18" "00000000" "0 { }" kom_create_person "P19" "PW19" "00000000" "0 { }" kom_login 6 "PW6" 0 kom_add_member 10 17 200 9999 "00000000" lyskomd_expect "Person 17 added to conference 10 by 6." kom_login 9 "PW9" 0 send "1000 106 9 1\n" simple_expect "=1000" send "1001 100 10 9 100 9999 00000000\n" simple_expect "=1001" send "1002 100 11 9 100 9999 00000000\n" simple_expect "=1002" send "1003 100 12 9 100 9999 00000000\n" simple_expect "=1003" send "1004 86 [holl "T1"] 4 { 0 1 0 10 0 11 0 12 } 0 { }\n" simple_expect "=1004 1" send "1005 86 [holl "T2"] 4 { 0 1 0 10 0 11 0 12 } 0 { }\n" simple_expect "=1005 2" send "1006 86 [holl "T3"] 4 { 0 1 0 10 0 11 0 12 } 0 { }\n" simple_expect "=1006 3" send "1007 27 10 2 { 1 3 }\n" simple_expect "=1007" send "1008 27 11 2 { 1 3 }\n" simple_expect "=1008" send "1009 27 12 2 { 1 3 }\n" simple_expect "=1009" kom_login 6 "PW6" 0 kom_add_member 10 18 200 9999 "00000000" lyskomd_expect "Person 18 added to conference 10 by 6." kom_add_member 10 19 200 9999 "00000000" lyskomd_expect "Person 19 added to conference 10 by 6." # Get membership from a person with unread-is-secret set kom_login 8 "PW8" 0 send "1100 99 9 0 9999 1\n" simple_expect "=1100 4 { 0 $any_time 9 255 0 0 \\* 9 $any_time 00000000 1 $any_time 10 100 0 0 \\* 9 $any_time 00000000 2 $any_time 11 100 0 0 \\* 9 $any_time 00000000 3 $any_time 12 100 0 0 \\* 9 $any_time 00000000 }" # Call add_membership with WHERE set way too high kom_login 9 "PW9" 0 send "1200 100 13 9 100 9999 00000000\n" simple_expect "=1200" # Move an existing membership from N to N-2, N-2 to N send "1201 100 13 9 100 1 00000000\n" simple_expect "=1201" send "1202 100 13 9 100 4 00000000\n" simple_expect "=1202" send "1203 15 10 9\n" simple_expect "=1203" # Add a member with priority 0 and fake_passive ON # This *really* should have been tested in 05.exp! send "1300 14 10 9 0 9999\n" simple_expect "=1300" # Restore the flags kom_login 9 "PW9" 0 send "1301 102 9 10 00000000\n" simple_expect "=1301" # Remove a member from conf X when member is logged on with CWC X client_start 1 talk_to client 1 kom_connect "DejaGnu Test Suite" kom_accept_async "1 { 8 }" kom_login 6 "PW6" 0 kom_add_member 10 6 100 9999 00000000 kom_change_conference 10 talk_to client 0 kom_login 6 "PW6" 0 send "1401 15 10 6\n" simple_expect "=1401" talk_to client 1 simple_expect ":1 8 10" send "1400 55 0\n" simple_expect "=1400" client_death 1 talk_to client 0 # Remove a membership in the middle of the membership list kom_login 9 "PW9" 0 send "1500 15 11 9\n" simple_expect "=1500" # Remove a member without being supervisor of conf or person kom_login 6 "PW6" 0 send "1600 100 15 9 100 9999 00000000\n" lyskomd_expect "Person 9 added to conference 15 by 6." simple_expect "=1600" send "1601 100 11 9 100 9999 00100000\n" lyskomd_expect "Person 9 added to conference 11 by 6." simple_expect "=1601" # Remove with read access to conf and membership kom_login 8 "PW8" 0 send "1602 15 12 9\n" simple_expect "%1602 12 12" # Remove secret conf send "1603 15 15 9\n" simple_expect "%1603 9 15" # Remove secret membership send "1604 15 11 9\n" simple_expect "%1604 13 11" # Add a member to a rd_prot conference without access to conf kom_login 8 "Pw8" 0 send "1700 100 14 8 100 9999 00000000\n" simple_expect "%1700 11 14" # Add a member to a secret conf we don't know about send "1701 100 15 8 100 9999 00000000\n" simple_expect "%1701 9 15" # Try to add a member who is already a secret member kom_login 9 "PW9" 0 send "1702 99 9 0 100 0\n" extracting_expect "=1702 ($any*)" tmp 1 regsub -all "\\*" "$tmp" "\\*" mship kom_login 8 "PW8" 0 send "1703 100 11 9 100 9999 00000000\n" simple_expect "=1703" kom_login 9 "PW9" 0 send "1704 99 9 0 100 0\n" simple_expect "=1704 $mship" # Try to change someone else's priorities kom_login 8 "PW8" 0 send "1705 100 12 9 200 9999 00000000\n" simple_expect "%1705 12 9" # Attempt to mark a text as read in a conf the person is not a member of kom_login 9 "PW9" 0 send "1800 27 1 3 { 1 2 3 }\n" simple_expect "%1800 13 1" # Attempt to mark local text zero as read send "1801 27 10 1 { 0 }\n" simple_expect "%1801 17 0" # As person 6 mark text with rcpt,cc,bcc 6 as read send "1802 86 [holl "T4"] 2 { 0 6 0 9 } 0 { }\n" simple_expect "=1802 4" send "1803 86 [holl "T5"] 2 { 1 6 0 9 } 0 { }\n" simple_expect "=1803 5" send "1804 86 [holl "T6"] 2 { 15 6 0 9 } 0 { }\n" simple_expect "=1804 6" kom_login 6 "PW6" 0 send "1805 27 6 3 { 1 2 3 }\n" simple_expect "=1805" # Create a conf with 5 text, with conf as CWC # Create a bunch of texts, read a nonconsecutive range # Delete all texts in that range and one more # Read the first existing text kom_login 6 "PW6" 0 send "1900 86 [holl "T7"] 1 { 0 16 } 0 { }\n" simple_expect "=1900 7" send "1901 86 [holl "T8"] 1 { 0 16 } 0 { }\n" simple_expect "=1901 8" send "1902 86 [holl "T9"] 1 { 0 16 } 0 { }\n" simple_expect "=1902 9" send "1903 86 [holl "T10"] 1 { 0 16 } 0 { }\n" simple_expect "=1903 10" send "1904 86 [holl "T11"] 1 { 0 16 } 0 { }\n" simple_expect "=1904 11" send "1905 2 16\n" simple_expect "=1905" send "1906 27 16 1 { 1 }\n" simple_expect "=1906" send "1907 27 16 1 { 3 }\n" simple_expect "=1907" send "1908 29 7\n" simple_expect "=1908" send "1909 29 8\n" simple_expect "=1909" send "1910 29 9\n" simple_expect "=1910" send "1911 29 10\n" simple_expect "=1911" send "1912 27 16 1 { 5 }\n" simple_expect "=1912" # Try to get the membership of a secret person kom_login 6 "PW6" 0 send "2000 99 7 0 9999 0\n" simple_expect "%2000 10 7" # Try to get membership with first WAY too high send "2001 99 6 999 9999 0\n" simple_expect "%2001 19 999" # Try to get the members of a secret conference kom_login 8 "PW8" 0 send "2100 101 15 0 9999\n" simple_expect "%2100 9 15" # Call set-unread on a conf we are not a member of # Call set-last-read on a conf we are not a member of kom_login 8 "PW8" 0 send "2200 40 10 0\n" simple_expect "%2200 13 10" send "2201 77 10 1\n" simple_expect "%2201 13 10" # Call set-membership-type for a secret conf we are not member of # Call set-membership-type for an open conf we are not member of send "2300 102 8 15 00000000\n" simple_expect "%2300 9 15" send "2301 102 8 10 00000000\n" simple_expect "%2301 13 10" # ====================================================================== # Shut it all down kom_login 5 "gazonk" 0 kom_enable 255 send "9999 44 0\n" simple_expect "=9999" client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/memory-cov.exp0000664000015100472110000000110406716300562020577 # Supplemental test cases to exercise memory.c # Call copy_aux_item_list with a non-empty aux_item_list # -- Probably has to be called from the garb # Stuff we can't call # -- Call to clear_mark_list with mark_list set to NULL # -- Call to clear_member_list with member_list set to NULL # -- Call to clear_membership with membership set to NULL # -- Call to clear_membership_list with membership set to NULL # -- Call to clear_text_stat when misc-info-list contains junk # Stuff that gets called when we get coverage elsewhere # -- copy_text_stat # Nothing more to do then... lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/null.exp0000664000015100472110000000242507721716134017466 # Test suite for lyskomd. # Copyright (C) 1999, 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # No test cases this just starts and stops the server # # This can be used as a baseline for other tests read_versions source "$srcdir/config/prot-a.exp" lyskomd_start client_start 0 kom_connect "DejaGnu Test Suite" kom_accept_async "0 { }" kom_login 5 "gazonk" 0 kom_enable 255 send "1 44 0\n" simple_expect "=1" client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/person-cov.exp0000664000015100472110000003317307721716134020613 # Test suite for lyskomd. # Copyright (C) 1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Supplemental test cases for person.c # X Attempt to mark a text in a secret conference # X Attempt to mark a text in an rd_prot conference # X Attempt to mark a text when it has reached the mark limit # X Attempt to unmark a text that has zero marks # X Attempt to set the user area to a text that has reached mark limit # X Set a user area when there already is a user area # X Set a user area when the current user area has zero marks # X Set a user area when the current user area is deleted # X Attempt to set-user-area for a secret person # X Attempt to ser-user-area for a person we don't have rights to # X Delete a person that has marked texts # X Delete a person that has a marked text that has zero marks # X Delete a person whose user area is deleted # X Try to log in with incorrect password # X Try to create a person before login with param.create_person_before_login set # X Try to create a person without the privs to do so # X Try to create a person with zero-length name # X Try to create a person with a non-printable character in the name # X Try to create a person with the name of a person already there # X Try to create a person with a password containing a NUL # X Create a person with an invalid aux-item-list # X Create persons so we hit the max number of confs # X get-pers-stat for person with secret letterbox # X get-pers-stat-old for person with secret letterbox # X get-created-texts for a person with secret letterbox # X Request 256 texts from map-created-texts # X Call map-created-texts for a secret person # X Attempt to change someone else's password # X Attempt to change password to one containing a NUL # X Attempt to query-read-texts for a secret person # X Attempt to query-read-texts for a secret conference # X Attempt to query-read-texts for an open conf we are not member of # X Attempt to query-read-texts for someone else's secret membership # X Attempt to query-read-texts for a person with unread_is_secret set # X Call set-pers-flags for self # X Call set-pers-flags for supervised person # X Call set-pers-flags as administrator # X Call set-pers-flags for a secret person we may not know about # X Call set-pers-flags for person 0 # X Call set-pers-flags for someone else # Hard to do # All the restart_kom calls... # Fail to create the password string in legal_passwd # Call to do_mark_text with pers_p equal NULL # Call to do_mark_text with text_s equal to NULL # Call to do_unmark_text with pers_p equal NULL # Call to do_set_user_area with pers_p equal NULL # In do_delete_person fail to remove the person as a member in a conf # -- Happens if the member/membership correspondence is FUBAR # Fail to create the password string in chk_passwd # Failure in cached_create_person (bloddy thing can't fail!) # Failure in cached_get_person_stat # Failure in do_set_passwd # Failure in access_perm read_versions source "$srcdir/config/prot-a.exp" lyskomd_start "" "" "\ Aux-item definition file: $srcdir/lyskomd.0/aux-items.conf Max conferences: 17 Max texts: 2000 Max marks per text: 1 Max conference name length: 60 DNS log threshold: 3600 Anyone can create new persons: false Allow creation of persons before login: false " client_start 0 talk_to client 0 kom_connect "DejaGnu Test Suite" kom_accept_async "0 { }" kom_login 5 "gazonk" 0 kom_enable 255 kom_create_person "P6" "PW6" "00000000" "0 { }" kom_create_person "P7" "PW7" "00000000" "0 { }" kom_create_person "P8" "PW8" "00000000" "0 { }" kom_create_person "P9" "PW9" "00000000" "0 { }" kom_set_conf_type 7 "10110000" kom_set_priv_bits 6 "0001110000000000" kom_login 6 "PW6" 0 kom_create_conference "C10" "00000000" "0 { }" kom_create_conference "C11" "00000000" "0 { }" kom_create_conference "C12" "00000000" "0 { }" kom_create_conference "C13" "10000000" "0 { }" kom_create_conference "C14" "10100000" "0 { }" kom_add_member 11 6 100 9999 00100000 kom_add_member 14 6 100 9999 00100000 kom_add_member 14 7 100 9999 00000000 lyskomd_expect "Person 7 added to conference 14 by 6." kom_add_member 10 7 100 9999 00000000 lyskomd_expect "Person 7 added to conference 10 by 6." kom_add_member 10 9 100 9999 00000000 lyskomd_expect "Person 9 added to conference 10 by 6." # Tests for text marking kom_login 6 "PW6" 0 send "1000 86 [holl "T1"] 1 { 0 14 } 0 { }\n" simple_expect "=1000 1" send "1001 86 [holl "T2"] 1 { 0 13 } 0 { }\n" simple_expect "=1001 2" send "1002 86 [holl "T3"] 1 { 0 10 } 0 { }\n" simple_expect "=1002 3" # Attempt to mark a text in a secret conference we don't know about kom_login 8 "PW8" 0 send "1003 72 1 0\n" simple_expect "%1003 14 1" # Attempt to mark a text in an rd_prot conference we're not members of send "1004 72 2 0\n" simple_expect "%1004 14 2" # Attempt to mark beyond mark-limit send "1005 72 3 0\n" simple_expect "=1005" kom_login 9 "PW9" 0 send "1006 72 3 0\n" simple_expect "%1006 36 3" # Attempt to unmark a text that has zero mark count but is marked kom_login 8 "PW8" 0 if {$debug_calls} { send "1007 1001 3 0\n" simple_expect "=1007" } else { unsupported "Use configure --with-debug-calls to enable" } send "1008 73 3\n" if {$debug_calls} { lyskomd_expect "WNG: do_unmark_text\\(\\): Text 3 has no_of_marks==0, but person 8 had marked the text\\." } simple_expect "=1008" # Tests for set-user-area # Attempt to set the user area to a text that has reached mark limit # Set a user area when there already is a user area # Set a user area when the current user area has zero marks # Set a user area when the current user area is deleted # Attempt to set-user-area for a secret person # Attempt to ser-user-area for a person we don't have rights to kom_login 6 "PW6" 0 send "2000 86 [holl "T4"] 1 { 0 10 } 0 { }\n" simple_expect "=2000 4" send "2001 86 [holl "T5"] 1 { 0 10 } 0 { }\n" simple_expect "=2001 5" send "2002 86 [holl "T6"] 1 { 0 10 } 0 { }\n" simple_expect "=2002 6" # Attempt to set a user area that has reached mark-limit kom_login 8 "PW8" 0 send "2003 72 4 1\n" simple_expect "=2003" send "2004 57 8 4\n" lyskomd_expect "LIMIT: set_user_area\\(8, 4\\): New user_area's mark count \\(1\\) > 1." simple_expect "%2004 36 4" # Set a user area when there already is a user area send "2005 57 8 5\n" simple_expect "=2005" send "2006 57 8 6\n" simple_expect "=2006" # Set a user area when the current one has zero marks if {$debug_calls} { send "2007 1001 6 0\n" simple_expect "=2007" } else { unsupported "Use configure --with-debug-calls to enable" } send "2008 57 8 5\n" if {$debug_calls} { lyskomd_expect "ERROR: set_user_area\\(8, 5\\): Old user_area 6 unmarked." } simple_expect "=2008" # Set a user area when the current one has been deleted kom_login 6 "PW6" 0 send "2009 29 5\n" simple_expect "=2009" kom_login 8 "PW8" 0 send "2010 57 8 6\n" simple_expect "=2010" # Attempt to set the user area for a secret person send "2011 57 7 6\n" simple_expect "%2011 10 7" # Attempt to set the user area for another person we don't have rights to send "2012 57 9 6\n" simple_expect "%2012 12 9" # Tests for deleting a person kom_login 6 "PW6" 0 kom_create_person "P15" "PW15" "00000000" "0 { }" kom_login 15 "PW15" 0 send "3000 86 [holl "T7"] 1 { 0 10 } 0 { }\n" simple_expect "=3000 7" send "3001 86 [holl "T8"] 1 { 0 10 } 0 { }\n" simple_expect "=3001 8" send "3002 86 [holl "T9"] 1 { 0 10 } 0 { }\n" simple_expect "=3002 9" send "3003 72 7 1\n" simple_expect "=3003" send "3004 72 8 1\n" simple_expect "=3004" if {$debug_calls} { send "3006 1001 8 0\n" simple_expect "=3006" } else { unsupported "Use configure --with-debug-calls to enable" } send "3007 57 15 9\n" simple_expect "=3007" send "3008 29 9\n" simple_expect "=3008" # The setup at this point is # Person 15 has user area 9, which is deleted # Person 15 has marked text 8 and 9 # Text 9 has had its mark count set to zero # Delete a user who has marked texts, whose user area is # deleted and who has a text marked that has zero marks send "3009 11 15\n" if {$debug_calls} { lyskomd_expect "WNG: do_unmark_text\\(\\): Text 8 has no_of_marks==0, but person 15 had marked the text\\." } simple_expect "=3009" # Login stuff. Try to log in with the bad password send "4000 62 6 [holl "BADPWD"] 0\n" simple_expect "%4000 4 6" # Create person stuff # Try to create a person without logging in when that's not allowed kom_logout send "5000 89 [holl "PXX"] [holl "PXX"] 00000000 0 { }\n" simple_expect "%5000 6 0" # Try to create a person without the privs to do so kom_login 8 "PW8" 0 send "5001 89 [holl "PXX"] [holl "PXX"] 00000000 0 { }\n" simple_expect "%5001 12 0" # Try to create a person with an empty name kom_login 6 "PW6" 0 send "5002 89 [holl ""] [holl "PXX"] 00000000 0 { }\n" simple_expect "%5002 18 0" # Try to create a person with a non-printable character in the name send "5003 89 [holl "X\001Y"] [holl "PXX"] 00000000 0 { }\n" simple_expect "%5003 18 0" # Try to create a person with a duplicate name send "5004 89 [holl "P6"] [holl "PWX"] 00000000 0 { }\n" simple_expect "%5004 21 0" # Try to create a person with a password with a NUL # Stupid TCL sort of FORGETS about the string after the NUL # # send "5005 89 [holl "PXX"] [holl "P\000X"] 00000000 0 { }\n" # simple_expect "%5005 18 0" # Attempt to create a person with an invalid aux-item list kom_login 6 "PW6" 0 send "5006 89 [holl "PXX"] [holl "PYY"] 00000000 1 { 0 00000000 0 [holl "A"] }\n" simple_expect "%5006 48 0" # Create persons til we hit the max number of confs kom_login 6 "PW6" 0 send "5006 89 [holl "P16"] [holl "PW16"] 00000000 0 { }\n" simple_expect "=5006 17" send "5007 89 [holl "P17"] [holl "PW17"] 00000000 0 { }\n" lyskomd_expect "ERROR: Couldn't create person. Too many conferences." simple_expect "%5007 19 18" # Tests for get-pers-stat send "6000 49 7\n" simple_expect "%6000 10 7" send "6001 6 7 1\n" simple_expect "%6001 10 7" # Tests for get-created-texts send "7000 47 7 0 9999\n" simple_expect "%7000 10 7" # Test for map-created-texts # Try to get too many entries send "7001 104 6 1 256\n" simple_expect "%7001 46 255" # Try to get created texts for a secret person send "7002 104 7 1 10\n" simple_expect "%7002 10 7" # Attempt to change someone else's password kom_login 8 "PW8" 0 send "8000 8 9 [holl "PW9"] [holl "9PW"]\n" simple_expect "%8000 12 9" # Attempt to change password to one with a NUL # Stupid TCL truncates the password at the NUL # # send "8001 8 [holl "PW8"] [holl "A\000B"]\n" # simple_expect "%8001 4 8" # Tests for query-read-texts kom_login 8 "PW8" 0 # Attempt to query-read-texts for a secret person send "9000 98 7 10\n" simple_expect "%9000 10 7" # Attempt to query-read-texts for a secret conference on an open person send "9001 98 6 14\n" simple_expect "%9001 9 14" # Attempt to query-read-texts for a conference we're not a member of send "9002 98 8 10\n" simple_expect "%9002 13 10" # Attempt to query-read-texts for someone else's secret membership send "9003 98 6 11\n" simple_expect "%9003 13 11" # Attempt to query-read-texts for a person with unread_is_secret set kom_login 5 "gazonk" 0 kom_enable 255 kom_add_member 10 9 100 9999 00000000 send "9004 106 9 10000000\n" simple_expect "=9004" send "9005 86 [holl "T10"] 1 { 0 10 } 0 { }\n" simple_expect "=9005 10" kom_login 9 "PW9" 0 send "9006 27 10 2 { 1 2 }\n" simple_expect "=9006" kom_login 6 "PW6" 0 send "9007 98 9 10\n" simple_expect "=9007 1 $any_time 10 100 0 0 \\* 6 $any_time 00000000" # Tests on set-pers-flags kom_login 9 "PW9" 0 send "10000 49 9\n" extracting_expect "=10000 $hollerith \[01\]+ 10000000 $any_time 0 $any_num ($any*)" pers 1 # Call on self send "10001 106 9 10011001\n" simple_expect "=10001" send "10001 49 9\n" simple_expect "=10001 $hollerith \[01\]+ 10011001 $any_time 0 $any_num $pers" # Call on supervised person kom_login 5 "gazonk" 0 kom_enable 0 send "10002 106 9 01100110\n" simple_expect "=10002" send "10002 49 9\n" simple_expect "=10002 $hollerith \[01\]+ 01100110 $any_time 0 $any_num $pers" # Call as administrator kom_login 5 "gazonk" 0 kom_enable 255 send "10003 106 9 11000011\n" simple_expect "=10003" send "10003 49 9\n" simple_expect "=10003 $hollerith \[01\]+ 11000011 $any_time 0 $any_num $pers" # Call on secret person we don't know about kom_login 8 "PW8" 0 send "10004 106 7 01010101\n" simple_expect "%10004 10 7" kom_login 5 "gazonk" 0 kom_enable 0 send "10005 49 7\n" simple_expect "=10005 $hollerith \[01\]+ 00000000 $any*" # Call on person 0 send "10006 106 0 01110111\n" simple_expect "%10006 8 0" # Call on non-supervised person kom_login 8 "PW8" 0 send "10007 106 9 10101010\n" simple_expect "%10007 12 9" send "10008 49 9\n" simple_expect "=10008 $hollerith \[01\]+ 11000011 $any_time 0 $any_num $pers" # ============================================================ # Shut it down talk_to client 0 kom_login 5 "gazonk" 0 kom_enable 255 send "99999 44 0\n" simple_expect "=99999" client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/prot-a-parse-cov.exp0000664000015100472110000002561107721716134021615 # Test suite for lyskomd. # Copyright (C) 1999, 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Supplemental test cases for prot-a-parse.c # FIXME (bug 229): check long strings: # Try to send a long string that is split into packages # Try to send a string that will get truncated and that gets sent # in several packages # These trigger the branches that longjump to ISC_MSG_INCOMPLETE # I think. But I'm not sure. source "$srcdir/config/prot-a.exp" read_versions set bignum [exec ./bignum] proc protocol_error {} { simple_expect "%% LysKOM protocol error." } lyskomd_start "" "\ Max password length: 8 Max aux_items deleted per call: 1 Max aux_items added per call: 1 Max links per text: 4 Max text length: 100 " # Send an insane token length client_start 0 talk_to client 0 kom_connect "DejaGnu Test Sweet" kom_accept_async "0 { }" hose_client simple_expect "%%Insane token length." client_death 0 # Send some numbers followed by alphanumerics client_start 0 talk_to client 0 kom_connect "DejaGnu Test Bitter" kom_accept_async "0 { }" send "1POPGOESTHEWEASEL 9999\n" protocol_error # Send a "negative" array size send "1000 80 -1 { 1 }\n" simple_expect "%% LysKOM protocol error." send "1000 80 $bignum { 1 }\n" simple_expect "%%Insane array size." client_death 0 # Forget the opening curly of an array client_start 0 talk_to client 0 kom_connect "DejaGnu Test Bitter" kom_accept_async "0 { }" send "1001 80 1 1 }\n" protocol_error # Forget the closing curly (or get the length wrong) send "1002 80 1 { 1 10 }\n" protocol_error # For completeness, specify the array as longer than it is send "1003 80 9 { 1 10 }\n" protocol_error # FIXME (bug 221): We should check that the parsers really handle # variable-length bitfields. # Sent a short or long aux-item-flags # send "1015 86 [holl "Text"] 0 { } 1 { 1 0000000 0 [holl "A"] }\n" # protocol_error # # send "1016 86 [holl "Text"] 0 { } 1 { 1 000000000 0 [holl "A"] }\n" # protocol_error # Send priv bits that are too long # send "1004 7 5 000000000000000\n" # protocol_error # send "1005 7 5 00000000000000000\n" # protocol_error # Send membership type that is not eight bits long # send "1006 102 5 5 0000000\n" # protocol_error # send "1007 102 5 5 000000000\n" # protocol_error # Send conf type that is not four or eight bits long # send "1008 21 5 000\n" # protocol_error # send "1009 21 5 00000\n" # protocol_error # send "1010 21 5 0000000\n" # protocol_error # send "1011 21 5 000000000\n" # protocol_error # Send a "negative" string length send "1012 62 5 -6Hgazonk 0\n" simple_expect "%% LysKOM protocol error." send "1012 62 5 ${bignum}Hgazonk 0\n" simple_expect "%%Insane string length." client_death 0 client_start 0 talk_to client 0 kom_connect "DejaGnu Test Bitter" kom_accept_async "0 { }" # Try to send a string without an H, with a Q send "1013 62 5 Hgazonk 0\n" protocol_error send "1014 62 5 6Qgazonk 0\n" protocol_error # Send a long string send "1015 86 [holl "This is a test of something I think"] 0 { } 0 { }\n" simple_expect "%1015 6 0" send "1015 86 [holl "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXX"] 0 { } 0 { }\n" simple_expect "%1015 6 0" # Forget opening brace in aux-item-list, closing brace, too long array # negative length send "1016 86 [holl "Text"] 0 { } 1 1 00000000 0 [holl "A"] }\n" protocol_error send "1017 86 [holl "Text"] 0 { } 1 { 1 00000000 0 [holl "A"] 1 00000000 0 [holl "A"] }\n" protocol_error send "1018 86 [holl "Text"] 0 { } 2 { 1 00000000 0 [holl "A"] }\n" protocol_error send "1019 86 [holl "Text"] 0 { } -1 { 1 00000000 0 [holl "A"] }\n" simple_expect "%% LysKOM protocol error." send "1019 86 [holl "Text"] 0 { } ${bignum} { 1 00000000 0 [holl "A"] }\n" simple_expect "%%Insane array size." client_death 0 client_start 0 kom_connect [holl "DejaGnu Test Suite"] kom_accept_async "0 { }" # Try to send a long number list kom_login 5 "gazonk" 0 send "1020 92 1 10 { 1 2 3 4 5 6 7 8 9 10 } 0 { }\n" simple_expect "%1020 46 1" send "1021 92 1 0 { } 3 { 1 00000000 0 [holl "A"] 2 00000000 0 [holl "B"] 3 00000000 0 [holl "C"] }\n" simple_expect "%1021 46 1" # Try to send a short delete list, add list and misc-info list send "1022 92 1 -1 { } 0 { }\n" simple_expect "%% LysKOM protocol error." send "1022 92 1 4294967295 { } 0 { }\n" simple_expect "%%Insane array size." client_death 0 client_start 0 talk_to client 0 kom_connect "DejaGnu Test Lager" kom_accept_async "0 { }" send "1023 92 1 0 { } -1 { }\n" simple_expect "%% LysKOM protocol error." send "1023 92 1 0 { } 4294967295 { }\n" simple_expect "%%Insane array size." client_death 0 client_start 0 talk_to client 0 kom_connect "DejaGnu Test Lager" kom_accept_async "0 { }" send "1024 86 [holl "TX"] -1 { } 0 { }\n" simple_expect "%% LysKOM protocol error." send "1024 86 [holl "TX"] 4294967295 { } 0 { }\n" simple_expect "%%Insane array size." client_death 0 client_start 0 talk_to client 0 kom_connect "DejaGnu Test Lager" kom_accept_async "0 { }" send "1025 86 [holl "TX"] 0 { } -1 { }\n" simple_expect "%% LysKOM protocol error." send "1025 86 [holl "TX"] 0 { } 4294967295 { }\n" simple_expect "%%Insane array size." client_death 0 client_start 0 talk_to client 0 kom_connect "DejaGnu Test Lager" kom_accept_async "0 { }" # Bad syntax for misc-info list send "1026 86 [holl "TX"] 1 2 0 { }\n" protocol_error send "1027 86 [holl "TX"] 1 { 0 2 0 { }\n" protocol_error # Send a long misc-info list kom_login 5 "gazonk" 0 send "1028 86 [holl "TX"] 6 { 0 1 0 2 0 3 0 4 0 9 0 10 } 0 { }\n" simple_expect "%1028 46 4" send "1029 86 [holl "TX"] 4 { 5 0 7 1 2 3 4 5 6 7 8 9 8 5 9 1 2 3 4 5 6 7 8 9 } 0 { }\n" simple_expect "%1029 25 0" # Send a misc-info list that contains an invalid item with complex data kom_login 5 "gazonk" 0 send "1042 86 [holl "TX"] 1 { 999 999 3HABC 1 { 1 { } } } 0 { }\n" simple_expect "%1042 26 999" # Tests for prot_a_hunt_nl send "1100 9999 A\n" protocol_error send "1101 9999 [holl "Data"] [holl "End of Data"]\n" simple_expect "%1101 2 0" send "1102 9999 1 { 12 } \r\t 1234\n" simple_expect "%1102 2 0" send "1103 9999 ERROR\n" protocol_error # Bad array tests send "2000 28 [holl "TX"] -1 { 0 5 }\n" simple_expect "%% LysKOM protocol error." send "2000 28 [holl "TX"] 4294967295 { 0 5 }\n" simple_expect "%%Insane array size." client_death 0 client_start 0 talk_to client 0 kom_connect "DejaGnu Test Lager" kom_accept_async "0 { }" send "2001 59 [holl "TX"] -1 { 0 5 }\n" simple_expect "%% LysKOM protocol error." send "2001 59 [holl "TX"] 4294967295 { 0 5 }\n" simple_expect "%%Insane array size." client_death 0 client_start 0 talk_to client 0 kom_connect "DejaGnu Test Lager" kom_accept_async "0 { }" send "2002 80 -1 { }\n" simple_expect "%% LysKOM protocol error." send "2002 80 4294967295 { }\n" simple_expect "%%Insane array size." client_death 0 client_start 0 talk_to client 0 kom_connect "DejaGnu Test Lager" kom_accept_async "0 { }" send "2003 86 [holl "TX"] -1 { } 0 { }\n" simple_expect "%% LysKOM protocol error." send "2003 86 [holl "TX"] 4294967295 { } 0 { }\n" simple_expect "%%Insane array size." client_death 0 client_start 0 talk_to client 0 kom_connect "DejaGnu Test Lager" kom_accept_async "0 { }" send "2003 87 [holl "TX"] -1 { } 0 { }\n" simple_expect "%% LysKOM protocol error." send "2003 87 [holl "TX"] 4294967295 { } 0 { }\n" simple_expect "%%Insane array size." client_death 0 client_start 0 talk_to client 0 kom_connect "DejaGnu Test Lager" kom_accept_async "0 { }" send "2004 86 [holl "TX"] 0 { } -1 { }\n" simple_expect "%% LysKOM protocol error." send "2004 86 [holl "TX"] 0 { } 4294967295 { }\n" simple_expect "%%Insane array size." client_death 0 client_start 0 talk_to client 0 kom_connect "DejaGnu Test Lager" kom_accept_async "0 { }" send "2005 87 [holl "TX"] 0 { } -1 { }\n" simple_expect "%% LysKOM protocol error." send "2005 87 [holl "TX"] 0 { } 4294967295 { }\n" simple_expect "%%Insane array size." client_death 0 client_start 0 talk_to client 0 kom_connect "DejaGnu Test Lager" kom_accept_async "0 { }" send "2006 88 [holl "CC"] 00000000 -1 { }\n" simple_expect "%% LysKOM protocol error." send "2006 88 [holl "CC"] 00000000 4294967295 { }\n" simple_expect "%%Insane array size." client_death 0 client_start 0 talk_to client 0 kom_connect "DejaGnu Test Lager" kom_accept_async "0 { }" send "2007 89 [holl "PP"] [holl "PW"] 0 -1 { }\n" simple_expect "%% LysKOM protocol error." send "2007 89 [holl "PP"] [holl "PW"] 0 ${bignum} { }\n" simple_expect "%%Insane array size." client_death 0 client_start 0 talk_to client 0 kom_connect "DejaGnu Test Lager" kom_accept_async "0 { }" send "2008 92 1 -1 { } 0 { }\n" simple_expect "%% LysKOM protocol error." send "2008 92 1 ${bignum} { } 0 { }\n" simple_expect "%%Insane array size." client_death 0 client_start 0 talk_to client 0 kom_connect "DejaGnu Test Lager" kom_accept_async "0 { }" send "2009 93 1 -1 { } 0 { }\n" simple_expect "%% LysKOM protocol error." send "2009 93 1 ${bignum} { } 0 { }\n" simple_expect "%%Insane array size." client_death 0 client_start 0 talk_to client 0 kom_connect "DejaGnu Test Lager" kom_accept_async "0 { }" send "2008 95 -1 { } 0 { }\n" simple_expect "%% LysKOM protocol error." send "2008 95 4294967295 { } 0 { }\n" simple_expect "%%Insane array size." client_death 0 client_start 0 talk_to client 0 kom_connect "DejaGnu Test Lager" kom_accept_async "0 { }" # Test some illegal stuff that has caused crashes in the past # Get a parse error while truncating an array send "3000 95 0 { } 10 { 10000 00000000 0 [holl "X"] 10000 00000000 0 [holl "X"] 10000 00000000 0 [holl "X"] 10000 00000000 0 [holl "X"] 10000 00000000 0 [holl "X"] 10000 00000000 0 [holl "X"] 10000 00000000 0 [holl "X"] 10000 00000000 0 [holl "X"] 10000 00000000 0 [holl "X"] }\n" protocol_error send "3001 95 10 { 1 2 3 4 5 6 7 8 9 XX } 0 { }\n" protocol_error send "3001 86 [holl "A Text"] 10 { 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 XX } 0 { }\n" protocol_error # Finish talk_to client 0 kom_login 5 "gazonk" 0 kom_enable 255 send "9999 44 0\n" simple_expect "=9999" client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/prot-a-send-async-cov.exp0000664000015100472110000000311207721716135022540 # Test suite for lyskomd. # Copyright (C) 1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Supplemental test cases for prot-a-send-async read_versions source "$srcdir/config/prot-a.exp" lyskomd_start "" " Open files: [expr $PROTECTED_FDS + 3]" client_start 0 talk_to client 0 kom_connect [holl "DejaGnu Test Suite"] kom_accept_async "1 { 11 }" client_start 1 talk_to client 1 kom_connect [holl "DejaGnu Test Suite"] kom_accept_async "0 { }" client_start 2 talk_to client 2 send "A[holl "DejaGnu Test Suite"]\n" simple_expect "%% No connections left." client_death 2 talk_to client 0 simple_expect ":0 11" kom_login 5 "gazonk" 0 kom_enable 255 send "1000 44 0\n" simple_expect "=1000" client_death 1 client_death 0 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/regexp-match-cov.exp0000664000015100472110000000616107721716135021667 # Test suite for lyskomd. # Copyright (C) 1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Additional test cases for session.c source "$srcdir/config/prot-a.exp" read_versions proc startup {} { lyskomd_start client_start 0 talk_to client 0 kom_connect "DejaGnu test suite" kom_accept_async "0 { }"; kom_login 5 "gazonk" 0 kom_create_person "QERSON 6" "" "00000000" "0 { }" kom_create_person "qerson 7" "" "00000000" "0 { }" kom_create_person "QersoN 8" "" "00000000" "0 { }" kom_create_person "CONFERENCE 9" "" "00000000" "0 { }" kom_create_person "conference 10" "" "00000000" "0 { }" kom_create_person "ConferencE 11" "" "00000000" "0 { }" kom_create_conference "CONFERENCE 12" "00000000" "0 { }" kom_create_conference "conference 13" "00000000" "0 { }" kom_create_conference "ConferencE 14" "00000000" "0 { }" kom_create_conference "QERSON 15" "00000000" "0 { }" kom_create_conference "qerson 16" "00000000" "0 { }" kom_create_conference "QersoN 17" "00000000" "0 { }" } proc shutdown {{expected_leaks {}}} { kom_logout kom_login 5 "gazonk" 0 kom_enable 255 send "9999 44 0\n" simple_expect "=9999" client_death 0 lyskomd_death $expected_leaks } startup send "1000 74 [holl "Q.*N"] 0 0\n" simple_expect "=1000 0 \\*" send "1001 74 [holl "Q.*N"] 0 1\n" simple_expect "=1001 2 { [holl "QERSON 15"] 0000 15 [holl "QersoN 17"] 0000 17 }" send "1002 74 [holl "Q.*N"] 1 0\n" simple_expect "=1002 2 { [holl "QERSON 6"] 1001 6 [holl "QersoN 8"] 1001 8 }" send "1003 74 [holl "Q.*N"] 1 1\n" simple_expect "=1003 4 { [holl "QERSON 6"] 1001 6 [holl "QersoN 8"] 1001 8 [holl "QERSON 15"] 0000 15 [holl "QersoN 17"] 0000 17 }" shutdown startup send "2000 74 [holl "Q.*N"] 0 0\n" simple_expect "=2000 0 \\*" send "2001 74 [holl "Q.*N"] 0 1\n" simple_expect "=2001 2 { [holl "QERSON 15"] 0000 15 [holl "QersoN 17"] 0000 17 }" send "2002 74 [holl "Q.*N"] 1 0\n" simple_expect "=2002 2 { [holl "QERSON 6"] 1001 6 [holl "QersoN 8"] 1001 8 }" send "2003 74 [holl "Q.*N"] 1 1\n" simple_expect "=2003 4 { [holl "QERSON 6"] 1001 6 [holl "QersoN 8"] 1001 8 [holl "QERSON 15"] 0000 15 [holl "QersoN 17"] 0000 17 }" send "3001 74 [holl "Error\["] 0 0\n" simple_expect "%3001 43 0" shutdown {"Bug 689" 0 0 0 26} lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/send-async-cov.exp0000664000015100472110000001231407721716135021344 # Test suite for lyskomd. # Copyright (C) 1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Supplemental test cases for send-async.c # Note: We can't get good coverage of this file since there # is lots of code that checks for protocol A. This code # is never run. source "$srcdir/config/prot-a.exp" read_versions proc send_async_test { async } { global any_time global any_num global hollerith global PROTECTED_FDS lyskomd_start "" "\ Send async: $async Open files: [expr $PROTECTED_FDS + 4]" client_start 0 talk_to client 0 kom_connect "DejaGnu Test Suite" client_start 1 talk_to client 1 kom_connect "DejaGnu Test Suite" kom_accept_async "0 { }" kom_create_person "P6" "PW6" 00000000 "0 { }" kom_login 6 "PW6" 1 client_start 2 talk_to client 0 kom_accept_async "14 { 0 5 6 7 8 9 11 12 13 14 15 16 17 18 }" # Test async 9 send "1000 62 5 [holl "gazonk"] 0\n" if { $async == "on" } { simple_expect ":2 9 5 1" } simple_expect "=1000" # Test async 0 and 15 send "1001 86 [holl "T1"] 1 { 0 5 } 0 { }\n" if { $async == "on" } { simple_expect ":16 0 1 $any_time 5 0 2 0 2 { 0 5 6 1 }" simple_expect ":18 15 1 $any_time 5 0 2 0 2 { 0 5 6 1 } 0 \\*" } simple_expect "=1001 1" send "1001 86 [holl "T2"] 1 { 0 5 } 0 { }\n" if { $async == "on" } { simple_expect ":16 0 2 $any_time 5 0 2 0 2 { 0 5 6 2 }" simple_expect ":18 15 2 $any_time 5 0 2 0 2 { 0 5 6 2 } 0 \\*" } simple_expect "=1001 2" # Test async 5 send "1002 3 5 [holl "Nameless Thing"]\n" if { $async == "on" } { simple_expect ":3 5 5 [holl "Administratör .för. LysKOM"] [holl "Nameless Thing"]" } simple_expect "=1002" # Test async 6 send "1003 4 [holl "Testing"]\n" if { $async == "on" } { simple_expect ":5 6 5 0 1 [holl "Testing"] $hollerith" } simple_expect "=1003" # Test async 7 kom_enable 255 send "1004 43\n" if { $async == "on" } { simple_expect ":0 7" simple_expect ":0 7" } simple_expect "=1004" # Test async 8 kom_add_member 1 6 100 0 00000000 lyskomd_expect "Person 6 added to conference 1 by 5." talk_to client 1 kom_accept_async "1 { 8 }" talk_to client 0 kom_enable 255 send "1100 15 1 6\n" simple_expect "=1100" talk_to client 1 if { $async == "on" } { simple_expect ":1 8 1" } talk_to client 0 kom_enable 0 # Test async 12 send "1200 53 0 [holl "Message"]\n" if { $async == "on" } { simple_expect ":3 12 0 5 [holl "Message"]" simple_expect "=1200" } else { simple_expect "%1200 52 0" } # Test async 13 send "1201 1\n" if { $async == "on" } { simple_expect ":2 13 5 1" } simple_expect "=1201" send "1202 62 5 [holl "gazonk"] 0\n" if { $async == "on" } { simple_expect ":2 9 5 1" } simple_expect "=1202" # Test async 14 send "1300 29 1\n" if { $async == "on" } { simple_expect ":18 14 1 $any_time 5 0 2 0 2 { 0 5 6 1 } 0 \\*" } simple_expect "=1300" # Test async 16 send "1400 30 2 4 0\n" if { $async == "on" } { simple_expect ":3 16 2 4 0" } simple_expect "=1400" # Test async 17 send "1500 31 2 4\n" if { $async == "on" } { simple_expect ":3 17 2 4 0" } simple_expect "=1500" # Test async 18 send "1600 100 4 5 100 0 00000000\n" if { $async == "on" } { simple_expect ":2 18 5 4" } simple_expect "=1600" kom_accept_async "0 { }" kom_login 5 "gazonk" 0 kom_enable 255 kom_accept_async "1 { 11 }" # Test async 11 client_start 3 talk_to client 3 send "A[holl "Reject Me"]\n" simple_expect "%% No connections left." client_death 3 talk_to client 0 if { $async == "on" } { simple_expect ":0 11" } talk_to client 2 kom_connect "Connect Me" kom_accept_async "0 { }" talk_to client 0 send "9999 44 0\n" simple_expect "=9999" client_death 2 client_death 1 client_death 0 lyskomd_death } send_async_test on send_async_test off lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/session-cov.exp0000664000015100472110000000517007721716135020765 # Test suite for lyskomd. # Copyright (C) 1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Additional test cases for session.c source "$srcdir/config/prot-a.exp" read_versions lyskomd_start "" "\ Max client data length: 10 Log login: true Max what am I doing length: 10 " client_start 0 talk_to client 0 kom_connect "DejaGnu Test Suite" kom_accept_async "0 { }" kom_create_person "P6" "PW6" "00000000" "0 { }" kom_create_person "P7" "PW7" "00000000" "0 { }" client_start 1 talk_to client 1 kom_connect "DejaGnu Test Suite" kom_accept_async "0 { }" kom_login 7 "PW7" 0 lyskomd_expect "Login 7 DejaGnu Test Suite\\($any*\\)@$lyskomd_host" talk_to client 0 kom_login_old 6 "PW6" lyskomd_expect "Login 6 DejaGnu Test Suite\\($any*\\)@$lyskomd_host" send "1000 4 [holl "Halley came to Jackson in 1912"]\n" simple_expect "%1000 5 10" send "1001 54 9999\n" simple_expect "%1001 42 9999" send "1002 84 9999\n" simple_expect "%1002 42 9999" send "1003 64 9999\n" simple_expect "%1003 42 9999" send "1004 55 9999\n" simple_expect "%1004 42 9999" send "1005 55 2\n" simple_expect "%1005 12 2" send "1006 69 [holl "She ain't go no hair"] [holl "0.0"]\n" simple_expect "%1006 5 10" send "1007 69 [holl "Iko Iko"] [holl "\ The Tennessee stud was long and lean the color of the sun and his eyes were green. He had the nerve and he had the blood There never was a horse like the Tennessee stud.\ "]\n" simple_expect "%1007 5 10" send "1008 70 9999\n" simple_expect "%1008 42 9999" send "1009 71 9999\n" simple_expect "%1009 42 9999" talk_to client 1 send "9998 55 0\n" simple_expect "=9998" talk_to client 0 kom_login 5 "gazonk" 0 lyskomd_expect "Login 5 DejaGnu Test Suite\\($any*\\)@$lyskomd_host" kom_enable 255 send "9999 44 0\n" simple_expect "=9999" client_death 0 client_death 1 lyskomd_death lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/summarize.sh0000775000015100472110000000333407721716135020352 #!/bin/sh # Copyright (C) 1998, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # Scan all test cases, and emit information about the coverage. # The first column in the output is the Protocol A call number. # If a line contains more than one column the second column is the # error number; otherwise the call succeeded. # # This script relies on the formatting of the test cases in obvious # ways. See the code below for more information. cat *.exp | sed -n -e 's/^send "\([0-9][0-9]* [0-9][0-9]*\).*\\n"$/\1/p' \ -e 's/^simple_expect "=\([0-9][0-9]*\).*".*/= \1/p' \ -e 's/^simple_expect "%\([0-9][0-9]*\) \([0-9][0-9]*\) \([0-9][0-9]*\)".*/% \1 \2 \3/p' \ | awk '$1 == "=" { ok[call] = ok[call] + 1; next } $1 == "%" { err[call " " $3] = err[call " " $3] + 1; next } { ref = $1; call = $2; next } END { for (k in ok) { print k } for (k in err) { print k } }' \ | sort +0n +1n lyskom-server-2.1.2/src/server/testsuite/lyskomd.0/text-cov.exp0000664000015100472110000006571207721716135020276 # Test suite for lyskomd. # Copyright (C) 1999, 2002-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # More coverage of text.c # SECOND ITERATION # Calls to sender, is_sender and is_comm_sender # Check the jubel crap # Module test greater # Make do_add_comment fail # Make do_add_footnote fail # Do get-last-text with... # No text 0. No text 1. No text 3. Text 4 newer. Text 5 newer. # MISSING # Call add_recipient when the misc-info list has an invalid item # Call to is_member_in_recpt when the misc-info list has an invalid item # Call to do_delete_misc with invalid misc item in list # Call to do_sub_recpt with invalud misc item in list # Call to skip_recpt with invalid misc item in list # Call to check_double_subm with invalid misc item in list # Call to filter_secret_info with invalid misc item in list # Call to check_double_subm with invalid misc item in list # Call to create_text_add_miscs with invalid misc item in list # Attempt to delete a text with misc-item list that starts with loc_no # ----Add debug call to add arbitrary (invalid) misc item anywhere # Call to do_delete_misc with loc that is out of range # ----Add debug call to delete specific misc item # Call to do_sub_recpt without text_s # ----Can't be done in the server right now # Call to do_sub_comment with text_s set to NULL # ----Can't be done in the server right now # Call to do_sub_comment with parent_s set to NULL # ----Can't be done in the server right now # Call to do_sub_comment when there is no comment # ----Can't be done in the server right now # Call to do_sub_comment when there is a comm-to but no comm-in link # ----Can't be done in the server right now # Same stuff to do_sub_footnote # Call to locate_mark with nonexistant person # ----Can't be done in current server # Call to filter_secret_info with viewer_p set to NULL # ----Can't be done in current server # Call to text_read_access with text_stat NULL # ----Can't be done in current server # Attempt to delete a recipient where do_sub_recpt fails # Fail to get the text stat of a newly created text read_versions source "$srcdir/config/prot-a.exp" lyskomd_start "" "\ Max footnotes per text: 3 Max comments per text: 3 Max recipients per text: 8 Max super_conf loop: 3 Max text length: 40 Jubel: 9 1 Jubel: 9 2 0" client_start 0 talk_to client 0 kom_connect "DejaGnu Test Suite" kom_accept_async "0 { }" kom_create_person "P6" "PW6" "00000000" "0 { }" kom_create_person "P7" "PW7" "00000000" "0 { }" kom_create_person "P8" "PW8" "00000000" "0 { }" kom_create_person "P9" "PW9" "00000000" "0 { }" kom_login 6 "PW6" 0 kom_create_conference "C10" "00001000" "0 { }" kom_create_conference "C11" "00001000" "0 { }" kom_create_conference "C12" "00001000" "0 { }" kom_create_conference "C13" "00001000" "0 { }" kom_create_conference "C14" "00001000" "0 { }" kom_create_conference "C15" "00000000" "0 { }" kom_create_conference "C16 (rd-prot)" "10000000" "0 { }" kom_create_conference "C17 (secret)" "10100000" "0 { }" kom_create_conference "C18 (no-anon)" "00000000" "0 { }" kom_create_conference "C19" "00000000" "0 { }" kom_set_permitted_submitters 18 5 kom_set_permitted_submitters 19 5 kom_set_super_conf 18 19 kom_set_super_conf 19 0 kom_create_conference "C20" "00000000" "0 { }" kom_create_conference "C21" "00000000" "0 { }" kom_create_conference "C22" "00000000" "0 { }" kom_create_conference "C23" "00000000" "0 { }" kom_create_conference "C24" "00000000" "0 { }" kom_create_conference "C25" "00000000" "0 { }" kom_create_conference "C26" "00000000" "0 { }" kom_set_permitted_submitters 20 5 kom_set_permitted_submitters 21 5 kom_set_permitted_submitters 22 5 kom_set_permitted_submitters 23 5 kom_set_permitted_submitters 24 5 kom_set_permitted_submitters 25 5 kom_set_super_conf 20 21 kom_set_super_conf 21 22 kom_set_super_conf 22 23 kom_set_super_conf 23 24 kom_set_super_conf 24 25 kom_set_super_conf 25 26 kom_set_super_conf 26 0 kom_create_conference "C27 (secret)" "10100000" "0 { }" # Check that jubel is denied two ways from tuesday kom_login 9 "PW9" 0 send "1000 86 [holl "T1 (oops)"] 1 { 0 10 } 0 { }\n" lyskomd_expect "Stopped person 9 from creating jubel 1." simple_expect "%1000 45 0" # Check that max footnotes is enforced in create text kom_login 6 "PW6" 0 send "1000 86 [holl "T1"] 1 { 0 10 } 1 { 10000 01000000 2 [holl "A1"] }\n" lyskomd_expect "Granted jubel 1 to person 6." simple_expect "=1000 1" send "1001 86 [holl "F11"] 2 { 0 10 4 1 } 0 { }\n" lyskomd_expect "Granted jubel 2 to person 6." simple_expect "=1001 2" send "1002 86 [holl "F12"] 2 { 0 10 4 1 } 0 { }\n" simple_expect "=1002 3" send "1003 86 [holl "F13"] 2 { 0 10 4 1 } 0 { }\n" lyskomd_expect "Granted jubel 4 to person 6." simple_expect "=1003 4" send "1004 86 [holl "F14"] 2 { 0 10 4 1 } 0 { }\n" simple_expect "%1004 35 1" # Check that max comments is enforced in create text send "1100 86 [holl "T5"] 1 { 0 10 } 0 { }\n" simple_expect "=1100 5" send "1101 86 [holl "C51"] 2 { 0 10 2 1 } 0 { }\n" lyskomd_expect "Granted jubel 6 to person 6." simple_expect "=1101 6" send "1102 86 [holl "C52"] 2 { 0 10 2 1 } 0 { }\n" simple_expect "=1102 7" send "1103 86 [holl "C53"] 2 { 0 10 2 1 } 0 { }\n" lyskomd_expect "Granted jubel 8 to person 6." simple_expect "=1103 8" send "1104 86 [holl "C54"] 2 { 0 10 2 1 } 0 { }\n" simple_expect "%1104 34 1" send "1200 86 [holl "T9"] 1 { 15 10 } 0 { }\n" simple_expect "=1200 9" # Call add-recipient when we have a BCC recipient send "1201 30 9 11 0\n" simple_expect "=1201" # Change a BCC recipient into a CC recipient send "1202 30 9 10 1\n" simple_expect "=1202" # Call add-recipient when we have a cc recpt different from the new recpt send "1203 30 9 12 0\n" simple_expect "=1203" # Remove a recipient when we have a cc recipient # Remove a recipient when we have a bcc recipient # Remove a BCC recipient send "1204 30 9 10 15\n" simple_expect "=1204" send "1205 31 9 11\n" simple_expect "=1205" send "1206 31 9 10\n" simple_expect "=1206" send "1207 31 9 12\n" simple_expect "=1207" # Attempt to remove a recipient that's not there send "1208 31 9 13\n" simple_expect "%1208 30 13" # Add a recipient with a bogus type send "1209 30 9 13 6\n" simple_expect "%1209 26 6" # Call create-text when we have no access to one of the recipients kom_login 7 "PW7" 0 send "1300 86 [holl "T10 (oops)"] 1 { 0 17 } 0 { }\n" lyskomd_expect "Granted jubel 10 to person 7." simple_expect "%1300 9 17" send "1301 86 [holl "T10 (oops)"] 1 { 1 17 } 0 { }\n" lyskomd_expect "Granted jubel 10 to person 7." simple_expect "%1301 9 17" send "1302 86 [holl "T10 (oops)"] 1 { 15 17 } 0 { }\n" lyskomd_expect "Granted jubel 10 to person 7." simple_expect "%1302 9 17" # Call create-text when we have no write access to one of the recipients # and no write access to the superconf send "1400 86 [holl "T10 (oops)"] 1 { 0 18 } 0 { }\n" lyskomd_expect "Granted jubel 10 to person 7." simple_expect "%1400 11 19" send "1401 86 [holl "T10 (oops)"] 1 { 1 18 } 0 { }\n" lyskomd_expect "Granted jubel 10 to person 7." simple_expect "%1401 11 19" send "1402 86 [holl "T10 (oops)"] 1 { 15 18 } 0 { }\n" lyskomd_expect "Granted jubel 10 to person 7." simple_expect "%1402 11 19" # Call create-text when we have no write access to the conf # and no write access to super confs and we exceed super-conf-loop send "1500 86 [holl "T10 (oops)"] 1 { 0 20 } 0 { }\n" lyskomd_expect "Granted jubel 10 to person 7." simple_expect "%1500 11 23" # Creaate a multi-line text send "1500 86 [holl "T10\nBody"] 1 { 0 10 } 0 { }\n" lyskomd_expect "Granted jubel 10 to person 7." simple_expect "=1500 10" # Attempt to create a footnote to a text wr did not author send "1501 86 [holl "T11 (oops)"] 2 { 0 10 4 1 } 0 { }\n" simple_expect "%1501 37 1" # Attempt to get a text we have marked (2nd mark of 3) and has no recipients kom_login 6 "PW6" 0 send "1600 86 [holl "T11\nBODY 1\nBODY 2"] 1 { 0 10 } 0 { }\n" simple_expect "=1600 11" kom_login 8 "PW8" 0 kom_mark_text 11 1 kom_login 7 "PW7" 0 kom_mark_text 11 111 kom_login 6 "PW6" 0 kom_mark_text 11 1 kom_sub_recipient 11 10 kom_login 7 "PW7" 0 send "1601 90 11\n" simple_expect "=1601 $any_time 6 2 17 3 0 \\* 0 \\*" # Check jubel blocking again kom_login 9 "PW9" 0 send "1699 86 [holl "T12 (oops)"] 1 { 0 10 } 0 { }\n" lyskomd_expect "Stopped person 9 from creating jubel 12." simple_expect "%1699 45 0" # Get a text with a recipient that we may not know about kom_login 6 "PW6" 0 send "1700 86 [holl "T12"] 2 { 0 17 0 10 } 0 { }\n" lyskomd_expect "Granted jubel 12 to person 6." simple_expect "=1700 12" send "1701 86 [holl "T13"] 2 { 1 17 0 10 } 0 { }\n" simple_expect "=1701 13" send "1702 86 [holl "T14"] 2 { 15 17 0 10 } 0 { }\n" lyskomd_expect "Granted jubel 14 to person 6." simple_expect "=1702 14" kom_login 7 "PW7" 0 send "1800 90 12\n" simple_expect "=1800 $any_time 6 0 3 0 2 { 0 10 6 $any_num } 0 \\*" send "1801 90 13\n" simple_expect "=1801 $any_time 6 0 3 0 2 { 0 10 6 $any_num } 0 \\*" send "1802 90 14\n" simple_expect "=1802 $any_time 6 0 3 0 2 { 0 10 6 $any_num } 0 \\*" # Get an invalid range of a text send "1803 25 14 100 101\n" simple_expect "%1803 19 $any_num" # Get a text that has a BCC recpt we added after the fact kom_login 6 "PW6" 0 send "1900 86 [holl "T15"] 1 { 0 10 } 0 { }\n" simple_expect "=1900 15" kom_login 7 "PW7" 0 send "1901 30 15 11 15\n" simple_expect "=1901" send "1902 90 15\n" simple_expect "=1902 $any_time 6 0 3 0 6 { 0 10 6 $any_num 15 11 6 $any_num 8 7 9 $any_time } 0 \\*" # Get a text that we did not write and has CWC as recpt, cc and bcc kom_login 6 "PW6" 0 send "2000 86 [holl "T16"] 3 { 0 10 1 11 15 12 } 0 { }\n" lyskomd_expect "Granted jubel 16 to person 6." simple_expect "=2000 16" kom_login 7 "PW7" 0 send "2001 90 16\n" simple_expect "=2001 $any_time 6 0 3 0 6 { 0 10 6 $any_num 1 11 6 $any_num 15 12 6 $any_num } 0 \\*" kom_add_member 10 7 0 255 00000000 kom_change_conference 10 send "2002 90 16\n" simple_expect "=2002 $any_time 6 0 3 0 6 { 0 10 6 $any_num 1 11 6 $any_num 15 12 6 $any_num } 0 \\*" kom_add_member 11 7 0 255 00000000 kom_change_conference 11 send "2003 90 16\n" simple_expect "=2003 $any_time 6 0 3 0 6 { 0 10 6 $any_num 1 11 6 $any_num 15 12 6 $any_num } 0 \\*" kom_add_member 12 7 0 255 00000000 kom_change_conference 12 send "2004 90 16\n" simple_expect "=2004 $any_time 6 0 3 0 6 { 0 10 6 $any_num 1 11 6 $any_num 15 12 6 $any_num } 0 \\*" # Get a text with secret recpt and public recpt, cc-recpt and bcc-recpt kom_login 6 "PW6" 0 send "2100 86 [holl "T17"] 2 { 0 17 0 10 } 0 { }\n" simple_expect "=2100 17" send "2101 86 [holl "T18"] 2 { 0 17 1 10 } 0 { }\n" lyskomd_expect "Granted jubel 18 to person 6." simple_expect "=2101 18" send "2102 86 [holl "T19"] 2 { 0 17 15 10 } 0 { }\n" simple_expect "=2102 19" kom_login 7 "PW7" 0 send "2103 90 17\n" simple_expect "=2103 $any_time 6 0 3 0 2 { 0 10 6 $any_num } 0 \\*" send "2104 90 18\n" simple_expect "=2104 $any_time 6 0 3 0 2 { 1 10 6 $any_num } 0 \\*" send "2105 90 19\n" simple_expect "=2105 $any_time 6 0 3 0 2 { 15 10 6 $any_num } 0 \\*" # Get a text that has an open conf we are not member of as cc, bcc kom_login 6 "PW6" 0 send "2200 86 [holl "T20"] 1 { 1 15 } 0 { }\n" lyskomd_expect "Granted jubel 20 to person 6." simple_expect "=2200 20" send "2201 86 [holl "T21"] 1 { 15 15 } 0 { }\n" simple_expect "=2201 21" kom_login 7 "PW7" 0 send "2202 90 20\n" simple_expect "=2202 $any_time 6 0 3 0 2 { 1 15 6 $any_num } 0 \\*" send "2203 90 21\n" simple_expect "=2203 $any_time 6 0 3 0 2 { 15 15 6 $any_num } 0 \\*" # Get a text BCCd to a conference we are supervisor of but not member of send "2204 86 [holl "T22"] 1 { 15 16 } 0 { }\n" lyskomd_expect "Granted jubel 22 to person 7." simple_expect "=2204 22" kom_login 6 "PW6" 0 send "2205 90 22\n" simple_expect "=2205 $any_time 7 0 3 0 2 { 15 16 6 $any_num } 0 \\*" # Attempt to delete a text that does not exist send "2300 29 9999\n" simple_expect "%2300 14 9999" # Attempt to delete a text we are not author of send "2301 29 22\n" simple_expect "%2301 37 22" # Delete a text that has a BCC recpt send "2302 29 21\n" simple_expect "=2302" # Delete a text that is a comment to something kom_login 6 "PW6" 0 send "2400 86 [holl "T23"] 1 { 0 10 } 0 { }\n" simple_expect "=2400 23" send "2401 86 [holl "T24"] 2 { 0 10 2 23 } 0 { }\n" lyskomd_expect "Granted jubel 24 to person 6." simple_expect "=2401 24" send "2402 29 24\n" simple_expect "=2402" # Delete a text that has a comment send "2403 86 [holl "T25"] 2 { 0 10 2 23 } 0 { }\n" simple_expect "=2403 25" send "2404 29 23\n" simple_expect "=2404" # Delete a text that is a footnote to something kom_login 6 "PW6" 0 send "2405 86 [holl "T26"] 1 { 0 10 } 0 { }\n" lyskomd_expect "Granted jubel 26 to person 6." simple_expect "=2405 26" send "2406 86 [holl "T27"] 2 { 0 10 4 26 } 0 { }\n" simple_expect "=2406 27" send "2407 29 27\n" simple_expect "=2407" # Delete a text that has a footnote send "2408 86 [holl "T28"] 2 { 0 10 4 26 } 0 { }\n" lyskomd_expect "Granted jubel 28 to person 6." simple_expect "=2408 28" send "2404 29 26\n" simple_expect "=2404" # Attempt to create a text with recpt equal other recpt, cc, bcc send "2500 86 [holl "T29 (oops)"] 2 { 0 10 0 10 } 0 { }\n" simple_expect "%2500 25 \[01\]" send "2501 86 [holl "T29 (oops)"] 2 { 0 10 1 10 } 0 { }\n" simple_expect "%2501 25 \[01\]" send "2502 86 [holl "T29 (oops)"] 2 { 0 10 15 10 } 0 { }\n" simple_expect "%2502 25 \[01\]" # Create text with recpt, cc, bcc send "2503 86 [holl "T29"] 3 { 0 10 1 11 15 12 } 0 { }\n" simple_expect "=2503 29" # Attempt to create text with two identical comm-to send "2504 86 [holl "T30 (oops)"] 3 { 0 10 2 29 2 29 } 0 { }\n" lyskomd_expect "Granted jubel 30 to person 6." simple_expect "%2504 25 \[12\]" # Attempt to create text with comm-to equal footn-to send "2505 86 [holl "T30 (oops)"] 3 { 0 10 2 29 4 29 } 0 { }\n" lyskomd_expect "Granted jubel 30 to person 6." simple_expect "%2505 25 \[12\]" # Create text with two different comm-to, two footn-to send "2506 86 [holl "T30"] 5 { 0 10 2 11 2 12 4 13 4 14 } 0 { }\n" lyskomd_expect "Granted jubel 30 to person 6." simple_expect "=2506 30" # Attempt to create a comment to a text that we may not read send "2507 86 [holl "T31"] 1 { 0 17 } 0 { }\n" simple_expect "=2507 31" kom_login 7 "PW7" 0 send "2508 86 [holl "T32 (oops)"] 2 { 0 10 2 31 } 0 { }\n" lyskomd_expect "Granted jubel 32 to person 7." simple_expect "%2508 14 31" # Attempt to create a footnote to a text that we may not read send "2509 86 [holl "T32 (oops)"] 2 { 0 10 4 31 } 0 { }\n" lyskomd_expect "Granted jubel 32 to person 7." simple_expect "%2509 14 31" # Attempt to add an anon text as recpt, cc, bcc to conf with forbid-anon kom_login 6 "PW6" 0 send "2600 87 [holl "T32"] 1 { 0 10 } 0 { }\n" lyskomd_expect "Granted jubel 32 to person 6." simple_expect "=2600 32" send "2601 30 32 15 0\n" simple_expect "%2601 47 0" send "2602 30 32 15 1\n" simple_expect "%2602 47 0" send "2603 30 32 15 15\n" simple_expect "%2603 47 0" # Attempt to crete a text with a comm-in item send "2604 86 [holl "T33 (oops)"] 2 { 0 10 3 32 } 0 { }\n" simple_expect "%2604 25 1" # Attempt to recpt, cc, bcc a conference that does not exist send "2605 30 32 9999 0\n" simple_expect "%2605 9 9999" send "2606 30 32 9999 1\n" simple_expect "%2606 9 9999" send "2607 30 32 9999 15\n" simple_expect "%2607 9 9999" # Attempt to add a recipient to a text we may not see kom_login 6 "PW6" 0 send "2700 86 [holl "T33"] 1 { 0 17 } 0 { }\n" simple_expect "=2700 33" kom_login 7 "PW7" 0 send "2701 30 33 10 0\n" simple_expect "%2701 14 33" # Attempt to add a recipient that is already a recipient kom_login 6 "PW6" 0 send "2702 86 [holl "T34"] 1 { 0 10 } 0 { }\n" lyskomd_expect "Granted jubel 34 to person 6." simple_expect "=2702 34" send "2703 30 34 10 0\n" simple_expect "%2703 27 10" # Attempt to add an existing recipient with invalid type send "2704 30 34 10 99\n" simple_expect "%2704 26 99" # Attempt to convert a recipient when not supervisor of recipient kom_login 7 "PW7" 0 send "2705 30 34 10 1\n" simple_expect "%2705 12 10" # Attempt to add too many recipients to a text send "2800 86 [holl "T35"] 1 { 0 10 } 0 { }\n" simple_expect "=2800 35" send "2801 30 35 11 0\n" simple_expect "=2801" send "2802 30 35 12 0\n" simple_expect "=2802" send "2803 30 35 13 0\n" simple_expect "=2803" send "2804 30 35 14 0\n" simple_expect "=2804" send "2805 30 35 15 0\n" simple_expect "=2805" send "2806 30 35 5 0\n" simple_expect "=2806" send "2807 30 35 6 0\n" simple_expect "=2807" send "2808 30 35 7 0\n" simple_expect "%2808 33 35" # Attempt to create anon text in non-anon conf kom_login 6 "PW6" 0 send "2900 87 [holl "T36 (oops)"] 1 { 0 15 } 0 { }\n" lyskomd_expect "Granted jubel 36 to person 6." simple_expect "%2900 47 15" send "2901 87 [holl "T36 (oops)"] 1 { 1 15 } 0 { }\n" lyskomd_expect "Granted jubel 36 to person 6." simple_expect "%2901 47 15" send "2902 87 [holl "T36 (oops)"] 1 { 15 15 } 0 { }\n" lyskomd_expect "Granted jubel 36 to person 6." simple_expect "%2902 47 15" send "2903 86 [holl "T36"] 1 { 0 10 } 0 { }\n" lyskomd_expect "Granted jubel 36 to person 6." simple_expect "=2903 36" # Attempt to add conf w no write access as recpt kom_login 7 "PW7" 0 send "3000 86 [holl "T37"] 1 { 0 10 } 0 { }\n" simple_expect "=3000 37" send "3001 30 37 19 0\n" simple_expect "%3001 11 19" send "3002 30 37 19 1\n" simple_expect "%3002 11 19" send "3003 30 37 19 15\n" simple_expect "%3003 11 19" # Attempt to add recpt w no write access to conf but to super conf send "3004 30 37 24 0\n" simple_expect "%3004 11 24" # Attempt to footnote a nonexistant text send "3100 86 [holl "T38 (oops)"] 2 { 0 10 4 9999 } 0 { }\n" lyskomd_expect "Granted jubel 38 to person 7." simple_expect "%3100 14 9999" send "3101 86 [holl "Well I'm on the downeaster Alexa, and I'm cruising through Block Island Sound. I have charted a course to the Vineyard, but tonight I am Nantucket Bound."] 1 { 0 10 } 0 { }\n" simple_expect "%3101 5 40" # Attempt to remove a recpt from text we have no access to kom_login 6 "PW6" 0 send "3200 86 [holl "T38"] 2 { 0 16 0 17 } 0 { }\n" lyskomd_expect "Granted jubel 38 to person 6." simple_expect "=3200 38" kom_login 7 "PW7" 0 send "3201 31 38 16\n" simple_expect "%3201 14 38" # Attempt to remove a recipient we may not know about from a text we # may know about kom_login 6 "PW6" 0 send "3202 30 38 10 0\n" simple_expect "=3202" kom_login 7 "PW7" 0 send "3203 31 38 17\n" simple_expect "%3203 9 17" send "3204 31 38 16\n" simple_expect "%3204 12 38" # Attempt to delete a secret conf thats not a recipient send "3205 31 38 27\n" simple_expect "%3205 9 27" # Attempt to remove a recipient that's not kom_login 6 "PW6" 0 send "3206 31 38 24\n" simple_expect "%3206 30 24" # Attempt to remove a recipient that doesn't even exist send "3207 31 38 9999\n" simple_expect "%3207 9 9999" # Attempt to make a text a comment of itself send "3300 86 [holl "T39"] 1 { 0 10 } 0 { }\n" simple_expect "=3300 39" send "3301 32 39 39\n" simple_expect "%3301 19 39" # Attempt to add a text we may not see as a comment to one we may see # Attempt to add a text as a comment to something we cannot see # Same with footnotes kom_login 6 "PW6" 0 send "3400 86 [holl "T40"] 1 { 0 16 } 0 { }\n" lyskomd_expect "Granted jubel 40 to person 6." simple_expect "=3400 40" kom_login 7 "PW7" 0 send "3401 86 [holl "T41"] 1 { 0 10 } 0 { }\n" simple_expect "=3401 41" send "3402 32 41 40\n" simple_expect "%3402 14 40" send "3403 32 40 41\n" simple_expect "%3403 14 40" send "3404 37 41 40\n" simple_expect "%3404 14 40" send "3405 37 40 41\n" simple_expect "%3405 14 40" send "3406 86 [holl "T42"] 1 { 0 10 } 0 { }\n" lyskomd_expect "Granted jubel 42 to person 7." simple_expect "=3406 42" # Attempt to add a text as a footnote to itself send "3411 37 42 42\n" simple_expect "%3411 19 42" # Attempt to add a text as a comment twice over # Same for footnote send "3407 32 42 41\n" simple_expect "=3407" send "3408 32 42 41\n" simple_expect "%3408 28 42" send "3409 37 41 42\n" simple_expect "=3409" send "3410 37 41 42\n" simple_expect "%3410 29 41" # Attempt to add a text as a footnote when authors differ kom_login 6 "PW6" 0 send "3500 86 [holl "T43"] 1 { 0 10 } 0 { }\n" simple_expect "=3500 43" kom_login 7 "PW7" 0 send "3501 86 [holl "T44"] 1 { 0 10 } 0 { }\n" lyskomd_expect "Granted jubel 44 to person 7." simple_expect "=3501 44" send "3502 37 44 43\n" simple_expect "%3502 37 43" # Attempt to add comment as person other than authors kom_login 6 "PW6" 0 send "3503 86 [holl "T45"] 1 { 0 10 } 0 { }\n" simple_expect "=3503 45" kom_login 7 "PW7" 0 send "3504 86 [holl "T46"] 1 { 0 10 } 0 { }\n" lyskomd_expect "Granted jubel 46 to person 7." simple_expect "=3504 46" kom_login 8 "PW8" 0 send "3505 32 46 45\n" simple_expect "=3505" # Attempt to remove a comment that's not really a comment kom_login 7 "PW7" 0 send "3600 33 45 44\n" simple_expect "%3600 31 45" # Attempt to remove a footnote that's not really a footnote send "3601 38 45 44\n" simple_expect "%3601 32 45" # Sub a footnote when adder, but not author of either text kom_login 8 "PW8" 0 send "3602 33 46 45\n" simple_expect "=3602" # Attempt to sub a comment when not author of either send "3603 33 42 41\n" simple_expect "%3603 12 42" # Attempt to sub a footnote when not author of either send "3604 38 41 42\n" simple_expect "%3604 12 41" # Do a get-map on conf we may not know about kom_login 7 "PW7" 0 send "3700 34 17 1 1\n" simple_expect "%3700 9 17" # Do a get-map on conf that is rd_prot send "3701 34 16 1 1\n" simple_expect "%3701 11 16" # Do a local-to-global on secret and rd_prot conf send "3702 103 17 1 1\n" simple_expect "%3702 9 17" send "3703 103 16 1 1\n" simple_expect "%3703 11 16" # Add a comment to a text that already has a comment kom_login 6 "PW6" 0 send "3800 86 [holl "T47"] 1 { 0 10 } 0 { }\n" simple_expect "=3800 47" send "3801 86 [holl "T48"] 2 { 0 10 2 47 } 0 { }\n" lyskomd_expect "Granted jubel 48 to person 6." simple_expect "=3801 48" send "3802 86 [holl "T49"] 1 { 0 10 } 0 { }\n" simple_expect "=3802 49" send "3803 32 49 47\n" simple_expect "=3803" # Add a footnote to a text that already has a footnote kom_login 6 "PW6" 0 send "3804 86 [holl "T50"] 1 { 0 10 } 0 { }\n" lyskomd_expect "Granted jubel 50 to person 6." simple_expect "=3804 50" send "3805 86 [holl "T51"] 2 { 0 10 4 50 } 0 { }\n" simple_expect "=3805 51" send "3806 86 [holl "T52"] 1 { 0 10 } 0 { }\n" lyskomd_expect "Granted jubel 52 to person 6." simple_expect "=3806 52" send "3807 37 52 50\n" simple_expect "=3807" # Remove a cc recipient from a text that has an earlier cc recpt send "3900 86 [holl "T53"] 3 { 1 10 1 11 1 12 } 0 { }\n" simple_expect "=3900 53" send "3901 31 53 11\n" simple_expect "=3901" # Call sub-recipient to remove single recpt as wrong person kom_login 6 "PW6" 0 send "4000 86 [holl "T54"] 1 { 0 10 } 0 { }\n" lyskomd_expect "Granted jubel 54 to person 6." simple_expect "=4000 54" kom_login 7 "PW7" 0 send "4001 31 54 10\n" simple_expect "%4001 12 54" # Call sub-recipient with misc-info list # --- recpt 7 # --- recpt 8 # --- recpt 13 sent-by 8 # --- cc-recpt 14 sent-by 8 # --- bcc-recpt 15 sent-by 8 # --- recpt 10 sent-by 7 # --- cc-recpt 11 sent-by 7 # --- bcc-recpt 12 send-by 7 # Then remove 12, 11 and 10. kom_login 6 "PW6" 0 send "4100 86 [holl "T55"] 2 { 0 7 0 8 } 0 { }\n" simple_expect "=4100 55" kom_login 8 "PW8" 0 send "4101 30 55 13 0\n" simple_expect "=4101" send "4102 30 55 14 1\n" simple_expect "=4102" send "4103 30 55 15 15\n" simple_expect "=4103" kom_login 7 "PW7" 0 send "4104 30 55 10 0\n" simple_expect "=4104" send "4105 30 55 11 1\n" simple_expect "=4105" send "4106 30 55 12 15\n" simple_expect "=4106" send "4107 31 55 12\n" simple_expect "=4107" send "4108 31 55 11\n" simple_expect "=4108" send "4109 31 55 10\n" simple_expect "=4109" # Get a text with a bcc to a conf we are not member of that we sent kom_login 6 "PW6" 0 send "4200 86 [holl "T56"] 1 { 0 10 } 0 { }\n" lyskomd_expect "Granted jubel 56 to person 6." simple_expect "=4200 56" kom_login 7 "PW7" 0 send "4201 30 56 5 15\n" simple_expect "=4201" send "4202 90 56\n" simple_expect "=4202 $any_time 6 0 3 0 6 { 0 10 6 $any_num 15 5 6 $any_num 8 7 9 $any_time } 0 \\*" # Check various permutations of double submission kom_login 6 "PW6" 0 send "4300 86 [holl "T57 (oops)"] 2 { 0 10 1 10 } 0 { }\n" simple_expect "%4300 25 \[12\]" send "4301 86 [holl "T57 (oops)"] 2 { 1 10 0 10 } 0 { }\n" simple_expect "%4301 25 \[12\]" send "4302 86 [holl "T57 (oops)"] 2 { 0 10 15 10 } 0 { }\n" simple_expect "%4302 25 \[12\]" send "4303 86 [holl "T57 (oops)"] 2 { 15 10 0 10 } 0 { }\n" simple_expect "%4303 25 \[12\]" send "4304 86 [holl "T57 (oops)"] 2 { 15 10 1 10 } 0 { }\n" simple_expect "%4304 25 \[12\]" send "4305 86 [holl "T57 (oops)"] 2 { 1 10 15 10 } 0 { }\n" simple_expect "%4305 25 \[12\]" # Check various permutations of double comments send "4400 86 [holl "T57"] 1 { 0 10 } 0 { }\n" simple_expect "=4400 57" send "4401 86 [holl "T58 (oops)"] 3 { 0 10 2 57 4 57 } 0 { }\n" lyskomd_expect "Granted jubel 58 to person 6." simple_expect "%4401 25 \[12\]" send "4402 86 [holl "T58 (oops)"] 3 { 0 10 4 57 2 57 } 0 { }\n" lyskomd_expect "Granted jubel 58 to person 6." simple_expect "%4402 25 \[12\]" # Add a footnote written by someone else to our text kom_login 6 "PW6" 0 send "4500 86 [holl "T58"] 1 { 0 10 } 0 { }\n" lyskomd_expect "Granted jubel 58 to person 6." simple_expect "=4500 58" kom_login 7 "PW7" 0 send "4501 86 [holl "T59"] 1 { 0 10 } 0 { }\n" simple_expect "=4501 59" kom_login 6 "PW6" 0 send "4502 37 59 58\n" simple_expect "%4502 37 59" # Add comments until we hit the limit kom_login 6 "PW6" 0 send "4600 86 [holl "T60"] 1 { 0 10 } 0 { }\n" lyskomd_expect "Granted jubel 60 to person 6." simple_expect "=4600 60" send "4601 86 [holl "T61"] 1 { 0 10 } 0 { }\n" simple_expect "=4601 61" send "4602 86 [holl "T62"] 1 { 0 10 } 0 { }\n" lyskomd_expect "Granted jubel 62 to person 6." simple_expect "=4602 62" send "4603 86 [holl "T63"] 1 { 0 10 } 0 { }\n" simple_expect "=4603 63" send "4604 86 [holl "T64"] 1 { 0 10 } 0 { }\n" lyskomd_expect "Granted jubel 64 to person 6." simple_expect "=4604 64" send "4605 32 61 60\n" simple_expect "=4605" send "4606 32 62 60\n" simple_expect "=4606" send "4607 32 63 60\n" simple_expect "=4607" send "4608 32 64 60\n" simple_expect "%4608 34 60" kom_login 5 "gazonk" 0 kom_enable 255 send "9999 44 0\n" simple_expect "=9999" client_death 0 lyskomd_death lyskom-server-2.1.2/run-support/0000777000015100472110000000000007723710421012420 5lyskom-server-2.1.2/run-support/Makefile.am0000664000015100472110000000363507722446215014407 # $Id: Makefile.am,v 1.17 2003/08/25 17:31:15 ceder Exp $ # Copyright (C) 1998-1999, 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # include $(top_srcdir)/scripts/common.make sbin_SCRIPTS = savecore-lyskom # config should be in sysconf_DATA, but we don't want to install it on # top of any configuration that the user may have edited. sysconf_DATA = aux-items.conf EXTRA_DIST = config .cvsignore savecore.sh aux-items.conf MOSTLYCLEANFILES = savecore-lyskom savecore-lyskom: savecore.sh sed -e 's%@ETCDIR@%$(sysconfdir)%g' < $(srcdir)/savecore.sh > $@.tmp chmod +x $@.tmp mv $@.tmp $@ install-data-local: installdirs test -f $(DESTDIR)$(sysconfdir)/lyskomd.conf \ || $(INSTALL_DATA) $(srcdir)/config \ $(DESTDIR)$(sysconfdir)/lyskomd.conf $(mkinstalldirs) $(DESTDIR)$(localstatedir)/lyskomd.cores \ $(DESTDIR)$(exportdir) \ $(DESTDIR)$(localstatedir)/run uninstall-local: ## Remove config, but only if it hasn't been locally modified. if cmp $(srcdir)/config $(DESTDIR)$(sysconfdir)/lyskomd.conf ; \ then \ $(RM) $(DESTDIR)$(sysconfdir)/lyskomd.conf ; \ fi lyskom-server-2.1.2/run-support/Makefile.in0000664000015100472110000002735007723707422014421 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # $Id: Makefile.am,v 1.17 2003/08/25 17:31:15 ceder Exp $ # Copyright (C) 1998-1999, 2001-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEBUG_CALLS = @DEBUG_CALLS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EFENCE = @EFENCE@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FLEX = @FLEX@ HAVE_PYTHON_FALSE = @HAVE_PYTHON_FALSE@ HAVE_PYTHON_TRUE = @HAVE_PYTHON_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSURE = @INSURE@ LANGUAGE_SUFFIX = @LANGUAGE_SUFFIX@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ SED = @SED@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRACED_ALLOCATIONS = @TRACED_ALLOCATIONS@ U = @U@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ YACC = @YACC@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ RM = rm -f dbdir = $(localstatedir)/lyskomd/db exportdir = $(localstatedir)/lyskomd/exportdb sbin_SCRIPTS = savecore-lyskom # config should be in sysconf_DATA, but we don't want to install it on # top of any configuration that the user may have edited. sysconf_DATA = aux-items.conf EXTRA_DIST = config .cvsignore savecore.sh aux-items.conf MOSTLYCLEANFILES = savecore-lyskom subdir = run-support ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = SCRIPTS = $(sbin_SCRIPTS) DIST_SOURCES = DATA = $(sysconf_DATA) DIST_COMMON = $(top_srcdir)/scripts/common.make Makefile.am Makefile.in all: all-am .SUFFIXES: $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/scripts/common.make $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu run-support/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) sbinSCRIPT_INSTALL = $(INSTALL_SCRIPT) install-sbinSCRIPTS: $(sbin_SCRIPTS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(sbindir) @list='$(sbin_SCRIPTS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f $$d$$p; then \ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ echo " $(sbinSCRIPT_INSTALL) $$d$$p $(DESTDIR)$(sbindir)/$$f"; \ $(sbinSCRIPT_INSTALL) $$d$$p $(DESTDIR)$(sbindir)/$$f; \ else :; fi; \ done uninstall-sbinSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(sbin_SCRIPTS)'; for p in $$list; do \ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ echo " rm -f $(DESTDIR)$(sbindir)/$$f"; \ rm -f $(DESTDIR)$(sbindir)/$$f; \ done uninstall-info-am: sysconfDATA_INSTALL = $(INSTALL_DATA) install-sysconfDATA: $(sysconf_DATA) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(sysconfdir) @list='$(sysconf_DATA)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f="`echo $$p | sed -e 's|^.*/||'`"; \ echo " $(sysconfDATA_INSTALL) $$d$$p $(DESTDIR)$(sysconfdir)/$$f"; \ $(sysconfDATA_INSTALL) $$d$$p $(DESTDIR)$(sysconfdir)/$$f; \ done uninstall-sysconfDATA: @$(NORMAL_UNINSTALL) @list='$(sysconf_DATA)'; for p in $$list; do \ f="`echo $$p | sed -e 's|^.*/||'`"; \ echo " rm -f $(DESTDIR)$(sysconfdir)/$$f"; \ rm -f $(DESTDIR)$(sysconfdir)/$$f; \ done tags: TAGS TAGS: ctags: CTAGS CTAGS: DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = .. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) $(mkinstalldirs) $(distdir)/../scripts @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(SCRIPTS) $(DATA) installdirs: $(mkinstalldirs) $(DESTDIR)$(sbindir) $(DESTDIR)$(sysconfdir) install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: info: info-am info-am: install-data-am: install-data-local install-exec-am: install-sbinSCRIPTS install-sysconfDATA install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am uninstall-local uninstall-sbinSCRIPTS \ uninstall-sysconfDATA .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am info info-am install \ install-am install-data install-data-am install-data-local \ install-exec install-exec-am install-info install-info-am \ install-man install-sbinSCRIPTS install-strip \ install-sysconfDATA installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \ uninstall-info-am uninstall-local uninstall-sbinSCRIPTS \ uninstall-sysconfDATA savecore-lyskom: savecore.sh sed -e 's%@ETCDIR@%$(sysconfdir)%g' < $(srcdir)/savecore.sh > $@.tmp chmod +x $@.tmp mv $@.tmp $@ install-data-local: installdirs test -f $(DESTDIR)$(sysconfdir)/lyskomd.conf \ || $(INSTALL_DATA) $(srcdir)/config \ $(DESTDIR)$(sysconfdir)/lyskomd.conf $(mkinstalldirs) $(DESTDIR)$(localstatedir)/lyskomd.cores \ $(DESTDIR)$(exportdir) \ $(DESTDIR)$(localstatedir)/run uninstall-local: if cmp $(srcdir)/config $(DESTDIR)$(sysconfdir)/lyskomd.conf ; \ then \ $(RM) $(DESTDIR)$(sysconfdir)/lyskomd.conf ; \ fi # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/run-support/config0000664000015100472110000000101707717407077013542 # Sample config file for lyskomd, installed as lyskomd.conf. # This file is placed in the public domain. # For complete information about this file, please read the documentation in # the lyskom.info file. # Mandatory options: Client port: 4894 Max conferences: 4765 Max texts: 2000000 # Default overrides: Log login: yes Sync interval: 30 Sync retry interval: 5 # Character set support. Note: these only determines which characters # that are allowed in conference names. # Locale: iso_8859_1 Force ISO 8859-1: yes lyskom-server-2.1.2/run-support/.cvsignore0000664000015100472110000000004507717403367014350 Makefile Makefile.in savecore-lyskom lyskom-server-2.1.2/run-support/savecore.sh0000664000015100472110000000207307721716116014510 #!/bin/sh # Save core files from lyskomd for future debugging. # Copyright (C) 1995, 2003 Lysator Academic Computer Association. # # 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 2, 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, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # This script can be modified to save core files. It is run # by updateLysKOM before it starts a new lyskomd. This script # does nothing by default, since most sites probably don't # want to save the core files anyhow. lyskom-server-2.1.2/run-support/aux-items.conf0000664000015100472110000003004607723464341015133 # # $Id: aux-items.conf,v 1.33 2003/08/28 20:36:21 kent Exp $ # Copyright (C) 1994-2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # # If you make an addition to this file that you feel is useful # you should contact the LysKOM developers to reserve a number # and to get the change incorporated into the server distribution. # # The file format is documented in lyskomd.info. # # Content type of a text (MIME type) # 1 : content-type (text) { author-only = true; unique = true; secret = false; hide-creator = false; dont-garb = false; inherit = false; inherit-limit = 1; validate = "^[^/]*/[^/]*(;.*)?$"; } # # Quick reply to a text # 2 : fast-reply (text) { secret = false; hide-creator = false; dont-garb = false; inherit = false; inherit-limit = 1; } # # Cross reference from one object to another # 3 : cross-reference (text, conference, letterbox) { dont-garb = false; inherit = false; inherit-limit = 1; validate = "^[CTP][0-9]+( .*)?$"; } # # Request for no comments to a text # 4 : no-comments (text) { secret = false; hide-creator = false; author-only = true; dont-garb = false; inherit = false; inherit-limit = 1; unique = true; validate = "^$"; } # # Request for personal comments only # 5 : personal-comment (text) { secret = false; hide-creator = false; author-only = true; dont-garb = false; inherit = false; inherit-limit = 1; unique = true; validate = "^$"; } # # Request for read confirmation # 6 : request-confirmation (text) { secret = false; unique = true; author-only = true; dont-garb = false; inherit = false; inherit-limit = 1; hide-creator = false; validate = "^$"; } # # Read confirmation (creator has read the text) # 7 : read-confirm (text) { secret = false; hide-creator = false; dont-garb = false; inherit = false; inherit-limit = 1; permanent = true; validate = "^$"; } # # Request redirect of texts from one conference to another or to e-mail # 8 : redirect (conference, letterbox) { dont-garb = false; supervisor-only = true; owner-delete = true; validate = "^(LysKOM|E-mail):"; inherit = false; inherit-limit = 1; secret = false; hide-creator = false; } # # Graphics in compface format # 9 : x-face (conference, letterbox, server) { secret = false; hide-creator = false; supervisor-only = true; owner-delete = true; dont-garb = false; inherit = false; inherit-limit = 1; } # # Alternate name (subject or name) selected by the creator # 10 : alternate-name (text, conference, letterbox) { dont-garb = false; inherit = false; } # # PGP signature of a text (created with pgp -fsba) # 11 : pgp-signature (text) { permanent = true; hide-creator = false; dont-garb = false; inherit = false; inherit-limit = 1; } # # Public key of a person # 12 : pgp-public-key (letterbox) { author-only = true; owner-delete = true; hide-creator = false; dont-garb = false; inherit = false; inherit-limit = 1; } # # E-mail address of a person or conference # 13 : e-mail-address (conference, letterbox, server) { author-only = true; hide-creator = false; owner-delete = true; dont-garb = false; inherit = false; inherit-limit = 1; } # # FAQ in Text # 14 : faq-text (conference, letterbox, server) { author-only = true; hide-creator = false; secret = false; inherit = false; unique-data = true; owner-delete = true; inherit-limit = 1; add-trigger = link-faq(); validate = "^[1-9][0-9]*$"; validate = existing-readable-text(); } # # Name of the creating software # 15 : creating-software (text) { author-only = true; permanent = true; unique = true; hide-creator = false; dont-garb = false; inherit = false; } # # Name of actual author. # 16 : mx-author (create text) { author-only = true; unique = true; inherit = false; hide-creator = false; dont-garb = false; secret = false; } # # From header of an imported e-mail # 17 : mx-from (text) { author-only = true; unique = false; inherit = false; hide-creator = false; dont-garb = false; secret = false; } # # Reply-To header of an imported e-mail # 18 : mx-reply-to (text) { author-only = true; unique = false; inherit = false; hide-creator = false; dont-garb = false; secret = false; } # # To header of an imported or to-be-exported e-mail # 19 : mx-to (text) { author-only = false; unique = false; inherit = false; hide-creator = false; secret = false; dont-garb = false; } # # CC header of an imported or to-be-exported e-mail # 20 : mx-cc (text) { author-only = false; unique = false; inherit = false; hide-creator = false; secret = false; dont-garb = false; } # # Date header of an imported e-mail # 21 : mx-date (text) { author-only = true; unique = true; inherit = false; hide-creator = false; secret = false; dont-garb = false; validate = "^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]( [-+][0-9][0-9][0-9][0-9])?$"; } # # Message-ID header of an imported e-mail # 22 : mx-message-id (text) { author-only = true; unique = true; inherit = false; hide-creator = false; secret = false; dont-garb = false; } # # In-Reply-To header of an imported e-mail # 23 : mx-in-reply-to (text) { author-only = true; unique = false; inherit = false; hide-creator = false; secret = false; dont-garb = false; } # # All mail headers # 24 : mx-misc (text) { author-only = true; unique = true; inherit = false; hide-creator = false; secret = false; dont-garb = false; } # # Mail filtering or something like that # Nobody quite knows how this will be used, so DON'T! # 25 : mx-allow-filter (conference, letterbox) disabled { author-only = true; unique = false; inherit = false; hide-creator = false; secret = false; dont-garb = false; } # # Mail rejection # Nobody quite knows how this will be used, so DON'T! # 26 : mx-reject-forward (conference, letterbox) disabled { author-only = true; unique = false; inherit = false; hide-creator = false; secret = false; dont-garb = false; } # # Notify user about comments to text # 27 : notify-comments (letterbox) { author-only = true; inherit = false; hide-creator = false; dont-garb = false; validate = "^[0-9]+$"; validate = existing-readable-text(); } # # Mirror of FAQ-text # 28 : faq-for-conf (text) { system-only = true; dont-garb = true; } # # Conferences that new members should be added to automatically. # 29 : recommended-conf (server) { secret = false; hide-creator = false; dont-garb = false; inherit = false; validate = "^[0-9]+(| [0-9]+(| [01]+))$"; } # # Allowed content-types # 30 : allowed-content-type (conference, letterbox, server) { supervisor-only = true; owner-delete = true; secret = false; hide-creator = false; dont-garb = false; inherit = false; validate = "^[0-9]+ [^/ ]*/[^/ ]*$"; } # # The canonical name of a LysKOM server # 31 : canonical-name (server) { supervisor-only = true; unique = true; secret = false; hide-creator = false; dont-garb = false; inherit = false; validate = "^[---A-Za-z0-9.]+(:[0-9]+)?$"; } # # The name of the list imported to this conference # 32 : mx-list-name (conference) { author-only = true; unique = true; owner-delete = true; secret = false; hide-creator = false; dont-garb = false; inherit = false; validate = "^[^@]+@[^@]+$"; } # # Where comments should be sent if the author isn't a member of any # of the recipients. 0 means no special action. # 33 : send-comments-to (letterbox) { author-only = true; unique = true; owner-delete = true; secret = false; hide-creator = false; validate = "^(0|[1-9][0-9]*)( (0|1|15))?$"; } # # Text should be readable without login. # 34 : world-readable (text) { author-only = true; unique = true; owner-delete = true; secret = false; dont-garb = false; hide-creator = false; validate = "^$"; inherit = false; inherit-limit = 1; } # # Should importers refuse to add this conference as a recipient? # 35 : mx-refuse-import (conference, letterbox) { supervisor-only = true; owner-delete = true; secret = false; hide-creator = false; validate = "^(all|spam|html)$"; dont-garb = false; inherit = false; unique = false; } # # The text number of the mail that this mime part belongs to # 10100 : mx-mime-belongs-to (text) { author-only = true; inherit = false; secret = false; hide-creator = false; dont-garb = false; validate = "^[0-9]+$"; validate = existing-readable-text(); } # # The text number of a mime part that belongs to this mail # 10101 : mx-mime-part-in (text) { author-only = true; inherit = false; secret = false; hide-creator = false; dont-garb = false; validate = "^[0-9]+$"; validate = existing-readable-text(); } # # All the mime headers for this imported text # 10102 : mx-mime-misc (text) { author-only = true; inherit = false; secret = false; hide-creator = false; dont-garb = false; unique = true; } # # The envelope sender of this imported text # 10103 : mx-envelope-sender (text) { author-only = true; unique = false; inherit = false; secret = false; hide-creator = false; dont-garb = false; } # # The file name of this mime part # 10104 : mx-mime-file-name (text) { author-only = true; inherit = false; secret = false; hide-creator = false; dont-garb = false; } lyskom-server-2.1.2/db-crypt/0000777000015100472110000000000007723710422011627 5lyskom-server-2.1.2/db-crypt/Makefile.am0000664000015100472110000000204507717413227013610 # $Id: Makefile.am,v 1.5 2003/08/16 11:29:11 ceder Exp $ # Copyright (C) 1998 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # include $(top_srcdir)/scripts/common.make SUBDIRS = db EXTRA_DIST = .cvsignore lyskom-server-2.1.2/db-crypt/Makefile.in0000664000015100472110000003453007723707417013631 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # $Id: Makefile.am,v 1.5 2003/08/16 11:29:11 ceder Exp $ # Copyright (C) 1998 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEBUG_CALLS = @DEBUG_CALLS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EFENCE = @EFENCE@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FLEX = @FLEX@ HAVE_PYTHON_FALSE = @HAVE_PYTHON_FALSE@ HAVE_PYTHON_TRUE = @HAVE_PYTHON_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSURE = @INSURE@ LANGUAGE_SUFFIX = @LANGUAGE_SUFFIX@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ SED = @SED@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRACED_ALLOCATIONS = @TRACED_ALLOCATIONS@ U = @U@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ YACC = @YACC@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ RM = rm -f dbdir = $(localstatedir)/lyskomd/db exportdir = $(localstatedir)/lyskomd/exportdb SUBDIRS = db EXTRA_DIST = .cvsignore subdir = db-crypt ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = DIST_SOURCES = RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \ ps-recursive install-info-recursive uninstall-info-recursive \ all-recursive install-data-recursive install-exec-recursive \ installdirs-recursive install-recursive uninstall-recursive \ check-recursive installcheck-recursive DIST_COMMON = $(top_srcdir)/scripts/common.make Makefile.am Makefile.in DIST_SUBDIRS = $(SUBDIRS) all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/scripts/common.make $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu db-crypt/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) uninstall-info-am: # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @set fnord $$MAKEFLAGS; amf=$$2; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ETAGS = etags ETAGSFLAGS = CTAGS = ctags CTAGSFLAGS = tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if (etags --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ else \ include_option=--include; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -f $$subdir/TAGS && \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$tags$$unique" \ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = .. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) $(mkinstalldirs) $(distdir)/../scripts @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d $(distdir)/$$subdir \ || mkdir $(distdir)/$$subdir \ || exit 1; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" \ distdir=../$(distdir)/$$subdir \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: info: info-recursive info-am: install-data-am: install-exec-am: install-info: install-info-recursive install-man: installcheck-am: maintainer-clean: maintainer-clean-recursive maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-info-am uninstall-info: uninstall-info-recursive .PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \ clean-generic clean-recursive ctags ctags-recursive distclean \ distclean-generic distclean-recursive distclean-tags distdir \ dvi dvi-am dvi-recursive info info-am info-recursive install \ install-am install-data install-data-am install-data-recursive \ install-exec install-exec-am install-exec-recursive \ install-info install-info-am install-info-recursive install-man \ install-recursive install-strip installcheck installcheck-am \ installdirs installdirs-am installdirs-recursive \ maintainer-clean maintainer-clean-generic \ maintainer-clean-recursive mostlyclean mostlyclean-generic \ mostlyclean-recursive pdf pdf-am pdf-recursive ps ps-am \ ps-recursive tags tags-recursive uninstall uninstall-am \ uninstall-info-am uninstall-info-recursive uninstall-recursive # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/db-crypt/.cvsignore0000664000015100472110000000002506551006334013540 Makefile Makefile.in lyskom-server-2.1.2/db-crypt/db/0000777000015100472110000000000007723710423012215 5lyskom-server-2.1.2/db-crypt/db/Makefile.am0000664000015100472110000000473607717413227014206 # $Id: Makefile.am,v 1.11 2003/08/16 11:29:11 ceder Exp $ # Copyright (C) 1998 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # include $(top_srcdir)/scripts/common.make LANGUAGE_SUFFIX=@LANGUAGE_SUFFIX@ # lyskomd-data and lyskomd-texts should be in db_DATA, but we don't # want to install them if they already exist. This is the same # situation that we have in run-support/Makefile.am. db_DATA = EXTRA_DIST = lyskomd-data lyskomd-texts .cvsignore lyskomd-data-en \ number.txt install-data-local: installdirs if test -f $(DESTDIR)$(dbdir)/lyskomd-data \ || test -f $(DESTDIR)$(dbdir)/lyskomd-backup \ || test -f $(DESTDIR)$(dbdir)/lyskomd-texts; \ then \ echo installed database found; \ else \ $(INSTALL_DATA) $(srcdir)/lyskomd-data$(LANGUAGE_SUFFIX) \ $(DESTDIR)$(dbdir)/lyskomd-data || exit 1 ; \ $(INSTALL_DATA) $(srcdir)/lyskomd-texts \ $(DESTDIR)$(dbdir)/lyskomd-texts || exit 1; \ $(INSTALL_DATA) $(srcdir)/number.txt \ $(DESTDIR)$(dbdir)/number.txt || exit 1; \ fi uninstall-local: if cmp $(srcdir)/lyskomd-data$(LANGUAGE_SUFFIX) \ $(DESTDIR)$(dbdir)/lyskomd-data \ && cmp $(srcdir)/lyskomd-texts \ $(DESTDIR)$(dbdir)/lyskomd-texts \ && cmp $(srcdir)/number.txt \ $(DESTDIR)$(dbdir)/number.txt ; \ then \ $(RM) $(DESTDIR)$(dbdir)/lyskomd-data \ $(DESTDIR)$(dbdir)/lyskomd-texts \ $(DESTDIR)$(dbdir)/number.txt; \ else \ echo '*******************************************************' ; \ echo 'Cowardly refusing to uninstall the modified database in' ; \ echo $(DESTDIR)$(dbdir) ; \ echo '*******************************************************' ; \ fi lyskom-server-2.1.2/db-crypt/db/Makefile.in0000664000015100472110000002653207723707420014213 # Makefile.in generated by automake 1.7.6 from Makefile.am. # @configure_input@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # $Id: Makefile.am,v 1.11 2003/08/16 11:29:11 ceder Exp $ # Copyright (C) 1998 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # # Copyright (C) 2003 Lysator Academic Computer Association. # # This file is part of the LysKOM server. # # LysKOM 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 1, or (at your option) # any later version. # # LysKOM 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 LysKOM; see the file COPYING. If not, write to # Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, # or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. # # Please report bugs at http://bugzilla.lysator.liu.se/. # srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BISON = @BISON@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECKER = @CHECKER@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEBUG_CALLS = @DEBUG_CALLS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EFENCE = @EFENCE@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FLEX = @FLEX@ HAVE_PYTHON_FALSE = @HAVE_PYTHON_FALSE@ HAVE_PYTHON_TRUE = @HAVE_PYTHON_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSURE = @INSURE@ LANGUAGE_SUFFIX = @LANGUAGE_SUFFIX@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ SED = @SED@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TRACED_ALLOCATIONS = @TRACED_ALLOCATIONS@ U = @U@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ YACC = @YACC@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ ac_ct_STRIP = @ac_ct_STRIP@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ oldincludedir = @oldincludedir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ RM = rm -f dbdir = $(localstatedir)/lyskomd/db exportdir = $(localstatedir)/lyskomd/exportdb # lyskomd-data and lyskomd-texts should be in db_DATA, but we don't # want to install them if they already exist. This is the same # situation that we have in run-support/Makefile.am. db_DATA = EXTRA_DIST = lyskomd-data lyskomd-texts .cvsignore lyskomd-data-en \ number.txt subdir = db-crypt/db ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = DIST_SOURCES = DATA = $(db_DATA) DIST_COMMON = $(top_srcdir)/scripts/common.make Makefile.am Makefile.in all: all-am .SUFFIXES: $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/scripts/common.make $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && \ $(AUTOMAKE) --gnu db-crypt/db/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) uninstall-info-am: dbDATA_INSTALL = $(INSTALL_DATA) install-dbDATA: $(db_DATA) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(dbdir) @list='$(db_DATA)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f="`echo $$p | sed -e 's|^.*/||'`"; \ echo " $(dbDATA_INSTALL) $$d$$p $(DESTDIR)$(dbdir)/$$f"; \ $(dbDATA_INSTALL) $$d$$p $(DESTDIR)$(dbdir)/$$f; \ done uninstall-dbDATA: @$(NORMAL_UNINSTALL) @list='$(db_DATA)'; for p in $$list; do \ f="`echo $$p | sed -e 's|^.*/||'`"; \ echo " rm -f $(DESTDIR)$(dbdir)/$$f"; \ rm -f $(DESTDIR)$(dbdir)/$$f; \ done tags: TAGS TAGS: ctags: CTAGS CTAGS: DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) top_distdir = ../.. distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) $(mkinstalldirs) $(distdir)/../../scripts @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkinstalldirs) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: $(mkinstalldirs) $(DESTDIR)$(dbdir) install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: info: info-am info-am: install-data-am: install-data-local install-dbDATA install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-dbDATA uninstall-info-am uninstall-local .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am info info-am install \ install-am install-data install-data-am install-data-local \ install-dbDATA install-exec install-exec-am install-info \ install-info-am install-man install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am uninstall uninstall-am uninstall-dbDATA \ uninstall-info-am uninstall-local install-data-local: installdirs if test -f $(DESTDIR)$(dbdir)/lyskomd-data \ || test -f $(DESTDIR)$(dbdir)/lyskomd-backup \ || test -f $(DESTDIR)$(dbdir)/lyskomd-texts; \ then \ echo installed database found; \ else \ $(INSTALL_DATA) $(srcdir)/lyskomd-data$(LANGUAGE_SUFFIX) \ $(DESTDIR)$(dbdir)/lyskomd-data || exit 1 ; \ $(INSTALL_DATA) $(srcdir)/lyskomd-texts \ $(DESTDIR)$(dbdir)/lyskomd-texts || exit 1; \ $(INSTALL_DATA) $(srcdir)/number.txt \ $(DESTDIR)$(dbdir)/number.txt || exit 1; \ fi uninstall-local: if cmp $(srcdir)/lyskomd-data$(LANGUAGE_SUFFIX) \ $(DESTDIR)$(dbdir)/lyskomd-data \ && cmp $(srcdir)/lyskomd-texts \ $(DESTDIR)$(dbdir)/lyskomd-texts \ && cmp $(srcdir)/number.txt \ $(DESTDIR)$(dbdir)/number.txt ; \ then \ $(RM) $(DESTDIR)$(dbdir)/lyskomd-data \ $(DESTDIR)$(dbdir)/lyskomd-texts \ $(DESTDIR)$(dbdir)/number.txt; \ else \ echo '*******************************************************' ; \ echo 'Cowardly refusing to uninstall the modified database in' ; \ echo $(DESTDIR)$(dbdir) ; \ echo '*******************************************************' ; \ fi # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lyskom-server-2.1.2/db-crypt/db/lyskomd-data0000664000015100472110000000140106721776354014457 CLEAN:00002 00000000000000000000 #C 6 #T 1 I 1 2 3 4 0 0 0 * C 1 27HPresentation (av nya) möten 0 * [1] 00001000 684774708 684774708 0 0 0 0 0 0 77 77 0 0 0 * C 2 31HPresentation (av nya) medlemmar 0 * [1] 00001000 684774708 684774708 0 0 0 0 0 0 77 77 0 0 0 * C 3 18HLappar (på) dörren 0 * [1] 00001000 684774708 684774708 0 0 0 0 0 0 77 77 0 0 0 * C 4 17HNyheter om LysKOM 0 * [1] 00001000 684774708 684774708 0 0 0 0 0 0 77 77 0 0 0 * C 5 26HAdministratör (för) LysKOM 1 { 5 5 684774889 00000000 } [1] 10011000 684774889 684774889 5 0 5 0 0 0 77 77 0 0 0 * P 5 64H9gR7fFYRjkjts 20HX(unknown)@localhost 1111111111111111 00000000 [1] 0 * 1 { 684774889 5 255 0 0 * 5 684774889 00000000 } 897463005 0 482 4 0 0 0 0 0 0 lyskom-server-2.1.2/db-crypt/db/lyskomd-texts0000664000015100472110000000000005064155750014675 lyskom-server-2.1.2/db-crypt/db/.cvsignore0000664000015100472110000000002506551747314014137 Makefile Makefile.in lyskom-server-2.1.2/db-crypt/db/lyskomd-data-en0000664000015100472110000000136407374315063015056 CLEAN:00002 00000000000000000000 #C 6 #T 1 I 1 2 3 4 0 0 0 * C 1 31HPresentations (for) conferences 0 * [1] 00001000 684774708 684774708 0 0 0 0 0 0 77 77 0 0 0 * C 2 27HPresentations (for) members 0 * [1] 00001000 684774708 684774708 0 0 0 0 0 0 77 77 0 0 0 * C 3 7HNotices 0 * [1] 00001000 684774708 684774708 0 0 0 0 0 0 77 77 0 0 0 * C 4 17HNews about LysKOM 0 * [1] 00001000 684774708 684774708 0 0 0 0 0 0 77 77 0 0 0 * C 5 25HAdministrator (of) LysKOM 1 { 5 5 684774889 00000000 } [1] 10011000 684774889 684774889 5 0 5 0 0 0 77 77 0 0 0 * P 5 64H9gR7fFYRjkjts 20HX(unknown)@localhost 1111111111111111 00000000 [1] 0 * 1 { 684774889 5 255 0 0 * 5 684774889 00000000 } 897463005 0 482 4 0 0 0 0 0 0 lyskom-server-2.1.2/db-crypt/db/number.txt0000664000015100472110000000003307561600321014153 Text_no: 1 Conf_no: 1 End.